summaryrefslogtreecommitdiff
path: root/chromium/content
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-12-10 16:19:40 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-12-10 16:01:50 +0000
commit51f6c2793adab2d864b3d2b360000ef8db1d3e92 (patch)
tree835b3b4446b012c75e80177cef9fbe6972cc7dbe /chromium/content
parent6036726eb981b6c4b42047513b9d3f4ac865daac (diff)
downloadqtwebengine-chromium-51f6c2793adab2d864b3d2b360000ef8db1d3e92.tar.gz
BASELINE: Update Chromium to 71.0.3578.93
Change-Id: I6a32086c33670e1b033f8b10e6bf1fd4da1d105d Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/content')
-rw-r--r--chromium/content/BUILD.gn2
-rw-r--r--chromium/content/OWNERS1
-rw-r--r--chromium/content/app/android/content_jni_onload.cc28
-rw-r--r--chromium/content/app/content_main_runner_impl.cc64
-rw-r--r--chromium/content/app/content_main_runner_impl.h5
-rw-r--r--chromium/content/app/strings/content_strings.grd56
-rw-r--r--chromium/content/app/strings/translations/content_strings_am.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_ar.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_bg.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_bn.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_ca.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_cs.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_da.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_de.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_el.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_en-GB.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_es-419.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_es.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_et.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_fa.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_fi.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_fil.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_fr.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_gu.xtb28
-rw-r--r--chromium/content/app/strings/translations/content_strings_hi.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_hr.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_hu.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_id.xtb12
-rw-r--r--chromium/content/app/strings/translations/content_strings_it.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_iw.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_ja.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_kn.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_ko.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_lt.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_lv.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_ml.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_mr.xtb18
-rw-r--r--chromium/content/app/strings/translations/content_strings_ms.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_nl.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_no.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_pl.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_pt-BR.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_pt-PT.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_ro.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_ru.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_sk.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_sl.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_sr.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_sv.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_sw.xtb12
-rw-r--r--chromium/content/app/strings/translations/content_strings_ta.xtb12
-rw-r--r--chromium/content/app/strings/translations/content_strings_te.xtb16
-rw-r--r--chromium/content/app/strings/translations/content_strings_th.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_tr.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_uk.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_vi.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_zh-CN.xtb10
-rw-r--r--chromium/content/app/strings/translations/content_strings_zh-TW.xtb10
-rw-r--r--chromium/content/browser/BUILD.gn73
-rw-r--r--chromium/content/browser/DEPS5
-rw-r--r--chromium/content/browser/accessibility/accessibility_action_browsertest.cc38
-rw-r--r--chromium/content/browser/accessibility/accessibility_event_recorder.cc14
-rw-r--r--chromium/content/browser/accessibility/accessibility_event_recorder.h17
-rw-r--r--chromium/content/browser/accessibility/accessibility_event_recorder_auralinux.cc401
-rw-r--r--chromium/content/browser/accessibility/accessibility_event_recorder_mac.mm25
-rw-r--r--chromium/content/browser/accessibility/accessibility_event_recorder_win.cc83
-rw-r--r--chromium/content/browser/accessibility/accessibility_mode_browsertest.cc2
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter.h6
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc192
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc5
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_browser.cc7
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_browser.h3
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm134
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_utils_auralinux.cc238
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_utils_auralinux.h19
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc11
-rw-r--r--chromium/content/browser/accessibility/accessibility_win_browsertest.cc426
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility.cc79
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility.h5
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_android.cc4
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_android.h2
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc155
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_cocoa.mm13
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_com_win.cc8
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_mac.h5
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_mac.mm15
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager.cc44
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager.h9
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_android.cc1
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc82
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h6
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm7
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_win.cc42
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_win.h8
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_position.cc6
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_position.h2
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_state_impl.cc10
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_state_impl.h3
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_state_impl_mac.mm2
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_state_impl_win.cc56
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_unittest.cc66
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_browsertest_base.cc12
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h6
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc60
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc31
-rw-r--r--chromium/content/browser/android/app_web_message_port.cc2
-rw-r--r--chromium/content/browser/android/app_web_message_port.h2
-rw-r--r--chromium/content/browser/android/background_sync_network_observer_android.cc28
-rw-r--r--chromium/content/browser/android/background_sync_network_observer_android.h15
-rw-r--r--chromium/content/browser/android/content_url_loader_factory.cc261
-rw-r--r--chromium/content/browser/android/content_url_loader_factory.h47
-rw-r--r--chromium/content/browser/android/dialog_overlay_impl.cc39
-rw-r--r--chromium/content/browser/android/dialog_overlay_impl.h19
-rw-r--r--chromium/content/browser/android/gesture_listener_manager.cc2
-rw-r--r--chromium/content/browser/android/ime_adapter_android.cc7
-rw-r--r--chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.h9
-rw-r--r--chromium/content/browser/android/java/gin_java_bridge_message_filter.cc17
-rw-r--r--chromium/content/browser/android/java/gin_java_bridge_message_filter.h11
-rw-r--r--chromium/content/browser/android/java/jni_reflect.cc63
-rw-r--r--chromium/content/browser/android/java/jni_reflect.h55
-rw-r--r--chromium/content/browser/android/scoped_surface_request_manager.cc6
-rw-r--r--chromium/content/browser/android/select_popup.cc2
-rw-r--r--chromium/content/browser/android/synchronous_compositor_host.cc6
-rw-r--r--chromium/content/browser/android/synchronous_compositor_sync_call_bridge.cc8
-rw-r--r--chromium/content/browser/android/synchronous_compositor_sync_call_bridge.h14
-rw-r--r--chromium/content/browser/android/text_suggestion_host_android.cc33
-rw-r--r--chromium/content/browser/android/text_suggestion_host_android.h7
-rw-r--r--chromium/content/browser/android/url_request_content_job.h3
-rw-r--r--chromium/content/browser/android/web_contents_observer_proxy.cc15
-rw-r--r--chromium/content/browser/android/web_contents_observer_proxy.h1
-rw-r--r--chromium/content/browser/appcache/appcache.cc4
-rw-r--r--chromium/content/browser/appcache/appcache_database.cc126
-rw-r--r--chromium/content/browser/appcache/appcache_database.h9
-rw-r--r--chromium/content/browser/appcache/appcache_database_unittest.cc475
-rw-r--r--chromium/content/browser/appcache/appcache_disk_cache.cc239
-rw-r--r--chromium/content/browser/appcache/appcache_disk_cache.h115
-rw-r--r--chromium/content/browser/appcache/appcache_disk_cache_unittest.cc14
-rw-r--r--chromium/content/browser/appcache/appcache_frontend_proxy.cc6
-rw-r--r--chromium/content/browser/appcache/appcache_group.cc6
-rw-r--r--chromium/content/browser/appcache/appcache_host.cc4
-rw-r--r--chromium/content/browser/appcache/appcache_internals_ui.cc55
-rw-r--r--chromium/content/browser/appcache/appcache_job.cc23
-rw-r--r--chromium/content/browser/appcache/appcache_job.h34
-rw-r--r--chromium/content/browser/appcache/appcache_manifest_parser.cc574
-rw-r--r--chromium/content/browser/appcache/appcache_manifest_parser.h11
-rw-r--r--chromium/content/browser/appcache/appcache_manifest_parser_unittest.cc3
-rw-r--r--chromium/content/browser/appcache/appcache_navigation_handle.cc6
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler.cc5
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler.h3
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler_unittest.cc5
-rw-r--r--chromium/content/browser/appcache/appcache_response.cc43
-rw-r--r--chromium/content/browser/appcache/appcache_response.h65
-rw-r--r--chromium/content/browser/appcache/appcache_response_unittest.cc74
-rw-r--r--chromium/content/browser/appcache/appcache_service_impl.cc6
-rw-r--r--chromium/content/browser/appcache/appcache_service_unittest.cc3
-rw-r--r--chromium/content/browser/appcache/appcache_storage.cc2
-rw-r--r--chromium/content/browser/appcache/appcache_storage.h11
-rw-r--r--chromium/content/browser/appcache/appcache_storage_impl.cc91
-rw-r--r--chromium/content/browser/appcache/appcache_storage_impl.h10
-rw-r--r--chromium/content/browser/appcache/appcache_storage_impl_unittest.cc2
-rw-r--r--chromium/content/browser/appcache/appcache_update_job.cc36
-rw-r--r--chromium/content/browser/appcache/appcache_update_job.h3
-rw-r--r--chromium/content/browser/appcache/appcache_update_job_unittest.cc173
-rw-r--r--chromium/content/browser/appcache/appcache_update_url_fetcher.cc2
-rw-r--r--chromium/content/browser/appcache/appcache_update_url_request.cc2
-rw-r--r--chromium/content/browser/appcache/appcache_url_loader_job.cc16
-rw-r--r--chromium/content/browser/appcache/appcache_url_request_job.cc20
-rw-r--r--chromium/content/browser/appcache/appcache_url_request_job_unittest.cc21
-rw-r--r--chromium/content/browser/appcache/chrome_appcache_service_unittest.cc6
-rw-r--r--chromium/content/browser/appcache/mock_appcache_storage.cc32
-rw-r--r--chromium/content/browser/appcache/mock_appcache_storage.h9
-rw-r--r--chromium/content/browser/background_fetch/background_fetch.proto6
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_context.cc299
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_context.h58
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_cross_origin_filter.cc2
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_data_manager.cc32
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_data_manager.h16
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_data_manager_observer.h8
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_data_manager_unittest.cc398
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_delegate_proxy.cc97
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_delegate_proxy.h8
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_delegate_proxy_unittest.cc38
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc16
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc26
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_job_controller.cc110
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_job_controller.h45
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_job_controller_unittest.cc103
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_metrics.cc50
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_metrics.h17
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_registration_notifier.cc38
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_registration_notifier.h22
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc113
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_request_info.cc25
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_request_info.h12
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_scheduler.cc50
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_scheduler.h21
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_scheduler_unittest.cc22
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_service_impl.cc17
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_service_impl.h1
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_service_unittest.cc21
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_test_base.cc15
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_test_base.h6
-rw-r--r--chromium/content/browser/background_fetch/mock_background_fetch_delegate.cc22
-rw-r--r--chromium/content/browser/background_fetch/storage/create_metadata_task.cc132
-rw-r--r--chromium/content/browser/background_fetch/storage/create_metadata_task.h4
-rw-r--r--chromium/content/browser/background_fetch/storage/database_helpers.cc14
-rw-r--r--chromium/content/browser/background_fetch/storage/database_helpers.h3
-rw-r--r--chromium/content/browser/background_fetch/storage/get_settled_fetches_task.cc28
-rw-r--r--chromium/content/browser/background_fetch/storage/get_settled_fetches_task.h5
-rw-r--r--chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc10
-rw-r--r--chromium/content/browser/background_fetch/storage/mark_request_complete_task.cc38
-rw-r--r--chromium/content/browser/background_fetch/storage/mark_request_complete_task.h7
-rw-r--r--chromium/content/browser/background_fetch/storage/start_next_pending_request_task.cc61
-rw-r--r--chromium/content/browser/background_fetch/storage/start_next_pending_request_task.h11
-rw-r--r--chromium/content/browser/background_sync/background_sync_browsertest.cc14
-rw-r--r--chromium/content/browser/background_sync/background_sync_context.cc16
-rw-r--r--chromium/content/browser/background_sync/background_sync_manager.cc26
-rw-r--r--chromium/content/browser/background_sync/background_sync_manager_unittest.cc48
-rw-r--r--chromium/content/browser/background_sync/background_sync_network_observer.cc81
-rw-r--r--chromium/content/browser/background_sync/background_sync_network_observer.h54
-rw-r--r--chromium/content/browser/background_sync/background_sync_network_observer_unittest.cc84
-rw-r--r--chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc13
-rw-r--r--chromium/content/browser/bad_message.cc8
-rw-r--r--chromium/content/browser/blob_storage/blob_registry_wrapper.cc6
-rw-r--r--chromium/content/browser/blob_storage/blob_storage_browsertest.cc13
-rw-r--r--chromium/content/browser/blob_storage/blob_url_browsertest.cc10
-rw-r--r--chromium/content/browser/blob_storage/blob_url_unittest.cc5
-rw-r--r--chromium/content/browser/blob_storage/chrome_blob_storage_context.cc20
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.cc2
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc4
-rw-r--r--chromium/content/browser/browser_associated_interface_unittest.cc7
-rw-r--r--chromium/content/browser/browser_child_process_host_impl.cc33
-rw-r--r--chromium/content/browser/browser_context.cc114
-rw-r--r--chromium/content/browser/browser_ipc_logging.cc7
-rw-r--r--chromium/content/browser/browser_main_loop.cc190
-rw-r--r--chromium/content/browser/browser_main_loop.h16
-rw-r--r--chromium/content/browser/browser_main_loop_unittest.cc11
-rw-r--r--chromium/content/browser/browser_main_runner_impl.cc8
-rw-r--r--chromium/content/browser/browser_main_runner_impl.h7
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest.cc30
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest.h6
-rw-r--r--chromium/content/browser/browser_process_sub_thread.cc3
-rw-r--r--chromium/content/browser/browser_thread_impl.cc242
-rw-r--r--chromium/content/browser/browser_thread_impl.h9
-rw-r--r--chromium/content/browser/browser_thread_unittest.cc49
-rw-r--r--chromium/content/browser/browsing_data/OWNERS1
-rw-r--r--chromium/content/browser/browsing_data/browsing_data_filter_builder_impl.cc2
-rw-r--r--chromium/content/browser/browsing_data/browsing_data_remover_impl.cc6
-rw-r--r--chromium/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc10
-rw-r--r--chromium/content/browser/browsing_data/clear_site_data_handler.cc2
-rw-r--r--chromium/content/browser/browsing_data/clear_site_data_handler_browsertest.cc21
-rw-r--r--chromium/content/browser/browsing_data/clear_site_data_throttle.cc14
-rw-r--r--chromium/content/browser/browsing_data/clear_site_data_throttle_unittest.cc5
-rw-r--r--chromium/content/browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc10
-rw-r--r--chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.cc53
-rw-r--r--chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.h3
-rw-r--r--chromium/content/browser/browsing_instance.cc31
-rw-r--r--chromium/content/browser/browsing_instance.h8
-rw-r--r--chromium/content/browser/byte_stream.h4
-rw-r--r--chromium/content/browser/byte_stream_unittest.cc66
-rw-r--r--chromium/content/browser/cache_storage/cache_storage.cc16
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc14
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h1
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc5
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache.cc168
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache.h10
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc108
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_context_impl.cc13
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc9
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_histogram_utils.cc14
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_histogram_utils.h (renamed from chromium/content/browser/cache_storage/cache_storage_histogram_macros.h)37
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_manager.cc2
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc4
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_operation.cc2
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_scheduler.cc2
-rw-r--r--chromium/content/browser/child_process_launcher_helper.cc5
-rw-r--r--chromium/content/browser/child_process_launcher_helper_android.cc6
-rw-r--r--chromium/content/browser/child_process_launcher_helper_mac.cc40
-rw-r--r--chromium/content/browser/child_process_security_policy_browsertest.cc33
-rw-r--r--chromium/content/browser/child_process_security_policy_impl.cc211
-rw-r--r--chromium/content/browser/child_process_security_policy_impl.h57
-rw-r--r--chromium/content/browser/child_process_security_policy_unittest.cc86
-rw-r--r--chromium/content/browser/cocoa/system_hotkey_helper_mac.mm9
-rw-r--r--chromium/content/browser/code_cache/generated_code_cache.cc76
-rw-r--r--chromium/content/browser/code_cache/generated_code_cache.h23
-rw-r--r--chromium/content/browser/code_cache/generated_code_cache_context.cc23
-rw-r--r--chromium/content/browser/code_cache/generated_code_cache_context.h9
-rw-r--r--chromium/content/browser/code_cache/generated_code_cache_unittest.cc66
-rw-r--r--chromium/content/browser/compositor/gpu_process_transport_factory.cc46
-rw-r--r--chromium/content/browser/compositor/gpu_process_transport_factory.h2
-rw-r--r--chromium/content/browser/compositor/reflector_impl_unittest.cc7
-rw-r--r--chromium/content/browser/compositor/viz_process_transport_factory.cc26
-rw-r--r--chromium/content/browser/compositor/viz_process_transport_factory.h4
-rw-r--r--chromium/content/browser/content_service_browsertest.cc96
-rw-r--r--chromium/content/browser/content_service_delegate_impl.cc59
-rw-r--r--chromium/content/browser/content_service_delegate_impl.h1
-rw-r--r--chromium/content/browser/cookie_store/cookie_store_context.cc16
-rw-r--r--chromium/content/browser/cookie_store/cookie_store_manager_unittest.cc2
-rw-r--r--chromium/content/browser/devtools/browser_devtools_agent_host.cc4
-rw-r--r--chromium/content/browser/devtools/devtools_agent_host_impl.cc45
-rw-r--r--chromium/content/browser/devtools/devtools_agent_host_impl.h28
-rw-r--r--chromium/content/browser/devtools/devtools_http_handler.cc35
-rw-r--r--chromium/content/browser/devtools/devtools_http_handler_unittest.cc7
-rw-r--r--chromium/content/browser/devtools/devtools_interceptor_controller.cc22
-rw-r--r--chromium/content/browser/devtools/devtools_network_interceptor.cc9
-rw-r--r--chromium/content/browser/devtools/devtools_network_interceptor.h5
-rw-r--r--chromium/content/browser/devtools/devtools_pipe_handler.cc9
-rw-r--r--chromium/content/browser/devtools/devtools_renderer_channel.cc57
-rw-r--r--chromium/content/browser/devtools/devtools_renderer_channel.h55
-rw-r--r--chromium/content/browser/devtools/devtools_session.cc30
-rw-r--r--chromium/content/browser/devtools/devtools_session.h44
-rw-r--r--chromium/content/browser/devtools/devtools_stream_blob.cc39
-rw-r--r--chromium/content/browser/devtools/devtools_stream_file.cc9
-rw-r--r--chromium/content/browser/devtools/devtools_url_interceptor_request_job.cc86
-rw-r--r--chromium/content/browser/devtools/devtools_url_interceptor_request_job.h1
-rw-r--r--chromium/content/browser/devtools/devtools_url_loader_interceptor.cc97
-rw-r--r--chromium/content/browser/devtools/devtools_url_request_interceptor.cc22
-rw-r--r--chromium/content/browser/devtools/devtools_video_consumer.cc4
-rw-r--r--chromium/content/browser/devtools/devtools_video_consumer_unittest.cc9
-rw-r--r--chromium/content/browser/devtools/forwarding_agent_host.cc3
-rw-r--r--chromium/content/browser/devtools/forwarding_agent_host.h2
-rw-r--r--chromium/content/browser/devtools/protocol/browser_handler.cc5
-rw-r--r--chromium/content/browser/devtools/protocol/browser_handler.h2
-rw-r--r--chromium/content/browser/devtools/protocol/devtools_download_manager_delegate.cc7
-rw-r--r--chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc43
-rw-r--r--chromium/content/browser/devtools/protocol/devtools_protocol_test_support.cc2
-rw-r--r--chromium/content/browser/devtools/protocol/devtools_protocol_test_support.h12
-rw-r--r--chromium/content/browser/devtools/protocol/emulation_handler.cc26
-rw-r--r--chromium/content/browser/devtools/protocol/input_handler.cc5
-rw-r--r--chromium/content/browser/devtools/protocol/inspector_handler.cc6
-rw-r--r--chromium/content/browser/devtools/protocol/memory_handler.cc2
-rw-r--r--chromium/content/browser/devtools/protocol/network_handler.cc129
-rw-r--r--chromium/content/browser/devtools/protocol/page_handler.cc39
-rw-r--r--chromium/content/browser/devtools/protocol/page_handler.h3
-rw-r--r--chromium/content/browser/devtools/protocol/security_handler.cc5
-rw-r--r--chromium/content/browser/devtools/protocol/service_worker_handler.cc24
-rw-r--r--chromium/content/browser/devtools/protocol/storage_handler.cc44
-rw-r--r--chromium/content/browser/devtools/protocol/system_info_handler.cc10
-rw-r--r--chromium/content/browser/devtools/protocol/target_handler.cc112
-rw-r--r--chromium/content/browser/devtools/protocol/target_handler.h14
-rw-r--r--chromium/content/browser/devtools/protocol/tethering_handler.cc28
-rw-r--r--chromium/content/browser/devtools/protocol/tracing_handler.cc38
-rw-r--r--chromium/content/browser/devtools/protocol_config.json2
-rw-r--r--chromium/content/browser/devtools/render_frame_devtools_agent_host.cc99
-rw-r--r--chromium/content/browser/devtools/render_frame_devtools_agent_host.h8
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_agent_host.cc60
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_agent_host.h13
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_manager.cc10
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_manager.h1
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_agent_host.cc41
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_agent_host.h14
-rw-r--r--chromium/content/browser/do_not_track_browsertest.cc165
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_area_unittest.cc4
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_impl.cc6
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_impl_unittest.cc4
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_wrapper.cc28
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_wrapper.h7
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_database.cc2
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_database_unittest.cc2
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_namespace.cc6
-rw-r--r--chromium/content/browser/dom_storage/session_storage_context_mojo.cc3
-rw-r--r--chromium/content/browser/dom_storage/session_storage_database.cc4
-rw-r--r--chromium/content/browser/dom_storage/session_storage_database.h9
-rw-r--r--chromium/content/browser/dom_storage/session_storage_database_unittest.cc3
-rw-r--r--chromium/content/browser/dom_storage/session_storage_metadata.cc8
-rw-r--r--chromium/content/browser/dom_storage/session_storage_namespace_impl.cc12
-rw-r--r--chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo_unittest.cc5
-rw-r--r--chromium/content/browser/dom_storage/storage_area_impl.cc4
-rw-r--r--chromium/content/browser/download/download_browsertest.cc100
-rw-r--r--chromium/content/browser/download/download_manager_impl.cc43
-rw-r--r--chromium/content/browser/download/download_manager_impl_unittest.cc3
-rw-r--r--chromium/content/browser/download/download_request_core.cc9
-rw-r--r--chromium/content/browser/download/download_request_core.h7
-rw-r--r--chromium/content/browser/download/download_request_core_unittest.cc11
-rw-r--r--chromium/content/browser/download/download_request_handle.cc14
-rw-r--r--chromium/content/browser/download/download_request_utils.cc6
-rw-r--r--chromium/content/browser/download/download_resource_handler.cc28
-rw-r--r--chromium/content/browser/download/download_utils.cc11
-rw-r--r--chromium/content/browser/download/download_utils.h10
-rw-r--r--chromium/content/browser/download/drag_download_file.cc16
-rw-r--r--chromium/content/browser/download/drag_download_file_browsertest.cc6
-rw-r--r--chromium/content/browser/download/drag_download_util.cc12
-rw-r--r--chromium/content/browser/download/mhtml_generation_browsertest.cc19
-rw-r--r--chromium/content/browser/download/save_file_manager.cc24
-rw-r--r--chromium/content/browser/download/save_package.cc4
-rw-r--r--chromium/content/browser/download/url_downloader.cc10
-rw-r--r--chromium/content/browser/download/url_downloader_factory.cc5
-rw-r--r--chromium/content/browser/download/url_downloader_factory.h8
-rw-r--r--chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc4
-rw-r--r--chromium/content/browser/file_url_loader_factory.cc40
-rw-r--r--chromium/content/browser/fileapi/README.md23
-rw-r--r--chromium/content/browser/fileapi/browser_file_system_helper.cc5
-rw-r--r--chromium/content/browser/fileapi/file_system_browsertest.cc6
-rw-r--r--chromium/content/browser/fileapi/file_system_chooser.cc164
-rw-r--r--chromium/content/browser/fileapi/file_system_chooser.h17
-rw-r--r--chromium/content/browser/fileapi/file_system_chooser_browsertest.cc195
-rw-r--r--chromium/content/browser/fileapi/file_system_chooser_test_helpers.cc126
-rw-r--r--chromium/content/browser/fileapi/file_system_chooser_test_helpers.h60
-rw-r--r--chromium/content/browser/fileapi/file_system_chooser_unittest.cc168
-rw-r--r--chromium/content/browser/fileapi/file_system_manager_impl.cc31
-rw-r--r--chromium/content/browser/fileapi/file_system_manager_impl.h13
-rw-r--r--chromium/content/browser/fileapi/file_system_url_loader_factory.cc6
-rw-r--r--chromium/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc6
-rw-r--r--chromium/content/browser/find_request_manager.cc86
-rw-r--r--chromium/content/browser/find_request_manager.h15
-rw-r--r--chromium/content/browser/find_request_manager_browsertest.cc166
-rw-r--r--chromium/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc58
-rw-r--r--chromium/content/browser/font_unique_name_lookup/font_unique_name_lookup_service.cc10
-rw-r--r--chromium/content/browser/frame_host/cross_process_frame_connector.cc136
-rw-r--r--chromium/content/browser/frame_host/cross_process_frame_connector.h38
-rw-r--r--chromium/content/browser/frame_host/debug_urls.cc15
-rw-r--r--chromium/content/browser/frame_host/form_submission_throttle.cc14
-rw-r--r--chromium/content/browser/frame_host/form_submission_throttle.h2
-rw-r--r--chromium/content/browser/frame_host/frame_tree.cc27
-rw-r--r--chromium/content/browser/frame_host/frame_tree.h17
-rw-r--r--chromium/content/browser/frame_host/frame_tree_browsertest.cc24
-rw-r--r--chromium/content/browser/frame_host/frame_tree_node.cc96
-rw-r--r--chromium/content/browser/frame_host/frame_tree_node.h34
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_impl.cc12
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_impl.h3
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_navigator_impl.cc10
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_navigator_impl.h5
-rw-r--r--chromium/content/browser/frame_host/keep_alive_handle_factory.cc6
-rw-r--r--chromium/content/browser/frame_host/mixed_content_navigation_throttle.cc25
-rw-r--r--chromium/content/browser/frame_host/mixed_content_navigation_throttle.h4
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl.cc38
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl.h5
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc100
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc46
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_impl.cc13
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_impl.h3
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl.cc132
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl.h36
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl_browsertest.cc53
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc16
-rw-r--r--chromium/content/browser/frame_host/navigation_request.cc163
-rw-r--r--chromium/content/browser/frame_host/navigation_request.h18
-rw-r--r--chromium/content/browser/frame_host/navigator.cc3
-rw-r--r--chromium/content/browser/frame_host/navigator.h10
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.cc57
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.h8
-rw-r--r--chromium/content/browser/frame_host/navigator_impl_unittest.cc2
-rw-r--r--chromium/content/browser/frame_host/origin_policy_throttle.cc62
-rw-r--r--chromium/content/browser/frame_host/origin_policy_throttle.h17
-rw-r--r--chromium/content/browser/frame_host/origin_policy_throttle_unittest.cc4
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_delegate.cc8
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_delegate.h21
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_factory.cc11
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_factory.h3
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl.cc602
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl.h121
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc118
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager.cc141
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager.h22
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc25
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc12
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter.cc134
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter.h6
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc6
-rw-r--r--chromium/content/browser/frame_host/render_frame_proxy_host.cc8
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest.cc17
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest.h4
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc51
-rw-r--r--chromium/content/browser/frame_host/webui_navigation_browsertest.cc49
-rw-r--r--chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc37
-rw-r--r--chromium/content/browser/gpu/browser_gpu_channel_host_factory.h5
-rw-r--r--chromium/content/browser/gpu/browser_gpu_client_delegate.cc59
-rw-r--r--chromium/content/browser/gpu/browser_gpu_client_delegate.h5
-rw-r--r--chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc10
-rw-r--r--chromium/content/browser/gpu/compositor_util.cc10
-rw-r--r--chromium/content/browser/gpu/compositor_util.h3
-rw-r--r--chromium/content/browser/gpu/delegate_to_browser_gpu_service_accelerator_factory.cc16
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl.cc18
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl.h34
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private.cc180
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private.h32
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc71
-rw-r--r--chromium/content/browser/gpu/gpu_internals_ui.cc9
-rw-r--r--chromium/content/browser/gpu/gpu_ipc_browsertests.cc6
-rw-r--r--chromium/content/browser/gpu/gpu_memory_buffer_manager_singleton.cc8
-rw-r--r--chromium/content/browser/gpu/gpu_process_host.cc222
-rw-r--r--chromium/content/browser/gpu/gpu_process_host.h37
-rw-r--r--chromium/content/browser/gpu/in_process_gpu_thread_browsertests.cc8
-rw-r--r--chromium/content/browser/gpu/video_capture_dependencies.cc (renamed from chromium/content/browser/renderer_host/media/video_capture_dependencies.cc)13
-rw-r--r--chromium/content/browser/gpu/video_capture_dependencies.h (renamed from chromium/content/browser/renderer_host/media/video_capture_dependencies.h)9
-rw-r--r--chromium/content/browser/gpu_interface_provider.cc96
-rw-r--r--chromium/content/browser/gpu_interface_provider.h40
-rw-r--r--chromium/content/browser/histogram_controller.cc14
-rw-r--r--chromium/content/browser/histogram_synchronizer.cc22
-rw-r--r--chromium/content/browser/histogram_synchronizer.h8
-rw-r--r--chromium/content/browser/host_zoom_map_impl.cc10
-rw-r--r--chromium/content/browser/host_zoom_map_impl_unittest.cc9
-rw-r--r--chromium/content/browser/hyphenation/hyphenation_impl.cc18
-rw-r--r--chromium/content/browser/image_capture/image_capture_impl.cc14
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_active_blob_registry.cc6
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_backing_store.cc57
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_backing_store.h19
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc33
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_browsertest.cc300
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_callbacks.cc64
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc33
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_context_impl.cc57
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_context_impl.h15
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_database_callbacks.cc32
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc25
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_dispatcher_host.h2
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc42
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory.h25
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_impl.cc79
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_impl.h18
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc42
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_fake_backing_store.cc3
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_internals_ui.cc17
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.cc4
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_unittest.cc8
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_database.cc2
-rw-r--r--chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc2
-rw-r--r--chromium/content/browser/indexed_db/mock_indexed_db_factory.h70
-rw-r--r--chromium/content/browser/initiator_csp_context.cc24
-rw-r--r--chromium/content/browser/initiator_csp_context.h10
-rw-r--r--chromium/content/browser/interface_provider_filtering.cc6
-rw-r--r--chromium/content/browser/isolated_origin_browsertest.cc36
-rw-r--r--chromium/content/browser/isolated_origin_util.cc2
-rw-r--r--chromium/content/browser/loader/cors_file_origin_browsertest.cc175
-rw-r--r--chromium/content/browser/loader/cors_origin_access_list_browsertest.cc285
-rw-r--r--chromium/content/browser/loader/cross_site_document_blocking_browsertest.cc153
-rw-r--r--chromium/content/browser/loader/cross_site_document_resource_handler.cc36
-rw-r--r--chromium/content/browser/loader/cross_site_document_resource_handler_unittest.cc158
-rw-r--r--chromium/content/browser/loader/data_pipe_to_source_stream.cc2
-rw-r--r--chromium/content/browser/loader/data_pipe_to_source_stream_unittest.cc3
-rw-r--r--chromium/content/browser/loader/detachable_resource_handler.cc8
-rw-r--r--chromium/content/browser/loader/intercepting_resource_handler.cc4
-rw-r--r--chromium/content/browser/loader/intercepting_resource_handler.h2
-rw-r--r--chromium/content/browser/loader/loader_browsertest.cc36
-rw-r--r--chromium/content/browser/loader/loader_io_thread_notifier.cc6
-rw-r--r--chromium/content/browser/loader/merkle_integrity_source_stream_unittest.cc2
-rw-r--r--chromium/content/browser/loader/mime_sniffing_resource_handler.cc4
-rw-r--r--chromium/content/browser/loader/mime_sniffing_resource_handler.h17
-rw-r--r--chromium/content/browser/loader/mime_sniffing_resource_handler_unittest.cc17
-rw-r--r--chromium/content/browser/loader/mojo_async_resource_handler.cc3
-rw-r--r--chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc3
-rw-r--r--chromium/content/browser/loader/navigation_loader_interceptor.cc3
-rw-r--r--chromium/content/browser/loader/navigation_loader_interceptor.h8
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl.cc337
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl_unittest.cc9
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_unittest.cc3
-rw-r--r--chromium/content/browser/loader/prefetch_browsertest.cc39
-rw-r--r--chromium/content/browser/loader/prefetch_url_loader.cc54
-rw-r--r--chromium/content/browser/loader/prefetch_url_loader.h10
-rw-r--r--chromium/content/browser/loader/prefetch_url_loader_service.cc20
-rw-r--r--chromium/content/browser/loader/prefetch_url_loader_service.h17
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_impl.cc75
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_impl.h14
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_unittest.cc169
-rw-r--r--chromium/content/browser/loader/resource_hints_impl.cc109
-rw-r--r--chromium/content/browser/loader/resource_message_filter.cc6
-rw-r--r--chromium/content/browser/loader/resource_message_filter.h6
-rw-r--r--chromium/content/browser/loader/resource_request_info_impl.cc27
-rw-r--r--chromium/content/browser/loader/resource_request_info_impl.h12
-rw-r--r--chromium/content/browser/loader/shared_cors_origin_access_list_impl.cc51
-rw-r--r--chromium/content/browser/loader/shared_cors_origin_access_list_impl.h43
-rw-r--r--chromium/content/browser/loader/stream_writer.cc2
-rw-r--r--chromium/content/browser/loader/test_resource_handler.cc2
-rw-r--r--chromium/content/browser/loader/throttling_resource_handler_unittest.cc8
-rw-r--r--chromium/content/browser/loader/upload_data_stream_builder_unittest.cc8
-rw-r--r--chromium/content/browser/loader/url_loader_factory_impl_unittest.cc7
-rw-r--r--chromium/content/browser/mach_broker_mac.mm6
-rw-r--r--chromium/content/browser/manifest/manifest_icon_downloader.cc10
-rw-r--r--chromium/content/browser/media/android/browser_gpu_video_accelerator_factories.cc210
-rw-r--r--chromium/content/browser/media/android/browser_gpu_video_accelerator_factories.h76
-rw-r--r--chromium/content/browser/media/android/media_player_renderer.cc6
-rw-r--r--chromium/content/browser/media/android/media_resource_getter_impl.cc14
-rw-r--r--chromium/content/browser/media/audio_input_stream_broker.cc92
-rw-r--r--chromium/content/browser/media/audio_input_stream_broker.h6
-rw-r--r--chromium/content/browser/media/audio_input_stream_broker_unittest.cc4
-rw-r--r--chromium/content/browser/media/audio_loopback_stream_broker.cc91
-rw-r--r--chromium/content/browser/media/audio_loopback_stream_broker.h24
-rw-r--r--chromium/content/browser/media/audio_loopback_stream_broker_unittest.cc60
-rw-r--r--chromium/content/browser/media/audio_output_stream_broker.cc116
-rw-r--r--chromium/content/browser/media/audio_output_stream_broker.h15
-rw-r--r--chromium/content/browser/media/audio_stream_broker.cc47
-rw-r--r--chromium/content/browser/media/audio_stream_broker.h78
-rw-r--r--chromium/content/browser/media/audio_stream_monitor.cc14
-rw-r--r--chromium/content/browser/media/capture/audio_mirroring_manager.cc8
-rw-r--r--chromium/content/browser/media/capture/audio_mirroring_manager_unittest.cc13
-rw-r--r--chromium/content/browser/media/capture/aura_window_video_capture_device.cc10
-rw-r--r--chromium/content/browser/media/capture/aura_window_video_capture_device_browsertest.cc14
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device.cc6
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device_unittest.cc19
-rw-r--r--chromium/content/browser/media/capture/desktop_streams_registry_impl.cc8
-rw-r--r--chromium/content/browser/media/capture/fake_video_capture_stack.cc2
-rw-r--r--chromium/content/browser/media/capture/frame_sink_video_capture_device.cc18
-rw-r--r--chromium/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc13
-rw-r--r--chromium/content/browser/media/capture/lame_window_capturer_chromeos.cc8
-rw-r--r--chromium/content/browser/media/capture/lame_window_capturer_chromeos.h2
-rw-r--r--chromium/content/browser/media/capture/mouse_cursor_overlay_controller_browsertest.cc7
-rw-r--r--chromium/content/browser/media/capture/screen_capture_device_android_unittest.cc17
-rw-r--r--chromium/content/browser/media/capture/web_contents_audio_input_stream.cc35
-rw-r--r--chromium/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc6
-rw-r--r--chromium/content/browser/media/capture/web_contents_audio_muter.cc14
-rw-r--r--chromium/content/browser/media/capture/web_contents_tracker.cc13
-rw-r--r--chromium/content/browser/media/capture/web_contents_video_capture_device.cc14
-rw-r--r--chromium/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc14
-rw-r--r--chromium/content/browser/media/cdm_storage_impl.cc2
-rw-r--r--chromium/content/browser/media/encrypted_media_browsertest.cc42
-rw-r--r--chromium/content/browser/media/forwarding_audio_stream_factory.cc344
-rw-r--r--chromium/content/browser/media/forwarding_audio_stream_factory.h246
-rw-r--r--chromium/content/browser/media/forwarding_audio_stream_factory_unittest.cc272
-rw-r--r--chromium/content/browser/media/in_process_audio_loopback_stream_creator.cc113
-rw-r--r--chromium/content/browser/media/media_browsertest.cc3
-rw-r--r--chromium/content/browser/media/media_browsertest.h4
-rw-r--r--chromium/content/browser/media/media_color_browsertest.cc5
-rw-r--r--chromium/content/browser/media/media_devices_permission_checker.cc10
-rw-r--r--chromium/content/browser/media/media_devices_util.cc6
-rw-r--r--chromium/content/browser/media/media_internals.cc171
-rw-r--r--chromium/content/browser/media/media_internals.h24
-rw-r--r--chromium/content/browser/media/media_internals_proxy.cc14
-rw-r--r--chromium/content/browser/media/media_internals_unittest.cc138
-rw-r--r--chromium/content/browser/media/media_source_browsertest.cc12
-rw-r--r--chromium/content/browser/media/media_suspend_browsertest.cc6
-rw-r--r--chromium/content/browser/media/media_web_contents_observer.cc21
-rw-r--r--chromium/content/browser/media/media_web_contents_observer.h6
-rw-r--r--chromium/content/browser/media/midi_host_unittest.cc7
-rw-r--r--chromium/content/browser/media/session/audio_focus_delegate.h23
-rw-r--r--chromium/content/browser/media/session/audio_focus_delegate_android.cc13
-rw-r--r--chromium/content/browser/media/session/audio_focus_delegate_android.h9
-rw-r--r--chromium/content/browser/media/session/audio_focus_delegate_default.cc131
-rw-r--r--chromium/content/browser/media/session/audio_focus_delegate_default_browsertest.cc162
-rw-r--r--chromium/content/browser/media/session/audio_focus_manager.cc173
-rw-r--r--chromium/content/browser/media/session/audio_focus_manager.h76
-rw-r--r--chromium/content/browser/media/session/audio_focus_manager_unittest.cc550
-rw-r--r--chromium/content/browser/media/session/audio_focus_observer.cc43
-rw-r--r--chromium/content/browser/media/session/audio_focus_observer.h9
-rw-r--r--chromium/content/browser/media/session/media_session_android.cc6
-rw-r--r--chromium/content/browser/media/session/media_session_browsertest.cc18
-rw-r--r--chromium/content/browser/media/session/media_session_controllers_manager_unittest.cc5
-rw-r--r--chromium/content/browser/media/session/media_session_impl.cc269
-rw-r--r--chromium/content/browser/media/session/media_session_impl.h145
-rw-r--r--chromium/content/browser/media/session/media_session_impl_browsertest.cc624
-rw-r--r--chromium/content/browser/media/session/media_session_impl_uma_unittest.cc22
-rw-r--r--chromium/content/browser/media/session/media_session_impl_unittest.cc427
-rw-r--r--chromium/content/browser/media/webaudio/audio_context_manager_browsertest.cc65
-rw-r--r--chromium/content/browser/media/webaudio/audio_context_manager_impl.cc60
-rw-r--r--chromium/content/browser/media/webaudio/audio_context_manager_impl.h22
-rw-r--r--chromium/content/browser/media/webaudio/audio_context_manager_impl_unittest.cc102
-rw-r--r--chromium/content/browser/memory/memory_coordinator_impl_browsertest.cc6
-rw-r--r--chromium/content/browser/memory/memory_monitor_android.cc25
-rw-r--r--chromium/content/browser/memory/memory_monitor_android.h4
-rw-r--r--chromium/content/browser/memory/memory_monitor_win.cc6
-rw-r--r--chromium/content/browser/message_port_provider.cc2
-rw-r--r--chromium/content/browser/mojo_sandbox_browsertest.cc10
-rw-r--r--chromium/content/browser/navigation_browsertest.cc (renamed from chromium/content/browser/browser_side_navigation_browsertest.cc)252
-rw-r--r--chromium/content/browser/net/network_quality_observer_impl.cc179
-rw-r--r--chromium/content/browser/net/network_quality_observer_impl.h36
-rw-r--r--chromium/content/browser/net/network_quality_observer_impl_unittest.cc23
-rw-r--r--chromium/content/browser/net/quota_policy_cookie_store.cc5
-rw-r--r--chromium/content/browser/net_info_browsertest.cc202
-rw-r--r--chromium/content/browser/network_service_browsertest.cc116
-rw-r--r--chromium/content/browser/network_service_client.cc105
-rw-r--r--chromium/content/browser/network_service_client.h15
-rw-r--r--chromium/content/browser/network_service_instance.cc131
-rw-r--r--chromium/content/browser/network_service_restart_browsertest.cc394
-rw-r--r--chromium/content/browser/notification_service_impl.cc3
-rw-r--r--chromium/content/browser/notifications/blink_notification_service_impl.cc83
-rw-r--r--chromium/content/browser/notifications/blink_notification_service_impl.h32
-rw-r--r--chromium/content/browser/notifications/blink_notification_service_impl_unittest.cc196
-rw-r--r--chromium/content/browser/notifications/notification_database.cc10
-rw-r--r--chromium/content/browser/notifications/notification_database_data.proto6
-rw-r--r--chromium/content/browser/notifications/notification_database_data_conversions.cc32
-rw-r--r--chromium/content/browser/notifications/notification_database_data_unittest.cc38
-rw-r--r--chromium/content/browser/notifications/notification_database_unittest.cc8
-rw-r--r--chromium/content/browser/notifications/notification_event_dispatcher_impl.cc20
-rw-r--r--chromium/content/browser/notifications/notification_id_generator.cc2
-rw-r--r--chromium/content/browser/notifications/platform_notification_context_impl.cc59
-rw-r--r--chromium/content/browser/notifications/platform_notification_context_unittest.cc6
-rw-r--r--chromium/content/browser/ns_view_bridge_factory_host.mm51
-rw-r--r--chromium/content/browser/ns_view_bridge_factory_impl.mm63
-rw-r--r--chromium/content/browser/oop_browsertest.cc10
-rw-r--r--chromium/content/browser/payments/payment_app_content_unittest_base.cc5
-rw-r--r--chromium/content/browser/payments/payment_app_context_impl.cc14
-rw-r--r--chromium/content/browser/payments/payment_app_info_fetcher.cc13
-rw-r--r--chromium/content/browser/payments/payment_app_installer.cc30
-rw-r--r--chromium/content/browser/payments/payment_app_provider_impl.cc70
-rw-r--r--chromium/content/browser/payments/payment_instrument_icon_fetcher.cc19
-rw-r--r--chromium/content/browser/permissions/permission_service_impl.cc3
-rw-r--r--chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc28
-rw-r--r--chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h5
-rw-r--r--chromium/content/browser/plugin_data_remover_impl.cc14
-rw-r--r--chromium/content/browser/plugin_private_storage_helper.cc17
-rw-r--r--chromium/content/browser/plugin_service_impl.cc10
-rw-r--r--chromium/content/browser/plugin_service_impl_browsertest.cc6
-rw-r--r--chromium/content/browser/pointer_lock_browsertest.cc49
-rw-r--r--chromium/content/browser/portal/portal.cc32
-rw-r--r--chromium/content/browser/portal/portal.h2
-rw-r--r--chromium/content/browser/portal/portal_browsertest.cc139
-rw-r--r--chromium/content/browser/power_monitor_browsertest.cc10
-rw-r--r--chromium/content/browser/ppapi_plugin_process_host.cc30
-rw-r--r--chromium/content/browser/presentation/presentation_service_impl_unittest.cc6
-rw-r--r--chromium/content/browser/process_internals/BUILD.gn4
-rw-r--r--chromium/content/browser/process_internals/process_internals.mojom35
-rw-r--r--chromium/content/browser/process_internals/process_internals_handler_impl.cc64
-rw-r--r--chromium/content/browser/process_internals/process_internals_handler_impl.h3
-rw-r--r--chromium/content/browser/process_internals/process_internals_ui.cc14
-rw-r--r--chromium/content/browser/process_internals/process_internals_ui.h5
-rw-r--r--chromium/content/browser/push_messaging/push_messaging_manager.cc60
-rw-r--r--chromium/content/browser/push_messaging/push_messaging_router.cc10
-rw-r--r--chromium/content/browser/quota_dispatcher_host.cc20
-rw-r--r--chromium/content/browser/renderer_host/browser_compositor_view_mac.h1
-rw-r--r--chromium/content/browser/renderer_host/browser_compositor_view_mac.mm4
-rw-r--r--chromium/content/browser/renderer_host/clipboard_host_impl.cc22
-rw-r--r--chromium/content/browser/renderer_host/clipboard_host_impl.h6
-rw-r--r--chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc65
-rw-r--r--chromium/content/browser/renderer_host/code_cache_host_impl.cc239
-rw-r--r--chromium/content/browser/renderer_host/code_cache_host_impl.h104
-rw-r--r--chromium/content/browser/renderer_host/compositor_impl_android.cc212
-rw-r--r--chromium/content/browser/renderer_host/compositor_impl_android.h18
-rw-r--r--chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc2
-rw-r--r--chromium/content/browser/renderer_host/delegated_frame_host.cc124
-rw-r--r--chromium/content/browser/renderer_host/delegated_frame_host.h17
-rw-r--r--chromium/content/browser/renderer_host/delegated_frame_host_client_aura.cc4
-rw-r--r--chromium/content/browser/renderer_host/delegated_frame_host_client_aura.h1
-rw-r--r--chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win_unittest.cc22
-rw-r--r--chromium/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc4
-rw-r--r--chromium/content/browser/renderer_host/hit_test_debug_key_event_observer.cc76
-rw-r--r--chromium/content/browser/renderer_host/hit_test_debug_key_event_observer.h40
-rw-r--r--chromium/content/browser/renderer_host/input/OWNERS1
-rw-r--r--chromium/content/browser/renderer_host/input/autoscroll_browsertest.cc163
-rw-r--r--chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc22
-rw-r--r--chromium/content/browser/renderer_host/input/fling_browsertest.cc32
-rw-r--r--chromium/content/browser/renderer_host/input/fling_controller.cc9
-rw-r--r--chromium/content/browser/renderer_host/input/fling_controller.h5
-rw-r--r--chromium/content/browser/renderer_host/input/fling_controller_unittest.cc173
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl.cc42
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl.h3
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc97
-rw-r--r--chromium/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc24
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc3
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.cc21
-rw-r--r--chromium/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc5
-rw-r--r--chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc3
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture.cc4
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture.h6
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_controller.cc9
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_controller.h2
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc65
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_mouse_driver.cc14
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc16
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pointer_action.h1
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pointer_action_unittest.cc123
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc4
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_tap_gesture.h1
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_touch_driver.cc53
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_touch_driver.h6
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_browsertest.cc84
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_filter.cc88
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_filter.h13
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc114
-rw-r--r--chromium/content/browser/renderer_host/input/touch_emulator.cc8
-rw-r--r--chromium/content/browser/renderer_host/input/touch_emulator.h9
-rw-r--r--chromium/content/browser/renderer_host/input/touch_input_browsertest.cc9
-rw-r--r--chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc106
-rw-r--r--chromium/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc8
-rw-r--r--chromium/content/browser/renderer_host/input/touch_selection_controller_client_manager_android.cc51
-rw-r--r--chromium/content/browser/renderer_host/input/touch_selection_controller_client_manager_android.h3
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm4
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_delegate_impl.cc24
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_device_manager.cc21
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc4
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_authorization_handler.cc10
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc59
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_delegate_impl.cc18
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_delegate_impl_unittest.cc77
-rw-r--r--chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc10
-rw-r--r--chromium/content/browser/renderer_host/media/media_capture_devices_impl.cc22
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.cc22
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_manager.cc25
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_manager.h2
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc12
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_manager.cc88
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc1
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.cc4
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc26
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc21
-rw-r--r--chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.cc14
-rw-r--r--chromium/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory.cc6
-rw-r--r--chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc22
-rw-r--r--chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc338
-rw-r--r--chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h62
-rw-r--r--chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc33
-rw-r--r--chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc260
-rw-r--r--chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h86
-rw-r--r--chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc15
-rw-r--r--chromium/content/browser/renderer_host/media/service_video_capture_device_launcher.cc6
-rw-r--r--chromium/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc47
-rw-r--r--chromium/content/browser/renderer_host/media/service_video_capture_provider.cc15
-rw-r--r--chromium/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc65
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_browsertest.cc18
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc145
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_controller.cc85
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_controller_event_handler.h1
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc175
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_host.cc19
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_host.h1
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_manager.cc64
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_manager.h18
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_manager_unittest.cc119
-rw-r--r--chromium/content/browser/renderer_host/overscroll_controller.cc10
-rw-r--r--chromium/content/browser/renderer_host/overscroll_controller_unittest.cc216
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc3
-rw-r--r--chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc3
-rw-r--r--chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h7
-rw-r--r--chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc14
-rw-r--r--chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h8
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc31
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc33
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc8
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc39
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.h13
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc6
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.cc6
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper.cc6
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper_unittest.cc10
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc303
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h62
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc1434
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h263
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc12
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.cc4
-rw-r--r--chromium/content/browser/renderer_host/pepper/quota_reservation.cc17
-rw-r--r--chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc5
-rw-r--r--chromium/content/browser/renderer_host/pepper/ssl_context_helper.cc42
-rw-r--r--chromium/content/browser/renderer_host/pepper/ssl_context_helper.h59
-rw-r--r--chromium/content/browser/renderer_host/popup_window_mac.h3
-rw-r--r--chromium/content/browser/renderer_host/popup_window_mac.mm4
-rw-r--r--chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc11
-rw-r--r--chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h2
-rw-r--r--chromium/content/browser/renderer_host/render_message_filter.cc171
-rw-r--r--chromium/content/browser/renderer_host/render_message_filter.h45
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_browsertest.cc14
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_impl.cc279
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_impl.h32
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate.h15
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate_view.cc2
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate_view.h4
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_impl.cc165
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_impl.h17
-rw-r--r--chromium/content/browser/renderer_host/render_widget_helper.cc26
-rw-r--r--chromium/content/browser/renderer_host/render_widget_helper.h6
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_browsertest.cc158
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_delegate.cc8
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_delegate.h9
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.cc249
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.h37
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc327
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_input_event_router.h18
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h43
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.mm55
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_ns_view_client_helper.h (renamed from chromium/content/browser/renderer_host/render_widget_host_ns_view_client.h)24
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_ns_view_client_helper.mm100
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h5
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_unittest.cc95
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_android.cc42
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_android.h11
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura.cc152
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura.h9
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc356
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_base.cc166
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_base.h66
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc45
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc2
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc12
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_cocoa.h16
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_cocoa.mm170
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc55
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_event_handler.h3
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac.h28
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac.mm111
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm4
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm22
-rw-r--r--chromium/content/browser/renderer_host/render_widget_targeter.cc217
-rw-r--r--chromium/content/browser/renderer_host/render_widget_targeter.h63
-rw-r--r--chromium/content/browser/renderer_host/text_input_manager.cc4
-rw-r--r--chromium/content/browser/renderer_host/text_input_manager.h7
-rw-r--r--chromium/content/browser/renderer_host/ui_events_helper.cc5
-rw-r--r--chromium/content/browser/renderer_host/web_database_host_impl.cc8
-rw-r--r--chromium/content/browser/renderer_interface_binders.cc12
-rw-r--r--chromium/content/browser/resources/gpu/info_view.js1
-rw-r--r--chromium/content/browser/resources/media/client_renderer.js97
-rw-r--r--chromium/content/browser/resources/media/main.js4
-rw-r--r--chromium/content/browser/resources/media/manager.js19
-rw-r--r--chromium/content/browser/resources/media/media_internals.html12
-rw-r--r--chromium/content/browser/resources/media/stats_graph_helper.js4
-rw-r--r--chromium/content/browser/resources/media/util.js12
-rw-r--r--chromium/content/browser/resources/process/process_internals.css86
-rw-r--r--chromium/content/browser/resources/process/process_internals.html43
-rw-r--r--chromium/content/browser/resources/process/process_internals.js173
-rw-r--r--chromium/content/browser/scheduler/OWNERS4
-rw-r--r--chromium/content/browser/scheduler/browser_task_executor.cc153
-rw-r--r--chromium/content/browser/scheduler/browser_task_executor.h74
-rw-r--r--chromium/content/browser/scheduler/browser_task_executor_unittest.cc51
-rw-r--r--chromium/content/browser/scheduler/responsiveness/README2
-rw-r--r--chromium/content/browser/scheduler/responsiveness/native_event_observer.cc49
-rw-r--r--chromium/content/browser/scheduler/responsiveness/native_event_observer.h23
-rw-r--r--chromium/content/browser/scheduler/responsiveness/watcher.cc44
-rw-r--r--chromium/content/browser/scheduler/responsiveness/watcher.h10
-rw-r--r--chromium/content/browser/scheduler/responsiveness/watcher_unittest.cc26
-rw-r--r--chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc2
-rw-r--r--chromium/content/browser/screenlock_monitor/OWNERS1
-rw-r--r--chromium/content/browser/screenlock_monitor/screenlock_monitor.cc56
-rw-r--r--chromium/content/browser/screenlock_monitor/screenlock_monitor.h53
-rw-r--r--chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source.cc21
-rw-r--r--chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source.h89
-rw-r--r--chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_chromeos.cc35
-rw-r--r--chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_mac.mm52
-rw-r--r--chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_win.cc70
-rw-r--r--chromium/content/browser/screenlock_monitor/screenlock_monitor_source.cc31
-rw-r--r--chromium/content/browser/screenlock_monitor/screenlock_monitor_source.h31
-rw-r--r--chromium/content/browser/screenlock_monitor/screenlock_monitor_unittest.cc89
-rw-r--r--chromium/content/browser/security_exploit_browsertest.cc324
-rw-r--r--chromium/content/browser/service_manager/common_browser_interfaces.cc5
-rw-r--r--chromium/content/browser/service_manager/service_manager_context.cc20
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance.cc195
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance.h10
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc4
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_registry.cc6
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_test_helper.cc51
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_test_helper.h16
-rw-r--r--chromium/content/browser/service_worker/payment_handler_support.cc14
-rw-r--r--chromium/content/browser/service_worker/service_worker_browsertest.cc567
-rw-r--r--chromium/content/browser/service_worker/service_worker_cache_writer.cc70
-rw-r--r--chromium/content/browser/service_worker/service_worker_cache_writer.h26
-rw-r--r--chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc516
-rw-r--r--chromium/content/browser/service_worker/service_worker_client_utils.cc53
-rw-r--r--chromium/content/browser/service_worker/service_worker_content_settings_proxy_impl.cc2
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core.cc13
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_request_handler.cc11
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc15
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_unittest.cc20
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_watcher.cc34
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_wrapper.cc137
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_wrapper.h8
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc96
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler.h8
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc9
-rw-r--r--chromium/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc19
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.cc22
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.h1
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.proto5
-rw-r--r--chromium/content/browser/service_worker/service_worker_database_unittest.cc161
-rw-r--r--chromium/content/browser/service_worker/service_worker_disk_cache.cc10
-rw-r--r--chromium/content/browser/service_worker/service_worker_disk_cache.h13
-rw-r--r--chromium/content/browser/service_worker/service_worker_dispatcher_host.cc6
-rw-r--r--chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc9
-rw-r--r--chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc44
-rw-r--r--chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h9
-rw-r--r--chromium/content/browser/service_worker/service_worker_installed_script_reader.cc38
-rw-r--r--chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc7
-rw-r--r--chromium/content/browser/service_worker/service_worker_internals_ui.cc34
-rw-r--r--chromium/content/browser/service_worker/service_worker_job_unittest.cc157
-rw-r--r--chromium/content/browser/service_worker/service_worker_metrics.cc15
-rw-r--r--chromium/content/browser/service_worker/service_worker_metrics.h9
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc6
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_loader.cc192
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_loader.h34
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc241
-rw-r--r--chromium/content/browser/service_worker/service_worker_new_script_loader.cc15
-rw-r--r--chromium/content/browser/service_worker/service_worker_new_script_loader_unittest.cc5
-rw-r--r--chromium/content/browser/service_worker/service_worker_object_host.cc4
-rw-r--r--chromium/content/browser/service_worker/service_worker_object_host_unittest.cc10
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host.cc103
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host.h39
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc114
-rw-r--r--chromium/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc12
-rw-r--r--chromium/content/browser/service_worker/service_worker_register_job.cc70
-rw-r--r--chromium/content/browser/service_worker/service_worker_register_job.h21
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration.cc84
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration.h11
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_object_host.cc48
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_object_host.h11
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_unittest.cc356
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler.cc34
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler.h11
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc18
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_cache_map.cc9
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_loader_factory.cc13
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_loader_factory.h3
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc3
-rw-r--r--chromium/content/browser/service_worker/service_worker_single_script_update_checker.cc385
-rw-r--r--chromium/content/browser/service_worker/service_worker_single_script_update_checker.h141
-rw-r--r--chromium/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc288
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage.cc12
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage_unittest.cc33
-rw-r--r--chromium/content/browser/service_worker/service_worker_test_utils.cc171
-rw-r--r--chromium/content/browser/service_worker/service_worker_test_utils.h164
-rw-r--r--chromium/content/browser/service_worker/service_worker_tls_browsertest.cc146
-rw-r--r--chromium/content/browser/service_worker/service_worker_update_checker.cc74
-rw-r--r--chromium/content/browser/service_worker/service_worker_update_checker.h56
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_job_wrapper.cc8
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_job_wrapper.h6
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job.cc20
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job.h10
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc50
-rw-r--r--chromium/content/browser/service_worker/service_worker_version.cc128
-rw-r--r--chromium/content/browser/service_worker/service_worker_version.h81
-rw-r--r--chromium/content/browser/service_worker/service_worker_version_unittest.cc53
-rw-r--r--chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc37
-rw-r--r--chromium/content/browser/service_worker/service_worker_write_to_cache_job.h4
-rw-r--r--chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc17
-rw-r--r--chromium/content/browser/shareable_file_reference_unittest.cc4
-rw-r--r--chromium/content/browser/shared_worker/mock_shared_worker.cc7
-rw-r--r--chromium/content/browser/shared_worker/mock_shared_worker.h9
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_connector_impl.cc2
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.cc4
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_host.cc151
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_host.h31
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_host_unittest.cc126
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_script_fetcher.cc205
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_script_fetcher.h97
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_script_loader.cc45
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_script_loader.h23
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_script_loader_factory.cc41
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_script_loader_factory.h13
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl.cc321
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl.h39
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc2
-rw-r--r--chromium/content/browser/shared_worker/worker_browsertest.cc5
-rw-r--r--chromium/content/browser/site_instance_impl.cc91
-rw-r--r--chromium/content/browser/site_instance_impl.h42
-rw-r--r--chromium/content/browser/site_instance_impl_unittest.cc122
-rw-r--r--chromium/content/browser/site_per_process_browsertest.cc328
-rw-r--r--chromium/content/browser/site_per_process_hit_test_browsertest.cc768
-rw-r--r--chromium/content/browser/site_per_process_mac_browsertest.mm6
-rw-r--r--chromium/content/browser/speech/speech_recognition_browsertest.cc10
-rw-r--r--chromium/content/browser/speech/speech_recognition_dispatcher_host.cc12
-rw-r--r--chromium/content/browser/speech/speech_recognition_engine_unittest.cc11
-rw-r--r--chromium/content/browser/speech/speech_recognition_manager_impl.cc8
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl.cc41
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl_android.cc46
-rw-r--r--chromium/content/browser/ssl/ssl_client_auth_handler.cc18
-rw-r--r--chromium/content/browser/ssl/ssl_error_handler.cc18
-rw-r--r--chromium/content/browser/ssl/ssl_manager.cc71
-rw-r--r--chromium/content/browser/startup_helper.cc110
-rw-r--r--chromium/content/browser/startup_helper.h23
-rw-r--r--chromium/content/browser/startup_task_runner.cc4
-rw-r--r--chromium/content/browser/storage_partition_impl.cc168
-rw-r--r--chromium/content/browser/storage_partition_impl_map.cc32
-rw-r--r--chromium/content/browser/storage_partition_impl_unittest.cc473
-rw-r--r--chromium/content/browser/streams/stream.cc3
-rw-r--r--chromium/content/browser/streams/stream_context.cc6
-rw-r--r--chromium/content/browser/streams/stream_registry.cc4
-rw-r--r--chromium/content/browser/streams/stream_unittest.cc12
-rw-r--r--chromium/content/browser/streams/stream_url_request_job_unittest.cc24
-rw-r--r--chromium/content/browser/top_document_isolation_browsertest.cc616
-rw-r--r--chromium/content/browser/tracing/background_startup_tracing_observer.cc6
-rw-r--r--chromium/content/browser/tracing/background_tracing_config_unittest.cc7
-rw-r--r--chromium/content/browser/tracing/background_tracing_manager_browsertest.cc25
-rw-r--r--chromium/content/browser/tracing/background_tracing_manager_impl.cc25
-rw-r--r--chromium/content/browser/tracing/background_tracing_rule.cc10
-rw-r--r--chromium/content/browser/tracing/etw_tracing_agent_win.cc8
-rw-r--r--chromium/content/browser/tracing/trace_message_filter.cc12
-rw-r--r--chromium/content/browser/tracing/tracing_controller_browsertest.cc8
-rw-r--r--chromium/content/browser/tracing/tracing_controller_impl.cc47
-rw-r--r--chromium/content/browser/tracing/tracing_controller_impl.h7
-rw-r--r--chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc9
-rw-r--r--chromium/content/browser/tracing/tracing_ui.cc3
-rw-r--r--chromium/content/browser/url_loader_factory_getter.cc14
-rw-r--r--chromium/content/browser/url_loader_factory_getter.h13
-rw-r--r--chromium/content/browser/utility_process_host.cc74
-rw-r--r--chromium/content/browser/utility_process_host_browsertest.cc23
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc4
-rw-r--r--chromium/content/browser/web_contents/web_contents_android.cc16
-rw-r--r--chromium/content/browser/web_contents/web_contents_android.h3
-rw-r--r--chromium/content/browser/web_contents/web_contents_getter_registry.cc51
-rw-r--r--chromium/content/browser/web_contents/web_contents_getter_registry.h49
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl.cc473
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl.h68
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl_browsertest.cc153
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl_unittest.cc93
-rw-r--r--chromium/content/browser/web_contents/web_contents_ns_view_bridge.h54
-rw-r--r--chromium/content/browser/web_contents/web_contents_ns_view_bridge.mm65
-rw-r--r--chromium/content/browser/web_contents/web_contents_view.h12
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_android.cc7
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_android.h4
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_aura.cc16
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_aura.h2
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_child_frame.cc13
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_child_frame.h4
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_guest.cc20
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_guest.h4
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_mac.h51
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_mac.mm130
-rw-r--r--chromium/content/browser/web_contents/web_drag_source_mac.mm11
-rw-r--r--chromium/content/browser/web_package/mock_signed_exchange_handler.cc13
-rw-r--r--chromium/content/browser/web_package/mock_signed_exchange_handler.h11
-rw-r--r--chromium/content/browser/web_package/origins_list.cc82
-rw-r--r--chromium/content/browser/web_package/origins_list.h52
-rw-r--r--chromium/content/browser/web_package/origins_list_unittest.cc77
-rw-r--r--chromium/content/browser/web_package/signed_exchange_cert_fetcher.cc12
-rw-r--r--chromium/content/browser/web_package/signed_exchange_cert_fetcher.h4
-rw-r--r--chromium/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc29
-rw-r--r--chromium/content/browser/web_package/signed_exchange_certificate_chain.h1
-rw-r--r--chromium/content/browser/web_package/signed_exchange_consts.h2
-rw-r--r--chromium/content/browser/web_package/signed_exchange_devtools_proxy.cc22
-rw-r--r--chromium/content/browser/web_package/signed_exchange_envelope.cc49
-rw-r--r--chromium/content/browser/web_package/signed_exchange_envelope.h2
-rw-r--r--chromium/content/browser/web_package/signed_exchange_envelope_unittest.cc11
-rw-r--r--chromium/content/browser/web_package/signed_exchange_error.h31
-rw-r--r--chromium/content/browser/web_package/signed_exchange_handler.cc221
-rw-r--r--chromium/content/browser/web_package/signed_exchange_handler.h31
-rw-r--r--chromium/content/browser/web_package/signed_exchange_handler_unittest.cc99
-rw-r--r--chromium/content/browser/web_package/signed_exchange_loader.cc28
-rw-r--r--chromium/content/browser/web_package/signed_exchange_loader.h7
-rw-r--r--chromium/content/browser/web_package/signed_exchange_prefetch_handler.cc18
-rw-r--r--chromium/content/browser/web_package/signed_exchange_prefetch_handler.h6
-rw-r--r--chromium/content/browser/web_package/signed_exchange_prefetch_metric_recorder.cc23
-rw-r--r--chromium/content/browser/web_package/signed_exchange_prefetch_metric_recorder.h35
-rw-r--r--chromium/content/browser/web_package/signed_exchange_request_handler.cc16
-rw-r--r--chromium/content/browser/web_package/signed_exchange_request_handler.h8
-rw-r--r--chromium/content/browser/web_package/signed_exchange_request_handler_browsertest.cc896
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_header_field.cc22
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_header_field.h11
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc56
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_verifier.cc140
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_verifier.h35
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc176
-rw-r--r--chromium/content/browser/web_package/signed_exchange_utils.cc94
-rw-r--r--chromium/content/browser/web_package/signed_exchange_utils.h26
-rw-r--r--chromium/content/browser/web_package/signed_exchange_utils_unittest.cc97
-rw-r--r--chromium/content/browser/webauth/authenticator_impl.cc186
-rw-r--r--chromium/content/browser/webauth/authenticator_impl.h3
-rw-r--r--chromium/content/browser/webauth/authenticator_impl_unittest.cc63
-rw-r--r--chromium/content/browser/webauth/authenticator_type_converters.cc19
-rw-r--r--chromium/content/browser/webauth/authenticator_type_converters.h7
-rw-r--r--chromium/content/browser/webauth/scoped_virtual_authenticator_environment.cc2
-rw-r--r--chromium/content/browser/webauth/scoped_virtual_authenticator_environment.h4
-rw-r--r--chromium/content/browser/webauth/virtual_discovery.cc8
-rw-r--r--chromium/content/browser/webauth/virtual_discovery.h11
-rw-r--r--chromium/content/browser/webauth/webauth_browsertest.cc12
-rw-r--r--chromium/content/browser/webrtc/webrtc_audio_browsertest.cc86
-rw-r--r--chromium/content/browser/webrtc/webrtc_browsertest.cc9
-rw-r--r--chromium/content/browser/webrtc/webrtc_content_browsertest_base.cc3
-rw-r--r--chromium/content/browser/webrtc/webrtc_depth_capture_browsertest.cc11
-rw-r--r--chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc79
-rw-r--r--chromium/content/browser/webrtc/webrtc_internals.cc6
-rw-r--r--chromium/content/browser/webrtc/webrtc_internals_unittest.cc8
-rw-r--r--chromium/content/browser/webrtc/webrtc_video_capture_browsertest.cc2
-rw-r--r--chromium/content/browser/webrtc/webrtc_video_capture_service_browsertest.cc149
-rw-r--r--chromium/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc160
-rw-r--r--chromium/content/browser/webrtc/webrtc_webcam_browsertest.cc5
-rw-r--r--chromium/content/browser/websockets/websocket_manager.cc10
-rw-r--r--chromium/content/browser/webui/shared_resources_data_source.cc80
-rw-r--r--chromium/content/browser/webui/url_data_manager.cc24
-rw-r--r--chromium/content/browser/webui/url_data_manager_backend.cc23
-rw-r--r--chromium/content/browser/webui/url_data_source_impl.cc6
-rw-r--r--chromium/content/browser/webui/web_ui_message_handler_unittest.cc37
-rw-r--r--chromium/content/browser/webui/web_ui_mojo_browsertest.cc25
-rw-r--r--chromium/content/browser/webui/web_ui_url_loader_factory.cc9
-rw-r--r--chromium/content/child/BUILD.gn3
-rw-r--r--chromium/content/child/blink_platform_impl.cc88
-rw-r--r--chromium/content/child/blink_platform_impl.h25
-rw-r--r--chromium/content/child/blink_platform_impl_unittest.cc13
-rw-r--r--chromium/content/child/child_process.cc12
-rw-r--r--chromium/content/child/child_process.h14
-rw-r--r--chromium/content/child/child_process_sandbox_support_impl_linux.cc25
-rw-r--r--chromium/content/child/child_process_sandbox_support_impl_linux.h14
-rw-r--r--chromium/content/child/child_thread_impl.cc61
-rw-r--r--chromium/content/child/child_thread_impl.h7
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc14
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc11
-rw-r--r--chromium/content/child/font_warmup_win.cc23
-rw-r--r--chromium/content/child/memory/child_memory_coordinator_impl_unittest.cc6
-rw-r--r--chromium/content/child/runtime_features.cc62
-rw-r--r--chromium/content/common/BUILD.gn21
-rw-r--r--chromium/content/common/DEPS2
-rw-r--r--chromium/content/common/OWNERS3
-rw-r--r--chromium/content/common/accessibility_messages.h1
-rw-r--r--chromium/content/common/background_fetch/background_fetch_struct_traits.cc2
-rw-r--r--chromium/content/common/background_fetch/background_fetch_struct_traits.h4
-rw-r--r--chromium/content/common/background_fetch/background_fetch_struct_traits_unittest.cc4
-rw-r--r--chromium/content/common/background_fetch/background_fetch_types.cc6
-rw-r--r--chromium/content/common/background_fetch/background_fetch_types.h6
-rw-r--r--chromium/content/common/browser_plugin/browser_plugin_messages.h4
-rw-r--r--chromium/content/common/common_param_traits_unittest.cc8
-rw-r--r--chromium/content/common/content_message_generator.h5
-rw-r--r--chromium/content/common/content_param_traits.cc85
-rw-r--r--chromium/content/common/content_param_traits.h14
-rw-r--r--chromium/content/common/content_param_traits_macros.h8
-rw-r--r--chromium/content/common/content_security_policy/content_security_policy.cc26
-rw-r--r--chromium/content/common/content_security_policy/content_security_policy.h2
-rw-r--r--chromium/content/common/content_security_policy/content_security_policy_unittest.cc63
-rw-r--r--chromium/content/common/content_security_policy/csp_context.cc10
-rw-r--r--chromium/content/common/content_security_policy/csp_context.h4
-rw-r--r--chromium/content/common/content_security_policy/csp_source.cc8
-rw-r--r--chromium/content/common/content_security_policy/csp_source.h2
-rw-r--r--chromium/content/common/content_security_policy/csp_source_list.cc29
-rw-r--r--chromium/content/common/content_security_policy/csp_source_list.h6
-rw-r--r--chromium/content/common/dom_storage/dom_storage_namespace_ids.cc21
-rw-r--r--chromium/content/common/dom_storage/dom_storage_namespace_ids.h19
-rw-r--r--chromium/content/common/font_cache_dispatcher_win.cc5
-rw-r--r--chromium/content/common/frame.mojom20
-rw-r--r--chromium/content/common/frame_message_enums.h2
-rw-r--r--chromium/content/common/frame_messages.h77
-rw-r--r--chromium/content/common/input/actions_parser.cc (renamed from chromium/content/renderer/gpu/actions_parser.cc)66
-rw-r--r--chromium/content/common/input/actions_parser.h (renamed from chromium/content/renderer/gpu/actions_parser.h)14
-rw-r--r--chromium/content/common/input/actions_parser_unittest.cc250
-rw-r--r--chromium/content/common/input/input_event_struct_traits.cc13
-rw-r--r--chromium/content/common/input/input_handler.mojom9
-rw-r--r--chromium/content/common/input/synthetic_pointer_action_params.cc24
-rw-r--r--chromium/content/common/input/synthetic_pointer_action_params.h20
-rw-r--r--chromium/content/common/input/synthetic_web_input_event_builders.cc3
-rw-r--r--chromium/content/common/input/synthetic_web_input_event_builders_unittest.cc4
-rw-r--r--chromium/content/common/input/web_mouse_wheel_event_traits.cc40
-rw-r--r--chromium/content/common/input/web_mouse_wheel_event_traits.h28
-rw-r--r--chromium/content/common/input_messages.h2
-rw-r--r--chromium/content/common/media/media_player_delegate_messages.h10
-rw-r--r--chromium/content/common/media/media_stream.mojom23
-rw-r--r--chromium/content/common/media/media_stream.typemap5
-rw-r--r--chromium/content/common/media/media_stream_mojom_traits.cc30
-rw-r--r--chromium/content/common/media/media_stream_mojom_traits.h55
-rw-r--r--chromium/content/common/media/media_stream_param_traits.cc33
-rw-r--r--chromium/content/common/media/media_stream_param_traits.h33
-rw-r--r--chromium/content/common/native_types.mojom3
-rw-r--r--chromium/content/common/native_types.typemap2
-rw-r--r--chromium/content/common/navigation_gesture.h4
-rw-r--r--chromium/content/common/navigation_params.cc20
-rw-r--r--chromium/content/common/navigation_params.h50
-rw-r--r--chromium/content/common/notifications/DEPS3
-rw-r--r--chromium/content/common/notifications/OWNERS10
-rw-r--r--chromium/content/common/notifications/notification_struct_traits.cc194
-rw-r--r--chromium/content/common/notifications/notification_struct_traits.h182
-rw-r--r--chromium/content/common/notifications/notification_struct_traits_unittest.cc267
-rw-r--r--chromium/content/common/notifications/notification_types.typemap20
-rw-r--r--chromium/content/common/origin_util.cc2
-rw-r--r--chromium/content/common/page_state_serialization.cc59
-rw-r--r--chromium/content/common/plugin_list.h14
-rw-r--r--chromium/content/common/render_frame_metadata.mojom2
-rw-r--r--chromium/content/common/render_frame_metadata.typemap1
-rw-r--r--chromium/content/common/render_frame_metadata_struct_traits.cc2
-rw-r--r--chromium/content/common/render_frame_metadata_struct_traits.h2
-rw-r--r--chromium/content/common/render_message_filter.mojom22
-rw-r--r--chromium/content/common/render_widget_host_ns_view.mojom7
-rw-r--r--chromium/content/common/render_widget_surface_properties.cc7
-rw-r--r--chromium/content/common/render_widget_surface_properties.h2
-rw-r--r--chromium/content/common/sandbox_policy_fuchsia.cc7
-rw-r--r--chromium/content/common/service_manager/service_manager_connection_impl.cc8
-rw-r--r--chromium/content/common/service_manager/service_manager_connection_impl_unittest.cc4
-rw-r--r--chromium/content/common/service_worker/controller_service_worker.mojom8
-rw-r--r--chromium/content/common/service_worker/embedded_worker.mojom7
-rw-r--r--chromium/content/common/service_worker/service_worker.mojom45
-rw-r--r--chromium/content/common/service_worker/service_worker_container.mojom8
-rw-r--r--chromium/content/common/service_worker/service_worker_fetch_request.typemap11
-rw-r--r--chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.cc189
-rw-r--r--chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.h11
-rw-r--r--chromium/content/common/service_worker/service_worker_loader_helpers.cc96
-rw-r--r--chromium/content/common/service_worker/service_worker_loader_helpers.h13
-rw-r--r--chromium/content/common/service_worker/service_worker_types.cc37
-rw-r--r--chromium/content/common/service_worker/service_worker_types.h30
-rw-r--r--chromium/content/common/service_worker/service_worker_types_unittest.cc35
-rw-r--r--chromium/content/common/service_worker/service_worker_utils.cc30
-rw-r--r--chromium/content/common/service_worker/service_worker_utils.h5
-rw-r--r--chromium/content/common/service_worker/service_worker_utils_unittest.cc32
-rw-r--r--chromium/content/common/shared_worker/shared_worker.mojom3
-rw-r--r--chromium/content/common/shared_worker/shared_worker_factory.mojom22
-rw-r--r--chromium/content/common/swapped_out_messages.cc5
-rw-r--r--chromium/content/common/throttling_url_loader.cc75
-rw-r--r--chromium/content/common/throttling_url_loader.h8
-rw-r--r--chromium/content/common/throttling_url_loader_unittest.cc29
-rw-r--r--chromium/content/common/typemaps.gni1
-rw-r--r--chromium/content/common/url_loader_factory_bundle.cc79
-rw-r--r--chromium/content/common/url_loader_factory_bundle.h77
-rw-r--r--chromium/content/common/url_loader_factory_bundle.mojom10
-rw-r--r--chromium/content/common/url_loader_factory_bundle_struct_traits.cc23
-rw-r--r--chromium/content/common/url_loader_factory_bundle_struct_traits.h9
-rw-r--r--chromium/content/common/url_schemes.cc6
-rw-r--r--chromium/content/common/user_agent.cc55
-rw-r--r--chromium/content/common/view_message_enums.h25
-rw-r--r--chromium/content/common/view_messages.h287
-rw-r--r--chromium/content/common/widget_messages.h319
-rw-r--r--chromium/content/content_resources.grd2
-rw-r--r--chromium/content/gpu/gpu_child_thread.cc43
-rw-r--r--chromium/content/gpu/gpu_child_thread.h16
-rw-r--r--chromium/content/gpu/gpu_main.cc15
-rw-r--r--chromium/content/gpu/gpu_sandbox_hook_linux.cc40
-rw-r--r--chromium/content/gpu/gpu_service_factory.cc6
-rw-r--r--chromium/content/gpu/gpu_service_factory.h3
-rw-r--r--chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc31
-rw-r--r--chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h2
-rw-r--r--chromium/content/ppapi_plugin/ppapi_broker_main.cc7
-rw-r--r--chromium/content/ppapi_plugin/ppapi_plugin_main.cc8
-rw-r--r--chromium/content/ppapi_plugin/ppapi_thread.cc12
-rw-r--r--chromium/content/ppapi_plugin/ppapi_thread.h4
-rw-r--r--chromium/content/public/android/BUILD.gn7
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/BindingManagerTest.java259
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/ChildProcessRankingTest.java216
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/SpareChildConnectionTest.java232
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/androidoverlay/DialogOverlayCoreTest.java360
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/input/RangeTest.java68
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/input/TextInputStateTest.java47
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionFactoryTest.java289
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java354
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/picker/DateDialogNormalizerTest.java160
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectImplTest.java861
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectRegistryTest.java72
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/selection/MagnifierAnimatorTest.java158
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java551
-rw-r--r--chromium/content/public/android/junit/src/org/chromium/content/browser/selection/SmartSelectionMetricsLoggerTest.java451
-rw-r--r--chromium/content/public/app/BUILD.gn1
-rw-r--r--chromium/content/public/app/content_jni_onload.h22
-rw-r--r--chromium/content/public/app/content_main_delegate.cc8
-rw-r--r--chromium/content/public/app/content_main_delegate.h23
-rw-r--r--chromium/content/public/app/mojo/content_browser_manifest.json17
-rw-r--r--chromium/content/public/app/mojo/content_packaged_services_manifest.json10
-rw-r--r--chromium/content/public/app/mojo/content_renderer_manifest.json4
-rw-r--r--chromium/content/public/browser/BUILD.gn27
-rw-r--r--chromium/content/public/browser/DEPS2
-rw-r--r--chromium/content/public/browser/android/compositor_client.h5
-rw-r--r--chromium/content/public/browser/android/gpu_video_accelerator_factories_provider.h29
-rw-r--r--chromium/content/public/browser/authenticator_request_client_delegate.cc10
-rw-r--r--chromium/content/public/browser/authenticator_request_client_delegate.h24
-rw-r--r--chromium/content/public/browser/ax_event_notification_details.cc7
-rw-r--r--chromium/content/public/browser/ax_event_notification_details.h4
-rw-r--r--chromium/content/public/browser/background_fetch_delegate.h24
-rw-r--r--chromium/content/public/browser/background_fetch_description.cc6
-rw-r--r--chromium/content/public/browser/background_fetch_description.h6
-rw-r--r--chromium/content/public/browser/background_fetch_response.cc14
-rw-r--r--chromium/content/public/browser/background_fetch_response.h13
-rw-r--r--chromium/content/public/browser/browser_accessibility_state.h2
-rw-r--r--chromium/content/public/browser/browser_associated_interface.h6
-rw-r--r--chromium/content/public/browser/browser_context.h21
-rw-r--r--chromium/content/public/browser/browser_main_parts.cc4
-rw-r--r--chromium/content/public/browser/browser_main_parts.h5
-rw-r--r--chromium/content/public/browser/browser_message_filter.cc10
-rw-r--r--chromium/content/public/browser/browser_task_traits.h26
-rw-r--r--chromium/content/public/browser/browser_task_traits_unittest.nc2
-rw-r--r--chromium/content/public/browser/browser_thread.h80
-rw-r--r--chromium/content/public/browser/content_browser_client.cc41
-rw-r--r--chromium/content/public/browser/content_browser_client.h92
-rw-r--r--chromium/content/public/browser/delegate_to_browser_gpu_service_accelerator_factory.h25
-rw-r--r--chromium/content/public/browser/devtools_agent_host.h10
-rw-r--r--chromium/content/public/browser/devtools_agent_host_client.cc12
-rw-r--r--chromium/content/public/browser/devtools_agent_host_client.h11
-rw-r--r--chromium/content/public/browser/dom_storage_context.h12
-rw-r--r--chromium/content/public/browser/file_select_listener.h31
-rw-r--r--chromium/content/public/browser/gpu_interface_provider_factory.h22
-rw-r--r--chromium/content/public/browser/gpu_service_registry.cc3
-rw-r--r--chromium/content/public/browser/gpu_utils.cc25
-rw-r--r--chromium/content/public/browser/gpu_utils.h6
-rw-r--r--chromium/content/public/browser/guest_host.h2
-rw-r--r--chromium/content/public/browser/media_session.h43
-rw-r--r--chromium/content/public/browser/navigation_controller.cc5
-rw-r--r--chromium/content/public/browser/navigation_controller.h10
-rw-r--r--chromium/content/public/browser/navigation_handle.h3
-rw-r--r--chromium/content/public/browser/network_quality_observer_factory.h11
-rw-r--r--chromium/content/public/browser/network_service_instance.h32
-rw-r--r--chromium/content/public/browser/notification_database_data.h4
-rw-r--r--chromium/content/public/browser/ns_view_bridge_factory_host.h44
-rw-r--r--chromium/content/public/browser/ns_view_bridge_factory_impl.h47
-rw-r--r--chromium/content/public/browser/origin_policy_error_reason.h19
-rw-r--r--chromium/content/public/browser/overlay_window.h1
-rw-r--r--chromium/content/public/browser/permission_type.h1
-rw-r--r--chromium/content/public/browser/picture_in_picture_window_controller.h5
-rw-r--r--chromium/content/public/browser/platform_notification_service.h15
-rw-r--r--chromium/content/public/browser/push_messaging_service.cc21
-rw-r--r--chromium/content/public/browser/render_frame_host.h30
-rw-r--r--chromium/content/public/browser/render_process_host.h5
-rw-r--r--chromium/content/public/browser/render_view_host.h3
-rw-r--r--chromium/content/public/browser/render_widget_host.h3
-rw-r--r--chromium/content/public/browser/resource_hints.h50
-rw-r--r--chromium/content/public/browser/resource_request_info.h11
-rw-r--r--chromium/content/public/browser/screenlock_observer.h27
-rw-r--r--chromium/content/public/browser/shared_cors_origin_access_list.h58
-rw-r--r--chromium/content/public/browser/site_instance.h5
-rw-r--r--chromium/content/public/browser/site_isolation_policy.cc84
-rw-r--r--chromium/content/public/browser/site_isolation_policy.h13
-rw-r--r--chromium/content/public/browser/tracing_controller.h17
-rw-r--r--chromium/content/public/browser/url_data_source.cc10
-rw-r--r--chromium/content/public/browser/url_data_source.h3
-rw-r--r--chromium/content/public/browser/web_contents.h24
-rw-r--r--chromium/content/public/browser/web_contents_delegate.cc29
-rw-r--r--chromium/content/public/browser/web_contents_delegate.h53
-rw-r--r--chromium/content/public/browser/web_contents_observer.h14
-rw-r--r--chromium/content/public/common/BUILD.gn20
-rw-r--r--chromium/content/public/common/common_param_traits.cc18
-rw-r--r--chromium/content/public/common/common_param_traits.h11
-rw-r--r--chromium/content/public/common/common_param_traits_macros.h5
-rw-r--r--chromium/content/public/common/content_client.cc5
-rw-r--r--chromium/content/public/common/content_client.h5
-rw-r--r--chromium/content/public/common/content_features.cc105
-rw-r--r--chromium/content/public/common/content_features.h18
-rw-r--r--chromium/content/public/common/content_switches.cc17
-rw-r--r--chromium/content/public/common/content_switches.h4
-rw-r--r--chromium/content/public/common/file_chooser_file_info.cc18
-rw-r--r--chromium/content/public/common/file_chooser_file_info.h8
-rw-r--r--chromium/content/public/common/file_chooser_params.cc17
-rw-r--r--chromium/content/public/common/file_chooser_params.h69
-rw-r--r--chromium/content/public/common/gpu_stream_constants.h (renamed from chromium/content/common/gpu_stream_constants.h)6
-rw-r--r--chromium/content/public/common/media_stream_request.cc43
-rw-r--r--chromium/content/public/common/media_stream_request.h8
-rw-r--r--chromium/content/public/common/notification_resources.cc16
-rw-r--r--chromium/content/public/common/notification_resources.h40
-rw-r--r--chromium/content/public/common/ns_view_bridge_factory.mojom36
-rw-r--r--chromium/content/public/common/platform_notification_data.cc23
-rw-r--r--chromium/content/public/common/platform_notification_data.h123
-rw-r--r--chromium/content/public/common/previews_state.h6
-rw-r--r--chromium/content/public/common/renderer_preferences.cc3
-rw-r--r--chromium/content/public/common/renderer_preferences.h6
-rw-r--r--chromium/content/public/common/request_context_type.h50
-rw-r--r--chromium/content/public/common/url_utils.cc10
-rw-r--r--chromium/content/public/common/url_utils_unittest.cc61
-rw-r--r--chromium/content/public/common/use_zoom_for_dsf_policy.cc2
-rw-r--r--chromium/content/public/common/user_agent.h5
-rw-r--r--chromium/content/public/common/was_activated_option.h27
-rw-r--r--chromium/content/public/common/web_contents_ns_view_bridge.mojom31
-rw-r--r--chromium/content/public/common/web_preferences.cc12
-rw-r--r--chromium/content/public/common/web_preferences.h16
-rw-r--r--chromium/content/public/common/widget_type.h (renamed from chromium/content/public/renderer/navigation_state.cc)7
-rw-r--r--chromium/content/public/renderer/BUILD.gn2
-rw-r--r--chromium/content/public/renderer/associated_resource_fetcher.h2
-rw-r--r--chromium/content/public/renderer/content_renderer_client.cc15
-rw-r--r--chromium/content/public/renderer/content_renderer_client.h25
-rw-r--r--chromium/content/public/renderer/document_state.cc17
-rw-r--r--chromium/content/public/renderer/document_state.h11
-rw-r--r--chromium/content/public/renderer/navigation_state.h35
-rw-r--r--chromium/content/public/renderer/render_frame.h2
-rw-r--r--chromium/content/public/renderer/render_frame_observer.h9
-rw-r--r--chromium/content/public/renderer/render_thread.h15
-rw-r--r--chromium/content/public/renderer/render_view.h2
-rw-r--r--chromium/content/public/renderer/render_view_observer.h2
-rw-r--r--chromium/content/public/renderer/resource_fetcher.h2
-rw-r--r--chromium/content/public/test/android/BUILD.gn64
-rw-r--r--chromium/content/renderer/BUILD.gn38
-rw-r--r--chromium/content/renderer/OWNERS1
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc676
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_enum_conversion.h42
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_tree_source.cc122
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_tree_source.h2
-rw-r--r--chromium/content/renderer/accessibility/render_accessibility_impl.cc123
-rw-r--r--chromium/content/renderer/accessibility/render_accessibility_impl.h12
-rw-r--r--chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc1
-rw-r--r--chromium/content/renderer/appcache/appcache_frontend_impl.cc12
-rw-r--r--chromium/content/renderer/browser_plugin/browser_plugin.cc43
-rw-r--r--chromium/content/renderer/browser_plugin/browser_plugin.h15
-rw-r--r--chromium/content/renderer/categorized_worker_pool.cc2
-rw-r--r--chromium/content/renderer/child_frame_compositing_helper.cc8
-rw-r--r--chromium/content/renderer/child_frame_compositing_helper_unittest.cc3
-rw-r--r--chromium/content/renderer/child_frame_compositor.h3
-rw-r--r--chromium/content/renderer/dom_serializer_browsertest.cc8
-rw-r--r--chromium/content/renderer/dom_storage/dom_storage_cached_area.cc9
-rw-r--r--chromium/content/renderer/dom_storage/dom_storage_cached_area_unittest.cc5
-rw-r--r--chromium/content/renderer/dom_storage/dom_storage_dispatcher.cc2
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_areas.cc7
-rw-r--r--chromium/content/renderer/fetchers/associated_resource_fetcher_impl.cc2
-rw-r--r--chromium/content/renderer/fetchers/associated_resource_fetcher_impl.h2
-rw-r--r--chromium/content/renderer/fetchers/manifest_fetcher.cc2
-rw-r--r--chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc4
-rw-r--r--chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h4
-rw-r--r--chromium/content/renderer/fetchers/resource_fetcher_browsertest.cc16
-rw-r--r--chromium/content/renderer/fetchers/resource_fetcher_impl.cc6
-rw-r--r--chromium/content/renderer/fetchers/resource_fetcher_impl.h2
-rw-r--r--chromium/content/renderer/file_info_util.cc30
-rw-r--r--chromium/content/renderer/file_info_util.h22
-rw-r--r--chromium/content/renderer/fileapi/OWNERS4
-rw-r--r--chromium/content/renderer/fileapi/file_system_dispatcher.cc739
-rw-r--r--chromium/content/renderer/fileapi/file_system_dispatcher.h253
-rw-r--r--chromium/content/renderer/fileapi/webfilesystem_impl.cc483
-rw-r--r--chromium/content/renderer/fileapi/webfilesystem_impl.h114
-rw-r--r--chromium/content/renderer/fileapi/webfilewriter_base.cc151
-rw-r--r--chromium/content/renderer/fileapi/webfilewriter_base.h71
-rw-r--r--chromium/content/renderer/fileapi/webfilewriter_base_unittest.cc416
-rw-r--r--chromium/content/renderer/fileapi/webfilewriter_impl.cc67
-rw-r--r--chromium/content/renderer/fileapi/webfilewriter_impl.h54
-rw-r--r--chromium/content/renderer/gpu/gpu_benchmarking_extension.cc52
-rw-r--r--chromium/content/renderer/gpu/layer_tree_view.cc47
-rw-r--r--chromium/content/renderer/gpu/layer_tree_view.h20
-rw-r--r--chromium/content/renderer/gpu/layer_tree_view_delegate.h23
-rw-r--r--chromium/content/renderer/gpu/layer_tree_view_unittest.cc6
-rw-r--r--chromium/content/renderer/gpu/queue_message_swap_promise.cc4
-rw-r--r--chromium/content/renderer/gpu/queue_message_swap_promise_unittest.cc8
-rw-r--r--chromium/content/renderer/idle_user_detector.cc27
-rw-r--r--chromium/content/renderer/idle_user_detector.h28
-rw-r--r--chromium/content/renderer/image_downloader/image_downloader_base.cc6
-rw-r--r--chromium/content/renderer/image_downloader/image_downloader_impl.cc3
-rw-r--r--chromium/content/renderer/indexed_db/webidbdatabase_impl.cc39
-rw-r--r--chromium/content/renderer/indexed_db/webidbdatabase_impl.h6
-rw-r--r--chromium/content/renderer/indexed_db/webidbdatabase_impl_unittest.cc5
-rw-r--r--chromium/content/renderer/input/OWNERS1
-rw-r--r--chromium/content/renderer/input/frame_input_handler_impl.cc49
-rw-r--r--chromium/content/renderer/input/frame_input_handler_impl.h6
-rw-r--r--chromium/content/renderer/input/input_target_client_impl.cc9
-rw-r--r--chromium/content/renderer/input/input_target_client_impl.h1
-rw-r--r--chromium/content/renderer/input/main_thread_event_queue_unittest.cc1
-rw-r--r--chromium/content/renderer/internal_document_state_data.cc15
-rw-r--r--chromium/content/renderer/internal_document_state_data.h20
-rw-r--r--chromium/content/renderer/loader/child_url_loader_factory_bundle.cc124
-rw-r--r--chromium/content/renderer/loader/child_url_loader_factory_bundle.h30
-rw-r--r--chromium/content/renderer/loader/code_cache_loader_impl.cc25
-rw-r--r--chromium/content/renderer/loader/code_cache_loader_impl.h8
-rw-r--r--chromium/content/renderer/loader/request_extra_data.h7
-rw-r--r--chromium/content/renderer/loader/resource_dispatcher.cc58
-rw-r--r--chromium/content/renderer/loader/resource_dispatcher_unittest.cc4
-rw-r--r--chromium/content/renderer/loader/shared_memory_data_consumer_handle_unittest.cc28
-rw-r--r--chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.cc42
-rw-r--r--chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.h13
-rw-r--r--chromium/content/renderer/loader/url_loader_client_impl.cc4
-rw-r--r--chromium/content/renderer/loader/url_loader_client_impl_unittest.cc9
-rw-r--r--chromium/content/renderer/loader/url_response_body_consumer_unittest.cc17
-rw-r--r--chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc38
-rw-r--r--chromium/content/renderer/loader/web_url_loader_impl.cc134
-rw-r--r--chromium/content/renderer/loader/web_url_loader_impl_unittest.cc25
-rw-r--r--chromium/content/renderer/loader/web_url_request_util.cc168
-rw-r--r--chromium/content/renderer/loader/web_url_request_util.h8
-rw-r--r--chromium/content/renderer/loader/web_worker_fetch_context_impl.cc12
-rw-r--r--chromium/content/renderer/loader/weburlresponse_extradata_impl.h5
-rw-r--r--chromium/content/renderer/manifest/manifest_manager.cc10
-rw-r--r--chromium/content/renderer/manifest/manifest_manager.h4
-rw-r--r--chromium/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc8
-rw-r--r--chromium/content/renderer/media/audio/audio_renderer_mixer_manager.cc4
-rw-r--r--chromium/content/renderer/media/audio/audio_renderer_sink_cache_impl.cc22
-rw-r--r--chromium/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc26
-rw-r--r--chromium/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc47
-rw-r--r--chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc111
-rw-r--r--chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h33
-rw-r--r--chromium/content/renderer/media/media_factory.cc143
-rw-r--r--chromium/content/renderer/media/media_factory.h13
-rw-r--r--chromium/content/renderer/media/media_permission_dispatcher.cc21
-rw-r--r--chromium/content/renderer/media/media_permission_dispatcher.h16
-rw-r--r--chromium/content/renderer/media/midi/midi_message_filter.cc5
-rw-r--r--chromium/content/renderer/media/pepper/pepper_to_video_track_adapter.cc250
-rw-r--r--chromium/content/renderer/media/pepper/pepper_to_video_track_adapter.h54
-rw-r--r--chromium/content/renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc111
-rw-r--r--chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.cc140
-rw-r--r--chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.h81
-rw-r--r--chromium/content/renderer/media/pepper/video_track_to_pepper_adapter_unittest.cc76
-rw-r--r--chromium/content/renderer/media/render_media_log_unittest.cc4
-rw-r--r--chromium/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc10
-rw-r--r--chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc12
-rw-r--r--chromium/content/renderer/media/renderer_webmediaplayer_delegate.h6
-rw-r--r--chromium/content/renderer/media/stream/aec_dump_message_filter.cc11
-rw-r--r--chromium/content/renderer/media/stream/apply_constraints_processor.cc2
-rw-r--r--chromium/content/renderer/media/stream/local_media_stream_audio_source.cc26
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_processor.cc58
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_processor.h4
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_processor_options.cc14
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_processor_options.h8
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_processor_unittest.cc30
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_source.h11
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_unittest.cc4
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util.cc2
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util.h15
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_audio.cc6
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc10
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.cc221
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.h23
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc101
-rw-r--r--chromium/content/renderer/media/stream/media_stream_device_observer.cc4
-rw-r--r--chromium/content/renderer/media/stream/media_stream_video_source.cc13
-rw-r--r--chromium/content/renderer/media/stream/media_stream_video_source.h2
-rw-r--r--chromium/content/renderer/media/stream/media_stream_video_source_unittest.cc44
-rw-r--r--chromium/content/renderer/media/stream/media_stream_video_track.cc11
-rw-r--r--chromium/content/renderer/media/stream/processed_local_audio_source.cc4
-rw-r--r--chromium/content/renderer/media/stream/processed_local_audio_source_unittest.cc5
-rw-r--r--chromium/content/renderer/media/stream/user_media_client_impl.cc4
-rw-r--r--chromium/content/renderer/media/stream/user_media_client_impl.h1
-rw-r--r--chromium/content/renderer/media/stream/user_media_client_impl_unittest.cc21
-rw-r--r--chromium/content/renderer/media/stream/user_media_processor.cc12
-rw-r--r--chromium/content/renderer/media/stream/user_media_processor.h2
-rw-r--r--chromium/content/renderer/media/stream/video_track_adapter.cc2
-rw-r--r--chromium/content/renderer/media/stream/webmediaplayer_ms.cc201
-rw-r--r--chromium/content/renderer/media/stream/webmediaplayer_ms.h30
-rw-r--r--chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.cc144
-rw-r--r--chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.h49
-rw-r--r--chromium/content/renderer/media/stream/webmediaplayer_ms_unittest.cc444
-rw-r--r--chromium/content/renderer/media/video_capture_impl.cc50
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc1
-rw-r--r--chromium/content/renderer/media/webrtc/mock_peer_connection_dependency_factory.cc17
-rw-r--r--chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc12
-rw-r--r--chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h4
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc28
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc4
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_tracker.cc28
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_tracker.h9
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc12
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc11
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h7
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc4
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc3
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc4
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_decoder.cc8
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc44
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter.h25
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter_unittest.cc34
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_decoder_factory.cc12
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_encoder.cc2
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc3
-rw-r--r--chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc10
-rw-r--r--chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h4
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc18
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc16
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc16
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_sink.h6
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc17
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h18
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc35
-rw-r--r--chromium/content/renderer/media_capture_from_element/canvas_capture_handler_unittest.cc2
-rw-r--r--chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc7
-rw-r--r--chromium/content/renderer/media_recorder/media_recorder_handler.cc6
-rw-r--r--chromium/content/renderer/media_recorder/video_track_recorder.cc3
-rw-r--r--chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc30
-rw-r--r--chromium/content/renderer/mus/mus_embedded_frame_delegate.h5
-rw-r--r--chromium/content/renderer/mus/renderer_window_tree_client.cc22
-rw-r--r--chromium/content/renderer/mus/renderer_window_tree_client.h3
-rw-r--r--chromium/content/renderer/navigation_state.cc (renamed from chromium/content/renderer/navigation_state_impl.cc)38
-rw-r--r--chromium/content/renderer/navigation_state.h (renamed from chromium/content/renderer/navigation_state_impl.h)35
-rw-r--r--chromium/content/renderer/notifications/notification_data_conversions.cc12
-rw-r--r--chromium/content/renderer/notifications/notification_data_conversions.h6
-rw-r--r--chromium/content/renderer/notifications/notification_data_conversions_unittest.cc12
-rw-r--r--chromium/content/renderer/p2p/host_address_request.cc2
-rw-r--r--chromium/content/renderer/p2p/ipc_network_manager.cc3
-rw-r--r--chromium/content/renderer/p2p/socket_client_impl.cc2
-rw-r--r--chromium/content/renderer/p2p/socket_dispatcher.cc27
-rw-r--r--chromium/content/renderer/p2p/socket_dispatcher.h6
-rw-r--r--chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc27
-rw-r--r--chromium/content/renderer/pepper/host_globals.cc15
-rw-r--r--chromium/content/renderer/pepper/host_var_tracker.cc12
-rw-r--r--chromium/content/renderer/pepper/message_channel.cc8
-rw-r--r--chromium/content/renderer/pepper/pepper_broker.cc9
-rw-r--r--chromium/content/renderer/pepper/pepper_browser_connection.cc3
-rw-r--r--chromium/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc5
-rw-r--r--chromium/content/renderer/pepper/pepper_file_chooser_host.cc21
-rw-r--r--chromium/content/renderer/pepper/pepper_file_chooser_host.h5
-rw-r--r--chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc30
-rw-r--r--chromium/content/renderer/pepper/pepper_file_system_host.cc1
-rw-r--r--chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc4
-rw-r--r--chromium/content/renderer/pepper/pepper_media_device_manager.cc2
-rw-r--r--chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc21
-rw-r--r--chromium/content/renderer/pepper/pepper_plugin_registry.cc10
-rw-r--r--chromium/content/renderer/pepper/pepper_url_loader_host.cc2
-rw-r--r--chromium/content/renderer/pepper/pepper_video_decoder_host.cc9
-rw-r--r--chromium/content/renderer/pepper/pepper_video_destination_host.cc108
-rw-r--r--chromium/content/renderer/pepper/pepper_video_destination_host.h59
-rw-r--r--chromium/content/renderer/pepper/pepper_video_encoder_host.cc2
-rw-r--r--chromium/content/renderer/pepper/pepper_video_source_host.cc322
-rw-r--r--chromium/content/renderer/pepper/pepper_video_source_host.h90
-rw-r--r--chromium/content/renderer/pepper/pepper_webplugin_impl.cc2
-rw-r--r--chromium/content/renderer/pepper/pepper_webplugin_impl.h2
-rw-r--r--chromium/content/renderer/pepper/pepper_websocket_host.cc4
-rw-r--r--chromium/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc4
-rw-r--r--chromium/content/renderer/pepper/plugin_module.cc11
-rw-r--r--chromium/content/renderer/pepper/plugin_object.cc5
-rw-r--r--chromium/content/renderer/pepper/plugin_power_saver_helper.cc4
-rw-r--r--chromium/content/renderer/pepper/plugin_power_saver_helper.h4
-rw-r--r--chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc1
-rw-r--r--chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc20
-rw-r--r--chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc2
-rw-r--r--chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc34
-rw-r--r--chromium/content/renderer/pepper/resource_converter.cc13
-rw-r--r--chromium/content/renderer/pepper/resource_creation_impl.cc8
-rw-r--r--chromium/content/renderer/pepper/resource_creation_impl.h2
-rw-r--r--chromium/content/renderer/pepper/url_request_info_util.cc14
-rw-r--r--chromium/content/renderer/pepper/v8_var_converter.cc23
-rw-r--r--chromium/content/renderer/pepper/v8_var_converter_unittest.cc7
-rw-r--r--chromium/content/renderer/pepper/video_decoder_shim.cc9
-rw-r--r--chromium/content/renderer/render_frame_impl.cc1004
-rw-r--r--chromium/content/renderer/render_frame_impl.h126
-rw-r--r--chromium/content/renderer/render_frame_impl_browsertest.cc63
-rw-r--r--chromium/content/renderer/render_frame_metadata_observer_impl.cc6
-rw-r--r--chromium/content/renderer/render_frame_proxy.cc26
-rw-r--r--chromium/content/renderer/render_frame_proxy.h5
-rw-r--r--chromium/content/renderer/render_process_impl.cc18
-rw-r--r--chromium/content/renderer/render_process_impl.h8
-rw-r--r--chromium/content/renderer/render_thread_impl.cc193
-rw-r--r--chromium/content/renderer/render_thread_impl.h47
-rw-r--r--chromium/content/renderer/render_thread_impl_browsertest.cc4
-rw-r--r--chromium/content/renderer/render_view_browsertest.cc90
-rw-r--r--chromium/content/renderer/render_view_impl.cc273
-rw-r--r--chromium/content/renderer/render_view_impl.h84
-rw-r--r--chromium/content/renderer/render_view_impl_android.cc54
-rw-r--r--chromium/content/renderer/render_widget.cc541
-rw-r--r--chromium/content/renderer/render_widget.h137
-rw-r--r--chromium/content/renderer/render_widget_fullscreen_pepper.cc46
-rw-r--r--chromium/content/renderer/render_widget_fullscreen_pepper.h9
-rw-r--r--chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc12
-rw-r--r--chromium/content/renderer/render_widget_owner_delegate.h6
-rw-r--r--chromium/content/renderer/render_widget_unittest.cc17
-rw-r--r--chromium/content/renderer/renderer_blink_platform_impl.cc143
-rw-r--r--chromium/content/renderer/renderer_blink_platform_impl.h29
-rw-r--r--chromium/content/renderer/renderer_main.cc14
-rw-r--r--chromium/content/renderer/renderer_main_platform_delegate_mac.mm27
-rw-r--r--chromium/content/renderer/renderer_webcookiejar_impl.cc3
-rw-r--r--chromium/content/renderer/service_worker/controller_service_worker_connector.h13
-rw-r--r--chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.cc72
-rw-r--r--chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.h20
-rw-r--r--chromium/content/renderer/service_worker/service_worker_context_client.cc443
-rw-r--r--chromium/content/renderer/service_worker/service_worker_context_client.h116
-rw-r--r--chromium/content/renderer/service_worker/service_worker_context_client_unittest.cc95
-rw-r--r--chromium/content/renderer/service_worker/service_worker_network_provider.cc14
-rw-r--r--chromium/content/renderer/service_worker/service_worker_network_provider.h6
-rw-r--r--chromium/content/renderer/service_worker/service_worker_provider_context.cc55
-rw-r--r--chromium/content/renderer/service_worker/service_worker_provider_context.h41
-rw-r--r--chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc115
-rw-r--r--chromium/content/renderer/service_worker/service_worker_provider_state_for_client.h7
-rw-r--r--chromium/content/renderer/service_worker/service_worker_subresource_loader.cc132
-rw-r--r--chromium/content/renderer/service_worker/service_worker_subresource_loader.h24
-rw-r--r--chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc208
-rw-r--r--chromium/content/renderer/service_worker/service_worker_timeout_timer.cc53
-rw-r--r--chromium/content/renderer/service_worker/service_worker_timeout_timer.h25
-rw-r--r--chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc42
-rw-r--r--chromium/content/renderer/service_worker/service_worker_type_converters.cc18
-rw-r--r--chromium/content/renderer/service_worker/service_worker_type_converters.h9
-rw-r--r--chromium/content/renderer/service_worker/thread_safe_script_container.cc78
-rw-r--r--chromium/content/renderer/service_worker/thread_safe_script_container.h93
-rw-r--r--chromium/content/renderer/service_worker/thread_safe_script_container_unittest.cc226
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_impl.cc144
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_impl.h123
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.cc310
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h49
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl_unittest.cc417
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc24
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_provider_impl.h8
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc72
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_registration_impl.h14
-rw-r--r--chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc136
-rw-r--r--chromium/content/renderer/shared_worker/embedded_shared_worker_stub.h36
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc13
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_factory_impl.h6
-rw-r--r--chromium/content/renderer/skia_benchmarking_extension.cc17
-rw-r--r--chromium/content/renderer/stats_collection_controller.cc74
-rw-r--r--chromium/content/renderer/stats_collection_observer.cc37
-rw-r--r--chromium/content/renderer/stats_collection_observer.h44
-rw-r--r--chromium/content/renderer/v8_value_converter_impl.cc16
-rw-r--r--chromium/content/renderer/web_ui_extension.cc11
-rw-r--r--chromium/content/renderer/web_ui_extension_data.cc3
-rw-r--r--chromium/content/renderer/webgraphicscontext3d_provider_impl.cc25
-rw-r--r--chromium/content/renderer/webgraphicscontext3d_provider_impl.h6
-rw-r--r--chromium/content/renderer/worker_thread_registry.cc2
-rw-r--r--chromium/content/renderer/worker_thread_registry_unittest.cc4
-rw-r--r--chromium/content/shell/BUILD.gn34
-rw-r--r--chromium/content/shell/android/BUILD.gn1
-rw-r--r--chromium/content/shell/common/layout_test.mojom2
-rw-r--r--chromium/content/shell/common/layout_test/OWNERS2
-rw-r--r--chromium/content/shell/common/layout_test/layout_test_messages.cc6
-rw-r--r--chromium/content/shell/common/layout_test/layout_test_messages.h6
-rw-r--r--chromium/content/shell/common/layout_test/layout_test_switches.cc9
-rw-r--r--chromium/content/shell/common/layout_test/layout_test_switches.h2
-rw-r--r--chromium/content/shell/common/shell_messages.cc6
-rw-r--r--chromium/content/shell/common/shell_messages.h6
-rw-r--r--chromium/content/shell/common/shell_switches.cc7
-rw-r--r--chromium/content/shell/common/shell_switches.h2
-rw-r--r--chromium/content/shell/common/v8_breakpad_support_win.h15
-rw-r--r--chromium/content/shell/common/v8_crashpad_support_win.cc (renamed from chromium/content/shell/common/v8_breakpad_support_win.cc)6
-rw-r--r--chromium/content/shell/common/v8_crashpad_support_win.h15
-rw-r--r--chromium/content/shell/test_runner/BUILD.gn4
-rw-r--r--chromium/content/test/BUILD.gn80
-rw-r--r--chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.cc23
-rw-r--r--chromium/content/utility/utility_main.cc6
-rw-r--r--chromium/content/utility/utility_thread_impl.cc8
-rw-r--r--chromium/content/utility/utility_thread_impl.h2
1758 files changed, 49142 insertions, 33859 deletions
diff --git a/chromium/content/BUILD.gn b/chromium/content/BUILD.gn
index 835bd6d5808..0ca39d7d5b0 100644
--- a/chromium/content/BUILD.gn
+++ b/chromium/content/BUILD.gn
@@ -10,8 +10,8 @@ import("//ppapi/buildflags/buildflags.gni")
config("content_implementation") {
defines = [ "CONTENT_IMPLEMENTATION" ]
configs = [
- "//build/config/compiler:wexit_time_destructors",
"//build/config/compiler:noshadowing",
+ "//build/config/compiler:wexit_time_destructors",
]
}
diff --git a/chromium/content/OWNERS b/chromium/content/OWNERS
index 239b4e6552c..c2ab1df254a 100644
--- a/chromium/content/OWNERS
+++ b/chromium/content/OWNERS
@@ -8,7 +8,6 @@ jam@chromium.org
jochen@chromium.org
kinuko@chromium.org
nasko@chromium.org
-nick@chromium.org
pfeldman@chromium.org
piman@chromium.org
diff --git a/chromium/content/app/android/content_jni_onload.cc b/chromium/content/app/android/content_jni_onload.cc
new file mode 100644
index 00000000000..db6ed89f737
--- /dev/null
+++ b/chromium/content/app/android/content_jni_onload.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 "content/public/app/content_jni_onload.h"
+
+#include <vector>
+
+#include "base/android/base_jni_onload.h"
+#include "base/android/jni_android.h"
+#include "base/android/library_loader/library_loader_hooks.h"
+#include "base/bind.h"
+#include "content/app/android/library_loader_hooks.h"
+#include "content/public/app/content_main.h"
+
+namespace content {
+namespace android {
+
+bool OnJNIOnLoadInit() {
+ if (!base::android::OnJNIOnLoadInit())
+ return false;
+
+ base::android::SetLibraryLoadedHook(&content::LibraryLoaded);
+ return true;
+}
+
+} // namespace android
+} // namespace content
diff --git a/chromium/content/app/content_main_runner_impl.cc b/chromium/content/app/content_main_runner_impl.cc
index 61ef09f6958..6ed770290b1 100644
--- a/chromium/content/app/content_main_runner_impl.cc
+++ b/chromium/content/app/content_main_runner_impl.cc
@@ -43,7 +43,9 @@
#include "content/app/mojo/mojo_init.h"
#include "content/browser/browser_process_sub_thread.h"
#include "content/browser/browser_thread_impl.h"
+#include "content/browser/scheduler/browser_task_executor.h"
#include "content/browser/startup_data_impl.h"
+#include "content/browser/startup_helper.h"
#include "content/common/content_constants_internal.h"
#include "content/common/url_schemes.h"
#include "content/public/app/content_main_delegate.h"
@@ -73,6 +75,7 @@
#include <cstring>
#include "base/trace_event/trace_event_etw_export_win.h"
+#include "ui/base/l10n/l10n_util_win.h"
#include "ui/display/win/dpi.h"
#elif defined(OS_MACOSX)
#include "base/mac/mach_port_broker.h"
@@ -194,8 +197,9 @@ void LoadV8SnapshotFile() {
base::ScopedFD fd =
file_descriptor_store.MaybeTakeFD(snapshot_data_descriptor, &region);
if (fd.is_valid()) {
- gin::V8Initializer::LoadV8SnapshotFromFD(fd.get(), region.offset,
- region.size, kSnapshotType);
+ base::File file(fd.release());
+ gin::V8Initializer::LoadV8SnapshotFromFile(std::move(file), &region,
+ kSnapshotType);
return;
}
#endif // OS_POSIX && !OS_MACOSX
@@ -213,8 +217,8 @@ void LoadV8NativesFile() {
base::ScopedFD fd =
file_descriptor_store.MaybeTakeFD(kV8NativesDataDescriptor, &region);
if (fd.is_valid()) {
- gin::V8Initializer::LoadV8NativesFromFD(fd.get(), region.offset,
- region.size);
+ base::File file(fd.release());
+ gin::V8Initializer::LoadV8NativesFromFile(std::move(file), &region);
return;
}
#endif // OS_POSIX && !OS_MACOSX
@@ -395,12 +399,6 @@ void PreSandboxInit() {
#endif // OS_LINUX
-bool IsRootProcess() {
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- return command_line.GetSwitchValueASCII(switches::kProcessType).empty();
-}
-
} // namespace
class ContentClientInitializer {
@@ -658,14 +656,6 @@ int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
return exit_code;
completed_basic_startup_ = true;
- // We will need to use data from resources.pak in later cl, so load the file
- // now.
- if (IsRootProcess()) {
- ui::DataPack* data_pack = delegate_->LoadServiceManifestDataPack();
- // TODO(ranj): Read manifest from this data pack.
- ignore_result(data_pack);
- }
-
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
std::string process_type =
@@ -870,19 +860,20 @@ int ContentMainRunnerImpl::Run(bool start_service_manager_only) {
main_params.startup_data = startup_data_.get();
if (GetContentClient()->browser()->ShouldCreateTaskScheduler()) {
- // Create the TaskScheduler early to allow upcoming code to use
- // the post_task.h API. Note: This is okay because RunBrowserProcessMain()
- // will soon result in invoking TaskScheduler::GetInstance()->Start().
- // The TaskScheduler being started soon is a strict requirement (delaying
- // this start would result in posted tasks not running).
+ // Create and start the TaskScheduler early to allow upcoming code to use
+ // the post_task.h API.
base::TaskScheduler::Create("Browser");
}
- // Register the TaskExecutor for posting task to the BrowserThreads. It is
- // incorrect to post to a BrowserThread before this point.
- BrowserThreadImpl::CreateTaskExecutor();
-
delegate_->PreCreateMainMessageLoop();
+#if defined(OS_WIN)
+ if (l10n_util::GetLocaleOverrides().empty()) {
+ // Override the configured locale with the user's preferred UI language.
+ // Don't do this if the locale is already set, which is done by
+ // integration tests to ensure tests always run with the same locale.
+ l10n_util::OverrideLocaleWithUILanguageList();
+ }
+#endif
// Create a MessageLoop if one does not already exist for the current
// thread. This thread won't be promoted as BrowserThread::UI until
@@ -890,7 +881,22 @@ int ContentMainRunnerImpl::Run(bool start_service_manager_only) {
if (!base::MessageLoopCurrentForUI::IsSet())
main_message_loop_ = std::make_unique<base::MessageLoopForUI>();
- delegate_->PostEarlyInitialization();
+ if (delegate_->ShouldCreateFeatureList()) {
+ DCHECK(!field_trial_list_);
+ field_trial_list_ = SetUpFieldTrialsAndFeatureList();
+ }
+
+ delegate_->PostEarlyInitialization(main_params.ui_task != nullptr);
+
+ if (GetContentClient()->browser()->ShouldCreateTaskScheduler()) {
+ // The FeatureList needs to create before starting the TaskScheduler.
+ StartBrowserTaskScheduler();
+ }
+
+ // Register the TaskExecutor for posting task to the BrowserThreads. It is
+ // incorrect to post to a BrowserThread before this point.
+ BrowserTaskExecutor::Create();
+
return RunBrowserProcessMain(main_params, delegate_);
}
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
@@ -911,8 +917,10 @@ void ContentMainRunnerImpl::Shutdown() {
delegate_->ProcessExiting(process_type);
}
+#if !defined(CHROME_MULTIPLE_DLL_CHILD)
// The message loop needs to be destroyed before |exit_manager_|.
main_message_loop_.reset();
+#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
#if defined(OS_WIN)
#ifdef _CRTDBG_MAP_ALLOC
diff --git a/chromium/content/app/content_main_runner_impl.h b/chromium/content/app/content_main_runner_impl.h
index aff316c59df..c402da274b0 100644
--- a/chromium/content/app/content_main_runner_impl.h
+++ b/chromium/content/app/content_main_runner_impl.h
@@ -10,6 +10,7 @@
#include "base/callback_forward.h"
#include "base/memory/scoped_refptr.h"
#include "base/message_loop/message_loop.h"
+#include "base/metrics/field_trial.h"
#include "build/build_config.h"
#include "content/browser/startup_data_impl.h"
#include "content/public/app/content_main.h"
@@ -72,10 +73,14 @@ class ContentMainRunnerImpl : public ContentMainRunner {
CreatedMainPartsClosure* created_main_parts_closure_ = nullptr;
+#if !defined(CHROME_MULTIPLE_DLL_CHILD)
std::unique_ptr<base::MessageLoop> main_message_loop_;
std::unique_ptr<StartupDataImpl> startup_data_;
+ std::unique_ptr<base::FieldTrialList> field_trial_list_;
+#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
+
DISALLOW_COPY_AND_ASSIGN(ContentMainRunnerImpl);
};
diff --git a/chromium/content/app/strings/content_strings.grd b/chromium/content/app/strings/content_strings.grd
index 79f5ebed630..8017be1ed44 100644
--- a/chromium/content/app/strings/content_strings.grd
+++ b/chromium/content/app/strings/content_strings.grd
@@ -704,22 +704,6 @@ below:
video
</message>
- <message name="IDS_AX_MEDIA_MUTE_BUTTON_HELP" desc="Accessibility help description for mute button">
- mute audio track
- </message>
-
- <message name="IDS_AX_MEDIA_UNMUTE_BUTTON_HELP" desc="Accessibility help description for turn mute off button">
- unmute audio track
- </message>
-
- <message name="IDS_AX_MEDIA_PLAY_BUTTON_HELP" desc="Accessibility help description for play button">
- begin playback
- </message>
-
- <message name="IDS_AX_MEDIA_PAUSE_BUTTON_HELP" desc="Accessibility help description for pause button">
- pause playback
- </message>
-
<message name="IDS_AX_MEDIA_AUDIO_SLIDER_HELP" desc="Accessibility help description for audio timeline slider">
audio time scrubber
</message>
@@ -728,6 +712,10 @@ below:
movie time scrubber
</message>
+ <message name="IDS_AX_MEDIA_VOLUME_SLIDER_HELP" desc="Accessibility help description for volume slider">
+ volume slider
+ </message>
+
<message name="IDS_AX_MEDIA_CURRENT_TIME_DISPLAY_HELP" desc="Accessibility help description for elapsed time display">
current time in seconds
</message>
@@ -736,42 +724,6 @@ below:
number of seconds of movie remaining
</message>
- <message name="IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON_HELP" desc="Accessibility help description for enter fullscreen button">
- play movie in full screen mode
- </message>
-
- <message name="IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON_HELP" desc="Accessibility help description for exit fullscreen button">
- exit full screen
- </message>
-
- <message name="IDS_AX_MEDIA_DISPLAY_CUT_OUT_FULL_SCREEN_BUTTON_HELP" desc="Accessibility help description for display cutout fullscreen button">
- toggle fullscreen into display cutout area
- </message>
-
- <message name="IDS_AX_MEDIA_ENTER_PICTURE_IN_PICTURE_BUTTON_HELP" desc="Accessibility help description for enter Picture-in-Picture button">
- play video in picture-in-picture mode
- </message>
-
- <message name="IDS_AX_MEDIA_EXIT_PICTURE_IN_PICTURE_BUTTON_HELP" desc="Accessibility help description for exit Picture-in-Picture button">
- exit picture-in-picture
- </message>
-
- <message name="IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP" desc="Accessibility help description for show closed captions button">
- start displaying closed captions
- </message>
-
- <message name="IDS_AX_MEDIA_HIDE_CLOSED_CAPTIONS_BUTTON_HELP" desc="Accessibility help description for hide closed captions button">
- stop displaying closed captions
- </message>
-
- <message name="IDS_AX_MEDIA_CAST_OFF_BUTTON_HELP" desc="Accessibility help description for remote playback button">
- play on remote device
- </message>
-
- <message name="IDS_AX_MEDIA_CAST_ON_BUTTON_HELP" desc="Accessibility help description for remote playback control button">
- control remote playback
- </message>
-
<message name="IDS_AX_MEDIA_OVERFLOW_BUTTON_HELP" desc="Accessibility help description for overflow button.">
more options
</message>
diff --git a/chromium/content/app/strings/translations/content_strings_am.xtb b/chromium/content/app/strings/translations/content_strings_am.xtb
index 7213b247e5e..eb88b778f7f 100644
--- a/chromium/content/app/strings/translations/content_strings_am.xtb
+++ b/chromium/content/app/strings/translations/content_strings_am.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="am">
<translation id="1018939186200882850">የምናሌ ንጥል</translation>
-<translation id="1020833440720551630">የድምጽ ትራክ ላይ ድምጸ-ከል አድርግ</translation>
<translation id="10623998915015855">የማቀያየሪያ አዝራር</translation>
<translation id="1088086359088493902">ሰኮንዶች</translation>
<translation id="1171774979989969504">እባክዎ የኢሜይል አድራሻ ያስገቡ።</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">ክሬዲቶች</translation>
<translation id="1342835525016946179">ጽሑፍ</translation>
<translation id="1359897965706325498">ሰንደቅ</translation>
-<translation id="1548116112524424341">ቪዲዮን በስዕል-ውስጥ-ስዕል ሁነታ አጫውት</translation>
<translation id="1589122976691792535">ክልል</translation>
<translation id="1591562245178063882">በዚህ ወር</translation>
<translation id="1637811476055996098">ፋይሎችን ይምረጡ</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">የዛፍ ፍርግርግ</translation>
<translation id="1822429046913737220">ጥዋት/ከሰዓት</translation>
<translation id="1832974991323546415">በርቀት መሳሪያ ላይ አጫውት</translation>
-<translation id="1838818994221231429">ሙሉ ማያ ገጽን ወደ የተቆረጠው የማሳያ አካባቢ ይቀይሩ</translation>
<translation id="190587075670221089">ስረዛ</translation>
<translation id="1907737156431278478">ምሳሌ</translation>
<translation id="1921819250265091946">ቀቀ</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">ሰዓት</translation>
<translation id="5630795885300617244">10 ሴ ለመዝለል ወደ ግራ ወይም ቀኝ ሁለቴ መታ ያድርጉ</translation>
<translation id="5631759159893697722">ረቂቅ</translation>
-<translation id="5641012560118721995">መልሶ ማጫወትን ለአፍታ አቁም</translation>
<translation id="5643186887447432888">አዝራር</translation>
<translation id="5677946354068040947">ተጨማሪ አማራጮች</translation>
<translation id="576709008726043716">መግቢያ</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">ዳግም አስጀምር</translation>
<translation id="5966707198760109579">ሳምንት</translation>
<translation id="5987525920412732405">ማሾሪያ አዝራር</translation>
+<translation id="6011459053400940133">የድምጽ ተንሸራታች</translation>
<translation id="6015796118275082299">ዓመት</translation>
<translation id="6023896073578205740">የዝርዝር ሳጥን</translation>
-<translation id="6101327004457443354">የድምጹ ትራክ ድምጸ-ከል አንሳ</translation>
<translation id="6150588977291308318">ዋቢ መጽሐፍት</translation>
<translation id="6164829606128959761">ሜትር</translation>
<translation id="6166809985690652833">ድሕረ ቃል</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">ሰዓቶች</translation>
<translation id="7681220483256441252">መረጃ ጠቋሚ</translation>
<translation id="7720026100085573005">ቀሪ ጊዜ</translation>
-<translation id="7740016676195725605">የተዘጉ የስዕል መግለጫዎችን ማሳየት አቁም</translation>
<translation id="7740050170769002709">የኤች ቲ ኤም ኤል ይዘት</translation>
<translation id="7750228210027921155">በሥዕል ውስጥ ሥዕል</translation>
<translation id="7789962463072032349">ላፍታ አቁም</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">የጽሑፍ መስክ ፈልግ</translation>
<translation id="8057695513531652401">ማስታወቂያ</translation>
<translation id="8105797009065549151">ማስታወሻ ማጣቀሻ</translation>
-<translation id="8115662671911883373">የተዘጉ የስዕል መግለጫዎችን ማሳየት ጀምር</translation>
<translation id="8117451130807776954">በዚህ ሳምንት</translation>
-<translation id="819205353528511139">ፊልሙን በሙሉ ማያ ገጽ ሁነታ አጫውት</translation>
<translation id="8199524924445686405">ዓዓዓዓ</translation>
<translation id="8284326494547611709">መግለጫ ጽሑፎች</translation>
<translation id="835897206747267392">ልክ ያልሆነ እሴት።</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">በርቀት መልሶ ማጫወትን ተቆጣጠር</translation>
<translation id="862370744433916922">የግርጌ ጽሑፍ</translation>
<translation id="8750798805984357768">እባክዎ ከእነዚህ አማራጮች ውስጥ አንዱን ይምረጡ።</translation>
-<translation id="8785498733064193001">መልሶ ማጫወት ይጀምሩ</translation>
<translation id="8808573423886751634">ምዕራፍ</translation>
<translation id="8845239796550121995">አሁን ወደ የእርስዎ ቴሌቪዥን cast በማድረግ ላይ</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ar.xtb b/chromium/content/app/strings/translations/content_strings_ar.xtb
index e75e94de136..82b23d473b7 100644
--- a/chromium/content/app/strings/translations/content_strings_ar.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ar.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ar">
<translation id="1018939186200882850">عنصر القائمة</translation>
-<translation id="1020833440720551630">كتم صوت المقطع الصوتي</translation>
<translation id="10623998915015855">زر التبديل</translation>
<translation id="1088086359088493902">ثوانٍ‬‬</translation>
<translation id="1171774979989969504">يُرجى إدخال عنوان البريد الإلكتروني.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">إسهامات</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">إعلان بانر</translation>
-<translation id="1548116112524424341">تشغيل الفيديو في وضع "نافذة ضمن نافذة"</translation>
<translation id="1589122976691792535">منطقة</translation>
<translation id="1591562245178063882">هذا الشهر</translation>
<translation id="1637811476055996098">اختيار الملفات</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">شبكة متفرعة</translation>
<translation id="1822429046913737220">صباحًا/مساءً</translation>
<translation id="1832974991323546415">تشغيل على جهاز بعيد</translation>
-<translation id="1838818994221231429">تبديل وضع ملء الشاشة إلى صورة مقطوعة للشاشة</translation>
<translation id="190587075670221089">حذف</translation>
<translation id="1907737156431278478">مثال</translation>
<translation id="1921819250265091946">يوم</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">الوقت</translation>
<translation id="5630795885300617244">انقر مرّتين جهة اليمين أو اليسار لتخطي 10 ثوانٍ.</translation>
<translation id="5631759159893697722">نبذة مختصرة</translation>
-<translation id="5641012560118721995">إيقاف التشغيل مؤقتًا</translation>
<translation id="5643186887447432888">زر</translation>
<translation id="5677946354068040947">خيارات إضافية</translation>
<translation id="576709008726043716">مقدمة</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">إعادة</translation>
<translation id="5966707198760109579">الأسبوع</translation>
<translation id="5987525920412732405">زر الدوران</translation>
+<translation id="6011459053400940133">شريط تمرير مستوى الصوت</translation>
<translation id="6015796118275082299">عام</translation>
<translation id="6023896073578205740">مربع القائمة</translation>
-<translation id="6101327004457443354">إعادة صوت المقطع الصوتي</translation>
<translation id="6150588977291308318">قائمة مراجع</translation>
<translation id="6164829606128959761">متر</translation>
<translation id="6166809985690652833">كلمة ختامية</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">ساعات</translation>
<translation id="7681220483256441252">فهرس</translation>
<translation id="7720026100085573005">المدة المتبقية</translation>
-<translation id="7740016676195725605">إيقاف عرض الترجمة والشرح</translation>
<translation id="7740050170769002709">‏محتوى HTML</translation>
<translation id="7750228210027921155">نافذة ضمن النافذة</translation>
<translation id="7789962463072032349">إيقاف مؤقت</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">الحقل النصي للبحث</translation>
<translation id="8057695513531652401">ملاحظة</translation>
<translation id="8105797009065549151">ملاحظة مرجعية</translation>
-<translation id="8115662671911883373">بدء عرض الترجمة والشرح</translation>
<translation id="8117451130807776954">هذا الأسبوع</translation>
-<translation id="819205353528511139">تشغيل الفيلم في وضع ملء الشاشة</translation>
<translation id="8199524924445686405">سنة</translation>
<translation id="8284326494547611709">الترجمة والشرح</translation>
<translation id="835897206747267392">قيمة غير صحيحة</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">التحكم في التشغيل عن بعد</translation>
<translation id="862370744433916922">ترجمة مصاحِبة</translation>
<translation id="8750798805984357768">يُرجى اختيار أحد هذه الخيارات.</translation>
-<translation id="8785498733064193001">بدء التشغيل</translation>
<translation id="8808573423886751634">فصل</translation>
<translation id="8845239796550121995">يتم الآن الإرسال إلى جهاز التلفزيون</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_bg.xtb b/chromium/content/app/strings/translations/content_strings_bg.xtb
index 6a49487bf0f..55e8e96f391 100644
--- a/chromium/content/app/strings/translations/content_strings_bg.xtb
+++ b/chromium/content/app/strings/translations/content_strings_bg.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="bg">
<translation id="1018939186200882850">елемент от меню</translation>
-<translation id="1020833440720551630">заглушаване на аудиозаписа</translation>
<translation id="10623998915015855">бутон за превключване</translation>
<translation id="1088086359088493902">Секунди</translation>
<translation id="1171774979989969504">Моля, въведете имейл адрес.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">признания за източника</translation>
<translation id="1342835525016946179">статия</translation>
<translation id="1359897965706325498">банер</translation>
-<translation id="1548116112524424341">възпроизвеждане на видеоклипа в режим „картина в картината“</translation>
<translation id="1589122976691792535">регион</translation>
<translation id="1591562245178063882">Този месец</translation>
<translation id="1637811476055996098">Избор на файлове</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">дървовидна таблица</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">възпроизвеждане на отдалечено устройство</translation>
-<translation id="1838818994221231429">превключване между цял екран и екран с прорез</translation>
<translation id="190587075670221089">изтриване</translation>
<translation id="1907737156431278478">пример</translation>
<translation id="1921819250265091946">дд</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Докоснете два пъти стрелката наляво или надясно, за да пропуснете 10 сек</translation>
<translation id="5631759159893697722">резюме</translation>
-<translation id="5641012560118721995">поставяне на възпроизвеждането на пауза</translation>
<translation id="5643186887447432888">бутон</translation>
<translation id="5677946354068040947">още опции</translation>
<translation id="576709008726043716">въведение</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Нулиране</translation>
<translation id="5966707198760109579">Седмица</translation>
<translation id="5987525920412732405">брояч</translation>
+<translation id="6011459053400940133">плъзгач за силата на звука</translation>
<translation id="6015796118275082299">Година</translation>
<translation id="6023896073578205740">списъчно поле</translation>
-<translation id="6101327004457443354">пускане на аудиозаписа</translation>
<translation id="6150588977291308318">библиография</translation>
<translation id="6164829606128959761">индикатор</translation>
<translation id="6166809985690652833">послеслов</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Часове</translation>
<translation id="7681220483256441252">показалец</translation>
<translation id="7720026100085573005">оставащо време</translation>
-<translation id="7740016676195725605">спиране на показването на надписите</translation>
<translation id="7740050170769002709">HTML съдържание</translation>
<translation id="7750228210027921155">Картина в картината</translation>
<translation id="7789962463072032349">поставяне на пауза</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">текстово поле за търсене</translation>
<translation id="8057695513531652401">известие</translation>
<translation id="8105797009065549151">препратка към бележка</translation>
-<translation id="8115662671911883373">започване на показването на надписите</translation>
<translation id="8117451130807776954">Тази седмица</translation>
-<translation id="819205353528511139">пускане на филма в режим на цял екран</translation>
<translation id="8199524924445686405">гггг</translation>
<translation id="8284326494547611709">Надписи</translation>
<translation id="835897206747267392">Невалидна стойност.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">управление на отдалеченото възпроизвеждане</translation>
<translation id="862370744433916922">подзаглавие</translation>
<translation id="8750798805984357768">Моля, изберете една от тези опции.</translation>
-<translation id="8785498733064193001">начало на възпроизвеждането</translation>
<translation id="8808573423886751634">глава</translation>
<translation id="8845239796550121995">В момента се предава към телевизора ви</translation>
<translation id="8851136666856101339">основен елемент</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_bn.xtb b/chromium/content/app/strings/translations/content_strings_bn.xtb
index bf23203b1ac..4abf7705dc8 100644
--- a/chromium/content/app/strings/translations/content_strings_bn.xtb
+++ b/chromium/content/app/strings/translations/content_strings_bn.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="bn">
<translation id="1018939186200882850">মেনু আইটেম</translation>
-<translation id="1020833440720551630">অডিও ট্র্যাক মিউট করুন</translation>
<translation id="10623998915015855">টগল বোতাম</translation>
<translation id="1088086359088493902">সেকেন্ড</translation>
<translation id="1171774979989969504">অনুগ্রহ করে কোন ইমেল আইডি লিখুন:</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">ক্রেডিট</translation>
<translation id="1342835525016946179">নিবন্ধ</translation>
<translation id="1359897965706325498">ব্যানার</translation>
-<translation id="1548116112524424341">ছবির-মধ্যে-ছবি মোডে ভিডিও চালান</translation>
<translation id="1589122976691792535">অঞ্চল</translation>
<translation id="1591562245178063882">এই মাস</translation>
<translation id="1637811476055996098">ফাইল বেছে নিন</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">ট্রি গ্রিড</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">রিমোট ডিভাইসে প্লে করুন</translation>
-<translation id="1838818994221231429">ডিসপ্লে কাট-আউট থেকে ফুল-স্ক্রিনে টগল করুন</translation>
<translation id="190587075670221089">মোছা হচ্ছে</translation>
<translation id="1907737156431278478">উদাহরণ</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">১০ সেকেন্ড আগে পরে করার জন্য বাঁ অথবা ডান দিকে ডবল ট্যাপ করুন</translation>
<translation id="5631759159893697722">বিমূর্ত</translation>
-<translation id="5641012560118721995">প্লেব্যাক বিরতি</translation>
<translation id="5643186887447432888">বোতাম</translation>
<translation id="5677946354068040947">আরও বিকল্প</translation>
<translation id="576709008726043716">পরিচয়</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">রিসেট করুন</translation>
<translation id="5966707198760109579">সপ্তাহ</translation>
<translation id="5987525920412732405">ঘোড়ানোর বোতাম</translation>
+<translation id="6011459053400940133">ভলিউম স্লাইডার</translation>
<translation id="6015796118275082299">বছর</translation>
<translation id="6023896073578205740">তালিকা বাক্স</translation>
-<translation id="6101327004457443354">অডিও ট্র্যাক সশব্দ করুন</translation>
<translation id="6150588977291308318">বিবলিওগ্রাফি</translation>
<translation id="6164829606128959761">মিটার</translation>
<translation id="6166809985690652833">পরিশিষ্ট</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">ঘণ্টা</translation>
<translation id="7681220483256441252">সূচি</translation>
<translation id="7720026100085573005">অবশিষ্ট সময়</translation>
-<translation id="7740016676195725605">বদ্ধ পরিচয়লিপিগুলির প্রদর্শন থামান</translation>
<translation id="7740050170769002709">HTML সামগ্রী</translation>
<translation id="7750228210027921155">ছবির-মধ্যে-ছবি</translation>
<translation id="7789962463072032349">বিরাম</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">সার্চ পাঠ্য ফিল্ড</translation>
<translation id="8057695513531652401">বিজ্ঞপ্তি</translation>
<translation id="8105797009065549151">নোটের রেফারেন্স</translation>
-<translation id="8115662671911883373">বন্ধ পরিচয়লিপিগুলির প্রদর্শন শুরু করুন</translation>
<translation id="8117451130807776954">এই সপ্তাহ</translation>
-<translation id="819205353528511139">পূর্ণ স্ক্রিন মোডে চলচ্চিত্র চালান</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">পরিচয়লিপিগুলি</translation>
<translation id="835897206747267392">অকার্যকর মান৷</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">রিমোট প্লেব্যাক নিয়ন্ত্রণ করুন</translation>
<translation id="862370744433916922">সাবটাইটেল</translation>
<translation id="8750798805984357768">দয়া করে বিকল্পগুলির একটি নির্বাচন করুন৷</translation>
-<translation id="8785498733064193001">প্লেব্যাক শুরু করুন</translation>
<translation id="8808573423886751634">অধ্যায়</translation>
<translation id="8845239796550121995">এখন আপনার TV তে কাস্ট করা হচ্ছে</translation>
<translation id="8851136666856101339">প্রধান</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ca.xtb b/chromium/content/app/strings/translations/content_strings_ca.xtb
index d396d40d4bb..9509f539b10 100644
--- a/chromium/content/app/strings/translations/content_strings_ca.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ca.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ca">
<translation id="1018939186200882850">element del menú</translation>
-<translation id="1020833440720551630">silencia la pista d'àudio</translation>
<translation id="10623998915015855">botó de commutació</translation>
<translation id="1088086359088493902">Segons</translation>
<translation id="1171774979989969504">Introduïu una adreça electrònica.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">crèdits</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">bàner</translation>
-<translation id="1548116112524424341">reprodueix el vídeo en mode de pantalla en pantalla</translation>
<translation id="1589122976691792535">regió</translation>
<translation id="1591562245178063882">Aquest mes</translation>
<translation id="1637811476055996098">Trieu els fitxers</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">quadrícula d'arbre</translation>
<translation id="1822429046913737220">a. m./p. m.</translation>
<translation id="1832974991323546415">reprodueix al dispositiu remot</translation>
-<translation id="1838818994221231429">activa o desactiva la pantalla completa a l'àrea del retall de pantalla</translation>
<translation id="190587075670221089">supressió</translation>
<translation id="1907737156431278478">exemple</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Fes doble toc a l'esquerra o a la dreta per saltar 10 s</translation>
<translation id="5631759159893697722">resum</translation>
-<translation id="5641012560118721995">pausa la reproducció</translation>
<translation id="5643186887447432888">botó</translation>
<translation id="5677946354068040947">més opcions</translation>
<translation id="576709008726043716">introducció</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Restableix</translation>
<translation id="5966707198760109579">Setmana</translation>
<translation id="5987525920412732405">botó de selecció de valors</translation>
+<translation id="6011459053400940133">control lliscant de volum</translation>
<translation id="6015796118275082299">Any</translation>
<translation id="6023896073578205740">quadre de llista</translation>
-<translation id="6101327004457443354">deixa de silenciar la pista d'àudio</translation>
<translation id="6150588977291308318">bibliografia</translation>
<translation id="6164829606128959761">comptador</translation>
<translation id="6166809985690652833">cloenda</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Hores</translation>
<translation id="7681220483256441252">índex</translation>
<translation id="7720026100085573005">temps restant</translation>
-<translation id="7740016676195725605">deixa de mostrar subtítols ocults</translation>
<translation id="7740050170769002709">Contingut HTML</translation>
<translation id="7750228210027921155">Pantalla en pantalla</translation>
<translation id="7789962463072032349">posa en pausa</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">camp de text de la cerca</translation>
<translation id="8057695513531652401">avís</translation>
<translation id="8105797009065549151">referència de la nota</translation>
-<translation id="8115662671911883373">comença a mostrar subtítols ocults</translation>
<translation id="8117451130807776954">Aquesta setmana</translation>
-<translation id="819205353528511139">reprodueix la pel·lícula en mode de pantalla completa</translation>
<translation id="8199524924445686405">aaaa</translation>
<translation id="8284326494547611709">Subtítols</translation>
<translation id="835897206747267392">Valor no vàlid.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">reproducció amb comandament</translation>
<translation id="862370744433916922">subtítol</translation>
<translation id="8750798805984357768">Seleccioneu una d'aquestes opcions.</translation>
-<translation id="8785498733064193001">inicia la reproducció</translation>
<translation id="8808573423886751634">capítol</translation>
<translation id="8845239796550121995">S'està emetent al televisor</translation>
<translation id="8851136666856101339">principal</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_cs.xtb b/chromium/content/app/strings/translations/content_strings_cs.xtb
index bfa537c9a77..0f96cf73b2d 100644
--- a/chromium/content/app/strings/translations/content_strings_cs.xtb
+++ b/chromium/content/app/strings/translations/content_strings_cs.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="cs">
<translation id="1018939186200882850">položka nabídky</translation>
-<translation id="1020833440720551630">ztlumit zvukovou stopu</translation>
<translation id="10623998915015855">přepínací tlačítko</translation>
<translation id="1088086359088493902">Sekundy</translation>
<translation id="1171774979989969504">Zadejte prosím e-mailovou adresu.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">poděkování</translation>
<translation id="1342835525016946179">čl</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">přehrát video v režimu obrazu v obraze</translation>
<translation id="1589122976691792535">oblast</translation>
<translation id="1591562245178063882">Tento měsíc</translation>
<translation id="1637811476055996098">Zvolit soubory</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">stromová mřížka</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">přehrát ve vzdáleném zařízení</translation>
-<translation id="1838818994221231429">přepnout celou obrazovku na oblast výřezu displeje</translation>
<translation id="190587075670221089">smazání</translation>
<translation id="1907737156431278478">příklad</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">čas</translation>
<translation id="5630795885300617244">Dvojitým klepnutím na šipku vlevo nebo vpravo přeskočíte o 10 s</translation>
<translation id="5631759159893697722">abstrakt</translation>
-<translation id="5641012560118721995">pozastavit přehrávání</translation>
<translation id="5643186887447432888">tlačítko</translation>
<translation id="5677946354068040947">další možnosti</translation>
<translation id="576709008726043716">úvod</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Resetovat</translation>
<translation id="5966707198760109579">Týden</translation>
<translation id="5987525920412732405">číselník</translation>
+<translation id="6011459053400940133">posuvník hlasitosti</translation>
<translation id="6015796118275082299">Rok</translation>
<translation id="6023896073578205740">seznam</translation>
-<translation id="6101327004457443354">zapnout zvukovou stopu</translation>
<translation id="6150588977291308318">bibliografie</translation>
<translation id="6164829606128959761">měřič</translation>
<translation id="6166809985690652833">doslov</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Hodiny</translation>
<translation id="7681220483256441252">rejstřík</translation>
<translation id="7720026100085573005">zbývající čas</translation>
-<translation id="7740016676195725605">ukončit zobrazování titulků</translation>
<translation id="7740050170769002709">Obsah ve formátu HTML</translation>
<translation id="7750228210027921155">Obraz v obraze</translation>
<translation id="7789962463072032349">pozastavit</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">pole pro vyhledání textu</translation>
<translation id="8057695513531652401">oznámení</translation>
<translation id="8105797009065549151">odkaz na poznámku</translation>
-<translation id="8115662671911883373">zahájit zobrazování titulků</translation>
<translation id="8117451130807776954">Tento týden</translation>
-<translation id="819205353528511139">přehrát film v režimu celé obrazovky</translation>
<translation id="8199524924445686405">rrrr</translation>
<translation id="8284326494547611709">Titulky</translation>
<translation id="835897206747267392">Neplatná hodnota.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">ovládání vzdáleného přehrávání</translation>
<translation id="862370744433916922">titulek</translation>
<translation id="8750798805984357768">Vyberte jednu z těchto možností.</translation>
-<translation id="8785498733064193001">zahájit přehrávání</translation>
<translation id="8808573423886751634">kapitola</translation>
<translation id="8845239796550121995">Odesílání do televize</translation>
<translation id="8851136666856101339">hlavní</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_da.xtb b/chromium/content/app/strings/translations/content_strings_da.xtb
index 2f768137392..5d5f8835b01 100644
--- a/chromium/content/app/strings/translations/content_strings_da.xtb
+++ b/chromium/content/app/strings/translations/content_strings_da.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="da">
<translation id="1018939186200882850">menupunkt</translation>
-<translation id="1020833440720551630">slå lydspor fra</translation>
<translation id="10623998915015855">til/fra-knap</translation>
<translation id="1088086359088493902">Sekunder</translation>
<translation id="1171774979989969504">Angiv en mailadresse.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">anerkendelser</translation>
<translation id="1342835525016946179">artikel</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">afspil video i tilstanden integreret billede</translation>
<translation id="1589122976691792535">område</translation>
<translation id="1591562245178063882">Denne måned</translation>
<translation id="1637811476055996098">Vælg filer</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">trægitter</translation>
<translation id="1822429046913737220">f.m./e.m.</translation>
<translation id="1832974991323546415">afspil på en enhed via fjernadgang</translation>
-<translation id="1838818994221231429">skift fra fuld skærm til skærmhak</translation>
<translation id="190587075670221089">sletning</translation>
<translation id="1907737156431278478">eksempel</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">tidspunkt</translation>
<translation id="5630795885300617244">Tryk to gange til venstre eller højre for at springe ti sekunder over</translation>
<translation id="5631759159893697722">abstrakt</translation>
-<translation id="5641012560118721995">pause</translation>
<translation id="5643186887447432888">knap</translation>
<translation id="5677946354068040947">flere valgmuligheder</translation>
<translation id="576709008726043716">indledning</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Nulstil</translation>
<translation id="5966707198760109579">Uge</translation>
<translation id="5987525920412732405">skalafelt</translation>
+<translation id="6011459053400940133">lydstyrkeskyder</translation>
<translation id="6015796118275082299">År</translation>
<translation id="6023896073578205740">listefelt</translation>
-<translation id="6101327004457443354">slå lydspor til</translation>
<translation id="6150588977291308318">bibliografi</translation>
<translation id="6164829606128959761">måler</translation>
<translation id="6166809985690652833">efterskrift</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Timer</translation>
<translation id="7681220483256441252">indeks</translation>
<translation id="7720026100085573005">resterende tid</translation>
-<translation id="7740016676195725605">stop visning af undertekster</translation>
<translation id="7740050170769002709">HTML-indhold</translation>
<translation id="7750228210027921155">Integreret billede</translation>
<translation id="7789962463072032349">pause</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">tekstfelt til søgning</translation>
<translation id="8057695513531652401">meddelelse</translation>
<translation id="8105797009065549151">reference i noter</translation>
-<translation id="8115662671911883373">start visning af undertekster</translation>
<translation id="8117451130807776954">Denne uge</translation>
-<translation id="819205353528511139">afspil film i fuld skærm</translation>
<translation id="8199524924445686405">åååå</translation>
<translation id="8284326494547611709">Undertekster</translation>
<translation id="835897206747267392">Ugyldig værdi.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">kontrollér afspilning via fjernadgang</translation>
<translation id="862370744433916922">undertitel</translation>
<translation id="8750798805984357768">Vælg en af disse muligheder.</translation>
-<translation id="8785498733064193001">start afspilning</translation>
<translation id="8808573423886751634">kapitel</translation>
<translation id="8845239796550121995">Caster nu til dit fjernsyn</translation>
<translation id="8851136666856101339">hovd</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_de.xtb b/chromium/content/app/strings/translations/content_strings_de.xtb
index 93cebecf40a..fe67a37079f 100644
--- a/chromium/content/app/strings/translations/content_strings_de.xtb
+++ b/chromium/content/app/strings/translations/content_strings_de.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="de">
<translation id="1018939186200882850">Menüpunkt</translation>
-<translation id="1020833440720551630">Ton ausschalten</translation>
<translation id="10623998915015855">Schaltfläche zum Umschalten</translation>
<translation id="1088086359088493902">Sekunden</translation>
<translation id="1171774979989969504">Geben Sie eine E-Mail-Adresse ein.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">Mitwirkende</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">Banner</translation>
-<translation id="1548116112524424341">Video im Bild-im-Bild-Modus abspielen</translation>
<translation id="1589122976691792535">Region</translation>
<translation id="1591562245178063882">Aktueller Monat</translation>
<translation id="1637811476055996098">Dateien auswählen</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">Baumraster</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">auf Remote-Gerät wiedergeben</translation>
-<translation id="1838818994221231429">Ansicht von Vollbildmodus in Display-Aussparung ein-/ausschalten</translation>
<translation id="190587075670221089">Löschen</translation>
<translation id="1907737156431278478">Beispiel</translation>
<translation id="1921819250265091946">tt</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Tippen Sie links oder rechts doppelt, um 10 s zu überspringen</translation>
<translation id="5631759159893697722">Zusammenfassung</translation>
-<translation id="5641012560118721995">Wiedergabe anhalten</translation>
<translation id="5643186887447432888">Schaltfläche</translation>
<translation id="5677946354068040947">weitere Optionen</translation>
<translation id="576709008726043716">Einleitung</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Zurücksetzen</translation>
<translation id="5966707198760109579">Woche</translation>
<translation id="5987525920412732405">Drehfeld</translation>
+<translation id="6011459053400940133">Schieberegler für die Lautstärke</translation>
<translation id="6015796118275082299">Jahr</translation>
<translation id="6023896073578205740">Listenfeld</translation>
-<translation id="6101327004457443354">Ton anschalten</translation>
<translation id="6150588977291308318">Bibliografie</translation>
<translation id="6164829606128959761">Messinstrument</translation>
<translation id="6166809985690652833">Nachwort</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Stunden</translation>
<translation id="7681220483256441252">Index</translation>
<translation id="7720026100085573005">Verbleibende Zeit</translation>
-<translation id="7740016676195725605">Keine Untertitel mehr anzeigen</translation>
<translation id="7740050170769002709">HTML-Inhalte</translation>
<translation id="7750228210027921155">Bild-in-Bild</translation>
<translation id="7789962463072032349">Pausieren</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">Feld für den Suchtext</translation>
<translation id="8057695513531652401">Bemerkung</translation>
<translation id="8105797009065549151">Hinweisreferenz</translation>
-<translation id="8115662671911883373">Untertitel ab sofort anzeigen</translation>
<translation id="8117451130807776954">Diese Woche</translation>
-<translation id="819205353528511139">Film im Vollbildmodus ansehen</translation>
<translation id="8199524924445686405">jjjj</translation>
<translation id="8284326494547611709">Untertitel</translation>
<translation id="835897206747267392">Ungültiger Wert.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">Remote-Wiedergabe steuern</translation>
<translation id="862370744433916922">Untertitel</translation>
<translation id="8750798805984357768">Wählen Sie eine dieser Optionen aus.</translation>
-<translation id="8785498733064193001">Wiedergabe starten</translation>
<translation id="8808573423886751634">Kapitel</translation>
<translation id="8845239796550121995">Wird gerade auf Ihren Fernseher gestreamt</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_el.xtb b/chromium/content/app/strings/translations/content_strings_el.xtb
index 1b24c5048c8..3cb9a6a139a 100644
--- a/chromium/content/app/strings/translations/content_strings_el.xtb
+++ b/chromium/content/app/strings/translations/content_strings_el.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="el">
<translation id="1018939186200882850">στοιχείο μενού</translation>
-<translation id="1020833440720551630">σίγαση ήχου</translation>
<translation id="10623998915015855">κουμπί εναλλαγής</translation>
<translation id="1088086359088493902">Δευτερόλεπτα</translation>
<translation id="1171774979989969504">Εισαγάγετε μια διεύθυνση ηλεκτρονικού ταχυδρομείου.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">συντελεστές</translation>
<translation id="1342835525016946179">άρθρο</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">αναπαραγωγή βίντεο σε λειτουργία picture-in-picture</translation>
<translation id="1589122976691792535">περιοχή</translation>
<translation id="1591562245178063882">Αυτόν το μήνα</translation>
<translation id="1637811476055996098">Επιλογή αρχείων</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">πλέγμα δέντρου</translation>
<translation id="1822429046913737220">Π.Μ./Μ.Μ.</translation>
<translation id="1832974991323546415">αναπαραγωγή σε απομακρυσμένη συσκευή</translation>
-<translation id="1838818994221231429">εναλλαγή πλήρους οθόνης σε περιοχή εγκοπής οθόνης</translation>
<translation id="190587075670221089">διαγραφή</translation>
<translation id="1907737156431278478">παράδειγμα</translation>
<translation id="1921819250265091946">ηη</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">ώρα</translation>
<translation id="5630795885300617244">Πατήστε δύο φορές αριστερά ή δεξιά, για να παραβλέψετε 10 δευτ.</translation>
<translation id="5631759159893697722">περίληψη</translation>
-<translation id="5641012560118721995">παύση αναπαραγωγής</translation>
<translation id="5643186887447432888">κουμπί</translation>
<translation id="5677946354068040947">περισσότερες επιλογές</translation>
<translation id="576709008726043716">εισαγωγή</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Επαναφορά</translation>
<translation id="5966707198760109579">Εβδομάδα</translation>
<translation id="5987525920412732405">κουμπί αυξομείωσης</translation>
+<translation id="6011459053400940133">ρυθμιστικό έντασης ήχου</translation>
<translation id="6015796118275082299">Έτος</translation>
<translation id="6023896073578205740">πλαίσιο λίστας</translation>
-<translation id="6101327004457443354">κατάργηση σίγασης ήχου</translation>
<translation id="6150588977291308318">βιβλιογραφία</translation>
<translation id="6164829606128959761">μετρητής</translation>
<translation id="6166809985690652833">επίλογος</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Ώρες</translation>
<translation id="7681220483256441252">ευρετήριο</translation>
<translation id="7720026100085573005">χρόνος που απομένει</translation>
-<translation id="7740016676195725605">διακοπή προβολής υπότιτλων</translation>
<translation id="7740050170769002709">Περιεχόμενο HTML</translation>
<translation id="7750228210027921155">Picture in picture</translation>
<translation id="7789962463072032349">παύση</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">αναζήτηση πεδίου κειμένου</translation>
<translation id="8057695513531652401">ειδοποίηση</translation>
<translation id="8105797009065549151">παραπομπή</translation>
-<translation id="8115662671911883373">έναρξη προβολής υπότιτλων</translation>
<translation id="8117451130807776954">Αυτήν την εβδομάδα</translation>
-<translation id="819205353528511139">αναπαραγωγή ταινίας σε λειτουργία πλήρους οθόνης</translation>
<translation id="8199524924445686405">εεεε</translation>
<translation id="8284326494547611709">Υπότιτλοι</translation>
<translation id="835897206747267392">Μη έγκυρη τιμή.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">έλεγχος απομακρυσμένης αναπαραγωγής</translation>
<translation id="862370744433916922">υπότιτλος</translation>
<translation id="8750798805984357768">Ορίστε μία από αυτές τις επιλογές.</translation>
-<translation id="8785498733064193001">έναρξη αναπαραγωγής</translation>
<translation id="8808573423886751634">κεφάλαιο</translation>
<translation id="8845239796550121995">Γίνεται μετάδοση στην TV</translation>
<translation id="8851136666856101339">κύριο</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_en-GB.xtb b/chromium/content/app/strings/translations/content_strings_en-GB.xtb
index 229660dd131..e260505d102 100644
--- a/chromium/content/app/strings/translations/content_strings_en-GB.xtb
+++ b/chromium/content/app/strings/translations/content_strings_en-GB.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="en-GB">
<translation id="1018939186200882850">menu item</translation>
-<translation id="1020833440720551630">mute audio track</translation>
<translation id="10623998915015855">toggle button</translation>
<translation id="1088086359088493902">Seconds</translation>
<translation id="1171774979989969504">Please enter an email address.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">credits</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">play video in picture-in-picture mode</translation>
<translation id="1589122976691792535">region</translation>
<translation id="1591562245178063882">This month</translation>
<translation id="1637811476055996098">Choose Files</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">tree grid</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">play on remote device</translation>
-<translation id="1838818994221231429">toggle full screen into display cutout area</translation>
<translation id="190587075670221089">deletion</translation>
<translation id="1907737156431278478">example</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Double-tap left or right to skip 10s</translation>
<translation id="5631759159893697722">abstract</translation>
-<translation id="5641012560118721995">pause playback</translation>
<translation id="5643186887447432888">button</translation>
<translation id="5677946354068040947">more options</translation>
<translation id="576709008726043716">introduction</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Reset</translation>
<translation id="5966707198760109579">Week</translation>
<translation id="5987525920412732405">spin button</translation>
+<translation id="6011459053400940133">volume slider</translation>
<translation id="6015796118275082299">Year</translation>
<translation id="6023896073578205740">list box</translation>
-<translation id="6101327004457443354">un-mute audio track</translation>
<translation id="6150588977291308318">bibliography</translation>
<translation id="6164829606128959761">meter</translation>
<translation id="6166809985690652833">afterword</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Hours</translation>
<translation id="7681220483256441252">index</translation>
<translation id="7720026100085573005">remaining time</translation>
-<translation id="7740016676195725605">stop displaying closed captions</translation>
<translation id="7740050170769002709">HTML content</translation>
<translation id="7750228210027921155">Picture-in-picture</translation>
<translation id="7789962463072032349">pause</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">search text field</translation>
<translation id="8057695513531652401">notice</translation>
<translation id="8105797009065549151">note reference</translation>
-<translation id="8115662671911883373">start displaying closed captions</translation>
<translation id="8117451130807776954">This week</translation>
-<translation id="819205353528511139">play film in full screen mode</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">Captions</translation>
<translation id="835897206747267392">Invalid value.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">control remote playback</translation>
<translation id="862370744433916922">subtitle</translation>
<translation id="8750798805984357768">Please select one of these options.</translation>
-<translation id="8785498733064193001">begin playback</translation>
<translation id="8808573423886751634">chapter</translation>
<translation id="8845239796550121995">Now casting to your TV</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_es-419.xtb b/chromium/content/app/strings/translations/content_strings_es-419.xtb
index 546330e9062..b70aad3e063 100644
--- a/chromium/content/app/strings/translations/content_strings_es-419.xtb
+++ b/chromium/content/app/strings/translations/content_strings_es-419.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="es-419">
<translation id="1018939186200882850">elemento del menú</translation>
-<translation id="1020833440720551630">silenciar pista de audio</translation>
<translation id="10623998915015855">botón de activación</translation>
<translation id="1088086359088493902">Segundos</translation>
<translation id="1171774979989969504">Ingresa una dirección de correo electrónico.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">créditos</translation>
<translation id="1342835525016946179">artículo</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">reproducir video en modo de pantalla en pantalla</translation>
<translation id="1589122976691792535">región</translation>
<translation id="1591562245178063882">Este mes</translation>
<translation id="1637811476055996098">Elegir archivos</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">cuadrícula de árbol</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">jugar en el dispositivo remoto</translation>
-<translation id="1838818994221231429">activar o desactivar la pantalla completa en el área de corte de pantalla</translation>
<translation id="190587075670221089">contenido borrado</translation>
<translation id="1907737156431278478">ejemplo</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Presiona dos veces a la derecha o izquierda para omitir 10 s</translation>
<translation id="5631759159893697722">resumen</translation>
-<translation id="5641012560118721995">pausar reproducción</translation>
<translation id="5643186887447432888">botón</translation>
<translation id="5677946354068040947">más opciones</translation>
<translation id="576709008726043716">introducción</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Restablecer</translation>
<translation id="5966707198760109579">Semana</translation>
<translation id="5987525920412732405">botón de control numérico</translation>
+<translation id="6011459053400940133">control deslizante del volumen</translation>
<translation id="6015796118275082299">Año</translation>
<translation id="6023896073578205740">cuadro de lista</translation>
-<translation id="6101327004457443354">desactivar silencio de la pista de audio</translation>
<translation id="6150588977291308318">bibliografía</translation>
<translation id="6164829606128959761">medidor</translation>
<translation id="6166809985690652833">posfacio</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Horas</translation>
<translation id="7681220483256441252">índice</translation>
<translation id="7720026100085573005">tiempo restante</translation>
-<translation id="7740016676195725605">dejar de mostrar subtítulos</translation>
<translation id="7740050170769002709">Contenido HTML</translation>
<translation id="7750228210027921155">Pantalla en pantalla</translation>
<translation id="7789962463072032349">pausa</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">campo de texto de búsqueda</translation>
<translation id="8057695513531652401">aviso</translation>
<translation id="8105797009065549151">nota de referencia</translation>
-<translation id="8115662671911883373">empezar a mostrar subtítulos</translation>
<translation id="8117451130807776954">Esta semana</translation>
-<translation id="819205353528511139">reproducir la película en modo de pantalla completa</translation>
<translation id="8199524924445686405">aaaa</translation>
<translation id="8284326494547611709">Subtítulos</translation>
<translation id="835897206747267392">Valor no válido.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">controlar la reproducción remota</translation>
<translation id="862370744433916922">subtítulo</translation>
<translation id="8750798805984357768">Selecciona una de estas opciones.</translation>
-<translation id="8785498733064193001">comenzar la reproducción</translation>
<translation id="8808573423886751634">capítulo</translation>
<translation id="8845239796550121995">Transmitiendo a tu TV</translation>
<translation id="8851136666856101339">ppal</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_es.xtb b/chromium/content/app/strings/translations/content_strings_es.xtb
index decbe9e4df0..5b414835315 100644
--- a/chromium/content/app/strings/translations/content_strings_es.xtb
+++ b/chromium/content/app/strings/translations/content_strings_es.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="es">
<translation id="1018939186200882850">elemento de menú</translation>
-<translation id="1020833440720551630">silenciar pista de audio</translation>
<translation id="10623998915015855">botón de activación</translation>
<translation id="1088086359088493902">Segundos</translation>
<translation id="1171774979989969504">Introduce una dirección de correo electrónico</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">créditos</translation>
<translation id="1342835525016946179">artículo</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">reproducir vídeo en modo imagen en imagen</translation>
<translation id="1589122976691792535">región</translation>
<translation id="1591562245178063882">Este mes</translation>
<translation id="1637811476055996098">Elegir archivos</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">cuadrícula de árbol</translation>
<translation id="1822429046913737220">A.M./P.M.</translation>
<translation id="1832974991323546415">reproducir en dispositivo remoto</translation>
-<translation id="1838818994221231429">activar pantalla completa en el área de recorte de la pantalla</translation>
<translation id="190587075670221089">eliminación</translation>
<translation id="1907737156431278478">ejemplo</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Toca dos veces a la derecha o a la izquierda para saltar 10 segundos</translation>
<translation id="5631759159893697722">resumen</translation>
-<translation id="5641012560118721995">pausar reproducción</translation>
<translation id="5643186887447432888">botón</translation>
<translation id="5677946354068040947">más opciones</translation>
<translation id="576709008726043716">introducción</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Restablecer</translation>
<translation id="5966707198760109579">Semana</translation>
<translation id="5987525920412732405">botón de control numérico</translation>
+<translation id="6011459053400940133">control deslizante de volumen</translation>
<translation id="6015796118275082299">Año</translation>
<translation id="6023896073578205740">cuadro de lista</translation>
-<translation id="6101327004457443354">activar sonido de la pista de audio</translation>
<translation id="6150588977291308318">bibliografía</translation>
<translation id="6164829606128959761">medidor</translation>
<translation id="6166809985690652833">epílogo</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Horas</translation>
<translation id="7681220483256441252">índice</translation>
<translation id="7720026100085573005">tiempo restante</translation>
-<translation id="7740016676195725605">dejar de mostrar subtítulos</translation>
<translation id="7740050170769002709">Contenido HTML</translation>
<translation id="7750228210027921155">Imagen en imagen</translation>
<translation id="7789962463072032349">pausar</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">campo para buscar texto</translation>
<translation id="8057695513531652401">aviso</translation>
<translation id="8105797009065549151">referencia de nota</translation>
-<translation id="8115662671911883373">iniciar la visualización de subtítulos</translation>
<translation id="8117451130807776954">Esta semana</translation>
-<translation id="819205353528511139">reproducir la película en modo de pantalla completa</translation>
<translation id="8199524924445686405">aaaa</translation>
<translation id="8284326494547611709">Subtítulos</translation>
<translation id="835897206747267392">Valor no válido</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">reproducción de control remoto</translation>
<translation id="862370744433916922">subtítulo</translation>
<translation id="8750798805984357768">Selecciona una de estas opciones</translation>
-<translation id="8785498733064193001">iniciar reproducción</translation>
<translation id="8808573423886751634">capítulo</translation>
<translation id="8845239796550121995">Se está enviando contenido a tu TV</translation>
<translation id="8851136666856101339">principal</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_et.xtb b/chromium/content/app/strings/translations/content_strings_et.xtb
index 7e674c7db33..b7c840c0b52 100644
--- a/chromium/content/app/strings/translations/content_strings_et.xtb
+++ b/chromium/content/app/strings/translations/content_strings_et.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="et">
<translation id="1018939186200882850">menüü-üksus</translation>
-<translation id="1020833440720551630">heliraja vaigistamine</translation>
<translation id="10623998915015855">ümberlülitusnupp</translation>
<translation id="1088086359088493902">Sekundid</translation>
<translation id="1171774979989969504">Sisestage meiliaadress.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">tiitrid</translation>
<translation id="1342835525016946179">artikkel</translation>
<translation id="1359897965706325498">bänner</translation>
-<translation id="1548116112524424341">esita videot režiimis Pilt pildis</translation>
<translation id="1589122976691792535">piirkond</translation>
<translation id="1591562245178063882">See kuu</translation>
<translation id="1637811476055996098">Vali failid</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">puuruudustik</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">kaugseadmes esitamine</translation>
-<translation id="1838818994221231429">ekraani väljalõike piirkonnas täisekraanrežiimi sisse-/väljalülitamine</translation>
<translation id="190587075670221089">kustutamine</translation>
<translation id="1907737156431278478">näide</translation>
<translation id="1921819250265091946">pp</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">10 sekundi võrra kerimiseks topeltpuudutage vasakul või paremal</translation>
<translation id="5631759159893697722">abstraktne</translation>
-<translation id="5641012560118721995">taasesituse peatamine</translation>
<translation id="5643186887447432888">nupp</translation>
<translation id="5677946354068040947">rohkem valikuid</translation>
<translation id="576709008726043716">sissejuhatus</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Lähtesta</translation>
<translation id="5966707198760109579">Nädal</translation>
<translation id="5987525920412732405">pöördnupp</translation>
+<translation id="6011459053400940133">helitugevuse liugur</translation>
<translation id="6015796118275082299">Aasta</translation>
<translation id="6023896073578205740">loendikast</translation>
-<translation id="6101327004457443354">heliraja vaigistamise tühistamine</translation>
<translation id="6150588977291308318">bibliograafia</translation>
<translation id="6164829606128959761">mõõdik</translation>
<translation id="6166809985690652833">järelsõna</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Tunnid</translation>
<translation id="7681220483256441252">register</translation>
<translation id="7720026100085573005">järelejäänud aeg</translation>
-<translation id="7740016676195725605">subtiitrite kuvamise peatamine</translation>
<translation id="7740050170769002709">HTML-sisu</translation>
<translation id="7750228210027921155">Pilt pildis</translation>
<translation id="7789962463072032349">peata</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">otsinguteksti väli</translation>
<translation id="8057695513531652401">teatis</translation>
<translation id="8105797009065549151">märkuse viide</translation>
-<translation id="8115662671911883373">subtiitrite kuvamise alustamine</translation>
<translation id="8117451130807776954">See nädal</translation>
-<translation id="819205353528511139">video esitus täisekraani režiimis</translation>
<translation id="8199524924445686405">aaaa</translation>
<translation id="8284326494547611709">Subtiitrid</translation>
<translation id="835897206747267392">Kehtetu väärtus.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">kaugesituse juhtimine</translation>
<translation id="862370744433916922">alapealkiri</translation>
<translation id="8750798805984357768">Tehke üks nendest valikutest.</translation>
-<translation id="8785498733064193001">taasesituse alustamine</translation>
<translation id="8808573423886751634">peatükk</translation>
<translation id="8845239796550121995">Kantakse nüüd üle telerisse</translation>
<translation id="8851136666856101339">pea</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_fa.xtb b/chromium/content/app/strings/translations/content_strings_fa.xtb
index 1fbae91dccb..ac843293ca9 100644
--- a/chromium/content/app/strings/translations/content_strings_fa.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fa.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="fa">
<translation id="1018939186200882850">مورد منو</translation>
-<translation id="1020833440720551630">بیصداکردن تراک صوتی</translation>
<translation id="10623998915015855">دکمه تغییر حالت</translation>
<translation id="1088086359088493902">ثانیه</translation>
<translation id="1171774979989969504">لطفاً یک نشانی ایمیل وارد کنید.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">دست‌اندرکاران</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">برنما</translation>
-<translation id="1548116112524424341">پخش ویدیو در حالت تصویر در تصویر</translation>
<translation id="1589122976691792535">منطقه</translation>
<translation id="1591562245178063882">این ماه</translation>
<translation id="1637811476055996098">انتخاب فایل‌ها</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">شبکه درختی</translation>
<translation id="1822429046913737220">ق.ظ/ب.ظ</translation>
<translation id="1832974991323546415">پخش در دستگاه راه دور</translation>
-<translation id="1838818994221231429">جابه‌جایی تمام‌صفحه به ناحیه برش نمایشگر</translation>
<translation id="190587075670221089">حذف</translation>
<translation id="1907737156431278478">مثال</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">زمان</translation>
<translation id="5630795885300617244">روی سمت راست یا چپ دو ضربه سریع بزنید تا ۱۰ ثانیه رد شود</translation>
<translation id="5631759159893697722">انتزاعی</translation>
-<translation id="5641012560118721995">مکث بازپخش</translation>
<translation id="5643186887447432888">دکمه</translation>
<translation id="5677946354068040947">گزینه‌های بیشتر</translation>
<translation id="576709008726043716">مقدمه</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">بازنشانی</translation>
<translation id="5966707198760109579">هفته</translation>
<translation id="5987525920412732405">دکمه چرخش</translation>
+<translation id="6011459053400940133">لغزنده میزان صدا</translation>
<translation id="6015796118275082299">سال</translation>
<translation id="6023896073578205740">کادر فهرست</translation>
-<translation id="6101327004457443354">صدادارکردن تراک صوتی</translation>
<translation id="6150588977291308318">فهرست منابع</translation>
<translation id="6164829606128959761">متر</translation>
<translation id="6166809985690652833">سخن پایانی</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">ساعت</translation>
<translation id="7681220483256441252">فهرست موضوعی</translation>
<translation id="7720026100085573005">زمان باقی‌مانده</translation>
-<translation id="7740016676195725605">توقف نمایش زیرنویس ناشنوایان</translation>
<translation id="7740050170769002709">‏محتوای HTML</translation>
<translation id="7750228210027921155">تصویردرتصویر</translation>
<translation id="7789962463072032349">مکث</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">فیلد نوشتاری جستجو</translation>
<translation id="8057695513531652401">اطلاعیه</translation>
<translation id="8105797009065549151">مرجع یادداشت</translation>
-<translation id="8115662671911883373">شروع به نمایش زیرنویس ناشنوایان</translation>
<translation id="8117451130807776954">این هفته</translation>
-<translation id="819205353528511139">پخش فیلم در حالت تمام صفحه</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">زیرنویس‌ها</translation>
<translation id="835897206747267392">مقدار نامعتبر.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">کنترل بازپخش راه دور</translation>
<translation id="862370744433916922">زیرنویس</translation>
<translation id="8750798805984357768">لطفاً یکی از این گزینه‌ها را انتخاب کنید.</translation>
-<translation id="8785498733064193001">شروع بازپخش</translation>
<translation id="8808573423886751634">فصل</translation>
<translation id="8845239796550121995">درحال ارسال محتوا به تلویزیون</translation>
<translation id="8851136666856101339">اصلی</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_fi.xtb b/chromium/content/app/strings/translations/content_strings_fi.xtb
index 43e44a61b07..c34a64d9649 100644
--- a/chromium/content/app/strings/translations/content_strings_fi.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fi.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="fi">
<translation id="1018939186200882850">valikkokohde</translation>
-<translation id="1020833440720551630">mykistä ääniraita</translation>
<translation id="10623998915015855">vaihtopainike</translation>
<translation id="1088086359088493902">Sekuntia</translation>
<translation id="1171774979989969504">Anna sähköpostiosoite.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">tunnustukset</translation>
<translation id="1342835525016946179">artikkeli</translation>
<translation id="1359897965706325498">banneri</translation>
-<translation id="1548116112524424341">toista video kuva kuvassa ‑tilassa</translation>
<translation id="1589122976691792535">alue</translation>
<translation id="1591562245178063882">Tässä kuussa</translation>
<translation id="1637811476055996098">Valitse tiedostot</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">puuruudukko</translation>
<translation id="1822429046913737220">AP/IP</translation>
<translation id="1832974991323546415">toista etälaitteella</translation>
-<translation id="1838818994221231429">näyttölovi on/ei ole osa koko näytön tilaa</translation>
<translation id="190587075670221089">poisto</translation>
<translation id="1907737156431278478">esimerkki</translation>
<translation id="1921819250265091946">pp</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Ohita 10 sekuntia kaksoisnapauttamalla vasemmalle tai oikealle.</translation>
<translation id="5631759159893697722">tiivistelmä</translation>
-<translation id="5641012560118721995">keskeytä toisto</translation>
<translation id="5643186887447432888">painike</translation>
<translation id="5677946354068040947">lisäasetukset</translation>
<translation id="576709008726043716">johdanto</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Tyhjennä</translation>
<translation id="5966707198760109579">Viikko</translation>
<translation id="5987525920412732405">pyöräytyspainike</translation>
+<translation id="6011459053400940133">äänenvoimakkuuden liukusäädin</translation>
<translation id="6015796118275082299">Vuosi</translation>
<translation id="6023896073578205740">luetteloruutu</translation>
-<translation id="6101327004457443354">peruuta ääniraidan mykistys</translation>
<translation id="6150588977291308318">lähdeluettelo</translation>
<translation id="6164829606128959761">mittari</translation>
<translation id="6166809985690652833">jälkipuhe</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Tuntia</translation>
<translation id="7681220483256441252">hakemisto</translation>
<translation id="7720026100085573005">jäljellä oleva aika</translation>
-<translation id="7740016676195725605">älä näytä tekstityksiä</translation>
<translation id="7740050170769002709">HTML-sisältö</translation>
<translation id="7750228210027921155">Kuva kuvassa</translation>
<translation id="7789962463072032349">tauko</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">hakutekstikenttä</translation>
<translation id="8057695513531652401">ilmoitus</translation>
<translation id="8105797009065549151">muistiinpanoviittaus</translation>
-<translation id="8115662671911883373">näytä tekstitykset</translation>
<translation id="8117451130807776954">Tällä viikolla</translation>
-<translation id="819205353528511139">toista elokuva koko näytön tilassa</translation>
<translation id="8199524924445686405">vvvv</translation>
<translation id="8284326494547611709">Tekstitykset</translation>
<translation id="835897206747267392">Virheellinen arvo.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">hallinnoi etätoistoa</translation>
<translation id="862370744433916922">alaotsikko</translation>
<translation id="8750798805984357768">Valitse yksi vaihtoehdoista.</translation>
-<translation id="8785498733064193001">aloita toisto</translation>
<translation id="8808573423886751634">luku</translation>
<translation id="8845239796550121995">Suoratoistetaan televisioosi</translation>
<translation id="8851136666856101339">pää</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_fil.xtb b/chromium/content/app/strings/translations/content_strings_fil.xtb
index b57abce9893..1e8b8d8d29c 100644
--- a/chromium/content/app/strings/translations/content_strings_fil.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fil.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="fil">
<translation id="1018939186200882850">item sa menu</translation>
-<translation id="1020833440720551630">i-mute ang audio track</translation>
<translation id="10623998915015855">button sa pag-toggle</translation>
<translation id="1088086359088493902">Segundo</translation>
<translation id="1171774979989969504">Mangyaring magpasok ng email address.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">mga credit</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">i-play ang video sa picture-in-picture mode</translation>
<translation id="1589122976691792535">rehiyon</translation>
<translation id="1591562245178063882">Buwang ito</translation>
<translation id="1637811476055996098">Pumili ng Mga File</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">tree grid</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">i-play sa malayuang device</translation>
-<translation id="1838818994221231429">i-toggle ang fullscreen sa bahagi ng cutout ng display</translation>
<translation id="190587075670221089">pag-delete</translation>
<translation id="1907737156431278478">halimbawa</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">oras</translation>
<translation id="5630795885300617244">Mag-double tap sa kaliwa o kanan upang lumaktaw nang 10s</translation>
<translation id="5631759159893697722">abstract</translation>
-<translation id="5641012560118721995">i-pause ang pag-playback</translation>
<translation id="5643186887447432888">button</translation>
<translation id="5677946354068040947">higit pang opsyon</translation>
<translation id="576709008726043716">panimula</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">I-reset</translation>
<translation id="5966707198760109579">Linggo</translation>
<translation id="5987525920412732405">button ng pag-spin</translation>
+<translation id="6011459053400940133">slider ng volume</translation>
<translation id="6015796118275082299">Taon</translation>
<translation id="6023896073578205740">kahon ng listahan</translation>
-<translation id="6101327004457443354">i-unmute ang audio track</translation>
<translation id="6150588977291308318">bibliograpiya</translation>
<translation id="6164829606128959761">metro</translation>
<translation id="6166809985690652833">afterword</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Oras</translation>
<translation id="7681220483256441252">index</translation>
<translation id="7720026100085573005">natitirang oras</translation>
-<translation id="7740016676195725605">ihinto ang pagpapakita ng mga nakasarang caption</translation>
<translation id="7740050170769002709">HTML na nilalaman</translation>
<translation id="7750228210027921155">Picture in picture</translation>
<translation id="7789962463072032349">i-pause</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">text field ng paghahanap</translation>
<translation id="8057695513531652401">paunawa</translation>
<translation id="8105797009065549151">sanggunian sa tala</translation>
-<translation id="8115662671911883373">simulan ang pagpapakita ng mga nakasarang caption</translation>
<translation id="8117451130807776954">Linggong ito</translation>
-<translation id="819205353528511139">i-play ang pelikula sa full screen mode</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">Mga Caption</translation>
<translation id="835897206747267392">Di-wastong halaga.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">kontrolin ang malayuang pag-playback</translation>
<translation id="862370744433916922">subtitle</translation>
<translation id="8750798805984357768">Mangyaring pumili ng isa sa mga opsyong ito.</translation>
-<translation id="8785498733064193001">simulan ang pag-playback</translation>
<translation id="8808573423886751634">kabanata</translation>
<translation id="8845239796550121995">Ikina-cast ngayon sa iyong TV</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_fr.xtb b/chromium/content/app/strings/translations/content_strings_fr.xtb
index 391f83d95ef..0224225e947 100644
--- a/chromium/content/app/strings/translations/content_strings_fr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fr.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="fr">
<translation id="1018939186200882850">élément de menu</translation>
-<translation id="1020833440720551630">désactiver le son de la piste audio</translation>
<translation id="10623998915015855">bouton d'activation/de désactivation</translation>
<translation id="1088086359088493902">Secondes</translation>
<translation id="1171774979989969504">Veuillez saisir une adresse e-mail.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">crédits</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">bannière</translation>
-<translation id="1548116112524424341">diffuser la vidéo en mode PIP</translation>
<translation id="1589122976691792535">région</translation>
<translation id="1591562245178063882">Ce mois</translation>
<translation id="1637811476055996098">Sélect. fichiers</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">arborescence</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">lire sur un appareil à distance</translation>
-<translation id="1838818994221231429">activer/désactiver le passage du mode plein écran en encoche</translation>
<translation id="190587075670221089">suppression</translation>
<translation id="1907737156431278478">exemple</translation>
<translation id="1921819250265091946">jj</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">horodatage</translation>
<translation id="5630795885300617244">Appuyez deux fois à gauche/droite pour reculer/avancer de 10 s</translation>
<translation id="5631759159893697722">résumé</translation>
-<translation id="5641012560118721995">interrompre la lecture</translation>
<translation id="5643186887447432888">bouton</translation>
<translation id="5677946354068040947">plus d'options</translation>
<translation id="576709008726043716">introduction</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Réinitialiser</translation>
<translation id="5966707198760109579">Semaine</translation>
<translation id="5987525920412732405">bouton toupie</translation>
+<translation id="6011459053400940133">curseur de volume</translation>
<translation id="6015796118275082299">Année</translation>
<translation id="6023896073578205740">zone de liste</translation>
-<translation id="6101327004457443354">réactiver le son de la piste audio</translation>
<translation id="6150588977291308318">bibliographie</translation>
<translation id="6164829606128959761">outil de mesure</translation>
<translation id="6166809985690652833">postface</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Heures</translation>
<translation id="7681220483256441252">index</translation>
<translation id="7720026100085573005">temps restant</translation>
-<translation id="7740016676195725605">ne plus afficher les sous-titres</translation>
<translation id="7740050170769002709">Contenu HTML</translation>
<translation id="7750228210027921155">Mode PIP (Picture-in-Picture)</translation>
<translation id="7789962463072032349">pause</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">champ de recherche de texte</translation>
<translation id="8057695513531652401">notification</translation>
<translation id="8105797009065549151">référence de note</translation>
-<translation id="8115662671911883373">commencer à afficher les sous-titres</translation>
<translation id="8117451130807776954">Cette semaine</translation>
-<translation id="819205353528511139">lire le film en mode plein écran</translation>
<translation id="8199524924445686405">aaaa</translation>
<translation id="8284326494547611709">Sous-titres</translation>
<translation id="835897206747267392">Valeur incorrecte</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">contrôler la lecture à distance</translation>
<translation id="862370744433916922">sous-titre</translation>
<translation id="8750798805984357768">Veuillez sélectionner l'une de ces options.</translation>
-<translation id="8785498733064193001">commencer la lecture</translation>
<translation id="8808573423886751634">chapitre</translation>
<translation id="8845239796550121995">En cours de diffusion sur votre téléviseur</translation>
<translation id="8851136666856101339">principal</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_gu.xtb b/chromium/content/app/strings/translations/content_strings_gu.xtb
index ac414a8a3a7..48da84bc283 100644
--- a/chromium/content/app/strings/translations/content_strings_gu.xtb
+++ b/chromium/content/app/strings/translations/content_strings_gu.xtb
@@ -2,10 +2,9 @@
<!DOCTYPE translationbundle>
<translationbundle lang="gu">
<translation id="1018939186200882850">મેનૂ આઇટમ</translation>
-<translation id="1020833440720551630">ઑડિઓ ટ્રેક મ્યૂટ કરો</translation>
<translation id="10623998915015855">ટોગલ બટન</translation>
<translation id="1088086359088493902">સેકંડ</translation>
-<translation id="1171774979989969504">કૃપા કરી કોઈ ઇમેઇલ સરનામું દાખલ કરો.</translation>
+<translation id="1171774979989969504">કૃપા કરી કોઈ ઇમેઇલ ઍડ્રેસ દાખલ કરો.</translation>
<translation id="1178581264944972037">થોભો</translation>
<translation id="1188858454923323853">પૂરક</translation>
<translation id="1206619573307042055">માર્કી</translation>
@@ -16,18 +15,16 @@
<translation id="1335095011850992622">ક્રેડિટ</translation>
<translation id="1342835525016946179">લેખ</translation>
<translation id="1359897965706325498">બેનર</translation>
-<translation id="1548116112524424341">ચિત્ર-માં-ચિત્ર મોડમાં વીડિઓ ચલાવો</translation>
<translation id="1589122976691792535">પ્રદેશ</translation>
<translation id="1591562245178063882">આ મહિને</translation>
<translation id="1637811476055996098">ફાઇલો પસંદ કરો</translation>
<translation id="1650423536718072820">પુલક્વોટ</translation>
-<translation id="1729654308190250600">કૃપા કરીને એક બિન-ખાલી ઇમેઇલ સરનામું દાખલ કરો.</translation>
+<translation id="1729654308190250600">કૃપા કરીને ખાલી ન હોય એવું ઇમેઇલ ઍડ્રેસ દાખલ કરો.</translation>
<translation id="1758486001363313524">અન્ય...</translation>
<translation id="1806710327868736751">ચેતવણી_સંવાદ</translation>
<translation id="1821985195704844674">ટ્રી ગ્રિડ</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">રિમોટ ઉપકરણ પર ચલાવો</translation>
-<translation id="1838818994221231429">પૂર્ણસ્ક્રીનને ડિસ્પ્લેમાં જ સામેલ વિસ્તારમાં જ ટૉગલ કરો</translation>
<translation id="190587075670221089">ડિલીટ કરો</translation>
<translation id="1907737156431278478">ઉદાહરણ</translation>
<translation id="1921819250265091946">dd</translation>
@@ -57,7 +54,7 @@
<translation id="2709516037105925701">સ્વતઃભરો</translation>
<translation id="2723001399770238859">ઑડિઓ</translation>
<translation id="2746543609216772311">મૂલ્ય <ph name="MINIMUM_DATE_OR_TIME" /> અથવા પછીનું હોવું આવશ્યક છે.</translation>
-<translation id="2759744352195237655">પોપ અપ બટન</translation>
+<translation id="2759744352195237655">પૉપ-અપ બટન</translation>
<translation id="2761667185364618470">જો તમે આગળ વધવા માંગતા હો તો કૃપા કરીને આ બૉક્સને ચેક કરો.</translation>
<translation id="2896972712917208084">રેડિઓ જૂથ</translation>
<translation id="2908441821576996758">કૃપા કરીને અલ્પવિરામથી વિભાજિત ઇમેઇલ સરનામાંઓની સૂચિ દાખલ કરો.</translation>
@@ -90,7 +87,7 @@
<translation id="4103419683916926126">મીલીસેકન્ડ</translation>
<translation id="4151657705144244502">ગ્રાફિક</translation>
<translation id="4193965531860883258">આમુખ</translation>
-<translation id="4201051445878709314">પહેલાનો મહિનો દર્શાવો</translation>
+<translation id="4201051445878709314">પાછળનો મહિનો બતાવો</translation>
<translation id="421884353938374759">રંગ ચૂંટનાર</translation>
<translation id="4248100235867064564">મેનૂ બાર</translation>
<translation id="4254339807215791271">કન્ટેન્ટની માહિતી</translation>
@@ -106,7 +103,7 @@
<translation id="4742539557769756338">કવર</translation>
<translation id="4748357248530471599">ડિસ્પ્લેમાં જ સામેલ પૂર્ણસ્ક્રીન ટૉગલ કરો</translation>
<translation id="4757246831282535685">ટેબ પેનલ</translation>
-<translation id="4763480195061959176">વિડિઓ</translation>
+<translation id="4763480195061959176">વીડિયો</translation>
<translation id="479989351350248267">search</translation>
<translation id="4812940957355064477">કૃપા કરીને એક નંબર દાખલ કરો.</translation>
<translation id="4912536737030637138">ગ્રંથસૂચિની એન્ટ્રી</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">સમય</translation>
<translation id="5630795885300617244">10 સેકન્ડ છોડવા માટે ડાબે અથવા જમણે બે વાર ટૅપ કરો</translation>
<translation id="5631759159893697722">અમૂર્ત</translation>
-<translation id="5641012560118721995">પ્લેબેક થોભાવો</translation>
<translation id="5643186887447432888">બટન</translation>
<translation id="5677946354068040947">વધુ વિકલ્પો</translation>
<translation id="576709008726043716">પ્રસ્તાવના</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">રીસેટ કરો</translation>
<translation id="5966707198760109579">અઠવાડિયું</translation>
<translation id="5987525920412732405">સ્પિન બટન</translation>
+<translation id="6011459053400940133">વોલ્યુમ સ્લાઇડર</translation>
<translation id="6015796118275082299">વર્ષ</translation>
<translation id="6023896073578205740">સૂચિ બૉક્સ</translation>
-<translation id="6101327004457443354">ઑડિઓ ટ્રેક અનમ્યૂટ કરો</translation>
<translation id="6150588977291308318">ગ્રંથસૂચિ</translation>
<translation id="6164829606128959761">મીટર</translation>
<translation id="6166809985690652833">સમાપન ભાષણ</translation>
@@ -167,7 +163,7 @@
<translation id="6820615603175220800">ગ્રંથસૂચિનો સંદર્ભ</translation>
<translation id="6843725295806269523">બંધ કરો</translation>
<translation id="6853785296079745596">ઉપશીર્ષક છુપાવો</translation>
-<translation id="6885760532393684712">નિર્દેશિકા</translation>
+<translation id="6885760532393684712">ડિરેક્ટરી</translation>
<translation id="689129560213475294">પ્રકાશકની માહિતી</translation>
<translation id="6934078000481955284">બ્લૉકક્વોટ</translation>
<translation id="6941933287844615239">મીડિયા ડાઉનલોડ કરો</translation>
@@ -185,26 +181,23 @@
<translation id="7460907917090416791"><ph name="QUANTITY" /> TB</translation>
<translation id="7491962110804786152">ટેબ</translation>
<translation id="7514365320538308">ડાઉનલોડ કરો</translation>
-<translation id="7529102961911894712">બૅક લિંક</translation>
+<translation id="7529102961911894712">પાછળ લઈ જતી લિંક</translation>
<translation id="7647456547678091388">ટિપ</translation>
<translation id="7661956066982048809">ગ્રાફિક્સ દસ્તાવેજ</translation>
<translation id="7673697353781729403">કલાક</translation>
<translation id="7681220483256441252">અનુક્રમણિકા</translation>
<translation id="7720026100085573005">બાકીનો સમય</translation>
-<translation id="7740016676195725605">વિગતવાર ઉપશીર્ષકનું પ્રદર્શન અટકાવો</translation>
<translation id="7740050170769002709">HTML માહિતી</translation>
<translation id="7750228210027921155">ચિત્રમાં ચિત્ર</translation>
<translation id="7789962463072032349">થોભો</translation>
<translation id="7802800022689234070">પ્રકટીકરણ ત્રિકોણ</translation>
-<translation id="7888071071722539607">કૃપા કરીને ઇમેઇલ સરનામાંમાં '<ph name="ATSIGN" />' શામેલ કરો. '<ph name="INVALIDADDRESS" />' માં '<ph name="ATSIGN" />' ખૂટી રહ્યું છે.</translation>
+<translation id="7888071071722539607">કૃપા કરીને ઇમેઇલ સરનામાંમાં '<ph name="ATSIGN" />' શામેલ કરો. '<ph name="INVALIDADDRESS" />'માં '<ph name="ATSIGN" />' ખૂટે છે.</translation>
<translation id="7891486169920085145">વિભાજનકર્તા</translation>
<translation id="795667975304826397">કોઈ ફાઇલ પસંદ કરેલી નથી</translation>
<translation id="8053789581856978548">ટેક્સ્ટ ફીલ્ડ શોધો</translation>
<translation id="8057695513531652401">સૂચના</translation>
<translation id="8105797009065549151">નોંધ સંદર્ભ</translation>
-<translation id="8115662671911883373">ઉપશીર્ષક પ્રદર્શન પ્રારંભ કરો</translation>
<translation id="8117451130807776954">આ અઠવાડિયે</translation>
-<translation id="819205353528511139">પૂર્ણ સ્ક્રીન મોડમાં મૂવી ચલાવો</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">કૅપ્શન્સ</translation>
<translation id="835897206747267392">અમાન્ય મૂલ્ય.</translation>
@@ -224,11 +217,10 @@
<translation id="8613126697340063924">રિમોટ પ્લેબેકનું નિયંત્રણ કરો</translation>
<translation id="862370744433916922">(સબટાઇટલ)</translation>
<translation id="8750798805984357768">કૃપા કરીને આ વિકલ્પોમાંથી કોઈ એક પસંદ કરો.</translation>
-<translation id="8785498733064193001">પ્લેબૅક શરૂ કરો</translation>
<translation id="8808573423886751634">પ્રકરણ</translation>
<translation id="8845239796550121995">હમણાં તમારા TV પર કાસ્ટ કરી રહ્યાં છીએ</translation>
<translation id="8851136666856101339">મુખ્ય</translation>
-<translation id="8875657656876809964">વીડિઓ પ્લેબૅક ભૂલ</translation>
+<translation id="8875657656876809964">વીડિયો પ્લેબૅક ભૂલ</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
<translation id="8987927404178983737">મહિનો</translation>
<translation id="901493112792887934">સેકન્ડ્સમાં વર્તમાન સમય</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_hi.xtb b/chromium/content/app/strings/translations/content_strings_hi.xtb
index 5f9ac7f2f5b..65b90e914b4 100644
--- a/chromium/content/app/strings/translations/content_strings_hi.xtb
+++ b/chromium/content/app/strings/translations/content_strings_hi.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="hi">
<translation id="1018939186200882850">मेनू आइटम</translation>
-<translation id="1020833440720551630">ऑडियो ट्रैक की आवाज़ बंद करें</translation>
<translation id="10623998915015855">टॉगल बटन</translation>
<translation id="1088086359088493902">सेकंड</translation>
<translation id="1171774979989969504">कृपया ई-मेल पता दर्ज करें.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">क्रेडिट</translation>
<translation id="1342835525016946179">लेख</translation>
<translation id="1359897965706325498">बैनर</translation>
-<translation id="1548116112524424341">वीडियो को पिक्चर में पिक्चर मोड में चलाएं</translation>
<translation id="1589122976691792535">क्षेत्र</translation>
<translation id="1591562245178063882">इस माह</translation>
<translation id="1637811476055996098">फ़ाइलें चुनें</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">ट्री ग्रिड</translation>
<translation id="1822429046913737220">पूर्वाह्न/अपराह्न</translation>
<translation id="1832974991323546415">दूरस्थ डिवाइस पर चलाएं</translation>
-<translation id="1838818994221231429">डिसप्ले कटआउट क्षेत्र में फ़ुलस्क्रीन टॉगल करें</translation>
<translation id="190587075670221089">मिटाना</translation>
<translation id="1907737156431278478">उदाहरण</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">समय</translation>
<translation id="5630795885300617244">10 सेकंड आगे या पीछे जाने के लिए बाएं या दाएं पर दो बार टैप करें</translation>
<translation id="5631759159893697722">संक्षेप</translation>
-<translation id="5641012560118721995">प्लेबैक रोकें</translation>
<translation id="5643186887447432888">बटन</translation>
<translation id="5677946354068040947">अधिक विकल्प</translation>
<translation id="576709008726043716">परिचय</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">रीसेट करें</translation>
<translation id="5966707198760109579">सप्ताह</translation>
<translation id="5987525920412732405">स्पिन बटन</translation>
+<translation id="6011459053400940133">वॉल्यूम स्लाइडर</translation>
<translation id="6015796118275082299">वर्ष</translation>
<translation id="6023896073578205740">सूची बॉक्स</translation>
-<translation id="6101327004457443354">ऑडियो ट्रैक अनम्यूट करें</translation>
<translation id="6150588977291308318">संदर्भ सूची</translation>
<translation id="6164829606128959761">मीटर</translation>
<translation id="6166809985690652833">उपसंहार</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">घंटे</translation>
<translation id="7681220483256441252">इंडेक्स</translation>
<translation id="7720026100085573005">शेष समय</translation>
-<translation id="7740016676195725605">बंद कैप्शन दिखाना रोकें</translation>
<translation id="7740050170769002709">HTML सामग्री</translation>
<translation id="7750228210027921155">पिक्चर में पिक्चर</translation>
<translation id="7789962463072032349">पॉज़ करें</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">लेख फ़ील्ड खोजें</translation>
<translation id="8057695513531652401">सूचना</translation>
<translation id="8105797009065549151">नोट संदर्भ</translation>
-<translation id="8115662671911883373">बंद कैप्शन दिखाना प्रारंभ करें</translation>
<translation id="8117451130807776954">इस सप्ताह</translation>
-<translation id="819205353528511139">फ़िल्म को पूर्ण स्क्रीन मोड में चलाएं</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">कैप्शन</translation>
<translation id="835897206747267392">अमान्य मान.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">दूरस्थ प्लेबैक नियंत्रित करें</translation>
<translation id="862370744433916922">सबटाइटल</translation>
<translation id="8750798805984357768">कृपया इनमें से कोई विकल्प चुनें.</translation>
-<translation id="8785498733064193001">प्लेबैक शुरू करें</translation>
<translation id="8808573423886751634">पाठ</translation>
<translation id="8845239796550121995">अब आपके टीवी पर कास्ट हो रहा है</translation>
<translation id="8851136666856101339">मुख्य</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_hr.xtb b/chromium/content/app/strings/translations/content_strings_hr.xtb
index 354c4accefd..d26162df319 100644
--- a/chromium/content/app/strings/translations/content_strings_hr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_hr.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="hr">
<translation id="1018939186200882850">stavka izbornika</translation>
-<translation id="1020833440720551630">isključivanje zvučnog zapisa</translation>
<translation id="10623998915015855">preklopni gumb</translation>
<translation id="1088086359088493902">Sekunde</translation>
<translation id="1171774979989969504">Unesite e-adresu.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">zasluge</translation>
<translation id="1342835525016946179">članak</translation>
<translation id="1359897965706325498">natpis</translation>
-<translation id="1548116112524424341">reprodukcija videozapisa u načnu slike u slici</translation>
<translation id="1589122976691792535">regija</translation>
<translation id="1591562245178063882">Ovaj mjesec</translation>
<translation id="1637811476055996098">Odabir datoteka</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">rešetka u obliku stabla</translation>
<translation id="1822429046913737220">prijepodne/poslijepodne</translation>
<translation id="1832974991323546415">reproduciraj na udaljenom uređaju</translation>
-<translation id="1838818994221231429">prebacite cijeli zaslon u područje za urez na zaslonu</translation>
<translation id="190587075670221089">brisanje</translation>
<translation id="1907737156431278478">primjer</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">vrijeme</translation>
<translation id="5630795885300617244">Dvaput dodirnite lijevo ili desno za preskakanje od 10 s</translation>
<translation id="5631759159893697722">sažetak</translation>
-<translation id="5641012560118721995">pauziranje reprodukcije</translation>
<translation id="5643186887447432888">gumb</translation>
<translation id="5677946354068040947">više opcija</translation>
<translation id="576709008726043716">uvod</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Ponovno postavi</translation>
<translation id="5966707198760109579">Tjedan</translation>
<translation id="5987525920412732405">okretni gumb</translation>
+<translation id="6011459053400940133">Klizač za glasnoću</translation>
<translation id="6015796118275082299">Godina</translation>
<translation id="6023896073578205740">okvir s popisom</translation>
-<translation id="6101327004457443354">uključivanje zvučnog zapisa</translation>
<translation id="6150588977291308318">bibliografija</translation>
<translation id="6164829606128959761">mjerač</translation>
<translation id="6166809985690652833">pogovor</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Sati</translation>
<translation id="7681220483256441252">indeks</translation>
<translation id="7720026100085573005">preostalo vrijeme</translation>
-<translation id="7740016676195725605">zaustavljanje prikazivanja titlova</translation>
<translation id="7740050170769002709">HTML sadržaj</translation>
<translation id="7750228210027921155">Slika u slici</translation>
<translation id="7789962463072032349">pauziraj</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">pretraži tekstno polje</translation>
<translation id="8057695513531652401">obavijest</translation>
<translation id="8105797009065549151">referenca bilješke</translation>
-<translation id="8115662671911883373">početak prikazivanja titlova</translation>
<translation id="8117451130807776954">Ovaj tjedan</translation>
-<translation id="819205353528511139">reprodukcija filma na cijelom zaslonu</translation>
<translation id="8199524924445686405">gggg</translation>
<translation id="8284326494547611709">Titlovi</translation>
<translation id="835897206747267392">Nevažeća vrijednost.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">upravljaj daljinskom reprodukcijom</translation>
<translation id="862370744433916922">titl</translation>
<translation id="8750798805984357768">Izaberite jednu od tih opcija.</translation>
-<translation id="8785498733064193001">početak reprodukcije</translation>
<translation id="8808573423886751634">poglavlje</translation>
<translation id="8845239796550121995">Emitira se na televizoru</translation>
<translation id="8851136666856101339">glav</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_hu.xtb b/chromium/content/app/strings/translations/content_strings_hu.xtb
index c16b586fb98..27be7ecadcb 100644
--- a/chromium/content/app/strings/translations/content_strings_hu.xtb
+++ b/chromium/content/app/strings/translations/content_strings_hu.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="hu">
<translation id="1018939186200882850">menüelem</translation>
-<translation id="1020833440720551630">hangsáv némítása</translation>
<translation id="10623998915015855">átkapcsológomb</translation>
<translation id="1088086359088493902">Másodperc</translation>
<translation id="1171774979989969504">Kérjük, adjon meg egy e-mail címet.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">készítők</translation>
<translation id="1342835525016946179">cikk</translation>
<translation id="1359897965706325498">szalaghirdetés</translation>
-<translation id="1548116112524424341">videó lejátszása kép a képben módban</translation>
<translation id="1589122976691792535">régió</translation>
<translation id="1591562245178063882">Ebben a hónapban</translation>
<translation id="1637811476055996098">Fájlok kiválasztása</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">farács</translation>
<translation id="1822429046913737220">de./du.</translation>
<translation id="1832974991323546415">lejátszás távoli eszközön</translation>
-<translation id="1838818994221231429">váltás teljes képernyőre a képernyőkivágás területén</translation>
<translation id="190587075670221089">törlés</translation>
<translation id="1907737156431278478">példa</translation>
<translation id="1921819250265091946">nn</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">idő</translation>
<translation id="5630795885300617244">A jobb/bal oldalon duplán koppintva ugorhat előre/vissza 10 másodpercet</translation>
<translation id="5631759159893697722">absztrakt</translation>
-<translation id="5641012560118721995">lejátszás szüneteltetése</translation>
<translation id="5643186887447432888">gomb</translation>
<translation id="5677946354068040947">további beállítások</translation>
<translation id="576709008726043716">bevezetés</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Visszaállítás</translation>
<translation id="5966707198760109579">Hét</translation>
<translation id="5987525920412732405">léptetőnyíl</translation>
+<translation id="6011459053400940133">hangerőcsúszka</translation>
<translation id="6015796118275082299">Év</translation>
<translation id="6023896073578205740">listamező</translation>
-<translation id="6101327004457443354">hangsáv némításának feloldása</translation>
<translation id="6150588977291308318">bibliográfia</translation>
<translation id="6164829606128959761">mérő</translation>
<translation id="6166809985690652833">utószó</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Óra</translation>
<translation id="7681220483256441252">tárgymutató</translation>
<translation id="7720026100085573005">hátralévő idő</translation>
-<translation id="7740016676195725605">feliratok elrejtése</translation>
<translation id="7740050170769002709">HTML-tartalom</translation>
<translation id="7750228210027921155">Kép a képben</translation>
<translation id="7789962463072032349">szüneteltetés</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">keresés a szövegmezőben</translation>
<translation id="8057695513531652401">közlés</translation>
<translation id="8105797009065549151">jegyzethivatkozás</translation>
-<translation id="8115662671911883373">feliratok megjelenítése</translation>
<translation id="8117451130807776954">Ezen a héten</translation>
-<translation id="819205353528511139">film lejátszása teljes képernyős nézetben</translation>
<translation id="8199524924445686405">éééé</translation>
<translation id="8284326494547611709">Feliratok</translation>
<translation id="835897206747267392">Érvénytelen érték.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">távoli lejátszás kezelése</translation>
<translation id="862370744433916922">felirat</translation>
<translation id="8750798805984357768">Kérjük, válassza ki az egyik opciót.</translation>
-<translation id="8785498733064193001">lejátszás indítása</translation>
<translation id="8808573423886751634">fejezet</translation>
<translation id="8845239796550121995">Átküldés a tévére folyamatban</translation>
<translation id="8851136666856101339">fő</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_id.xtb b/chromium/content/app/strings/translations/content_strings_id.xtb
index adc14868eb9..862201bff82 100644
--- a/chromium/content/app/strings/translations/content_strings_id.xtb
+++ b/chromium/content/app/strings/translations/content_strings_id.xtb
@@ -2,8 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="id">
<translation id="1018939186200882850">item menu</translation>
-<translation id="1020833440720551630">bisukan trek audio</translation>
-<translation id="10623998915015855">tombol beralih</translation>
+<translation id="10623998915015855">tombol</translation>
<translation id="1088086359088493902">Detik</translation>
<translation id="1171774979989969504">Masukkan alamat email.</translation>
<translation id="1178581264944972037">Jeda</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">daftar penghargaan</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">spanduk</translation>
-<translation id="1548116112524424341">memutar video dalam mode picture-in-picture</translation>
<translation id="1589122976691792535">wilayah</translation>
<translation id="1591562245178063882">Bulan ini</translation>
<translation id="1637811476055996098">Pilih File</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">kisi pohon</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">putar di perangkat jarak jauh</translation>
-<translation id="1838818994221231429">mengalihkan layar penuh ke area potongan layar</translation>
<translation id="190587075670221089">penghapusan</translation>
<translation id="1907737156431278478">contoh</translation>
<translation id="1921819250265091946">hh</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">waktu</translation>
<translation id="5630795885300617244">Tap dua kali ke kiri atau kanan untuk melewati 10 detik</translation>
<translation id="5631759159893697722">abstrak</translation>
-<translation id="5641012560118721995">jeda pemutaran</translation>
<translation id="5643186887447432888">tombol</translation>
<translation id="5677946354068040947">opsi lainnya</translation>
<translation id="576709008726043716">pendahuluan</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Setel ulang</translation>
<translation id="5966707198760109579">Minggu</translation>
<translation id="5987525920412732405">tombol putar</translation>
+<translation id="6011459053400940133">penggeser volume</translation>
<translation id="6015796118275082299">Tahun</translation>
<translation id="6023896073578205740">kotak daftar</translation>
-<translation id="6101327004457443354">suarakan trek audio</translation>
<translation id="6150588977291308318">bibliografi</translation>
<translation id="6164829606128959761">pengukur</translation>
<translation id="6166809985690652833">penutup</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Jam</translation>
<translation id="7681220483256441252">indeks</translation>
<translation id="7720026100085573005">sisa waktu</translation>
-<translation id="7740016676195725605">berhenti menampilkan teks</translation>
<translation id="7740050170769002709">Konten HTML</translation>
<translation id="7750228210027921155">Picture-in-picture</translation>
<translation id="7789962463072032349">jeda</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">bidang teks penelusuran</translation>
<translation id="8057695513531652401">pemberitahuan</translation>
<translation id="8105797009065549151">referensi catatan</translation>
-<translation id="8115662671911883373">mulai menampilkan teks</translation>
<translation id="8117451130807776954">Minggu ini</translation>
-<translation id="819205353528511139">putar film dalam mode layar penuh</translation>
<translation id="8199524924445686405">tttt</translation>
<translation id="8284326494547611709">Teks</translation>
<translation id="835897206747267392">Nilai tidak valid.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">kontrol pemutaran jarak jauh</translation>
<translation id="862370744433916922">subjudul</translation>
<translation id="8750798805984357768">Pilih salah satu opsi berikut.</translation>
-<translation id="8785498733064193001">mulai pemutaran</translation>
<translation id="8808573423886751634">bab</translation>
<translation id="8845239796550121995">Sekarang sedang mentransmisi ke TV Anda</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_it.xtb b/chromium/content/app/strings/translations/content_strings_it.xtb
index ecbcfe24e78..c23fa641bc4 100644
--- a/chromium/content/app/strings/translations/content_strings_it.xtb
+++ b/chromium/content/app/strings/translations/content_strings_it.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="it">
<translation id="1018939186200882850">voce di menu</translation>
-<translation id="1020833440720551630">disattiva traccia audio</translation>
<translation id="10623998915015855">pulsante di attivazione/disattivazione</translation>
<translation id="1088086359088493902">Secondi</translation>
<translation id="1171774979989969504">Inserisci un indirizzo email.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">ringraziamenti</translation>
<translation id="1342835525016946179">articolo</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">riproduci video in modalità picture in picture</translation>
<translation id="1589122976691792535">regione</translation>
<translation id="1591562245178063882">Questo mese</translation>
<translation id="1637811476055996098">Scegli file</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">griglia ad albero</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">riproduci su dispositivo remoto</translation>
-<translation id="1838818994221231429">attiva/disattiva lo schermo intero nell'area tagliata dalla visualizzazione</translation>
<translation id="190587075670221089">eliminazione</translation>
<translation id="1907737156431278478">esempio</translation>
<translation id="1921819250265091946">gg</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Tocca due volte a sinistra o destra per saltare di 10 secondi</translation>
<translation id="5631759159893697722">abstract</translation>
-<translation id="5641012560118721995">sospendi riproduzione</translation>
<translation id="5643186887447432888">pulsante</translation>
<translation id="5677946354068040947">altre opzioni</translation>
<translation id="576709008726043716">introduzione</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Ripristina</translation>
<translation id="5966707198760109579">Settimana</translation>
<translation id="5987525920412732405">pulsante di selezione</translation>
+<translation id="6011459053400940133">dispositivo di scorrimento del volume</translation>
<translation id="6015796118275082299">Anno</translation>
<translation id="6023896073578205740">casella di riepilogo</translation>
-<translation id="6101327004457443354">riattiva traccia audio</translation>
<translation id="6150588977291308318">bibliografia</translation>
<translation id="6164829606128959761">indicatore</translation>
<translation id="6166809985690652833">postfazione</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Orario</translation>
<translation id="7681220483256441252">indice</translation>
<translation id="7720026100085573005">tempo rimanente</translation>
-<translation id="7740016676195725605">interrompi la visualizzazione dei sottotitoli</translation>
<translation id="7740050170769002709">Contenuti HTML</translation>
<translation id="7750228210027921155">Picture in picture</translation>
<translation id="7789962463072032349">pausa</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">campo di testo della ricerca</translation>
<translation id="8057695513531652401">informativa</translation>
<translation id="8105797009065549151">riferimento note</translation>
-<translation id="8115662671911883373">avvia la visualizzazione dei sottotitoli</translation>
<translation id="8117451130807776954">Questa settimana</translation>
-<translation id="819205353528511139">riproduci filmato in modalità a schermo intero</translation>
<translation id="8199524924445686405">aaaa</translation>
<translation id="8284326494547611709">Sottotitoli</translation>
<translation id="835897206747267392">Valore non valido.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">gestisci riproduzione remota</translation>
<translation id="862370744433916922">sottotitolo</translation>
<translation id="8750798805984357768">Seleziona una di queste opzioni.</translation>
-<translation id="8785498733064193001">inizia riproduzione</translation>
<translation id="8808573423886751634">capitolo</translation>
<translation id="8845239796550121995">Ora in fase di trasmissione alla TV</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_iw.xtb b/chromium/content/app/strings/translations/content_strings_iw.xtb
index 05c05d45950..35b1d203aba 100644
--- a/chromium/content/app/strings/translations/content_strings_iw.xtb
+++ b/chromium/content/app/strings/translations/content_strings_iw.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="iw">
<translation id="1018939186200882850">פריט בתפריט</translation>
-<translation id="1020833440720551630">השתק רצועת אודיו</translation>
<translation id="10623998915015855">לחצן החלפה</translation>
<translation id="1088086359088493902">שניות</translation>
<translation id="1171774979989969504">הזן כתובת אימייל.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">קרדיטים</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">מודעת באנר</translation>
-<translation id="1548116112524424341">הפעלת הסרטון במצב 'תמונה בתוך תמונה'</translation>
<translation id="1589122976691792535">אזור</translation>
<translation id="1591562245178063882">החודש</translation>
<translation id="1637811476055996098">בחר קבצים</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">רשת של עץ</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">הפעלה במכשיר מרוחק</translation>
-<translation id="1838818994221231429">מעבר ממסך מלא לתצוגה באזור המגרעת של המסך</translation>
<translation id="190587075670221089">מחיקה</translation>
<translation id="1907737156431278478">דוגמה</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">הקשה כפולה בצד ימין או שמאל מדלגת על 10 שניות</translation>
<translation id="5631759159893697722">תקציר</translation>
-<translation id="5641012560118721995">השהה הפעלה</translation>
<translation id="5643186887447432888">לחצן</translation>
<translation id="5677946354068040947">אפשרויות נוספות</translation>
<translation id="576709008726043716">מבוא</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">אפס</translation>
<translation id="5966707198760109579">שבוע</translation>
<translation id="5987525920412732405">לחצן קביעת ערך</translation>
+<translation id="6011459053400940133">מחוון עוצמת קול</translation>
<translation id="6015796118275082299">שנה</translation>
<translation id="6023896073578205740">תיבת רשימה</translation>
-<translation id="6101327004457443354">בטל השתקה של רצועת אודיו</translation>
<translation id="6150588977291308318">ביבליוגרפיה</translation>
<translation id="6164829606128959761">מד</translation>
<translation id="6166809985690652833">אחרית דבר</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">שעות</translation>
<translation id="7681220483256441252">אינדקס</translation>
<translation id="7720026100085573005">זמן שנותר</translation>
-<translation id="7740016676195725605">הפסק להציג כתוביות סגורות</translation>
<translation id="7740050170769002709">‏תוכן HTML</translation>
<translation id="7750228210027921155">תמונה בתוך תמונה</translation>
<translation id="7789962463072032349">השהה</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">שדה טקסט לחיפוש</translation>
<translation id="8057695513531652401">הודעה</translation>
<translation id="8105797009065549151">הפניה להערה</translation>
-<translation id="8115662671911883373">התחל להציג כתוביות סגורות</translation>
<translation id="8117451130807776954">השבוע</translation>
-<translation id="819205353528511139">הפעל את הסרט במצב מסך מלא</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">כתוביות</translation>
<translation id="835897206747267392">ערך לא חוקי.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">שליטה בהפעלה מרחוק</translation>
<translation id="862370744433916922">כותרת משנה</translation>
<translation id="8750798805984357768">בחר אחת מהאפשרויות הבאות.</translation>
-<translation id="8785498733064193001">התחל בהפעלה</translation>
<translation id="8808573423886751634">פרק</translation>
<translation id="8845239796550121995">מעביר תוכן לטלוויזיה</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ja.xtb b/chromium/content/app/strings/translations/content_strings_ja.xtb
index 8d633af1344..0437ead9da4 100644
--- a/chromium/content/app/strings/translations/content_strings_ja.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ja.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ja">
<translation id="1018939186200882850">メニュー項目</translation>
-<translation id="1020833440720551630">音声トラックをミュート</translation>
<translation id="10623998915015855">切り替えボタン</translation>
<translation id="1088086359088493902">秒</translation>
<translation id="1171774979989969504">メール アドレスを入力してください。</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">クレジット</translation>
<translation id="1342835525016946179">記事</translation>
<translation id="1359897965706325498">バナー</translation>
-<translation id="1548116112524424341">ピクチャー イン ピクチャー モードで動画を再生します</translation>
<translation id="1589122976691792535">地域</translation>
<translation id="1591562245178063882">今月</translation>
<translation id="1637811476055996098">ファイル選択</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">ツリーグリッド</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">リモート デバイスで再生</translation>
-<translation id="1838818994221231429">全画面表示をディスプレイ カットアウト領域に合わせた表示に切り替えます</translation>
<translation id="190587075670221089">削除</translation>
<translation id="1907737156431278478">例</translation>
<translation id="1921819250265091946">日</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">日時</translation>
<translation id="5630795885300617244">左または右をダブルタップして 10 秒スキップします</translation>
<translation id="5631759159893697722">概要</translation>
-<translation id="5641012560118721995">再生を一時停止</translation>
<translation id="5643186887447432888">ボタン</translation>
<translation id="5677946354068040947">その他のオプション</translation>
<translation id="576709008726043716">序論</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">リセット</translation>
<translation id="5966707198760109579">週</translation>
<translation id="5987525920412732405">スピンボタン</translation>
+<translation id="6011459053400940133">音量スライダー</translation>
<translation id="6015796118275082299">年</translation>
<translation id="6023896073578205740">リストボックス</translation>
-<translation id="6101327004457443354">音声トラックのミュートを解除</translation>
<translation id="6150588977291308318">参考文献</translation>
<translation id="6164829606128959761">メーター</translation>
<translation id="6166809985690652833">後書き</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">時間</translation>
<translation id="7681220483256441252">索引</translation>
<translation id="7720026100085573005">残り時間</translation>
-<translation id="7740016676195725605">クローズド キャプションの表示を終了</translation>
<translation id="7740050170769002709">HTML コンテンツ</translation>
<translation id="7750228210027921155">ピクチャー イン ピクチャー</translation>
<translation id="7789962463072032349">一時停止</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">検索テキスト欄</translation>
<translation id="8057695513531652401">注記</translation>
<translation id="8105797009065549151">備考</translation>
-<translation id="8115662671911883373">クローズド キャプションの表示を開始</translation>
<translation id="8117451130807776954">今週</translation>
-<translation id="819205353528511139">全画面表示モードで再生</translation>
<translation id="8199524924445686405"> 年 </translation>
<translation id="8284326494547611709">字幕</translation>
<translation id="835897206747267392">値が無効です。</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">リモート再生をコントロール</translation>
<translation id="862370744433916922">副題</translation>
<translation id="8750798805984357768">これらのオプションから 1 つ選択してください。</translation>
-<translation id="8785498733064193001">再生を開始</translation>
<translation id="8808573423886751634">章</translation>
<translation id="8845239796550121995">テレビにキャストしています</translation>
<translation id="8851136666856101339">本文</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_kn.xtb b/chromium/content/app/strings/translations/content_strings_kn.xtb
index 61ca4f14f37..43ddc0cbfb1 100644
--- a/chromium/content/app/strings/translations/content_strings_kn.xtb
+++ b/chromium/content/app/strings/translations/content_strings_kn.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="kn">
<translation id="1018939186200882850">ಮೆನು ಐಟಂ</translation>
-<translation id="1020833440720551630">ಆಡಿಯೋ ಟ್ರ್ಯಾಕ್ ಮ್ಯೂಟ್ ಮಾಡಿ</translation>
<translation id="10623998915015855">ಟಾಗಲ್ ಬಟನ್</translation>
<translation id="1088086359088493902">ಸೆಕೆಂಡುಗಳು</translation>
<translation id="1171774979989969504">ದಯವಿಟ್ಟು ಇಮೇಲ್ ವಿಳಾಸವನ್ನು ನಮೂದಿಸಿ.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">ಕ್ರೆಡಿಟ್‌ಗಳು</translation>
<translation id="1342835525016946179">ಲೇಖನ</translation>
<translation id="1359897965706325498">ಬ್ಯಾನರ್</translation>
-<translation id="1548116112524424341">ಚಿತ್ರದಲ್ಲಿನ ಚಿತ್ರದ ಮೋಡ್‌ನಲ್ಲಿ ವೀಡಿಯೊ ಪ್ಲೇ ಮಾಡಿ</translation>
<translation id="1589122976691792535">ಪ್ರದೇಶ</translation>
<translation id="1591562245178063882">ಈ ತಿಂಗಳು</translation>
<translation id="1637811476055996098">ಫೈಲ್‌ಗಳನ್ನು ಆರಿಸಿ</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">ಟ್ರೀ ಗ್ರಿಡ್</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">ರಿಮೋಟ್ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಮಾಡಿ</translation>
-<translation id="1838818994221231429">ಪೂರ್ಣ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಡಿಸ್‌ಪ್ಲೇ ಕಟ್‌ಔಟ್ ಪ್ರದೇಶವಾಗಿ ಟಾಗಲ್ ಮಾಡಿ</translation>
<translation id="190587075670221089">ಅಳಿಸುವಿಕೆ</translation>
<translation id="1907737156431278478">ಉದಾಹರಣೆ</translation>
<translation id="1921819250265091946">ದಿದಿ</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">ಸಮಯ</translation>
<translation id="5630795885300617244">10ಸೆ ಸ್ಕಿಪ್ ಮಾಡಲು ಎಡಕ್ಕೆ ಅಥವಾ ಬಲಕ್ಕೆ ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ</translation>
<translation id="5631759159893697722">ಸಾರಾಂಶ</translation>
-<translation id="5641012560118721995">ಪ್ಲೇಬ್ಯಾಕ್ ವಿರಾಮಗೊಳಿಸು</translation>
<translation id="5643186887447432888">ಬಟನ್</translation>
<translation id="5677946354068040947">ಇನ್ನಷ್ಟು ಆಯ್ಕೆಗಳು</translation>
<translation id="576709008726043716">ಪರಿಚಯ</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">ಮರುಹೊಂದಿಸು</translation>
<translation id="5966707198760109579">ವಾರ</translation>
<translation id="5987525920412732405">ಸ್ಪಿನ್ ಬಟನ್</translation>
+<translation id="6011459053400940133">ವಾಲ್ಯೂಮ್ ಸ್ಲೈಡರ್</translation>
<translation id="6015796118275082299">ವರ್ಷ</translation>
<translation id="6023896073578205740">ಪಟ್ಟಿಯ ಬಾಕ್ಸ್</translation>
-<translation id="6101327004457443354">ಆಡಿಯೋ ಟ್ರ್ಯಾಕ್ ಅನ್‌ಮ್ಯೂಟ್ ಮಾಡು</translation>
<translation id="6150588977291308318">ಗ್ರಂಥಸೂಚಿ</translation>
<translation id="6164829606128959761">ಮೀಟರ್</translation>
<translation id="6166809985690652833">ನಂತರದ</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">ಗಂಟೆಗಳು</translation>
<translation id="7681220483256441252">ಸೂಚಿಕೆ</translation>
<translation id="7720026100085573005">ಉಳಿದಿರುವ ಸಮಯ</translation>
-<translation id="7740016676195725605">ಮುಚ್ಚಲಾಗಿರುವ ಶೀರ್ಷಿಕೆಗಳ ಪ್ರದರ್ಶಿಸುವಿಕೆಯನ್ನು ನಿಲ್ಲಿಸಿ</translation>
<translation id="7740050170769002709">HTML ವಿಷಯ</translation>
<translation id="7750228210027921155">ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ</translation>
<translation id="7789962463072032349">ವಿರಾಮ</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">ಪಠ್ಯ ಕ್ಷೇತ್ರವನ್ನು ಹುಡುಕಿ</translation>
<translation id="8057695513531652401">ಸೂಚನೆ</translation>
<translation id="8105797009065549151">ಸೂಚನೆ ಉಲ್ಲೇಖ</translation>
-<translation id="8115662671911883373">ಮುಚ್ಚಲಾಗಿರುವ ಶೀರ್ಷಿಕೆಗಳ ಪ್ರದರ್ಶಿಸುವಿಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಿ</translation>
<translation id="8117451130807776954">ಈ ವಾರ</translation>
-<translation id="819205353528511139">ಪೂರ್ಣ ಪರದೆಯ ಮೋಡ್‌‌ನಲ್ಲಿ ಚಲನಚಿತ್ರವನ್ನು ಪ್ಲೇ ಮಾಡಿ</translation>
<translation id="8199524924445686405">ವವವವ</translation>
<translation id="8284326494547611709">ಶೀರ್ಷಿಕೆಗಳು</translation>
<translation id="835897206747267392">ಅಮಾನ್ಯ ಮೌಲ್ಯ.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">ರಿಮೋಟ್ ಪ್ಲೇಬ್ಯಾಕ್ ನಿಯಂತ್ರಿಸಿ</translation>
<translation id="862370744433916922">ಉಪಶೀರ್ಷಿಕೆ</translation>
<translation id="8750798805984357768">ದಯವಿಟ್ಟು ಈ ಕೆಳಗಿನ ಆಯ್ಕೆಗಳಲ್ಲಿ ಒಂದನ್ನು ಆರಿಸಿ.</translation>
-<translation id="8785498733064193001">ಪ್ಲೇಬ್ಯಾಕ್ ಪ್ರಾರಂಭಿಸಿ</translation>
<translation id="8808573423886751634">ಅಧ್ಯಾಯ</translation>
<translation id="8845239796550121995">ಈಗ ನಿಮ್ಮ ಟಿವಿಯನ್ನು ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ</translation>
<translation id="8851136666856101339">ಮುಖ್ಯ</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ko.xtb b/chromium/content/app/strings/translations/content_strings_ko.xtb
index 4e41361c2e3..ba7d180cd02 100644
--- a/chromium/content/app/strings/translations/content_strings_ko.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ko.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ko">
<translation id="1018939186200882850">메뉴 항목</translation>
-<translation id="1020833440720551630">오디오 트랙 음소거</translation>
<translation id="10623998915015855">전환 버튼</translation>
<translation id="1088086359088493902">초</translation>
<translation id="1171774979989969504">이메일 주소를 입력하세요.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">저작권 표시</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">배너</translation>
-<translation id="1548116112524424341">PIP 모드로 동영상 재생</translation>
<translation id="1589122976691792535">지역</translation>
<translation id="1591562245178063882">이번 달</translation>
<translation id="1637811476055996098">파일 선택</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">트리 격자</translation>
<translation id="1822429046913737220">오전/오후</translation>
<translation id="1832974991323546415">원격 기기에서 재생</translation>
-<translation id="1838818994221231429">전체화면을 디스플레이 컷아웃 영역으로 전환</translation>
<translation id="190587075670221089">삭제</translation>
<translation id="1907737156431278478">예시</translation>
<translation id="1921819250265091946">일</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">10초를 건너뛰려면 왼쪽이나 오른쪽을 두 번 탭하세요.</translation>
<translation id="5631759159893697722">초록</translation>
-<translation id="5641012560118721995">재생 일시중지</translation>
<translation id="5643186887447432888">버튼</translation>
<translation id="5677946354068040947">옵션 더보기</translation>
<translation id="576709008726043716">소개</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">초기화</translation>
<translation id="5966707198760109579">주</translation>
<translation id="5987525920412732405">스핀 버튼</translation>
+<translation id="6011459053400940133">볼륨 슬라이더</translation>
<translation id="6015796118275082299">연도</translation>
<translation id="6023896073578205740">목록 상자</translation>
-<translation id="6101327004457443354">오디오 트랙 음소거 해제</translation>
<translation id="6150588977291308318">참고문헌</translation>
<translation id="6164829606128959761">미터</translation>
<translation id="6166809985690652833">후기</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">시간</translation>
<translation id="7681220483256441252">색인</translation>
<translation id="7720026100085573005">남은 시간</translation>
-<translation id="7740016676195725605">캡션 표시 중지</translation>
<translation id="7740050170769002709">HTML 콘텐츠</translation>
<translation id="7750228210027921155">PIP 모드</translation>
<translation id="7789962463072032349">일시중지</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">검색어 입력란</translation>
<translation id="8057695513531652401">안내문</translation>
<translation id="8105797009065549151">참고 자료</translation>
-<translation id="8115662671911883373">캡션 표시 시작</translation>
<translation id="8117451130807776954">이번 주</translation>
-<translation id="819205353528511139">전체화면 모드로 영화 재생</translation>
<translation id="8199524924445686405">연도</translation>
<translation id="8284326494547611709">자막</translation>
<translation id="835897206747267392">값이 잘못되었습니다.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">원격 재생 제어</translation>
<translation id="862370744433916922">부제</translation>
<translation id="8750798805984357768">다음 옵션 중 하나를 선택하세요.</translation>
-<translation id="8785498733064193001">재생 시작</translation>
<translation id="8808573423886751634">장</translation>
<translation id="8845239796550121995">TV로 전송 중</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_lt.xtb b/chromium/content/app/strings/translations/content_strings_lt.xtb
index 234fba4791e..adbcb2ddf6d 100644
--- a/chromium/content/app/strings/translations/content_strings_lt.xtb
+++ b/chromium/content/app/strings/translations/content_strings_lt.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="lt">
<translation id="1018939186200882850">meniu elementas</translation>
-<translation id="1020833440720551630">nutildyti garso įrašo takelį</translation>
<translation id="10623998915015855">perjungimo mygtukas</translation>
<translation id="1088086359088493902">Sekundės</translation>
<translation id="1171774979989969504">Įveskite el. pašto adresą.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">titrai</translation>
<translation id="1342835525016946179">artikelis</translation>
<translation id="1359897965706325498">reklamjuostė</translation>
-<translation id="1548116112524424341">leisti vaizdo įrašą vaizdo vaizde režimu</translation>
<translation id="1589122976691792535">regionas</translation>
<translation id="1591562245178063882">Šis mėnuo</translation>
<translation id="1637811476055996098">Pasirinkti failus</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">medžio tinklelis</translation>
<translation id="1822429046913737220">iki pietų / po pietų</translation>
<translation id="1832974991323546415">leisti naudojant nuotolinį įrenginį</translation>
-<translation id="1838818994221231429">perjungti visą ekraną į ekrano išpjovos zoną</translation>
<translation id="190587075670221089">trynimas</translation>
<translation id="1907737156431278478">pavyzdys</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Dukart palieskite kairėn arba dešinėn, kad praleistumėte 10 sek.</translation>
<translation id="5631759159893697722">santrauka</translation>
-<translation id="5641012560118721995">pristabdyti atkūrimą</translation>
<translation id="5643186887447432888">mygtukas</translation>
<translation id="5677946354068040947">daugiau parinkčių</translation>
<translation id="576709008726043716">įžanga</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Nustatyti iš naujo</translation>
<translation id="5966707198760109579">Savaitė</translation>
<translation id="5987525920412732405">sukimo mygtukas</translation>
+<translation id="6011459053400940133">garsumo šliaužiklis</translation>
<translation id="6015796118275082299">Metai</translation>
<translation id="6023896073578205740">sąrašo laukelis</translation>
-<translation id="6101327004457443354">įjungti garso įrašo takelio garsą</translation>
<translation id="6150588977291308318">bibliografija</translation>
<translation id="6164829606128959761">matuoklis</translation>
<translation id="6166809985690652833">baigiamasis žodis</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Valandos</translation>
<translation id="7681220483256441252">rodyklė</translation>
<translation id="7720026100085573005">likęs laikas</translation>
-<translation id="7740016676195725605">nebepateikti subtitrų</translation>
<translation id="7740050170769002709">HTML turinys</translation>
<translation id="7750228210027921155">Vaizdas vaizde</translation>
<translation id="7789962463072032349">pristabdyti</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">paieškos teksto laukas</translation>
<translation id="8057695513531652401">pranešimas</translation>
<translation id="8105797009065549151">pastabos nuoroda</translation>
-<translation id="8115662671911883373">pateikti subtitrus</translation>
<translation id="8117451130807776954">Ši savaitė</translation>
-<translation id="819205353528511139">paleisti filmą viso ekrano režimu</translation>
<translation id="8199524924445686405">mmmm</translation>
<translation id="8284326494547611709">Subtitrai</translation>
<translation id="835897206747267392">Neteisinga vertė.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">valdyti nuotolinį atkūrimą</translation>
<translation id="862370744433916922">paantraštė</translation>
<translation id="8750798805984357768">Pasirinkite vieną iš šių parinkčių.</translation>
-<translation id="8785498733064193001">pradėti atkūrimą</translation>
<translation id="8808573423886751634">skyrius</translation>
<translation id="8845239796550121995">Dabar perduodama į TV</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_lv.xtb b/chromium/content/app/strings/translations/content_strings_lv.xtb
index bfe6fa5bc27..dc17dc1eb3c 100644
--- a/chromium/content/app/strings/translations/content_strings_lv.xtb
+++ b/chromium/content/app/strings/translations/content_strings_lv.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="lv">
<translation id="1018939186200882850">izvēlnes vienums</translation>
-<translation id="1020833440720551630">izslēgt audio ieraksta skaņu</translation>
<translation id="10623998915015855">pārslēgšanas poga</translation>
<translation id="1088086359088493902">Sekundes</translation>
<translation id="1171774979989969504">Ievadiet e-pasta adresi.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">pateicības</translation>
<translation id="1342835525016946179">raksts</translation>
<translation id="1359897965706325498">reklāmkarogs</translation>
-<translation id="1548116112524424341">atskaņot videoklipu režīmā “attēls attēlā”</translation>
<translation id="1589122976691792535">reģions</translation>
<translation id="1591562245178063882">Šis mēnesis</translation>
<translation id="1637811476055996098">Izvēlēties failus</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">koka režģis</translation>
<translation id="1822429046913737220">priekšpusdienā/pēcpusdienā</translation>
<translation id="1832974991323546415">atskaņot attālinātā ierīcē</translation>
-<translation id="1838818994221231429">pārslēdz pilnekrāna režīmu displeja izgriezuma apgabalā</translation>
<translation id="190587075670221089">dzēšana</translation>
<translation id="1907737156431278478">piemērs</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">laiks</translation>
<translation id="5630795885300617244">Veiciet dubultskārienu pa labi vai pa kreisi, lai izlaistu 10 s.</translation>
<translation id="5631759159893697722">kopsavilkums</translation>
-<translation id="5641012560118721995">pauzēt atskaņošanu</translation>
<translation id="5643186887447432888">poga</translation>
<translation id="5677946354068040947">citas opcijas</translation>
<translation id="576709008726043716">ievads</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Atiestatīt</translation>
<translation id="5966707198760109579">Nedēļa</translation>
<translation id="5987525920412732405">skaitītājpoga</translation>
+<translation id="6011459053400940133">skaļuma slīdnis</translation>
<translation id="6015796118275082299">Gads</translation>
<translation id="6023896073578205740">sarakstlodziņš</translation>
-<translation id="6101327004457443354">ieslēgt audio ieraksta skaņu</translation>
<translation id="6150588977291308318">bibliogrāfija</translation>
<translation id="6164829606128959761">mērītājs</translation>
<translation id="6166809985690652833">pēcvārds</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Stundas</translation>
<translation id="7681220483256441252">rādītājs</translation>
<translation id="7720026100085573005">atlikušais laiks</translation>
-<translation id="7740016676195725605">apturēt slēgto parakstu rādīšanu</translation>
<translation id="7740050170769002709">HTML saturs</translation>
<translation id="7750228210027921155">Attēls attēlā</translation>
<translation id="7789962463072032349">pauzēt</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">meklēšanas teksta lauks</translation>
<translation id="8057695513531652401">paziņojums</translation>
<translation id="8105797009065549151">vēres atsauce</translation>
-<translation id="8115662671911883373">sākt slēgto parakstu rādīšanu</translation>
<translation id="8117451130807776954">Šī nedēļa</translation>
-<translation id="819205353528511139">atskaņot filmu pilnekrāna režīmā</translation>
<translation id="8199524924445686405">gggg</translation>
<translation id="8284326494547611709">Paraksti</translation>
<translation id="835897206747267392">Nederīga vērtība.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">kontrolēt attālināto atskaņošanu</translation>
<translation id="862370744433916922">apakšvirsraksts</translation>
<translation id="8750798805984357768">Lūdzu, atlasiet vienu no šīm opcijām.</translation>
-<translation id="8785498733064193001">sākt atskaņošanu</translation>
<translation id="8808573423886751634">nodaļa</translation>
<translation id="8845239796550121995">Pašlaik notiek apraide uz jūsu TV</translation>
<translation id="8851136666856101339">galvenais</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ml.xtb b/chromium/content/app/strings/translations/content_strings_ml.xtb
index 55a7feb6e98..f9b58d74b72 100644
--- a/chromium/content/app/strings/translations/content_strings_ml.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ml.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ml">
<translation id="1018939186200882850">മെനു ഇനം</translation>
-<translation id="1020833440720551630">ഓഡിയോ ട്രാക്ക് നിശബ്‌ദമാക്കുക</translation>
<translation id="10623998915015855">ടോഗിൾ ബട്ടൺ</translation>
<translation id="1088086359088493902">സെക്കൻഡ്</translation>
<translation id="1171774979989969504">ദയവായി ഒരു ഇമെയില്‍ വിലാസം നല്‍കുക.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">ക്രെഡിറ്റുകൾ</translation>
<translation id="1342835525016946179">ലേഖനം</translation>
<translation id="1359897965706325498">ബാനർ</translation>
-<translation id="1548116112524424341">ചിത്രത്തിനുള്ളിലെ ചിത്രം മോഡിൽ വീഡിയോ പ്ലേ ചെയ്യുക</translation>
<translation id="1589122976691792535">പ്രദേശം</translation>
<translation id="1591562245178063882">ഈ മാസം</translation>
<translation id="1637811476055996098">ഫയലുകൾ തിരഞ്ഞെടുക്കുക</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">ട്രീ ഗ്രിഡ്</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">വിദൂര ഉപകരണത്തിൽ പ്ലേ ചെയ്യുക</translation>
-<translation id="1838818994221231429">പൂർണ്ണ സ്ക്രീൻ, ഡിസ്‌പ്ലേ കട്ടൗട്ട് മേഖലയിലേക്ക് മാറ്റുക</translation>
<translation id="190587075670221089">ഇല്ലാതാക്കൽ</translation>
<translation id="1907737156431278478">ഉദാഹരണം</translation>
<translation id="1921819250265091946">തീയതി</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">സമയം</translation>
<translation id="5630795885300617244">10 സെക്കൻഡ് ഒഴിവാക്കാൻ ഇടത്തോട്ടോ വലത്തോട്ടോ രണ്ടുതവണ ടാപ്പ് ചെയ്യുക</translation>
<translation id="5631759159893697722">സംക്ഷേപം</translation>
-<translation id="5641012560118721995">പ്ലേബാക്ക് താൽക്കാലികമായി നിർത്തുക</translation>
<translation id="5643186887447432888">ബട്ടൺ</translation>
<translation id="5677946354068040947">കൂടുതൽ ഓപ്‌ഷനുകൾ</translation>
<translation id="576709008726043716">ആമുഖം</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">വീണ്ടും സജ്ജീകരിക്കുക</translation>
<translation id="5966707198760109579">ആഴ്‌ച</translation>
<translation id="5987525920412732405">സ്‌പിൻ ബട്ടൺ</translation>
+<translation id="6011459053400940133">വോളിയം സ്ലൈഡർ</translation>
<translation id="6015796118275082299">വര്‍ഷം</translation>
<translation id="6023896073578205740">ലിസ്റ്റ് ബോക്‌സ്</translation>
-<translation id="6101327004457443354">ഓഡിയോ ട്രാക്ക് ശബ്‌ദമുള്ളതാക്കുക</translation>
<translation id="6150588977291308318">ഗ്രന്ഥസൂചി</translation>
<translation id="6164829606128959761">മീറ്റർ</translation>
<translation id="6166809985690652833">പിൻ കുറിപ്പ്</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">മണിക്കൂര്‍‌</translation>
<translation id="7681220483256441252">സൂചിക</translation>
<translation id="7720026100085573005">അവശേഷിക്കുന്ന സമയം</translation>
-<translation id="7740016676195725605">അടച്ച അടിക്കുറിപ്പുകൾ പ്രദർശിപ്പിക്കുന്നത് നിർത്തുക</translation>
<translation id="7740050170769002709">HTML ഉള്ളടക്കം</translation>
<translation id="7750228210027921155">ചിത്രത്തിനുള്ളിലെ ചിത്രം</translation>
<translation id="7789962463072032349">താല്‍‌ക്കാലികമായി നിര്‍‌ത്തുക</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">തിരയൽ ടെക്‌സ്റ്റ് ഫീൽഡ്</translation>
<translation id="8057695513531652401">അറിയിപ്പ്</translation>
<translation id="8105797009065549151">കുറിപ്പ് റെഫറൻസ്</translation>
-<translation id="8115662671911883373">അടച്ച അടിക്കുറിപ്പുകൾ പ്രദർശിപ്പിക്കുന്നത് ആരംഭിക്കുക</translation>
<translation id="8117451130807776954">ഈ ആഴ്‌ച</translation>
-<translation id="819205353528511139">പൂർണ്ണ സ്‌ക്രീൻ മോഡിൽ മൂവി പ്ലേ ചെയ്യുക</translation>
<translation id="8199524924445686405">വർഷം</translation>
<translation id="8284326494547611709">അടിക്കുറിപ്പുകൾ</translation>
<translation id="835897206747267392">അസാധുവായ മൂല്യം.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">വിദൂര പ്ലേബാക്ക് നിയന്ത്രിക്കുക</translation>
<translation id="862370744433916922">ഉപശീർഷകം</translation>
<translation id="8750798805984357768">ഈ ഓപ്ഷനുകളിലൊന്ന് ദയവായി തിരഞ്ഞെടുക്കുക.</translation>
-<translation id="8785498733064193001">പ്ലേബാക്ക് ആരംഭിക്കുക</translation>
<translation id="8808573423886751634">അധ്യായം</translation>
<translation id="8845239796550121995">ഇപ്പോൾ നിങ്ങളുടെ ടിവിയിൽ കാസ്‌റ്റുചെയ്യുന്നു</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_mr.xtb b/chromium/content/app/strings/translations/content_strings_mr.xtb
index ad7e167229a..80244b14f5a 100644
--- a/chromium/content/app/strings/translations/content_strings_mr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_mr.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="mr">
<translation id="1018939186200882850">मेनू आयटम</translation>
-<translation id="1020833440720551630">ऑडिओ ट्रॅक निःशब्द करा</translation>
<translation id="10623998915015855">टॉगल बटण</translation>
<translation id="1088086359088493902">सेकंद</translation>
<translation id="1171774979989969504">कृपया एक ईमेल अॅड्रेस एंटर करा.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">श्रेय</translation>
<translation id="1342835525016946179">लेख</translation>
<translation id="1359897965706325498">बॅनर</translation>
-<translation id="1548116112524424341">व्हिडिओ चित्रात-चित्र मोडमध्ये प्ले करा</translation>
<translation id="1589122976691792535">प्रदेश</translation>
<translation id="1591562245178063882">या महिन्यात</translation>
<translation id="1637811476055996098">फायली निवडा</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">ट्री ग्रीड</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">दूरस्थ डिव्हाइसवर प्ले करा</translation>
-<translation id="1838818994221231429">डिस्प्ले कटआउट भागामध्ये फुलस्क्रीन टॉगल करा</translation>
<translation id="190587075670221089">हटवणे</translation>
<translation id="1907737156431278478">उदाहरण</translation>
<translation id="1921819250265091946">dd</translation>
@@ -38,7 +35,7 @@
<translation id="2060505056492490888">'<ph name="DOT" />' '<ph name="INVALIDDOMAIN" />' मध्ये चुकीच्या स्थितीवर वापरले आहे.</translation>
<translation id="2148716181193084225">आज</translation>
<translation id="2158401438286456825">पेज सूची</translation>
-<translation id="2226276347425096477">कृपया हा मजकूर <ph name="MAX_CHARACTERS" /> वर्ण लहान किंवा कमी करा (आपण सध्या <ph name="CURRENT_LENGTH" /> वर्ण वापरत आहात).</translation>
+<translation id="2226276347425096477">कृपया हा मजकूर <ph name="MAX_CHARACTERS" /> वर्ण लहान किंवा कमी करा (तुम्ही सध्या <ph name="CURRENT_LENGTH" /> वर्ण वापरत आहात).</translation>
<translation id="2247351761944213033">आठवडा <ph name="WEEKNUMBER" />, <ph name="YEAR" /></translation>
<translation id="2277199496770840904">ट्रॅक <ph name="NUMBER" /></translation>
<translation id="2291999235780842123">चेकबॉक्‍स</translation>
@@ -58,7 +55,7 @@
<translation id="2723001399770238859">ऑडिओ</translation>
<translation id="2746543609216772311">मूल्य <ph name="MINIMUM_DATE_OR_TIME" /> किंवा नंतरचे असणे आवश्यक आहे.</translation>
<translation id="2759744352195237655">पॉप अप बटण</translation>
-<translation id="2761667185364618470">कृपया आपण पुढे चालू ठेवू इच्छित असल्यास हा बॉक्स पहा.</translation>
+<translation id="2761667185364618470">कृपया तुम्ही पुढे चालू ठेवू इच्छित असल्यास हा बॉक्स पहा.</translation>
<translation id="2896972712917208084">रेडिओ गट</translation>
<translation id="2908441821576996758">कृपया ईमेल पत्त्यांची स्वल्पविरामाद्वारे विभक्त सूची एंटर करा.</translation>
<translation id="2940813599313844715">ऑब्जेक्ट</translation>
@@ -80,7 +77,7 @@
<translation id="3757388668994797779"><ph name="QUANTITY" /> GB</translation>
<translation id="3785482301506746191">चित्रपट वेळ स्क्रबर</translation>
<translation id="3808586225841795776">संज्ञा</translation>
-<translation id="3822383571486410024">कृपया हा मजकूर <ph name="MIN_CHARACTERS" /> वर्ण किंवा त्यापेक्षा अधिक मोठा करा (आपण सध्‍या <ph name="CURRENT_LENGTH" /> वर्ण वापरत आहात).</translation>
+<translation id="3822383571486410024">कृपया हा मजकूर <ph name="MIN_CHARACTERS" /> वर्ण किंवा त्यापेक्षा अधिक मोठा करा (तुम्ही सध्‍या <ph name="CURRENT_LENGTH" /> वर्ण वापरत आहात).</translation>
<translation id="383465348367842624">'<ph name="ATSIGN" />' मागुन येणार्‍या भागामध्ये '<ph name="INVALIDCHARACTER" />' चिन्ह नसावे.</translation>
<translation id="3846214748874656680">क्षेत्रेमधून बाहेर पडा</translation>
<translation id="3920932319529768807">निष्कर्ष</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">10 सेकंद वगळण्यासाठी डावीकडे किंवा उजवीकडे दोनदा टॅप करा</translation>
<translation id="5631759159893697722">अमूर्त</translation>
-<translation id="5641012560118721995">प्लेबॅकला विराम द्या</translation>
<translation id="5643186887447432888">बटण</translation>
<translation id="5677946354068040947">अधिक पर्याय</translation>
<translation id="576709008726043716">परिचय</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">रीसेट करा</translation>
<translation id="5966707198760109579">आठवडा</translation>
<translation id="5987525920412732405">स्पिन बटण</translation>
+<translation id="6011459053400940133">व्हॉल्यूम स्लायडर</translation>
<translation id="6015796118275082299">वर्ष</translation>
<translation id="6023896073578205740">सूची बॉक्स</translation>
-<translation id="6101327004457443354">ऑडिओ ट्रॅक सशब्द करा</translation>
<translation id="6150588977291308318">ग्रंथसूची</translation>
<translation id="6164829606128959761">मीटर</translation>
<translation id="6166809985690652833">अंतिम शब्द</translation>
@@ -172,7 +168,7 @@
<translation id="6934078000481955284">ब्लॉककोट</translation>
<translation id="6941933287844615239">मीडिया डाउनलोड करा</translation>
<translation id="6981594929165378967">घालणे</translation>
-<translation id="6989848892321993519">कृपया हा मजकूर <ph name="MIN_CHARACTERS" /> वर्ण किंवा त्यापेक्षा अधिक मोठा करा (आपण सध्‍या 1 वर्ण वापरत आहात).</translation>
+<translation id="6989848892321993519">कृपया हा मजकूर <ph name="MIN_CHARACTERS" /> वर्ण किंवा त्यापेक्षा अधिक मोठा करा (तुम्ही सध्‍या 1 वर्ण वापरत आहात).</translation>
<translation id="709897737746224366">कृपया विनंती केलेले स्वरूपन जुळवा.</translation>
<translation id="7139483182332611405">प्रस्तावना</translation>
<translation id="7223624360433298498">लोटलेला अवधी</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">तास</translation>
<translation id="7681220483256441252">अनुक्रमणिका</translation>
<translation id="7720026100085573005">शिल्लक वेळ</translation>
-<translation id="7740016676195725605">बंद मथळा प्रदर्शित करणे थांबवा</translation>
<translation id="7740050170769002709">HTML सामुग्री</translation>
<translation id="7750228210027921155">चित्रात-चित्र</translation>
<translation id="7789962463072032349">विराम द्या</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">मजकूर फील्ड दर्शवा</translation>
<translation id="8057695513531652401">सूचना</translation>
<translation id="8105797009065549151">टीप संदर्भ</translation>
-<translation id="8115662671911883373">बंद मथळा प्रदर्शित करणे प्रारंभ करा</translation>
<translation id="8117451130807776954">या आठवड्यात</translation>
-<translation id="819205353528511139">फुल स्क्रीन मोडमध्ये चित्रपट प्ले करा</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">मथळे</translation>
<translation id="835897206747267392">चुकीचे मूल्य.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">दूरस्थ प्लेबॅक नियंत्रित करा</translation>
<translation id="862370744433916922">उपशीर्षक</translation>
<translation id="8750798805984357768">कृपया या पर्यायांपैकी एक निवडा.</translation>
-<translation id="8785498733064193001">प्लेबॅक आरंभ करा</translation>
<translation id="8808573423886751634">प्रकरण</translation>
<translation id="8845239796550121995">आता तुमच्या टिव्हीवर कास्ट करत आहे</translation>
<translation id="8851136666856101339">मुख्य</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ms.xtb b/chromium/content/app/strings/translations/content_strings_ms.xtb
index fd00a061d61..ebfae93c576 100644
--- a/chromium/content/app/strings/translations/content_strings_ms.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ms.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ms">
<translation id="1018939186200882850">item menu</translation>
-<translation id="1020833440720551630">redamkan runut audio</translation>
<translation id="10623998915015855">butang togol</translation>
<translation id="1088086359088493902">Saat</translation>
<translation id="1171774979989969504">Sila masukkan alamat e-mel.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">kredit</translation>
<translation id="1342835525016946179">artikel</translation>
<translation id="1359897965706325498">sepanduk</translation>
-<translation id="1548116112524424341">mainkan video dalam mod gambar dalam gambar</translation>
<translation id="1589122976691792535">wilayah</translation>
<translation id="1591562245178063882">Bulan ini</translation>
<translation id="1637811476055996098">Pilih Fail</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">grid pohon</translation>
<translation id="1822429046913737220">PG / P/M</translation>
<translation id="1832974991323546415">main pada peranti jauh</translation>
-<translation id="1838818994221231429">togol skrin penuh menjadi kawasan potongan paparan</translation>
<translation id="190587075670221089">pemadaman</translation>
<translation id="1907737156431278478">contoh</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">masa</translation>
<translation id="5630795885300617244">Ketik dua kali ke kiri atau kanan untuk melangkau 10s</translation>
<translation id="5631759159893697722">abstrak</translation>
-<translation id="5641012560118721995">jeda main balik</translation>
<translation id="5643186887447432888">butang</translation>
<translation id="5677946354068040947">lagi pilihan</translation>
<translation id="576709008726043716">pengenalan</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Tetapkan semula</translation>
<translation id="5966707198760109579">Minggu</translation>
<translation id="5987525920412732405">butang putar</translation>
+<translation id="6011459053400940133">peluncur kelantangan</translation>
<translation id="6015796118275082299">Tahun</translation>
<translation id="6023896073578205740">kotak senarai</translation>
-<translation id="6101327004457443354">nyahredam runut audio</translation>
<translation id="6150588977291308318">bibliografi</translation>
<translation id="6164829606128959761">meter</translation>
<translation id="6166809985690652833">kata hujungan</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Jam</translation>
<translation id="7681220483256441252">indeks</translation>
<translation id="7720026100085573005">masa yang tinggal</translation>
-<translation id="7740016676195725605">berhenti memaparkan kapsyen tertutup</translation>
<translation id="7740050170769002709">Kandungan HTML</translation>
<translation id="7750228210027921155">Gambar dalam gambar</translation>
<translation id="7789962463072032349">jeda</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">medan teks carian</translation>
<translation id="8057695513531652401">notis</translation>
<translation id="8105797009065549151">rujukan nota</translation>
-<translation id="8115662671911883373">mula memaparkan kapsyen tertutup</translation>
<translation id="8117451130807776954">Minggu ini</translation>
-<translation id="819205353528511139">mainkan filem dalam mod skrin penuh</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">Kapsyen</translation>
<translation id="835897206747267392">Nilai tidak sah.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">kawal main balik jauh</translation>
<translation id="862370744433916922">sari kata</translation>
<translation id="8750798805984357768">Sila pilih salah satu pilihan ini.</translation>
-<translation id="8785498733064193001">mulakan main balik</translation>
<translation id="8808573423886751634">bab</translation>
<translation id="8845239796550121995">Menghantar ke TV anda sekarang</translation>
<translation id="8851136666856101339">utama</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_nl.xtb b/chromium/content/app/strings/translations/content_strings_nl.xtb
index 4bf78229f72..bd38d8a88b1 100644
--- a/chromium/content/app/strings/translations/content_strings_nl.xtb
+++ b/chromium/content/app/strings/translations/content_strings_nl.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="nl">
<translation id="1018939186200882850">menu-item</translation>
-<translation id="1020833440720551630">audiotrack dempen</translation>
<translation id="10623998915015855">schakelknop</translation>
<translation id="1088086359088493902">Seconden</translation>
<translation id="1171774979989969504">Geef een e-mailadres op.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">bronvermelding</translation>
<translation id="1342835525016946179">artikel</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">Video in de scherm-in-scherm-modus afspelen</translation>
<translation id="1589122976691792535">regio</translation>
<translation id="1591562245178063882">Deze maand</translation>
<translation id="1637811476055996098">Bestanden kiezen</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">boomstructuur</translation>
<translation id="1822429046913737220">a.m./p.m.</translation>
<translation id="1832974991323546415">afspelen op extern apparaat</translation>
-<translation id="1838818994221231429">volledig scherm met display-cutoutgebied schakelen</translation>
<translation id="190587075670221089">verwijdering</translation>
<translation id="1907737156431278478">voorbeeld</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">tijd</translation>
<translation id="5630795885300617244">Dubbeltik links of rechts om 10 seconden over te slaan</translation>
<translation id="5631759159893697722">uittreksel</translation>
-<translation id="5641012560118721995">afspelen onderbreken</translation>
<translation id="5643186887447432888">knop</translation>
<translation id="5677946354068040947">meer opties</translation>
<translation id="576709008726043716">inleiding</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Resetten</translation>
<translation id="5966707198760109579">Week</translation>
<translation id="5987525920412732405">draaiknop</translation>
+<translation id="6011459053400940133">volumeregelaar</translation>
<translation id="6015796118275082299">Jaar</translation>
<translation id="6023896073578205740">keuzelijst</translation>
-<translation id="6101327004457443354">dempen van audiotrack opheffen</translation>
<translation id="6150588977291308318">bibliografie</translation>
<translation id="6164829606128959761">meter</translation>
<translation id="6166809985690652833">nawoord</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Uur</translation>
<translation id="7681220483256441252">index</translation>
<translation id="7720026100085573005">resterende tijd</translation>
-<translation id="7740016676195725605">het weergeven van ondertiteling stoppen</translation>
<translation id="7740050170769002709">HTML-content</translation>
<translation id="7750228210027921155">Scherm-in-scherm</translation>
<translation id="7789962463072032349">onderbreken</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">zoektekstveld</translation>
<translation id="8057695513531652401">kennisgeving</translation>
<translation id="8105797009065549151">opmerkingsreferentie</translation>
-<translation id="8115662671911883373">het weergeven van ondertiteling starten</translation>
<translation id="8117451130807776954">Deze week</translation>
-<translation id="819205353528511139">film afspelen op volledig scherm</translation>
<translation id="8199524924445686405">jjjj</translation>
<translation id="8284326494547611709">Ondertiteling</translation>
<translation id="835897206747267392">Ongeldige waarde.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">afspelen bedienen op afstand</translation>
<translation id="862370744433916922">ondertitel</translation>
<translation id="8750798805984357768">Selecteer een van deze opties.</translation>
-<translation id="8785498733064193001">afspelen starten</translation>
<translation id="8808573423886751634">hoofdstuk</translation>
<translation id="8845239796550121995">Wordt nu gecast naar je tv</translation>
<translation id="8851136666856101339">hoofd</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_no.xtb b/chromium/content/app/strings/translations/content_strings_no.xtb
index 5eb145f1c33..75b033b673c 100644
--- a/chromium/content/app/strings/translations/content_strings_no.xtb
+++ b/chromium/content/app/strings/translations/content_strings_no.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="no">
<translation id="1018939186200882850">menyelement</translation>
-<translation id="1020833440720551630">slå av lydsporet</translation>
<translation id="10623998915015855">av/på-knapp</translation>
<translation id="1088086359088493902">Sekunder</translation>
<translation id="1171774979989969504">Skriv inn en e-postadresse.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">anerkjennelser</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">spill av videoen i bilde-i-bilde-modus</translation>
<translation id="1589122976691792535">område</translation>
<translation id="1591562245178063882">Denne måneden</translation>
<translation id="1637811476055996098">Velg filer</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">trerutenett</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">spill på ekstern enhet</translation>
-<translation id="1838818994221231429">slå av/på fullskjermsvisning av området med skjermutklipp</translation>
<translation id="190587075670221089">sletting</translation>
<translation id="1907737156431278478">eksempel</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Dobbelttrykk på venstre eller høyre side for å hoppe 10 sekunder</translation>
<translation id="5631759159893697722">abstrakt</translation>
-<translation id="5641012560118721995">stopp avspillingen midlertidig</translation>
<translation id="5643186887447432888">knapp</translation>
<translation id="5677946354068040947">flere alternativer</translation>
<translation id="576709008726043716">innledning</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Tilbakestill</translation>
<translation id="5966707198760109579">Uke</translation>
<translation id="5987525920412732405">verdisettingsknapp</translation>
+<translation id="6011459053400940133">glidebryter for volum</translation>
<translation id="6015796118275082299">År</translation>
<translation id="6023896073578205740">listefelt</translation>
-<translation id="6101327004457443354">slå på lydsporet</translation>
<translation id="6150588977291308318">bibliografi</translation>
<translation id="6164829606128959761">måler</translation>
<translation id="6166809985690652833">etterord</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Timer</translation>
<translation id="7681220483256441252">stikkordregister</translation>
<translation id="7720026100085573005">tid som gjenstår</translation>
-<translation id="7740016676195725605">slå av tekstingen</translation>
<translation id="7740050170769002709">HTML-innhold</translation>
<translation id="7750228210027921155">Bilde i bilde</translation>
<translation id="7789962463072032349">stans midlertidig</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">søketekstfelt</translation>
<translation id="8057695513531652401">merknad</translation>
<translation id="8105797009065549151">kommentarreferanse</translation>
-<translation id="8115662671911883373">slå på tekstingen</translation>
<translation id="8117451130807776954">Denne uken</translation>
-<translation id="819205353528511139">spill av filmen i fullskjermmodus</translation>
<translation id="8199524924445686405">åååå</translation>
<translation id="8284326494547611709">Teksting</translation>
<translation id="835897206747267392">Ugyldig verdi</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">kontrollér ekstern avspilling</translation>
<translation id="862370744433916922">undertittel</translation>
<translation id="8750798805984357768">Velg ett av følgende alternativer.</translation>
-<translation id="8785498733064193001">start avspillingen</translation>
<translation id="8808573423886751634">kapittel</translation>
<translation id="8845239796550121995">Caster til TV-en nå</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_pl.xtb b/chromium/content/app/strings/translations/content_strings_pl.xtb
index b65e5526e4e..21100321fca 100644
--- a/chromium/content/app/strings/translations/content_strings_pl.xtb
+++ b/chromium/content/app/strings/translations/content_strings_pl.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="pl">
<translation id="1018939186200882850">element menu</translation>
-<translation id="1020833440720551630">wycisz ścieżkę dźwiękową</translation>
<translation id="10623998915015855">przycisk przełączania</translation>
<translation id="1088086359088493902">Sekundy</translation>
<translation id="1171774979989969504">Wprowadź adres e-mail.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">autorzy</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">baner</translation>
-<translation id="1548116112524424341">wyświetl film w trybie obrazu w obrazie</translation>
<translation id="1589122976691792535">region</translation>
<translation id="1591562245178063882">W tym miesiącu</translation>
<translation id="1637811476055996098">Wybierz pliki</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">siatka drzewa</translation>
<translation id="1822429046913737220">rano/po południu</translation>
<translation id="1832974991323546415">odtwarzanie na urządzeniu zdalnym</translation>
-<translation id="1838818994221231429">przełącz z trybu pełnoekranowego na obszar z wycięciem w ekranie</translation>
<translation id="190587075670221089">usunięcie</translation>
<translation id="1907737156431278478">przykład</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Kliknij dwukrotnie z lewej lub prawej, by przewinąć o 10 s</translation>
<translation id="5631759159893697722">streszczenie</translation>
-<translation id="5641012560118721995">wstrzymaj odtwarzanie</translation>
<translation id="5643186887447432888">przycisk</translation>
<translation id="5677946354068040947">więcej opcji</translation>
<translation id="576709008726043716">wprowadzenie</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Resetuj</translation>
<translation id="5966707198760109579">Tydzień</translation>
<translation id="5987525920412732405">przycisk przewijany</translation>
+<translation id="6011459053400940133">suwak głośności</translation>
<translation id="6015796118275082299">Rok</translation>
<translation id="6023896073578205740">pole listy</translation>
-<translation id="6101327004457443354">wyłącz wyciszenie ścieżki dźwiękowej</translation>
<translation id="6150588977291308318">bibliografia</translation>
<translation id="6164829606128959761">miernik</translation>
<translation id="6166809985690652833">posłowie</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Godziny</translation>
<translation id="7681220483256441252">indeks</translation>
<translation id="7720026100085573005">pozostały czas</translation>
-<translation id="7740016676195725605">przestań pokazywać napisy</translation>
<translation id="7740050170769002709">Treść HTML</translation>
<translation id="7750228210027921155">Obraz w obrazie</translation>
<translation id="7789962463072032349">wstrzymaj</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">pole tekstowe wyszukiwania</translation>
<translation id="8057695513531652401">uwaga</translation>
<translation id="8105797009065549151">odsyłacz</translation>
-<translation id="8115662671911883373">zacznij pokazywać napisy</translation>
<translation id="8117451130807776954">W tym tygodniu</translation>
-<translation id="819205353528511139">odtwórz film w trybie pełnoekranowym</translation>
<translation id="8199524924445686405">rrrr</translation>
<translation id="8284326494547611709">Napisy</translation>
<translation id="835897206747267392">Nieprawidłowa wartość.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">sterowanie zdalnym odtwarzaniem</translation>
<translation id="862370744433916922">podtytuł</translation>
<translation id="8750798805984357768">Wybierz jedną z opcji.</translation>
-<translation id="8785498733064193001">rozpocznij odtwarzanie</translation>
<translation id="8808573423886751634">rozdział</translation>
<translation id="8845239796550121995">Przesyłam na telewizor</translation>
<translation id="8851136666856101339">główny</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_pt-BR.xtb b/chromium/content/app/strings/translations/content_strings_pt-BR.xtb
index 300d7385116..0a66a45747f 100644
--- a/chromium/content/app/strings/translations/content_strings_pt-BR.xtb
+++ b/chromium/content/app/strings/translations/content_strings_pt-BR.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="pt-BR">
<translation id="1018939186200882850">item de menu</translation>
-<translation id="1020833440720551630">desativar som da faixa de áudio</translation>
<translation id="10623998915015855">botão "alternar"</translation>
<translation id="1088086359088493902">Segundos</translation>
<translation id="1171774979989969504">Insira um endereço de e-mail.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">créditos</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">assistir vídeo no modo picture-in-picture</translation>
<translation id="1589122976691792535">região</translation>
<translation id="1591562245178063882">Este mês</translation>
<translation id="1637811476055996098">Escolher arquivos</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">grade de árvore</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">reproduzir em dispositivo remoto</translation>
-<translation id="1838818994221231429">alternar tela cheia para área com corte da tela</translation>
<translation id="190587075670221089">exclusão</translation>
<translation id="1907737156431278478">exemplo</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Toque duas vezes na esquerda ou direita para pular 10 s</translation>
<translation id="5631759159893697722">resumo</translation>
-<translation id="5641012560118721995">pausar reprodução</translation>
<translation id="5643186887447432888">botão</translation>
<translation id="5677946354068040947">mais opções</translation>
<translation id="576709008726043716">introdução</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Redefinir</translation>
<translation id="5966707198760109579">Semana</translation>
<translation id="5987525920412732405">botão de rotação</translation>
+<translation id="6011459053400940133">controle deslizante de volume</translation>
<translation id="6015796118275082299">Ano</translation>
<translation id="6023896073578205740">caixa de listagem</translation>
-<translation id="6101327004457443354">ativar som da faixa de áudio</translation>
<translation id="6150588977291308318">bibliografia</translation>
<translation id="6164829606128959761">medidor</translation>
<translation id="6166809985690652833">posfácio</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Horas</translation>
<translation id="7681220483256441252">índice</translation>
<translation id="7720026100085573005">tempo restante</translation>
-<translation id="7740016676195725605">parar de exibir legendas ocultas</translation>
<translation id="7740050170769002709">Conteúdo HTML</translation>
<translation id="7750228210027921155">Picture-in-picture</translation>
<translation id="7789962463072032349">pausar</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">campo de texto da pesquisa</translation>
<translation id="8057695513531652401">aviso</translation>
<translation id="8105797009065549151">referência de nota</translation>
-<translation id="8115662671911883373">começar a exibir legendas ocultas</translation>
<translation id="8117451130807776954">Esta semana</translation>
-<translation id="819205353528511139">reproduzir filme em tela cheia</translation>
<translation id="8199524924445686405">aaaa</translation>
<translation id="8284326494547611709">Legendas</translation>
<translation id="835897206747267392">Valor inválido.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">controlar reprodução remota</translation>
<translation id="862370744433916922">subtítulo</translation>
<translation id="8750798805984357768">Selecione uma das opções.</translation>
-<translation id="8785498733064193001">iniciar reprodução</translation>
<translation id="8808573423886751634">capítulo</translation>
<translation id="8845239796550121995">Reproduzindo agora na sua TV</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_pt-PT.xtb b/chromium/content/app/strings/translations/content_strings_pt-PT.xtb
index 7c1b85cf66e..12aafcc2c80 100644
--- a/chromium/content/app/strings/translations/content_strings_pt-PT.xtb
+++ b/chromium/content/app/strings/translations/content_strings_pt-PT.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="pt-PT">
<translation id="1018939186200882850">item de menu</translation>
-<translation id="1020833440720551630">desativar a faixa de áudio</translation>
<translation id="10623998915015855">botão alternar</translation>
<translation id="1088086359088493902">Segundos</translation>
<translation id="1171774979989969504">Introduza um endereço de email.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">créditos</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">reproduzir vídeo no modo ecrã no ecrã</translation>
<translation id="1589122976691792535">região</translation>
<translation id="1591562245178063882">Este mês</translation>
<translation id="1637811476055996098">Escolher Ficheiros</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">grelha de árvore</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">reproduzir no dispositivo remoto</translation>
-<translation id="1838818994221231429">ativar/desativar o ecrã inteiro na área de recorte no ecrã</translation>
<translation id="190587075670221089">eliminação</translation>
<translation id="1907737156431278478">exemplo</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">hora</translation>
<translation id="5630795885300617244">Toque duas vezes à esquerda ou à direita para avançar 10 seg.</translation>
<translation id="5631759159893697722">resumo</translation>
-<translation id="5641012560118721995">interromper a reprodução</translation>
<translation id="5643186887447432888">botão</translation>
<translation id="5677946354068040947">mais opções</translation>
<translation id="576709008726043716">introdução</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Repor</translation>
<translation id="5966707198760109579">Semana</translation>
<translation id="5987525920412732405">botão giratório</translation>
+<translation id="6011459053400940133">controlo de deslize do volume</translation>
<translation id="6015796118275082299">Ano</translation>
<translation id="6023896073578205740">caixa de lista</translation>
-<translation id="6101327004457443354">reativar a faixa de áudio</translation>
<translation id="6150588977291308318">bibliografia</translation>
<translation id="6164829606128959761">contador</translation>
<translation id="6166809985690652833">posfácio</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Horas</translation>
<translation id="7681220483256441252">índice</translation>
<translation id="7720026100085573005">tempo restante</translation>
-<translation id="7740016676195725605">parar de apresentar legendas ocultas</translation>
<translation id="7740050170769002709">Conteúdo HTML</translation>
<translation id="7750228210027921155">Ecrã no ecrã</translation>
<translation id="7789962463072032349">pausa</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">campo de texto de pesquisa</translation>
<translation id="8057695513531652401">aviso</translation>
<translation id="8105797009065549151">referência de nota</translation>
-<translation id="8115662671911883373">apresentar legendas ocultas</translation>
<translation id="8117451130807776954">Esta semana</translation>
-<translation id="819205353528511139">reproduzir o filme no modo de ecrã inteiro</translation>
<translation id="8199524924445686405">aaaa</translation>
<translation id="8284326494547611709">Legendas</translation>
<translation id="835897206747267392">Valor inválido.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">controlar a reprodução remota</translation>
<translation id="862370744433916922">legenda</translation>
<translation id="8750798805984357768">Seleccione uma destas opções.</translation>
-<translation id="8785498733064193001">iniciar reprodução</translation>
<translation id="8808573423886751634">capítulo</translation>
<translation id="8845239796550121995">A transmitir na sua TV…</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ro.xtb b/chromium/content/app/strings/translations/content_strings_ro.xtb
index 028076ef823..09492e93248 100644
--- a/chromium/content/app/strings/translations/content_strings_ro.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ro.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ro">
<translation id="1018939186200882850">element de meniu</translation>
-<translation id="1020833440720551630">dezactivați sunetul înregistrării audio</translation>
<translation id="10623998915015855">buton de comutare</translation>
<translation id="1088086359088493902">Secunde</translation>
<translation id="1171774979989969504">Introdu o adresă de e-mail.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">mulțumiri</translation>
<translation id="1342835525016946179">articol</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">redă videoclipul în modul picture-in-picture</translation>
<translation id="1589122976691792535">regiune</translation>
<translation id="1591562245178063882">Luna aceasta</translation>
<translation id="1637811476055996098">Alege fișierele</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">grilă arbore</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">redă pe dispozitiv la distanță</translation>
-<translation id="1838818994221231429">decupaj inclus în ecranul complet</translation>
<translation id="190587075670221089">ștergere</translation>
<translation id="1907737156431278478">exemplu</translation>
<translation id="1921819250265091946">zz</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">oră</translation>
<translation id="5630795885300617244">Atinge de două ori spre stânga sau spre dreapta pentru a derula cu 10 secunde</translation>
<translation id="5631759159893697722">rezumat</translation>
-<translation id="5641012560118721995">întrerupeți redarea</translation>
<translation id="5643186887447432888">buton</translation>
<translation id="5677946354068040947">mai multe opțiuni</translation>
<translation id="576709008726043716">introducere</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Resetează</translation>
<translation id="5966707198760109579">Săptămână</translation>
<translation id="5987525920412732405">buton incrementare/decrementare</translation>
+<translation id="6011459053400940133">glisor de volum</translation>
<translation id="6015796118275082299">An</translation>
<translation id="6023896073578205740">casetă listă</translation>
-<translation id="6101327004457443354">activați sunetul înregistrării audio</translation>
<translation id="6150588977291308318">bibliografie</translation>
<translation id="6164829606128959761">instrument de măsurare</translation>
<translation id="6166809985690652833">postfață</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Ore</translation>
<translation id="7681220483256441252">index</translation>
<translation id="7720026100085573005">timp rămas</translation>
-<translation id="7740016676195725605">nu mai afișați subtitrările</translation>
<translation id="7740050170769002709">Conținut HTML</translation>
<translation id="7750228210027921155">Picture-in-picture</translation>
<translation id="7789962463072032349">întrerupe</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">câmp pentru căutarea textului</translation>
<translation id="8057695513531652401">anunț</translation>
<translation id="8105797009065549151">trimitere la notă</translation>
-<translation id="8115662671911883373">începeți să afișați subtitrările</translation>
<translation id="8117451130807776954">Săptămâna aceasta</translation>
-<translation id="819205353528511139">redați filmul în modul ecran complet</translation>
<translation id="8199524924445686405">aaaa</translation>
<translation id="8284326494547611709">Subtitrări</translation>
<translation id="835897206747267392">Valoare nevalidă.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">controlează redarea la distanță</translation>
<translation id="862370744433916922">subtitlu</translation>
<translation id="8750798805984357768">Selectează una dintre aceste opțiuni.</translation>
-<translation id="8785498733064193001">începeți redarea</translation>
<translation id="8808573423886751634">capitol</translation>
<translation id="8845239796550121995">Acum se proiectează pe televizor</translation>
<translation id="8851136666856101339">principal</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ru.xtb b/chromium/content/app/strings/translations/content_strings_ru.xtb
index ab654d5186d..12a086a22c5 100644
--- a/chromium/content/app/strings/translations/content_strings_ru.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ru.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ru">
<translation id="1018939186200882850">элемент меню</translation>
-<translation id="1020833440720551630">отключение звуковой дорожки</translation>
<translation id="10623998915015855">кнопка-переключатель</translation>
<translation id="1088086359088493902">Секунды</translation>
<translation id="1171774979989969504">Введите адрес электронной почты.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">выходные сведения</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">баннер</translation>
-<translation id="1548116112524424341">воспроизвести видео в режиме "Картинка в картинке"</translation>
<translation id="1589122976691792535">регион</translation>
<translation id="1591562245178063882">В этом месяце</translation>
<translation id="1637811476055996098">Выбрать файлы</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">сетка в виде дерева</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">воспроизвести на удаленном устройстве</translation>
-<translation id="1838818994221231429">Переключить полный экран на вырезанную область</translation>
<translation id="190587075670221089">удаление</translation>
<translation id="1907737156431278478">пример</translation>
<translation id="1921819250265091946">дд</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Чтобы пропустить 10 секунд, нажмите дважды слева или справа.</translation>
<translation id="5631759159893697722">аннотация</translation>
-<translation id="5641012560118721995">пауза</translation>
<translation id="5643186887447432888">кнопка</translation>
<translation id="5677946354068040947">дополнительные параметры</translation>
<translation id="576709008726043716">введение</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Сбросить</translation>
<translation id="5966707198760109579">Неделя</translation>
<translation id="5987525920412732405">кнопка счетчика</translation>
+<translation id="6011459053400940133">регулятор громкости</translation>
<translation id="6015796118275082299">Год</translation>
<translation id="6023896073578205740">список</translation>
-<translation id="6101327004457443354">включение звуковой дорожки</translation>
<translation id="6150588977291308318">библиография</translation>
<translation id="6164829606128959761">счетчик</translation>
<translation id="6166809985690652833">послесловие</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Часы</translation>
<translation id="7681220483256441252">указатель</translation>
<translation id="7720026100085573005">оставшееся время</translation>
-<translation id="7740016676195725605">скрыть субтитры</translation>
<translation id="7740050170769002709">HTML-содержание</translation>
<translation id="7750228210027921155">Картинка в картинке</translation>
<translation id="7789962463072032349">Пауза</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">поле поиска</translation>
<translation id="8057695513531652401">примечание</translation>
<translation id="8105797009065549151">ссылка на примечание</translation>
-<translation id="8115662671911883373">показать субтитры</translation>
<translation id="8117451130807776954">На этой неделе</translation>
-<translation id="819205353528511139">воспроизведение в полноэкранном режиме</translation>
<translation id="8199524924445686405">гггг</translation>
<translation id="8284326494547611709">Титры</translation>
<translation id="835897206747267392">Недопустимые данные.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">управлять воспроизведением на удаленных устройствах</translation>
<translation id="862370744433916922">подзаголовок</translation>
<translation id="8750798805984357768">Выберите один из вариантов.</translation>
-<translation id="8785498733064193001">начать воспроизведение</translation>
<translation id="8808573423886751634">глава</translation>
<translation id="8845239796550121995">Транслируется на телевизор</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_sk.xtb b/chromium/content/app/strings/translations/content_strings_sk.xtb
index 9ec872f3b36..50a72359690 100644
--- a/chromium/content/app/strings/translations/content_strings_sk.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sk.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="sk">
<translation id="1018939186200882850">položka ponuky</translation>
-<translation id="1020833440720551630">stlmiť zvukovú stopu</translation>
<translation id="10623998915015855">tlačidlo prepínania</translation>
<translation id="1088086359088493902">Sekundy</translation>
<translation id="1171774979989969504">Zadajte e-mailovú adresu.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">titulky</translation>
<translation id="1342835525016946179">článok</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">prehrať video v režime obrazu v obraze</translation>
<translation id="1589122976691792535">oblasť</translation>
<translation id="1591562245178063882">Tento mesiac</translation>
<translation id="1637811476055996098">Vybrať súbory</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">stromová mriežka</translation>
<translation id="1822429046913737220">AM / PM</translation>
<translation id="1832974991323546415">prehrať na vzdialenom zariadení</translation>
-<translation id="1838818994221231429">prepnúť celú obrazovku na výrez obrazovky</translation>
<translation id="190587075670221089">odstránenie</translation>
<translation id="1907737156431278478">príklad</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">čas</translation>
<translation id="5630795885300617244">Dvojitým klepnutím doľava alebo doprava preskočíte o 10 s</translation>
<translation id="5631759159893697722">abstrakt</translation>
-<translation id="5641012560118721995">pozastaviť prehrávanie</translation>
<translation id="5643186887447432888">tlačidlo</translation>
<translation id="5677946354068040947">ďalšie možnosti</translation>
<translation id="576709008726043716">úvod</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Resetovať</translation>
<translation id="5966707198760109579">Týždeň</translation>
<translation id="5987525920412732405">tlačidlo otáčania</translation>
+<translation id="6011459053400940133">posúvač hlasitosti</translation>
<translation id="6015796118275082299">Rok</translation>
<translation id="6023896073578205740">pole s ponukou</translation>
-<translation id="6101327004457443354">obnoviť zvukovú stopu</translation>
<translation id="6150588977291308318">bibliografia</translation>
<translation id="6164829606128959761">meter</translation>
<translation id="6166809985690652833">doslov</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Hodiny</translation>
<translation id="7681220483256441252">index</translation>
<translation id="7720026100085573005">zostávajúci čas</translation>
-<translation id="7740016676195725605">ukončiť zobrazovanie skrytých titulkov</translation>
<translation id="7740050170769002709">Obsah HTML</translation>
<translation id="7750228210027921155">Obraz v obraze</translation>
<translation id="7789962463072032349">pozastaviť</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">textové pole pre vyhľadávanie</translation>
<translation id="8057695513531652401">upozornenie</translation>
<translation id="8105797009065549151">odkaz na poznámku</translation>
-<translation id="8115662671911883373">zobrazovať skryté titulky</translation>
<translation id="8117451130807776954">Tento týždeň</translation>
-<translation id="819205353528511139">prehrať film v režime celej obrazovky</translation>
<translation id="8199524924445686405">rrrr</translation>
<translation id="8284326494547611709">Titulky</translation>
<translation id="835897206747267392">Neplatná hodnota.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">ovládať vzdialené prehrávanie</translation>
<translation id="862370744433916922">podnadpis</translation>
<translation id="8750798805984357768">Vyberte jednu z týchto možností.</translation>
-<translation id="8785498733064193001">začať prehrávanie</translation>
<translation id="8808573423886751634">kapitola</translation>
<translation id="8845239796550121995">Prenáša sa do televízora</translation>
<translation id="8851136666856101339">hlavné</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_sl.xtb b/chromium/content/app/strings/translations/content_strings_sl.xtb
index 8a00c66a491..e2fc26a37ca 100644
--- a/chromium/content/app/strings/translations/content_strings_sl.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sl.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="sl">
<translation id="1018939186200882850">menijski element</translation>
-<translation id="1020833440720551630">izklop zvoka za zvočni posnetek</translation>
<translation id="10623998915015855">preklopni gumb</translation>
<translation id="1088086359088493902">Sekunde</translation>
<translation id="1171774979989969504">Vnesite e-poštni naslov</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">seznam sodelujočih</translation>
<translation id="1342835525016946179">člnk</translation>
<translation id="1359897965706325498">pasica</translation>
-<translation id="1548116112524424341">predvajanje videoposnetkov v načinu slike v sliki</translation>
<translation id="1589122976691792535">območje</translation>
<translation id="1591562245178063882">Ta mesec</translation>
<translation id="1637811476055996098">Izberi datoteke</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">drevesna mreža</translation>
<translation id="1822429046913737220">Dopoldne/popoldne</translation>
<translation id="1832974991323546415">predvajanje v oddaljeni napravi</translation>
-<translation id="1838818994221231429">preklop celozaslonskega načina na območje zareze zaslona</translation>
<translation id="190587075670221089">brisanje</translation>
<translation id="1907737156431278478">primer</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">čas</translation>
<translation id="5630795885300617244">Dvakrat se dotaknite levo ali desno, da preskočite 10 s</translation>
<translation id="5631759159893697722">izvleček</translation>
-<translation id="5641012560118721995">začasna ustavitev predvajanja</translation>
<translation id="5643186887447432888">gumb</translation>
<translation id="5677946354068040947">več možnosti</translation>
<translation id="576709008726043716">uvod</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Ponastavi</translation>
<translation id="5966707198760109579">Teden</translation>
<translation id="5987525920412732405">pomikalnik</translation>
+<translation id="6011459053400940133">drsnik za glasnost</translation>
<translation id="6015796118275082299">Leto</translation>
<translation id="6023896073578205740">polje s seznamom</translation>
-<translation id="6101327004457443354">vklop zvoka za zvočni posnetek</translation>
<translation id="6150588977291308318">bibliografija</translation>
<translation id="6164829606128959761">merilnik</translation>
<translation id="6166809985690652833">spremna beseda</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Ure</translation>
<translation id="7681220483256441252">kazalo</translation>
<translation id="7720026100085573005">preostali čas</translation>
-<translation id="7740016676195725605">ustavitev prikazovanja podnapisov</translation>
<translation id="7740050170769002709">Vsebina HTML</translation>
<translation id="7750228210027921155">Slika v sliki</translation>
<translation id="7789962463072032349">premor</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">besedilno polje za iskanje</translation>
<translation id="8057695513531652401">kritika</translation>
<translation id="8105797009065549151">sklicevanje na opombo</translation>
-<translation id="8115662671911883373">začetek predvajanja podnapisov</translation>
<translation id="8117451130807776954">Ta teden</translation>
-<translation id="819205353528511139">predvajanje filma v celozaslonskem načinu</translation>
<translation id="8199524924445686405">llll</translation>
<translation id="8284326494547611709">Napisi</translation>
<translation id="835897206747267392">Neveljavna vrednost.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">upravljanje oddaljenega predvajanja</translation>
<translation id="862370744433916922">podnaslov</translation>
<translation id="8750798805984357768">Izberite eno od teh možnosti.</translation>
-<translation id="8785498733064193001">začetek predvajanja</translation>
<translation id="8808573423886751634">poglavje</translation>
<translation id="8845239796550121995">Predvajanje na televizorju</translation>
<translation id="8851136666856101339">glavn</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_sr.xtb b/chromium/content/app/strings/translations/content_strings_sr.xtb
index cfc909163ee..ba4be7715bd 100644
--- a/chromium/content/app/strings/translations/content_strings_sr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sr.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="sr">
<translation id="1018939186200882850">ставка менија</translation>
-<translation id="1020833440720551630">искључите звук аудио снимка</translation>
<translation id="10623998915015855">дугме за укључивање/искључивање</translation>
<translation id="1088086359088493902">Секунде</translation>
<translation id="1171774979989969504">Унесите имејл адресу.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">заслуге</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">банер</translation>
-<translation id="1548116112524424341">пустите видео у режиму слике у слици</translation>
<translation id="1589122976691792535">регион</translation>
<translation id="1591562245178063882">Овај месец</translation>
<translation id="1637811476055996098">Избор датотека</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">мрежа стабла</translation>
<translation id="1822429046913737220">пре подне/по подне</translation>
<translation id="1832974991323546415">пуштајте на удаљеном уређају</translation>
-<translation id="1838818994221231429">укључује/искључује приказ на целом екрану без области изрезаног приказа</translation>
<translation id="190587075670221089">брисање</translation>
<translation id="1907737156431278478">пример</translation>
<translation id="1921819250265091946">дд</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">време</translation>
<translation id="5630795885300617244">Двапут додирните лево или десно да бисте прескочили 10 сек</translation>
<translation id="5631759159893697722">сажетак</translation>
-<translation id="5641012560118721995">паузирајте репродукцију</translation>
<translation id="5643186887447432888">дугме</translation>
<translation id="5677946354068040947">још опција</translation>
<translation id="576709008726043716">увод</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Ресетуј</translation>
<translation id="5966707198760109579">Недеља</translation>
<translation id="5987525920412732405">дугме за промену вредности</translation>
+<translation id="6011459053400940133">клизач за јачину звука</translation>
<translation id="6015796118275082299">Година</translation>
<translation id="6023896073578205740">оквир са листом</translation>
-<translation id="6101327004457443354">укључите звук аудио снимка</translation>
<translation id="6150588977291308318">библиографија</translation>
<translation id="6164829606128959761">мерач</translation>
<translation id="6166809985690652833">поговор</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Сати</translation>
<translation id="7681220483256441252">индекс</translation>
<translation id="7720026100085573005">преостало време</translation>
-<translation id="7740016676195725605">зауставите приказивање опционалног титла</translation>
<translation id="7740050170769002709">HTML садржај</translation>
<translation id="7750228210027921155">Слика у слици</translation>
<translation id="7789962463072032349">паузирај</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">поље за текст претраге</translation>
<translation id="8057695513531652401">обавештење</translation>
<translation id="8105797009065549151">референца напомене</translation>
-<translation id="8115662671911883373">започните приказивање опционалног титла</translation>
<translation id="8117451130807776954">Ова недеља</translation>
-<translation id="819205353528511139">пустите филм у режиму целог екрана</translation>
<translation id="8199524924445686405">гггг</translation>
<translation id="8284326494547611709">Титл</translation>
<translation id="835897206747267392">Неважећа вредност.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">контролишите репродукцију на удаљеном уређају</translation>
<translation id="862370744433916922">титл</translation>
<translation id="8750798805984357768">Изаберите неку од ових опција.</translation>
-<translation id="8785498733064193001">започните репродукцију</translation>
<translation id="8808573423886751634">поглавље</translation>
<translation id="8845239796550121995">Тренутно се пребацује на ТВ</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_sv.xtb b/chromium/content/app/strings/translations/content_strings_sv.xtb
index c3b676be786..9da1e3dd640 100644
--- a/chromium/content/app/strings/translations/content_strings_sv.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sv.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="sv">
<translation id="1018939186200882850">menyalternativ</translation>
-<translation id="1020833440720551630">stäng av ljudspår</translation>
<translation id="10623998915015855">växlingsknapp</translation>
<translation id="1088086359088493902">Sekunder</translation>
<translation id="1171774979989969504">Ange en e-postadress.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">medverkande</translation>
<translation id="1342835525016946179">artikel</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">spela upp video i bild-i-bild-läge</translation>
<translation id="1589122976691792535">område</translation>
<translation id="1591562245178063882">Den här månaden</translation>
<translation id="1637811476055996098">Välj filer</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">träddiagram</translation>
<translation id="1822429046913737220">FM/EM</translation>
<translation id="1832974991323546415">spela på en fjärrenhet</translation>
-<translation id="1838818994221231429">aktivera och inaktivera helskärm till området för utskärning</translation>
<translation id="190587075670221089">borttagning</translation>
<translation id="1907737156431278478">exempel</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">tid</translation>
<translation id="5630795885300617244">Hoppa över 10 s genom att trycka två gånger till vänster/höger</translation>
<translation id="5631759159893697722">abstract</translation>
-<translation id="5641012560118721995">pausa uppspelning</translation>
<translation id="5643186887447432888">knapp</translation>
<translation id="5677946354068040947">fler alternativ</translation>
<translation id="576709008726043716">inledning</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Återställ</translation>
<translation id="5966707198760109579">Vecka</translation>
<translation id="5987525920412732405">snurrknapp</translation>
+<translation id="6011459053400940133">volymreglage</translation>
<translation id="6015796118275082299">År</translation>
<translation id="6023896073578205740">listruta</translation>
-<translation id="6101327004457443354">spela upp ljudspåret</translation>
<translation id="6150588977291308318">bibliografi</translation>
<translation id="6164829606128959761">mätare</translation>
<translation id="6166809985690652833">efterord</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Timmar</translation>
<translation id="7681220483256441252">index</translation>
<translation id="7720026100085573005">återstående tid</translation>
-<translation id="7740016676195725605">sluta visa textning</translation>
<translation id="7740050170769002709">HTML-innehåll</translation>
<translation id="7750228210027921155">Bild-i-bild</translation>
<translation id="7789962463072032349">paus</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">fält för söktext</translation>
<translation id="8057695513531652401">anmärkning</translation>
<translation id="8105797009065549151">referensnot</translation>
-<translation id="8115662671911883373">börja visa textning</translation>
<translation id="8117451130807776954">Den här veckan</translation>
-<translation id="819205353528511139">spela upp filmen i helskärmsläge</translation>
<translation id="8199524924445686405">åååå</translation>
<translation id="8284326494547611709">Textning</translation>
<translation id="835897206747267392">Ogiltigt värde.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">styra fjärruppspelning</translation>
<translation id="862370744433916922">undertext</translation>
<translation id="8750798805984357768">Välj ett av följande alternativ.</translation>
-<translation id="8785498733064193001">starta uppspelning</translation>
<translation id="8808573423886751634">kapitel</translation>
<translation id="8845239796550121995">Castar nu till TV:n</translation>
<translation id="8851136666856101339">huvud</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_sw.xtb b/chromium/content/app/strings/translations/content_strings_sw.xtb
index 540815ff666..50cee022684 100644
--- a/chromium/content/app/strings/translations/content_strings_sw.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sw.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="sw">
<translation id="1018939186200882850">kipengee cha menyu</translation>
-<translation id="1020833440720551630">nyamazisha sauti ya wimbo</translation>
<translation id="10623998915015855">kitufe cha kugeuza</translation>
<translation id="1088086359088493902">Sekunde</translation>
<translation id="1171774979989969504">Tafadhali weka anwani ya barua pepe.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">walioshiriki</translation>
<translation id="1342835525016946179">makala</translation>
<translation id="1359897965706325498">bango</translation>
-<translation id="1548116112524424341">cheza video katika hali ya picha ndani ya picha</translation>
<translation id="1589122976691792535">eneo</translation>
<translation id="1591562245178063882">Mwezi huu</translation>
<translation id="1637811476055996098">Chagua Faili</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">gridi ya mti</translation>
<translation id="1822429046913737220">AM / PM</translation>
<translation id="1832974991323546415">cheza kwenye kifaa cha mbali</translation>
-<translation id="1838818994221231429">tumia skrini nzima katika eneo la mkato kwenye skrini</translation>
<translation id="190587075670221089">ufutaji</translation>
<translation id="1907737156431278478">mfano</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">wakati</translation>
<translation id="5630795885300617244">Gusa mara mbili kushoto au kulia ili uruke kwa sekunde 10</translation>
<translation id="5631759159893697722">ikisiri</translation>
-<translation id="5641012560118721995">sitisha kucheza</translation>
<translation id="5643186887447432888">kitufe</translation>
<translation id="5677946354068040947">chaguo zaidi</translation>
<translation id="576709008726043716">utangulizi</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Weka upya</translation>
<translation id="5966707198760109579">Juma</translation>
<translation id="5987525920412732405">kitufe cha kubadilishia</translation>
+<translation id="6011459053400940133">kitelezi cha sauti</translation>
<translation id="6015796118275082299">Mwaka</translation>
<translation id="6023896073578205740">kikasha cha orodha</translation>
-<translation id="6101327004457443354">washa sauti ya wimbo</translation>
<translation id="6150588977291308318">bibliografia</translation>
<translation id="6164829606128959761">mita</translation>
<translation id="6166809985690652833">maelezo kuhusu kitabu</translation>
@@ -163,7 +159,7 @@
<translation id="6709570249143506788">Ubora wa chini wa kucheza video</translation>
<translation id="6755330956360078551">kidirisha cha vidokezo</translation>
<translation id="6790428901817661496">Cheza</translation>
-<translation id="6820355525329141109">Haikuweza kupakia programu-jalizi.</translation>
+<translation id="6820355525329141109">Haikuweza kupakia programu jalizi.</translation>
<translation id="6820615603175220800">marejeleo ya bibliografia</translation>
<translation id="6843725295806269523">nyamazisha</translation>
<translation id="6853785296079745596">ficha manukuu yanayoweza kuonyeshwa</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Saa</translation>
<translation id="7681220483256441252">faharasa</translation>
<translation id="7720026100085573005">muda unaosalia</translation>
-<translation id="7740016676195725605">koma kuonyesha manukuu yanaweza kufichwa</translation>
<translation id="7740050170769002709">Maudhui ya HTML</translation>
<translation id="7750228210027921155">Picha ndani ya picha</translation>
<translation id="7789962463072032349">Sitisha</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">sehemu ya maandishi ya utafutaji</translation>
<translation id="8057695513531652401">ilani</translation>
<translation id="8105797009065549151">marejeleo ya dokezo</translation>
-<translation id="8115662671911883373">anza kuonyesha manukuu yaliyofungwa</translation>
<translation id="8117451130807776954">Wiki hii</translation>
-<translation id="819205353528511139">cheza filamu katika hali ya skrini kamili</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">Manukuu</translation>
<translation id="835897206747267392">Thamani batili.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">dhibiti kucheza kwa mbali</translation>
<translation id="862370744433916922">kichwa kidogo</translation>
<translation id="8750798805984357768">Tafadhali chagua moja wapo ya chaguo hizi.</translation>
-<translation id="8785498733064193001">anza kucheza</translation>
<translation id="8808573423886751634">sura</translation>
<translation id="8845239796550121995">Sasa inatuma kwenye TV yako</translation>
<translation id="8851136666856101339">kuu</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_ta.xtb b/chromium/content/app/strings/translations/content_strings_ta.xtb
index 3c9bb1331d6..15fb7b22599 100644
--- a/chromium/content/app/strings/translations/content_strings_ta.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ta.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="ta">
<translation id="1018939186200882850">மெனு உருப்படி</translation>
-<translation id="1020833440720551630">ஆடியோ டிராக்கை முடக்கு</translation>
<translation id="10623998915015855">நிலைமாற்றுதல் பொத்தான்</translation>
<translation id="1088086359088493902">வினாடிகள்</translation>
<translation id="1171774979989969504">ஒரு மின்னஞ்சல் முகவரியை உள்ளிடவும்.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">பங்களித்தவர்கள்</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">பேனர்</translation>
-<translation id="1548116112524424341">பிக்ச்சர்-இன்-பிக்ச்சர் பயன்முறையில் வீடியோவை இயக்கும்</translation>
<translation id="1589122976691792535">மண்டலம்</translation>
<translation id="1591562245178063882">இந்த மாதம்</translation>
<translation id="1637811476055996098">கோப்புகளைத் தேர்வுசெய்க</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">ட்ரீ கிரிட்</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">தொலைநிலைச் சாதனத்தில் இயக்கு</translation>
-<translation id="1838818994221231429">முழுத்திரைக் காட்சியை டிஸ்ப்ளே கட்அவுட் பகுதிக்கு நிலைமாற்றும்</translation>
<translation id="190587075670221089">நீக்கும்</translation>
<translation id="1907737156431278478">உதாரணம்</translation>
<translation id="1921819250265091946">dd</translation>
@@ -107,7 +104,7 @@
<translation id="4748357248530471599">டிஸ்ப்ளே கட்அவுட் முழுத்திரை நிலைமாற்ற பட்டன்</translation>
<translation id="4757246831282535685">தாவல் பலகம்</translation>
<translation id="4763480195061959176">வீடியோ</translation>
-<translation id="479989351350248267">Search</translation>
+<translation id="479989351350248267">தேடல்</translation>
<translation id="4812940957355064477">எண்ணை உள்ளிடுக.</translation>
<translation id="4912536737030637138">நூல்விவர அட்டவணை உள்ளீடு</translation>
<translation id="4975562563186953947"><ph name="SELECTED_COUNT" /> தேர்ந்தெடுக்கப்பட்டன</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">நேரம்</translation>
<translation id="5630795885300617244">10வி தவிர்க்க, இடது அல்லது வலதுபுறம் இருமுறை தட்டவும்</translation>
<translation id="5631759159893697722">சுருக்கம்</translation>
-<translation id="5641012560118721995">மறுஇயக்கத்தை இடைநிறுத்து</translation>
<translation id="5643186887447432888">பொத்தான்</translation>
<translation id="5677946354068040947">கூடுதல் விருப்பங்கள் பொத்தான்</translation>
<translation id="576709008726043716">அறிமுகம்</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">மீட்டமை</translation>
<translation id="5966707198760109579">வாரம்</translation>
<translation id="5987525920412732405">சுழல் பொத்தான்</translation>
+<translation id="6011459053400940133">ஒலியளவு ஸ்லைடர்</translation>
<translation id="6015796118275082299">ஆண்டு</translation>
<translation id="6023896073578205740">பட்டியல் பெட்டி</translation>
-<translation id="6101327004457443354">ஆடியோ டிராக்கை இயக்கு</translation>
<translation id="6150588977291308318">நூல்விவர அட்டவணை</translation>
<translation id="6164829606128959761">மீட்டர்</translation>
<translation id="6166809985690652833">பின்னுரை</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">மணிநேரம்</translation>
<translation id="7681220483256441252">பொருளடக்கம்</translation>
<translation id="7720026100085573005">மீதமுள்ள நேரம்</translation>
-<translation id="7740016676195725605">விரிவான வசனங்களைக் காட்டுவதை நிறுத்து</translation>
<translation id="7740050170769002709">HTML உள்ளடக்கம்</translation>
<translation id="7750228210027921155">பிக்ச்சர்-இன்-பிக்ச்சர்</translation>
<translation id="7789962463072032349">இடைநிறுத்து</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">தேடல் உரைப் புலம்</translation>
<translation id="8057695513531652401">அறிவிப்பு</translation>
<translation id="8105797009065549151">குறிப்பு மேற்கோள்</translation>
-<translation id="8115662671911883373">விரிவான வசனங்களைக் காட்டத் தொடங்கு</translation>
<translation id="8117451130807776954">இந்த வாரம்</translation>
-<translation id="819205353528511139">மூவியை முழுத்திரைப் பயன்முறையில் இயக்கு</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">வசனங்கள்</translation>
<translation id="835897206747267392">செல்லாத மதிப்பு.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">தொலைநிலை இயக்கத்தைக் கட்டுப்படுத்தவும்</translation>
<translation id="862370744433916922">துணை தலைப்பு</translation>
<translation id="8750798805984357768">தயவுசெய்து இந்த விருப்பங்களில் ஒன்றைத் தேர்ந்தெடுங்கள்.</translation>
-<translation id="8785498733064193001">மறுஇயக்கத்தைத் தொடங்கு</translation>
<translation id="8808573423886751634">அத்தியாயம்</translation>
<translation id="8845239796550121995">டிவிக்கு அனுப்புகிறது</translation>
<translation id="8851136666856101339">முதன்மை</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_te.xtb b/chromium/content/app/strings/translations/content_strings_te.xtb
index 4b6b9fd9953..d64662fb842 100644
--- a/chromium/content/app/strings/translations/content_strings_te.xtb
+++ b/chromium/content/app/strings/translations/content_strings_te.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="te">
<translation id="1018939186200882850">మెను అంశం</translation>
-<translation id="1020833440720551630">ఆడియో ట్రాక్‌ను మ్యూట్ చేయి</translation>
<translation id="10623998915015855">టోగుల్ బటన్</translation>
<translation id="1088086359088493902">సెకన్లు</translation>
<translation id="1171774979989969504">దయచేసి ఇమెయిల్ చిరునామాను ఎంటర్ చెయ్యండి.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">సహకారులు</translation>
<translation id="1342835525016946179">కథనం</translation>
<translation id="1359897965706325498">బ్యానర్</translation>
-<translation id="1548116112524424341">వీడియోను చిత్రంలో చిత్రం మోడ్‌లో ప్లే చేయండి</translation>
<translation id="1589122976691792535">ప్రాంతం</translation>
<translation id="1591562245178063882">ఈ నెల</translation>
<translation id="1637811476055996098">ఫైల్‌లను ఎంచుకోండి</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">వృక్షాంశ గ్రిడ్</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">రిమోట్ పరికరంలో ప్లే చేస్తుంది</translation>
-<translation id="1838818994221231429">పూర్తి స్క్రీన్‌ను డిస్‌ప్లే కత్తిరింపు భాగానికి తగినట్లు సక్రియం చేస్తుంది</translation>
<translation id="190587075670221089">తొలగింపు</translation>
<translation id="1907737156431278478">ఉదాహరణ</translation>
<translation id="1921819250265091946">dd</translation>
@@ -62,13 +59,13 @@
<translation id="2896972712917208084">రేడియో సమూహం</translation>
<translation id="2908441821576996758">దయచేసి కామాతో వేరు చేసిన ఇమెయిల్ చిరునామాల జాబితాను ఎంటర్ చెయ్యండి.</translation>
<translation id="2940813599313844715">ఆబ్జెక్ట్</translation>
-<translation id="2942448076852699108">ప్రముఖంగా చూపిన కంటెంట్</translation>
+<translation id="2942448076852699108">హైలైట్ చేయబడిన కంటెంట్</translation>
<translation id="3040011195152428237">లింక్</translation>
<translation id="3049748772180311791"><ph name="QUANTITY" /> MB</translation>
<translation id="3075154866155599887">దయచేసి చెల్లుబాటు అయ్యే విలువను నమోదు చేయండి. ఫీల్డ్ అసంపూర్ణంగా ఉంది లేదా చెల్లని తేదీని కలిగి ఉంది.</translation>
<translation id="3078740164268491126">పట్టిక</translation>
<translation id="3086746722712840547">note</translation>
-<translation id="310520048233152454">దయచేసి ఒక URLని ఎంటర్ చెయ్యండి.</translation>
+<translation id="310520048233152454">దయచేసి ఒక URLని ఎంటర్ చేయండి.</translation>
<translation id="3175736971608411871">టైమర్</translation>
<translation id="3199563858620722075">కాంబో పెట్టె</translation>
<translation id="3450233048674729344">విలువ ఖచ్చితంగా <ph name="MAXIMUM" /> కంటే తగ్గువగా లేదా సమానంగా ఉండాలి.</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">10సె దాటవేయడానికి రెండుసార్లు ఎడమ లేదా కుడివైపుకి నొక్కండి</translation>
<translation id="5631759159893697722">సంక్షేపం</translation>
-<translation id="5641012560118721995">ప్లేబ్యాక్‌ను పాజ్ చేయి</translation>
<translation id="5643186887447432888">బటన్</translation>
<translation id="5677946354068040947">మరిన్ని ఎంపికలు</translation>
<translation id="576709008726043716">పరిచయం</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">రీసెట్ చేయి</translation>
<translation id="5966707198760109579">వారం</translation>
<translation id="5987525920412732405">స్పిన్ బటన్</translation>
+<translation id="6011459053400940133">వాల్యూమ్ స్లయిడర్</translation>
<translation id="6015796118275082299">సంవత్సరం</translation>
<translation id="6023896073578205740">జాబితా పెట్టె</translation>
-<translation id="6101327004457443354">ఆడియో ట్రాక్‌ను అన్‌మ్యూట్ చేయి</translation>
<translation id="6150588977291308318">వివరణపట్టి</translation>
<translation id="6164829606128959761">మీటర్</translation>
<translation id="6166809985690652833">చివరిమాట</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">గంటలు</translation>
<translation id="7681220483256441252">సూచిక</translation>
<translation id="7720026100085573005">మిగిలి ఉన్న సమయం</translation>
-<translation id="7740016676195725605">సంవృత శీర్షికలను ప్రదర్శించడం ఆపివేయి</translation>
<translation id="7740050170769002709">HTML కంటెంట్</translation>
<translation id="7750228210027921155">చిత్రంలో చిత్రం</translation>
<translation id="7789962463072032349">నిలిపివేయి</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">శోధన వచనం ఫీల్డ్</translation>
<translation id="8057695513531652401">గమనిక</translation>
<translation id="8105797009065549151">గమనిక సూచన</translation>
-<translation id="8115662671911883373">సంవృత శీర్షికలను ప్రదర్శించడం ప్రారంభించు</translation>
<translation id="8117451130807776954">ఈ వారం</translation>
-<translation id="819205353528511139">చలనచిత్రాన్ని పూర్తి స్క్రీన్ మోడ్‌లో ప్లే చేయి</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">ఉపశీర్షికలు</translation>
<translation id="835897206747267392">చెల్లని విలువ.</translation>
@@ -220,11 +213,10 @@
<translation id="8550857728288566671">గ్రాఫిక్స్ చిహ్నం</translation>
<translation id="8583702881314752957">నిర్వచన జాబితా</translation>
<translation id="8597182159515967513">శీర్షిక</translation>
-<translation id="860475260694818407">విషయ పట్టిక</translation>
+<translation id="860475260694818407">కంటెంట్‌ల‌ పట్టిక</translation>
<translation id="8613126697340063924">రిమోట్ ప్లేబ్యాక్‌ను నియంత్రిస్తుంది</translation>
<translation id="862370744433916922">ఉపశీర్షిక</translation>
<translation id="8750798805984357768">దయచేసి ఈ ఎంపికలలో ఒకదాన్ని ఎంచుకోండి.</translation>
-<translation id="8785498733064193001">ప్లేబ్యాక్‌ను ప్రారంభించు</translation>
<translation id="8808573423886751634">అధ్యాయం</translation>
<translation id="8845239796550121995">ఇప్పుడు మీ టీవీలో ప్రసారం చేస్తోంది</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_th.xtb b/chromium/content/app/strings/translations/content_strings_th.xtb
index 57e893a8868..9b1efdb8c91 100644
--- a/chromium/content/app/strings/translations/content_strings_th.xtb
+++ b/chromium/content/app/strings/translations/content_strings_th.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="th">
<translation id="1018939186200882850">รายการเมนู</translation>
-<translation id="1020833440720551630">ปิดไฟล์เสียง</translation>
<translation id="10623998915015855">ปุ่มสลับ</translation>
<translation id="1088086359088493902">วินาที</translation>
<translation id="1171774979989969504">โปรดป้อนที่อยู่อีเมล</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">เครดิต</translation>
<translation id="1342835525016946179">บทความ</translation>
<translation id="1359897965706325498">แบนเนอร์</translation>
-<translation id="1548116112524424341">เล่นวิดีโอในโหมดการแสดงภาพซ้อนภาพ</translation>
<translation id="1589122976691792535">ภูมิภาค</translation>
<translation id="1591562245178063882">เดือนนี้</translation>
<translation id="1637811476055996098">เลือกไฟล์</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">แผนผังต้นไม้</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">เล่นในอุปกรณ์ระยะไกล</translation>
-<translation id="1838818994221231429">สลับจากเต็มหน้าจอเป็นพื้นที่หน้าจอรอยบาก</translation>
<translation id="190587075670221089">การลบ</translation>
<translation id="1907737156431278478">ตัวอย่าง</translation>
<translation id="1921819250265091946">วว</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">เวลา</translation>
<translation id="5630795885300617244">แตะ 2 ครั้งที่ด้านขวาหรือซ้ายเพื่อข้ามทีละ 10 วินาที</translation>
<translation id="5631759159893697722">บทคัดย่อ</translation>
-<translation id="5641012560118721995">หยุดเล่นชั่วคราว</translation>
<translation id="5643186887447432888">ปุ่ม</translation>
<translation id="5677946354068040947">ตัวเลือกเพิ่มเติม</translation>
<translation id="576709008726043716">บทนำ</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">รีเซ็ต</translation>
<translation id="5966707198760109579">สัปดาห์</translation>
<translation id="5987525920412732405">ปุ่มหมุน</translation>
+<translation id="6011459053400940133">แถบเลื่อนปรับระดับเสียง</translation>
<translation id="6015796118275082299">ปี</translation>
<translation id="6023896073578205740">ช่องรายการ</translation>
-<translation id="6101327004457443354">เปิดไฟล์เสียง</translation>
<translation id="6150588977291308318">บรรณานุกรม</translation>
<translation id="6164829606128959761">เมตร</translation>
<translation id="6166809985690652833">คำแถลงท้ายเล่ม</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">ชั่วโมง</translation>
<translation id="7681220483256441252">ดัชนี</translation>
<translation id="7720026100085573005">เวลาที่เหลือ</translation>
-<translation id="7740016676195725605">หยุดแสดงคำอธิบายภาพ</translation>
<translation id="7740050170769002709">เนื้อหา HTML</translation>
<translation id="7750228210027921155">การแสดงภาพซ้อนภาพ</translation>
<translation id="7789962463072032349">หยุดชั่วคราว</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">ช่องข้อความค้นหา</translation>
<translation id="8057695513531652401">ประกาศ</translation>
<translation id="8105797009065549151">ข้อมูลอ้างอิงหมายเหตุ</translation>
-<translation id="8115662671911883373">เริ่มแสดงคำอธิบายภาพ</translation>
<translation id="8117451130807776954">สัปดาห์นี้</translation>
-<translation id="819205353528511139">เล่นภาพยนตร์ในโหมดเต็มหน้าจอ</translation>
<translation id="8199524924445686405">ปปปป</translation>
<translation id="8284326494547611709">คำบรรยาย</translation>
<translation id="835897206747267392">ค่าไม่ถูกต้อง</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">ควบคุมการเล่นระยะไกล</translation>
<translation id="862370744433916922">คำบรรยาย</translation>
<translation id="8750798805984357768">โปรดเลือกตัวเลือกอย่างหนึ่งอย่างใดเหล่านี้</translation>
-<translation id="8785498733064193001">เริ่มเล่น</translation>
<translation id="8808573423886751634">บท</translation>
<translation id="8845239796550121995">ตอนนี้กำลังแคสต์ไปยัง TV</translation>
<translation id="8851136666856101339">หลัก</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_tr.xtb b/chromium/content/app/strings/translations/content_strings_tr.xtb
index 2ad6bf39f6d..a19b278606b 100644
--- a/chromium/content/app/strings/translations/content_strings_tr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_tr.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="tr">
<translation id="1018939186200882850">menü öğesi</translation>
-<translation id="1020833440720551630">ses kanalını kapat</translation>
<translation id="10623998915015855">geçiş düğmesi</translation>
<translation id="1088086359088493902">Saniye</translation>
<translation id="1171774979989969504">Lütfen e-posta adresi girin.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">katkıda bulunanlar</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
-<translation id="1548116112524424341">videoyu pencere içinde pencere modunda oynatın</translation>
<translation id="1589122976691792535">bölge</translation>
<translation id="1591562245178063882">Bu ay</translation>
<translation id="1637811476055996098">Dosyaları Seç</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">ağaç tablo</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">uzaktan cihazda oynat</translation>
-<translation id="1838818994221231429">tam ekranı ekran kesimi alanı olarak değiştirin</translation>
<translation id="190587075670221089">silme</translation>
<translation id="1907737156431278478">örnek</translation>
<translation id="1921819250265091946">gg</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">10 sn. atlamak için sola veya sağa iki kez dokunun</translation>
<translation id="5631759159893697722">özet</translation>
-<translation id="5641012560118721995">oynatmayı duraklat</translation>
<translation id="5643186887447432888">düğme</translation>
<translation id="5677946354068040947">diğer seçenekler</translation>
<translation id="576709008726043716">giriş</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Sıfırla</translation>
<translation id="5966707198760109579">Hafta</translation>
<translation id="5987525920412732405">dönme düğmesi</translation>
+<translation id="6011459053400940133">ses kaydırma çubuğu</translation>
<translation id="6015796118275082299">Yıl</translation>
<translation id="6023896073578205740">liste kutusu</translation>
-<translation id="6101327004457443354">ses kanalını aç</translation>
<translation id="6150588977291308318">kaynakça</translation>
<translation id="6164829606128959761">ölçüm aracı</translation>
<translation id="6166809985690652833">sonsöz</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Saat</translation>
<translation id="7681220483256441252">dizin</translation>
<translation id="7720026100085573005">kalan süre</translation>
-<translation id="7740016676195725605">altyazıların görüntülenmesini durdur</translation>
<translation id="7740050170769002709">HTML içeriği</translation>
<translation id="7750228210027921155">Pencere içinde pencere</translation>
<translation id="7789962463072032349">duraklat</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">arama metni alanı</translation>
<translation id="8057695513531652401">bildirim</translation>
<translation id="8105797009065549151">not referansı</translation>
-<translation id="8115662671911883373">altyazıları görüntülemeye başla</translation>
<translation id="8117451130807776954">Bu hafta</translation>
-<translation id="819205353528511139">filmi tam ekran modunda oynat</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">Altyazılar</translation>
<translation id="835897206747267392">Geçersiz değer.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">uzaktan oynatmayı kontrol et</translation>
<translation id="862370744433916922">alt başlık</translation>
<translation id="8750798805984357768">Lütfen bu seçeneklerden birini belirleyin.</translation>
-<translation id="8785498733064193001">oynatmayı başlat</translation>
<translation id="8808573423886751634">bölüm</translation>
<translation id="8845239796550121995">Şimdi TV'nize yayınlanıyor</translation>
<translation id="8851136666856101339">main</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_uk.xtb b/chromium/content/app/strings/translations/content_strings_uk.xtb
index a3a041c9c11..6dd8773636d 100644
--- a/chromium/content/app/strings/translations/content_strings_uk.xtb
+++ b/chromium/content/app/strings/translations/content_strings_uk.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="uk">
<translation id="1018939186200882850">пункт меню</translation>
-<translation id="1020833440720551630">вимкнути звукову доріжку</translation>
<translation id="10623998915015855">перемикач</translation>
<translation id="1088086359088493902">Секунди</translation>
<translation id="1171774979989969504">Введіть електронну адресу.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">подяки</translation>
<translation id="1342835525016946179">стаття</translation>
<translation id="1359897965706325498">банер</translation>
-<translation id="1548116112524424341">відтворювати відео в режимі "Картинка в картинці"</translation>
<translation id="1589122976691792535">регіон</translation>
<translation id="1591562245178063882">Цей місяць</translation>
<translation id="1637811476055996098">Вибрати файли</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">сітка дерева</translation>
<translation id="1822429046913737220">д.п./п.п.</translation>
<translation id="1832974991323546415">відтворити на віддаленому пристрої</translation>
-<translation id="1838818994221231429">використовувати або не використовувати зону вирізу екрана в повноекранному режимі</translation>
<translation id="190587075670221089">видалення</translation>
<translation id="1907737156431278478">приклад</translation>
<translation id="1921819250265091946">дд</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">час</translation>
<translation id="5630795885300617244">Двічі торкніться ліворуч або праворуч, щоб пропустити 10 с</translation>
<translation id="5631759159893697722">автореферат</translation>
-<translation id="5641012560118721995">призупинити відтворення</translation>
<translation id="5643186887447432888">кнопка</translation>
<translation id="5677946354068040947">більше опцій</translation>
<translation id="576709008726043716">вступ</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Скинути</translation>
<translation id="5966707198760109579">Тиждень</translation>
<translation id="5987525920412732405">лічильник</translation>
+<translation id="6011459053400940133">повзунок гучності</translation>
<translation id="6015796118275082299">Рік</translation>
<translation id="6023896073578205740">вікно списку</translation>
-<translation id="6101327004457443354">увімкнути звукову доріжку</translation>
<translation id="6150588977291308318">бібліографія</translation>
<translation id="6164829606128959761">вимірювач</translation>
<translation id="6166809985690652833">післямова</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Години</translation>
<translation id="7681220483256441252">покажчик</translation>
<translation id="7720026100085573005">залишилось часу</translation>
-<translation id="7740016676195725605">сховати приховані субтитри</translation>
<translation id="7740050170769002709">Вміст HTML</translation>
<translation id="7750228210027921155">Картинка в картинці</translation>
<translation id="7789962463072032349">призупинити</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">текстове поле пошуку</translation>
<translation id="8057695513531652401">примітка</translation>
<translation id="8105797009065549151">посилання на примітку</translation>
-<translation id="8115662671911883373">показати приховані субтитри</translation>
<translation id="8117451130807776954">Цей тиждень</translation>
-<translation id="819205353528511139">відтворити фільм у повноекранному режимі</translation>
<translation id="8199524924445686405">рррр</translation>
<translation id="8284326494547611709">Субтитри</translation>
<translation id="835897206747267392">Недійсне значення</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">керувати віддаленим відтворенням</translation>
<translation id="862370744433916922">підзаголовок</translation>
<translation id="8750798805984357768">Виберіть один із запропонованих варіантів.</translation>
-<translation id="8785498733064193001">розпочати відтворення</translation>
<translation id="8808573423886751634">розділ</translation>
<translation id="8845239796550121995">Транслюється на телевізор</translation>
<translation id="8851136666856101339">головний</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_vi.xtb b/chromium/content/app/strings/translations/content_strings_vi.xtb
index 87b3e3c9f68..b8395b16a99 100644
--- a/chromium/content/app/strings/translations/content_strings_vi.xtb
+++ b/chromium/content/app/strings/translations/content_strings_vi.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="vi">
<translation id="1018939186200882850">mục menu</translation>
-<translation id="1020833440720551630">tắt tiếng bản âm thanh</translation>
<translation id="10623998915015855">nút chuyển đổi</translation>
<translation id="1088086359088493902">Giây</translation>
<translation id="1171774979989969504">Vui lòng nhập địa chỉ email.</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">ghi nhận tác giả</translation>
<translation id="1342835525016946179">bài viết</translation>
<translation id="1359897965706325498">biểu ngữ</translation>
-<translation id="1548116112524424341">phát video ở chế độ hình trong hình</translation>
<translation id="1589122976691792535">khu vực</translation>
<translation id="1591562245178063882">Tháng này</translation>
<translation id="1637811476055996098">Chọn tệp</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">lưới dạng cây</translation>
<translation id="1822429046913737220">SA/CH</translation>
<translation id="1832974991323546415">phát trên thiết bị từ xa</translation>
-<translation id="1838818994221231429">chuyển từ chế độ toàn màn hình sang màn hình có vết cắt</translation>
<translation id="190587075670221089">xóa</translation>
<translation id="1907737156431278478">ví dụ</translation>
<translation id="1921819250265091946">dd</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">thời gian</translation>
<translation id="5630795885300617244">Nhấn đúp vào bên trái hoặc phải để bỏ qua sau 10 giây</translation>
<translation id="5631759159893697722">bản tóm tắt</translation>
-<translation id="5641012560118721995">tạm dừng phát lại</translation>
<translation id="5643186887447432888">nút</translation>
<translation id="5677946354068040947">tùy chọn khác</translation>
<translation id="576709008726043716">giới thiệu</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">Đặt lại</translation>
<translation id="5966707198760109579">Tuần</translation>
<translation id="5987525920412732405">nút quay tròn</translation>
+<translation id="6011459053400940133">thanh trượt âm lượng</translation>
<translation id="6015796118275082299">Năm</translation>
<translation id="6023896073578205740">hộp danh sách</translation>
-<translation id="6101327004457443354">bật tiếng bản âm thanh</translation>
<translation id="6150588977291308318">danh mục</translation>
<translation id="6164829606128959761">thước đo</translation>
<translation id="6166809985690652833">lời bạt</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">Giờ</translation>
<translation id="7681220483256441252">chú dẫn</translation>
<translation id="7720026100085573005">thời gian còn lại</translation>
-<translation id="7740016676195725605">ngừng hiển thị phụ đề chi tiết</translation>
<translation id="7740050170769002709">Nội dung HTML</translation>
<translation id="7750228210027921155">Hình trong hình</translation>
<translation id="7789962463072032349">tạm dừng</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">trường văn bản tìm kiếm</translation>
<translation id="8057695513531652401">lưu ý</translation>
<translation id="8105797009065549151">tham chiếu chú thích</translation>
-<translation id="8115662671911883373">bắt đầu hiển thị phụ đề chi tiết</translation>
<translation id="8117451130807776954">Tuần này</translation>
-<translation id="819205353528511139">phát phim ở chế độ toàn màn hình</translation>
<translation id="8199524924445686405">yyyy</translation>
<translation id="8284326494547611709">Phụ đề</translation>
<translation id="835897206747267392">Giá trị không hợp lệ.</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">điều khiển phát lại từ xa</translation>
<translation id="862370744433916922">phụ đề</translation>
<translation id="8750798805984357768">Vui lòng chọn một trong các tùy chọn sau.</translation>
-<translation id="8785498733064193001">bắt đầu phát lại</translation>
<translation id="8808573423886751634">chương</translation>
<translation id="8845239796550121995">Hiện đang truyền tới TV của bạn</translation>
<translation id="8851136666856101339">chính</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_zh-CN.xtb b/chromium/content/app/strings/translations/content_strings_zh-CN.xtb
index f5f5dfa4818..13f4882db72 100644
--- a/chromium/content/app/strings/translations/content_strings_zh-CN.xtb
+++ b/chromium/content/app/strings/translations/content_strings_zh-CN.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="zh-CN">
<translation id="1018939186200882850">菜单项</translation>
-<translation id="1020833440720551630">将音轨设为静音</translation>
<translation id="10623998915015855">切换按钮</translation>
<translation id="1088086359088493902">秒</translation>
<translation id="1171774979989969504">请输入电子邮件地址。</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">参与者名单</translation>
<translation id="1342835525016946179">文章标记</translation>
<translation id="1359897965706325498">横幅</translation>
-<translation id="1548116112524424341">在“画中画”模式中播放视频</translation>
<translation id="1589122976691792535">区域</translation>
<translation id="1591562245178063882">本月</translation>
<translation id="1637811476055996098">选择文件</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">树状网格</translation>
<translation id="1822429046913737220">上午/下午</translation>
<translation id="1832974991323546415">在远程设备上播放</translation>
-<translation id="1838818994221231429">切换到包含刘海屏区域的全屏模式</translation>
<translation id="190587075670221089">删除</translation>
<translation id="1907737156431278478">示例</translation>
<translation id="1921819250265091946">日</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">在左侧或右侧点按两次即可跳过 10 秒</translation>
<translation id="5631759159893697722">摘要</translation>
-<translation id="5641012560118721995">暂停播放</translation>
<translation id="5643186887447432888">按钮</translation>
<translation id="5677946354068040947">更多选项</translation>
<translation id="576709008726043716">简介</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">重置</translation>
<translation id="5966707198760109579">周</translation>
<translation id="5987525920412732405">微调按钮</translation>
+<translation id="6011459053400940133">音量滑块</translation>
<translation id="6015796118275082299">年</translation>
<translation id="6023896073578205740">列表框</translation>
-<translation id="6101327004457443354">取消对音轨静音</translation>
<translation id="6150588977291308318">参考书目</translation>
<translation id="6164829606128959761">计量条</translation>
<translation id="6166809985690652833">后记</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">小时</translation>
<translation id="7681220483256441252">索引</translation>
<translation id="7720026100085573005">剩余时间</translation>
-<translation id="7740016676195725605">停止显示可选字幕</translation>
<translation id="7740050170769002709">HTML 内容</translation>
<translation id="7750228210027921155">画中画</translation>
<translation id="7789962463072032349">暂停</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">搜索文本字段</translation>
<translation id="8057695513531652401">通知</translation>
<translation id="8105797009065549151">备注参考资料</translation>
-<translation id="8115662671911883373">开始显示可选字幕</translation>
<translation id="8117451130807776954">本周</translation>
-<translation id="819205353528511139">在全屏模式下播放电影</translation>
<translation id="8199524924445686405"> 年 </translation>
<translation id="8284326494547611709">字幕</translation>
<translation id="835897206747267392">值无效。</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">控制远程播放</translation>
<translation id="862370744433916922">副标题</translation>
<translation id="8750798805984357768">请从这些选项中选择一个。</translation>
-<translation id="8785498733064193001">开始播放</translation>
<translation id="8808573423886751634">章节</translation>
<translation id="8845239796550121995">现在正投射到您的电视上</translation>
<translation id="8851136666856101339">主体内容</translation>
diff --git a/chromium/content/app/strings/translations/content_strings_zh-TW.xtb b/chromium/content/app/strings/translations/content_strings_zh-TW.xtb
index 857bab97a0e..19ec8fbc372 100644
--- a/chromium/content/app/strings/translations/content_strings_zh-TW.xtb
+++ b/chromium/content/app/strings/translations/content_strings_zh-TW.xtb
@@ -2,7 +2,6 @@
<!DOCTYPE translationbundle>
<translationbundle lang="zh-TW">
<translation id="1018939186200882850">選單項目</translation>
-<translation id="1020833440720551630">將音軌設為靜音</translation>
<translation id="10623998915015855">切換按鈕</translation>
<translation id="1088086359088493902">秒</translation>
<translation id="1171774979989969504">請輸入電子郵件地址。</translation>
@@ -16,7 +15,6 @@
<translation id="1335095011850992622">參與名單</translation>
<translation id="1342835525016946179">文章</translation>
<translation id="1359897965706325498">橫幅</translation>
-<translation id="1548116112524424341">在子母畫面模式中播放影片</translation>
<translation id="1589122976691792535">區域</translation>
<translation id="1591562245178063882">本月</translation>
<translation id="1637811476055996098">選擇檔案</translation>
@@ -27,7 +25,6 @@
<translation id="1821985195704844674">樹狀目錄網格</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">在遠端裝置上播放</translation>
-<translation id="1838818994221231429">切換為包含螢幕凹口區域的全螢幕模式</translation>
<translation id="190587075670221089">刪除</translation>
<translation id="1907737156431278478">範例</translation>
<translation id="1921819250265091946">日</translation>
@@ -131,7 +128,6 @@
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">輕觸兩下左側或右側可跳過 10 秒</translation>
<translation id="5631759159893697722">摘要</translation>
-<translation id="5641012560118721995">暫停播放</translation>
<translation id="5643186887447432888">按鈕</translation>
<translation id="5677946354068040947">更多選項</translation>
<translation id="576709008726043716">簡介</translation>
@@ -142,9 +138,9 @@
<translation id="5939518447894949180">重設</translation>
<translation id="5966707198760109579">週</translation>
<translation id="5987525920412732405">微調按鈕</translation>
+<translation id="6011459053400940133">音量滑桿</translation>
<translation id="6015796118275082299">年</translation>
<translation id="6023896073578205740">清單方塊</translation>
-<translation id="6101327004457443354">取消音軌靜音</translation>
<translation id="6150588977291308318">參考書目</translation>
<translation id="6164829606128959761">計量器</translation>
<translation id="6166809985690652833">後記</translation>
@@ -191,7 +187,6 @@
<translation id="7673697353781729403">小時</translation>
<translation id="7681220483256441252">索引</translation>
<translation id="7720026100085573005">剩餘時間</translation>
-<translation id="7740016676195725605">停止顯示字幕</translation>
<translation id="7740050170769002709">HTML 內容</translation>
<translation id="7750228210027921155">子母畫面</translation>
<translation id="7789962463072032349">暫停</translation>
@@ -202,9 +197,7 @@
<translation id="8053789581856978548">搜尋文字欄位</translation>
<translation id="8057695513531652401">聲明</translation>
<translation id="8105797009065549151">附註參考資料</translation>
-<translation id="8115662671911883373">開始顯示字幕</translation>
<translation id="8117451130807776954">本週</translation>
-<translation id="819205353528511139">使用全螢幕模式播放電影</translation>
<translation id="8199524924445686405"> 年 </translation>
<translation id="8284326494547611709">字幕</translation>
<translation id="835897206747267392">無效的值。</translation>
@@ -224,7 +217,6 @@
<translation id="8613126697340063924">控制遠端播放</translation>
<translation id="862370744433916922">副標題</translation>
<translation id="8750798805984357768">請選取其中一個選項。</translation>
-<translation id="8785498733064193001">開始播放</translation>
<translation id="8808573423886751634">章節</translation>
<translation id="8845239796550121995">正在投放到電視上</translation>
<translation id="8851136666856101339">主要元素</translation>
diff --git a/chromium/content/browser/BUILD.gn b/chromium/content/browser/BUILD.gn
index 02d6ebe936c..cf4d96c6856 100644
--- a/chromium/content/browser/BUILD.gn
+++ b/chromium/content/browser/BUILD.gn
@@ -138,6 +138,7 @@ jumbo_source_set("browser") {
"//services/device/public/mojom:generic_sensor",
"//services/file:lib",
"//services/file/public/mojom",
+ "//services/media_session:lib",
"//services/media_session/public/cpp",
"//services/media_session/public/mojom",
"//services/metrics",
@@ -318,6 +319,8 @@ jumbo_source_set("browser") {
"android/content_protocol_handler_impl.h",
"android/content_startup_flags.cc",
"android/content_startup_flags.h",
+ "android/content_url_loader_factory.cc",
+ "android/content_url_loader_factory.h",
"android/devtools_auth.cc",
"android/dialog_overlay_impl.cc",
"android/dialog_overlay_impl.h",
@@ -556,7 +559,8 @@ jumbo_source_set("browser") {
"cache_storage/cache_storage_context_impl.h",
"cache_storage/cache_storage_dispatcher_host.cc",
"cache_storage/cache_storage_dispatcher_host.h",
- "cache_storage/cache_storage_histogram_macros.h",
+ "cache_storage/cache_storage_histogram_utils.cc",
+ "cache_storage/cache_storage_histogram_utils.h",
"cache_storage/cache_storage_index.cc",
"cache_storage/cache_storage_index.h",
"cache_storage/cache_storage_manager.cc",
@@ -588,6 +592,8 @@ jumbo_source_set("browser") {
"code_cache/generated_code_cache_context.h",
"startup_data_impl.cc",
"startup_data_impl.h",
+ "startup_helper.cc",
+ "startup_helper.h",
# NOTE: These files are here instead of in compositor_browser_sources
# because the latter is not built on Android, whereas these files are
@@ -625,6 +631,8 @@ jumbo_source_set("browser") {
"devtools/devtools_network_transaction_factory.cc",
"devtools/devtools_pipe_handler.cc",
"devtools/devtools_pipe_handler.h",
+ "devtools/devtools_renderer_channel.cc",
+ "devtools/devtools_renderer_channel.h",
"devtools/devtools_session.cc",
"devtools/devtools_session.h",
"devtools/devtools_stream_blob.cc",
@@ -886,6 +894,7 @@ jumbo_source_set("browser") {
"gpu/browser_gpu_client_delegate.h",
"gpu/compositor_util.cc",
"gpu/compositor_util.h",
+ "gpu/delegate_to_browser_gpu_service_accelerator_factory.cc",
"gpu/gpu_client.cc",
"gpu/gpu_data_manager_impl.cc",
"gpu/gpu_data_manager_impl.h",
@@ -903,6 +912,8 @@ jumbo_source_set("browser") {
"gpu/gpu_process_host.h",
"gpu/shader_cache_factory.cc",
"gpu/shader_cache_factory.h",
+ "gpu/video_capture_dependencies.cc",
+ "gpu/video_capture_dependencies.h",
"histogram_controller.cc",
"histogram_controller.h",
"histogram_subscriber.h",
@@ -1047,7 +1058,6 @@ jumbo_source_set("browser") {
"loader/resource_dispatcher_host_impl.h",
"loader/resource_handler.cc",
"loader/resource_handler.h",
- "loader/resource_hints_impl.cc",
"loader/resource_loader.cc",
"loader/resource_loader.h",
"loader/resource_loader_delegate.h",
@@ -1059,6 +1069,8 @@ jumbo_source_set("browser") {
"loader/resource_requester_info.h",
"loader/resource_scheduler_filter.cc",
"loader/resource_scheduler_filter.h",
+ "loader/shared_cors_origin_access_list_impl.cc",
+ "loader/shared_cors_origin_access_list_impl.h",
"loader/source_stream_to_data_pipe.cc",
"loader/source_stream_to_data_pipe.h",
"loader/stream_resource_handler.cc",
@@ -1080,6 +1092,8 @@ jumbo_source_set("browser") {
"manifest/manifest_icon_downloader.cc",
"manifest/manifest_manager_host.cc",
"manifest/manifest_manager_host.h",
+ "media/android/browser_gpu_video_accelerator_factories.cc",
+ "media/android/browser_gpu_video_accelerator_factories.h",
"media/android/browser_media_player_manager.cc",
"media/android/browser_media_player_manager.h",
"media/android/media_player_renderer.cc",
@@ -1148,8 +1162,6 @@ jumbo_source_set("browser") {
"media/session/audio_focus_delegate_android.cc",
"media/session/audio_focus_delegate_android.h",
"media/session/audio_focus_delegate_default.cc",
- "media/session/audio_focus_manager.cc",
- "media/session/audio_focus_manager.h",
"media/session/audio_focus_observer.cc",
"media/session/audio_focus_observer.h",
"media/session/media_metadata_sanitizer.cc",
@@ -1269,6 +1281,8 @@ jumbo_source_set("browser") {
"renderer_host/clipboard_host_impl.cc",
"renderer_host/clipboard_host_impl.h",
"renderer_host/clipboard_host_impl_mac.mm",
+ "renderer_host/code_cache_host_impl.cc",
+ "renderer_host/code_cache_host_impl.h",
"renderer_host/cursor_manager.cc",
"renderer_host/cursor_manager.h",
"renderer_host/dip_util.cc",
@@ -1292,6 +1306,8 @@ jumbo_source_set("browser") {
"renderer_host/frame_sink_provider_impl.h",
"renderer_host/frame_token_message_queue.cc",
"renderer_host/frame_token_message_queue.h",
+ "renderer_host/hit_test_debug_key_event_observer.cc",
+ "renderer_host/hit_test_debug_key_event_observer.h",
"renderer_host/input/fling_controller.cc",
"renderer_host/input/fling_controller.h",
"renderer_host/input/fling_scheduler.cc",
@@ -1445,8 +1461,6 @@ jumbo_source_set("browser") {
"renderer_host/media/video_capture_controller.cc",
"renderer_host/media/video_capture_controller.h",
"renderer_host/media/video_capture_controller_event_handler.h",
- "renderer_host/media/video_capture_dependencies.cc",
- "renderer_host/media/video_capture_dependencies.h",
"renderer_host/media/video_capture_device_launch_observer.h",
"renderer_host/media/video_capture_factory_delegate.cc",
"renderer_host/media/video_capture_factory_delegate.h",
@@ -1528,6 +1542,8 @@ jumbo_source_set("browser") {
"sandbox_ipc_linux.h",
"sandbox_parameters_mac.h",
"sandbox_parameters_mac.mm",
+ "scheduler/browser_task_executor.cc",
+ "scheduler/browser_task_executor.h",
"scheduler/responsiveness/calculator.cc",
"scheduler/responsiveness/calculator.h",
"scheduler/responsiveness/message_loop_observer.cc",
@@ -1541,6 +1557,15 @@ jumbo_source_set("browser") {
"scoped_active_url.h",
"screen_orientation/screen_orientation_provider.cc",
"screen_orientation/screen_orientation_provider.h",
+ "screenlock_monitor/screenlock_monitor.cc",
+ "screenlock_monitor/screenlock_monitor.h",
+ "screenlock_monitor/screenlock_monitor_device_source.cc",
+ "screenlock_monitor/screenlock_monitor_device_source.h",
+ "screenlock_monitor/screenlock_monitor_device_source_chromeos.cc",
+ "screenlock_monitor/screenlock_monitor_device_source_mac.mm",
+ "screenlock_monitor/screenlock_monitor_device_source_win.cc",
+ "screenlock_monitor/screenlock_monitor_source.cc",
+ "screenlock_monitor/screenlock_monitor_source.h",
"service_manager/common_browser_interfaces.cc",
"service_manager/common_browser_interfaces.h",
"service_manager/service_manager_context.cc",
@@ -1638,12 +1663,16 @@ jumbo_source_set("browser") {
"service_worker/service_worker_script_cache_map.h",
"service_worker/service_worker_script_loader_factory.cc",
"service_worker/service_worker_script_loader_factory.h",
+ "service_worker/service_worker_single_script_update_checker.cc",
+ "service_worker/service_worker_single_script_update_checker.h",
"service_worker/service_worker_storage.cc",
"service_worker/service_worker_storage.h",
"service_worker/service_worker_type_converters.cc",
"service_worker/service_worker_type_converters.h",
"service_worker/service_worker_unregister_job.cc",
"service_worker/service_worker_unregister_job.h",
+ "service_worker/service_worker_update_checker.cc",
+ "service_worker/service_worker_update_checker.h",
"service_worker/service_worker_url_job_wrapper.cc",
"service_worker/service_worker_url_job_wrapper.h",
"service_worker/service_worker_url_request_job.cc",
@@ -1660,6 +1689,8 @@ jumbo_source_set("browser") {
"shared_worker/shared_worker_host.h",
"shared_worker/shared_worker_instance.cc",
"shared_worker/shared_worker_instance.h",
+ "shared_worker/shared_worker_script_fetcher.cc",
+ "shared_worker/shared_worker_script_fetcher.h",
"shared_worker/shared_worker_script_loader.cc",
"shared_worker/shared_worker_script_loader.h",
"shared_worker/shared_worker_script_loader_factory.cc",
@@ -1743,6 +1774,8 @@ jumbo_source_set("browser") {
"web_contents/aura/shadow_layer_delegate.h",
"web_contents/aura/types.cc",
"web_contents/aura/types.h",
+ "web_contents/web_contents_getter_registry.cc",
+ "web_contents/web_contents_getter_registry.h",
"web_contents/web_contents_impl.cc",
"web_contents/web_contents_impl.h",
"web_contents/web_contents_view.h",
@@ -1760,6 +1793,8 @@ jumbo_source_set("browser") {
"web_contents/web_drag_source_mac.mm",
"web_contents/web_drag_utils_win.cc",
"web_contents/web_drag_utils_win.h",
+ "web_package/origins_list.cc",
+ "web_package/origins_list.h",
"web_package/signed_exchange_cert_fetcher.cc",
"web_package/signed_exchange_cert_fetcher.h",
"web_package/signed_exchange_cert_fetcher_factory.cc",
@@ -1779,6 +1814,8 @@ jumbo_source_set("browser") {
"web_package/signed_exchange_loader.h",
"web_package/signed_exchange_prefetch_handler.cc",
"web_package/signed_exchange_prefetch_handler.h",
+ "web_package/signed_exchange_prefetch_metric_recorder.cc",
+ "web_package/signed_exchange_prefetch_metric_recorder.h",
"web_package/signed_exchange_prologue.cc",
"web_package/signed_exchange_prologue.h",
"web_package/signed_exchange_request_handler.cc",
@@ -1851,6 +1888,7 @@ jumbo_source_set("browser") {
"tracing/cros_tracing_agent.cc",
"tracing/cros_tracing_agent.h",
]
+ deps += [ "//chromeos/resources" ]
} else {
sources += [
"memory/memory_monitor_linux.cc",
@@ -1895,6 +1933,8 @@ jumbo_source_set("browser") {
sources += [
"gpu/ca_transaction_gpu_coordinator.cc",
"gpu/ca_transaction_gpu_coordinator.h",
+ "web_contents/web_contents_ns_view_bridge.h",
+ "web_contents/web_contents_ns_view_bridge.mm",
]
deps += [ "//ui/events:dom_keyboard_layout" ]
}
@@ -1967,6 +2007,7 @@ jumbo_source_set("browser") {
"imm32.lib",
"oleacc.lib",
"portabledeviceguids.lib",
+ "wtsapi32.lib",
]
}
@@ -2057,8 +2098,6 @@ jumbo_source_set("browser") {
"renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.h",
"renderer_host/pepper/quota_reservation.cc",
"renderer_host/pepper/quota_reservation.h",
- "renderer_host/pepper/ssl_context_helper.cc",
- "renderer_host/pepper/ssl_context_helper.h",
"renderer_host/plugin_registry_impl.cc",
"renderer_host/plugin_registry_impl.h",
]
@@ -2093,13 +2132,18 @@ jumbo_source_set("browser") {
if (use_atk) {
sources += [
"accessibility/accessibility_tree_formatter_auralinux.cc",
+ "accessibility/accessibility_tree_formatter_utils_auralinux.cc",
+ "accessibility/accessibility_tree_formatter_utils_auralinux.h",
"accessibility/browser_accessibility_auralinux.cc",
"accessibility/browser_accessibility_auralinux.h",
"accessibility/browser_accessibility_manager_auralinux.cc",
"accessibility/browser_accessibility_manager_auralinux.h",
]
- configs += [ "//build/config/linux/atk" ]
+ configs += [
+ "//build/config/linux/atk",
+ "//build/config/linux:atspi2",
+ ]
if (use_glib) {
configs += [ "//build/config/linux:glib" ]
@@ -2232,8 +2276,6 @@ jumbo_source_set("browser") {
sources -= [
"browser_ipc_logging.cc",
"media/session/audio_focus_delegate_default.cc",
- "media/session/audio_focus_manager.cc",
- "media/session/audio_focus_manager.h",
"tracing/tracing_ui.cc",
"tracing/tracing_ui.h",
]
@@ -2319,11 +2361,14 @@ jumbo_source_set("browser") {
"IOSurface.framework",
]
sources += [
+ "ns_view_bridge_factory_host.mm",
+ "ns_view_bridge_factory_impl.mm",
"renderer_host/popup_window_mac.h",
"renderer_host/popup_window_mac.mm",
"renderer_host/render_widget_host_ns_view_bridge_local.h",
"renderer_host/render_widget_host_ns_view_bridge_local.mm",
- "renderer_host/render_widget_host_ns_view_client.h",
+ "renderer_host/render_widget_host_ns_view_client_helper.h",
+ "renderer_host/render_widget_host_ns_view_client_helper.mm",
"renderer_host/render_widget_host_view_cocoa.h",
"renderer_host/render_widget_host_view_cocoa.mm",
]
@@ -2334,6 +2379,7 @@ jumbo_source_set("browser") {
"//chromeos",
"//chromeos:power_manager_proto",
"//chromeos/assistant:buildflags",
+ "//components/session_manager/core",
]
}
@@ -2344,6 +2390,7 @@ jumbo_source_set("browser") {
if (use_aura) {
deps += [
"//services/ws/public/cpp",
+ "//services/ws/public/cpp/host",
"//services/ws/public/mojom",
"//ui/aura",
"//ui/aura_extra",
@@ -2352,6 +2399,8 @@ jumbo_source_set("browser") {
"//ui/wm/public",
]
sources += [
+ "gpu_interface_provider.cc",
+ "gpu_interface_provider.h",
"renderer_host/delegated_frame_host_client_aura.cc",
"renderer_host/delegated_frame_host_client_aura.h",
"renderer_host/render_widget_host_view_event_handler.cc",
diff --git a/chromium/content/browser/DEPS b/chromium/content/browser/DEPS
index a065eb289c4..7d8808294ea 100644
--- a/chromium/content/browser/DEPS
+++ b/chromium/content/browser/DEPS
@@ -2,6 +2,7 @@ include_rules = [
# Allow inclusion of specific components that we depend on.
# See comment in content/DEPS for which components are allowed.
"+components/discardable_memory/common",
+ "+components/discardable_memory/public",
"+components/discardable_memory/service",
"+components/download/database",
"+components/download/public/common",
@@ -11,6 +12,7 @@ include_rules = [
"+components/services/filesystem",
"+components/services/font/ppapi_fontconfig_matching.h",
"+components/services/leveldb",
+ "+components/session_manager/core",
"+components/link_header_util",
"+components/metrics",
"+components/metrics:single_sample_metrics",
@@ -106,19 +108,18 @@ include_rules = [
"+third_party/blink/public/platform/modules/locks/lock_manager.mojom.h",
"+third_party/blink/public/platform/modules/notifications/web_notification_constants.h",
"+third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h",
+ "+third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h",
"+third_party/blink/public/public_buildflags.h",
"+third_party/blink/public/web/web_ax_enums.h",
"+third_party/blink/public/web/web_console_message.h",
"+third_party/blink/public/web/web_context_menu_data.h",
"+third_party/blink/public/web/web_device_emulation_params.h",
"+third_party/blink/public/web/web_drag_status.h",
- "+third_party/blink/public/web/web_find_options.h",
"+third_party/blink/public/web/web_fullscreen_options.h",
"+third_party/blink/public/web/web_frame_serializer_cache_control_policy.h",
"+third_party/blink/public/web/web_ime_text_span.h",
"+third_party/blink/public/web/web_media_player_action.h",
"+third_party/blink/public/web/web_plugin_action.h",
- "+third_party/blink/public/web/web_popup_type.h",
"+third_party/blink/public/web/web_serialized_script_value_version.h",
"+third_party/blink/public/web/WebSharedWorkerCreationContextType.h",
"+third_party/blink/public/web/WebSharedWorkerCreationErrors.h",
diff --git a/chromium/content/browser/accessibility/accessibility_action_browsertest.cc b/chromium/content/browser/accessibility/accessibility_action_browsertest.cc
index cad16f8da69..2a074451b5b 100644
--- a/chromium/content/browser/accessibility/accessibility_action_browsertest.cc
+++ b/chromium/content/browser/accessibility/accessibility_action_browsertest.cc
@@ -150,6 +150,44 @@ IN_PROC_BROWSER_TEST_F(AccessibilityActionBrowserTest,
ax::mojom::FloatAttribute::kValueForRange));
}
+IN_PROC_BROWSER_TEST_F(AccessibilityActionBrowserTest, Scroll) {
+ NavigateToURL(shell(), GURL(url::kAboutBlankURL));
+
+ AccessibilityNotificationWaiter waiter(shell()->web_contents(),
+ ui::kAXModeComplete,
+ ax::mojom::Event::kLoadComplete);
+ GURL url(
+ "data:text/html,"
+ "<div style='width:100; height:50; overflow:scroll' "
+ "aria-label='shakespeare'>"
+ "To be or not to be, that is the question."
+ "</div>");
+
+ NavigateToURL(shell(), url);
+ waiter.WaitForNotification();
+
+ BrowserAccessibility* target =
+ FindNode(ax::mojom::Role::kGenericContainer, "shakespeare");
+ EXPECT_NE(target, nullptr);
+
+ int y_before = target->GetIntAttribute(ax::mojom::IntAttribute::kScrollY);
+
+ AccessibilityNotificationWaiter waiter2(
+ shell()->web_contents(), ui::kAXModeComplete,
+ ax::mojom::Event::kScrollPositionChanged);
+
+ ui::AXActionData data;
+ data.action = ax::mojom::Action::kScrollDown;
+ data.target_node_id = target->GetId();
+
+ target->manager()->delegate()->AccessibilityPerformAction(data);
+ waiter2.WaitForNotification();
+
+ int y_after = target->GetIntAttribute(ax::mojom::IntAttribute::kScrollY);
+
+ EXPECT_GT(y_after, y_before);
+}
+
IN_PROC_BROWSER_TEST_F(AccessibilityActionBrowserTest, CanvasGetImage) {
NavigateToURL(shell(), GURL(url::kAboutBlankURL));
diff --git a/chromium/content/browser/accessibility/accessibility_event_recorder.cc b/chromium/content/browser/accessibility/accessibility_event_recorder.cc
index a2de95e816a..e558d871725 100644
--- a/chromium/content/browser/accessibility/accessibility_event_recorder.cc
+++ b/chromium/content/browser/accessibility/accessibility_event_recorder.cc
@@ -5,24 +5,24 @@
#include "content/browser/accessibility/accessibility_event_recorder.h"
#include "build/build_config.h"
+#include "content/browser/accessibility/accessibility_buildflags.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
namespace content {
AccessibilityEventRecorder::AccessibilityEventRecorder(
- BrowserAccessibilityManager* manager,
- base::ProcessId pid)
+ BrowserAccessibilityManager* manager)
: manager_(manager) {}
AccessibilityEventRecorder::~AccessibilityEventRecorder() = default;
-#if !defined(OS_WIN) && !defined(OS_MACOSX)
+#if !defined(OS_WIN) && !defined(OS_MACOSX) && !BUILDFLAG(USE_ATK)
// static
-AccessibilityEventRecorder& AccessibilityEventRecorder::GetInstance(
+std::unique_ptr<AccessibilityEventRecorder> AccessibilityEventRecorder::Create(
BrowserAccessibilityManager* manager,
- base::ProcessId pid) {
- static base::NoDestructor<AccessibilityEventRecorder> instance(manager, pid);
- return *instance;
+ base::ProcessId pid,
+ const base::StringPiece& application_name_match_pattern) {
+ return std::make_unique<AccessibilityEventRecorder>(manager);
}
#endif
diff --git a/chromium/content/browser/accessibility/accessibility_event_recorder.h b/chromium/content/browser/accessibility/accessibility_event_recorder.h
index 4d03a1dbc01..c6276b801e4 100644
--- a/chromium/content/browser/accessibility/accessibility_event_recorder.h
+++ b/chromium/content/browser/accessibility/accessibility_event_recorder.h
@@ -5,12 +5,12 @@
#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_EVENT_RECORDER_H_
#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_EVENT_RECORDER_H_
+#include <memory>
#include <string>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
-#include "base/no_destructor.h"
#include "base/process/process_handle.h"
namespace content {
@@ -37,10 +37,14 @@ class BrowserAccessibilityManager;
// As currently designed, there should only be one instance of this class.
class AccessibilityEventRecorder {
public:
- // Get the right platform-specific subclass.
- static AccessibilityEventRecorder& GetInstance(
+ // Construct the right platform-specific subclass.
+ static std::unique_ptr<AccessibilityEventRecorder> Create(
BrowserAccessibilityManager* manager = nullptr,
- base::ProcessId pid = 0);
+ base::ProcessId pid = 0,
+ const base::StringPiece& application_name_match_pattern =
+ base::StringPiece());
+
+ AccessibilityEventRecorder(BrowserAccessibilityManager* manager);
virtual ~AccessibilityEventRecorder();
void set_only_web_events(bool only_web_events) {
@@ -55,16 +59,11 @@ class AccessibilityEventRecorder {
const std::vector<std::string>& event_logs() { return event_logs_; }
protected:
- AccessibilityEventRecorder(BrowserAccessibilityManager* manager,
- base::ProcessId pid);
-
void OnEvent(const std::string& event);
BrowserAccessibilityManager* const manager_;
bool only_web_events_ = false;
- friend class base::NoDestructor<AccessibilityEventRecorder>;
-
private:
std::vector<std::string> event_logs_;
AccessibilityEventCallback callback_;
diff --git a/chromium/content/browser/accessibility/accessibility_event_recorder_auralinux.cc b/chromium/content/browser/accessibility/accessibility_event_recorder_auralinux.cc
new file mode 100644
index 00000000000..203e2da5d4a
--- /dev/null
+++ b/chromium/content/browser/accessibility/accessibility_event_recorder_auralinux.cc
@@ -0,0 +1,401 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/accessibility/accessibility_event_recorder.h"
+
+#include <atk/atk.h>
+#include <atk/atkutil.h>
+#include <atspi/atspi.h>
+
+#include "base/process/process_handle.h"
+#include "base/stl_util.h"
+#include "base/strings/pattern.h"
+#include "base/strings/stringprintf.h"
+#include "content/browser/accessibility/accessibility_tree_formatter_utils_auralinux.h"
+#include "content/browser/accessibility/browser_accessibility_auralinux.h"
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+
+#if defined(ATK_CHECK_VERSION) && ATK_CHECK_VERSION(2, 16, 0)
+#define ATK_216
+#endif
+
+namespace content {
+
+// This class has two distinct event recording code paths. When we are
+// recording events in-process (typically this is used for
+// DumpAccessibilityEvents tests), we use ATK's global event handlers. Since
+// ATK doesn't support intercepting events from other processes, if we have a
+// non-zero PID or an accessibility application name pattern, we use AT-SPI2
+// directly to intercept events. Since AT-SPI2 should be capable of
+// intercepting events in-process as well, eventually it would be nice to
+// remove the ATK code path entirely.
+class AccessibilityEventRecorderAuraLinux : public AccessibilityEventRecorder {
+ public:
+ explicit AccessibilityEventRecorderAuraLinux(
+ BrowserAccessibilityManager* manager,
+ base::ProcessId pid,
+ const base::StringPiece& application_name_match_pattern);
+ ~AccessibilityEventRecorderAuraLinux() override;
+
+ void ProcessATKEvent(const char* event,
+ unsigned int n_params,
+ const GValue* params);
+ void ProcessATSPIEvent(const AtspiEvent* event);
+
+ static gboolean OnATKEventReceived(GSignalInvocationHint* hint,
+ unsigned int n_params,
+ const GValue* params,
+ gpointer data);
+
+ private:
+ bool ShouldUseATSPI();
+
+ void AddATKEventListener(const char* event_name);
+ void AddATKEventListeners();
+ void RemoveATKEventListeners();
+ bool IncludeState(AtkStateType state_type);
+
+ void AddATSPIEventListeners();
+ void RemoveATSPIEventListeners();
+
+ AtspiEventListener* atspi_event_listener_ = nullptr;
+ base::ProcessId pid_;
+ base::StringPiece application_name_match_pattern_;
+ std::vector<unsigned int> atk_listener_ids_;
+ static AccessibilityEventRecorderAuraLinux* instance_;
+
+ DISALLOW_COPY_AND_ASSIGN(AccessibilityEventRecorderAuraLinux);
+};
+
+// static
+AccessibilityEventRecorderAuraLinux*
+ AccessibilityEventRecorderAuraLinux::instance_ = nullptr;
+
+// static
+gboolean AccessibilityEventRecorderAuraLinux::OnATKEventReceived(
+ GSignalInvocationHint* hint,
+ unsigned int n_params,
+ const GValue* params,
+ gpointer data) {
+ GSignalQuery query;
+ g_signal_query(hint->signal_id, &query);
+
+ if (instance_) {
+ instance_->ProcessATKEvent(query.signal_name, n_params, params);
+ }
+
+ return true;
+}
+
+// static
+std::unique_ptr<AccessibilityEventRecorder> AccessibilityEventRecorder::Create(
+ BrowserAccessibilityManager* manager,
+ base::ProcessId pid,
+ const base::StringPiece& application_name_match_pattern) {
+ return std::make_unique<AccessibilityEventRecorderAuraLinux>(
+ manager, pid, application_name_match_pattern);
+}
+
+bool AccessibilityEventRecorderAuraLinux::ShouldUseATSPI() {
+ return pid_ != base::GetCurrentProcId() ||
+ !application_name_match_pattern_.empty();
+}
+
+AccessibilityEventRecorderAuraLinux::AccessibilityEventRecorderAuraLinux(
+ BrowserAccessibilityManager* manager,
+ base::ProcessId pid,
+ const base::StringPiece& application_name_match_pattern)
+ : AccessibilityEventRecorder(manager),
+ pid_(pid),
+ application_name_match_pattern_(application_name_match_pattern) {
+ CHECK(!instance_) << "There can be only one instance of"
+ << " AccessibilityEventRecorder at a time.";
+
+ if (ShouldUseATSPI()) {
+ AddATSPIEventListeners();
+ } else {
+ AddATKEventListeners();
+ }
+
+ instance_ = this;
+}
+
+AccessibilityEventRecorderAuraLinux::~AccessibilityEventRecorderAuraLinux() {
+ RemoveATSPIEventListeners();
+ instance_ = nullptr;
+}
+
+void AccessibilityEventRecorderAuraLinux::AddATKEventListener(
+ const char* event_name) {
+ unsigned id = atk_add_global_event_listener(OnATKEventReceived, event_name);
+ if (!id)
+ LOG(FATAL) << "atk_add_global_event_listener failed for " << event_name;
+
+ atk_listener_ids_.push_back(id);
+}
+
+void AccessibilityEventRecorderAuraLinux::AddATKEventListeners() {
+ GObject* gobject = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr, nullptr));
+ g_object_unref(atk_no_op_object_new(gobject));
+ g_object_unref(gobject);
+
+ AddATKEventListener("ATK:AtkObject:state-change");
+ AddATKEventListener("ATK:AtkObject:focus-event");
+ AddATKEventListener("ATK:AtkObject:property-change");
+}
+
+void AccessibilityEventRecorderAuraLinux::RemoveATKEventListeners() {
+ for (const auto& id : atk_listener_ids_)
+ atk_remove_global_event_listener(id);
+
+ atk_listener_ids_.clear();
+}
+
+// Pruning states which are not supported on older bots makes it possible to
+// run the events tests in more environments.
+bool AccessibilityEventRecorderAuraLinux::IncludeState(
+ AtkStateType state_type) {
+ switch (state_type) {
+#if defined(ATK_216)
+ case ATK_STATE_CHECKABLE:
+ case ATK_STATE_HAS_POPUP:
+ case ATK_STATE_READ_ONLY:
+ return false;
+#endif
+ case ATK_STATE_LAST_DEFINED:
+ return false;
+ default:
+ return true;
+ }
+}
+
+void AccessibilityEventRecorderAuraLinux::ProcessATKEvent(
+ const char* event,
+ unsigned int n_params,
+ const GValue* params) {
+ // If we don't have a root object, it means the tree is being destroyed.
+ if (!manager_->GetRoot()) {
+ RemoveATKEventListeners();
+ return;
+ }
+
+ std::string log;
+ if (std::string(event).find("property-change") != std::string::npos) {
+ DCHECK_GE(n_params, 2u);
+ AtkPropertyValues* property_values =
+ static_cast<AtkPropertyValues*>(g_value_get_pointer(&params[1]));
+
+ if (g_strcmp0(property_values->property_name, "accessible-value"))
+ return;
+
+ log += "VALUE-CHANGED:";
+ log +=
+ base::NumberToString(g_value_get_double(&property_values->new_value));
+ } else {
+ log += base::ToUpperASCII(event);
+ if (std::string(event).find("state-change") != std::string::npos) {
+ log += ":" + base::ToUpperASCII(g_value_get_string(&params[1]));
+ log += base::StringPrintf(":%s", g_strdup_value_contents(&params[2]));
+ }
+ }
+
+ AtkObject* obj = ATK_OBJECT(g_value_get_object(&params[0]));
+ std::string role = atk_role_get_name(atk_object_get_role(obj));
+ base::ReplaceChars(role, " ", "_", &role);
+ log += base::StringPrintf(" role=ROLE_%s", base::ToUpperASCII(role).c_str());
+ log += base::StringPrintf(" name='%s'", atk_object_get_name(obj));
+
+ std::string states = "";
+ AtkStateSet* state_set = atk_object_ref_state_set(obj);
+ for (int i = ATK_STATE_INVALID; i < ATK_STATE_LAST_DEFINED; i++) {
+ AtkStateType state_type = static_cast<AtkStateType>(i);
+ if (atk_state_set_contains_state(state_set, state_type) &&
+ IncludeState(state_type)) {
+ states += " " + base::ToUpperASCII(atk_state_type_get_name(state_type));
+ }
+ }
+ states = base::CollapseWhitespaceASCII(states, false);
+ base::ReplaceChars(states, " ", ",", &states);
+ log += base::StringPrintf(" %s", states.c_str());
+
+ OnEvent(log);
+}
+
+// This list is composed of the sorted event names taken from the list provided
+// in the libatspi documentation at:
+// https://developer.gnome.org/libatspi/stable/AtspiEventListener.html#atspi-event-listener-register
+const char* const kEventNames[] = {
+ "object:active-descendant-changed",
+ "object:children-changed",
+ "object:column-deleted",
+ "object:column-inserted",
+ "object:column-reordered",
+ "object:model-changed",
+ "object:property-change",
+ "object:property-change:accessible-description",
+ "object:property-change:accessible-name",
+ "object:property-change:accessible-parent",
+ "object:property-change:accessible-role",
+ "object:property-change:accessible-table-caption",
+ "object:property-change:accessible-table-column-description",
+ "object:property-change:accessible-table-column-header",
+ "object:property-change:accessible-table-row-description",
+ "object:property-change:accessible-table-row-header",
+ "object:property-change:accessible-table-summary",
+ "object:property-change:accessible-value",
+ "object:row-deleted",
+ "object:row-inserted",
+ "object:row-reordered",
+ "object:selection-changed",
+ "object:state-changed",
+ "object:text-caret-moved",
+ "object:text-changed",
+ "object:text-selection-changed",
+ "object:visible-data-changed",
+ "window:activate",
+ "window:close",
+ "window:create",
+ "window:deactivate",
+ "window:desktop-create",
+ "window:desktop-destroy",
+ "window:lower",
+ "window:maximize",
+ "window:minimize",
+ "window:move",
+ "window:raise",
+ "window:reparent",
+ "window:resize",
+ "window:restore",
+ "window:restyle",
+ "window:shade",
+ "window:unshade",
+};
+
+static void OnATSPIEventReceived(AtspiEvent* event, void* data) {
+ static_cast<AccessibilityEventRecorderAuraLinux*>(data)->ProcessATSPIEvent(
+ event);
+ g_boxed_free(ATSPI_TYPE_EVENT, static_cast<void*>(event));
+}
+
+void AccessibilityEventRecorderAuraLinux::AddATSPIEventListeners() {
+ atspi_init();
+ atspi_event_listener_ =
+ atspi_event_listener_new(OnATSPIEventReceived, this, nullptr);
+
+ GError* error = nullptr;
+ for (size_t i = 0; i < base::size(kEventNames); i++) {
+ atspi_event_listener_register(atspi_event_listener_, kEventNames[i],
+ &error);
+ if (error) {
+ LOG(ERROR) << "Could not register event listener for " << kEventNames[i];
+ g_clear_error(&error);
+ }
+ }
+}
+
+void AccessibilityEventRecorderAuraLinux::RemoveATSPIEventListeners() {
+ if (!atspi_event_listener_)
+ return;
+
+ GError* error = nullptr;
+ for (size_t i = 0; i < base::size(kEventNames); i++) {
+ atspi_event_listener_deregister(atspi_event_listener_, kEventNames[i],
+ nullptr);
+ if (error) {
+ LOG(ERROR) << "Could not deregister event listener for "
+ << kEventNames[i];
+ g_clear_error(&error);
+ }
+ }
+
+ g_object_unref(atspi_event_listener_);
+ atspi_event_listener_ = nullptr;
+}
+
+void AccessibilityEventRecorderAuraLinux::ProcessATSPIEvent(
+ const AtspiEvent* event) {
+ GError* error = nullptr;
+
+ if (!application_name_match_pattern_.empty()) {
+ AtspiAccessible* application =
+ atspi_accessible_get_application(event->source, &error);
+ if (error || !application)
+ return;
+
+ char* application_name = atspi_accessible_get_name(application, &error);
+ g_object_unref(application);
+ if (error || !application_name) {
+ g_clear_error(&error);
+ return;
+ }
+
+ if (!base::MatchPattern(application_name,
+ application_name_match_pattern_)) {
+ return;
+ }
+ free(application_name);
+ }
+
+ if (pid_) {
+ int pid = atspi_accessible_get_process_id(event->source, &error);
+ if (!error && pid != pid_)
+ return;
+ g_clear_error(&error);
+ }
+
+ std::stringstream output;
+ output << event->type << " ";
+
+ GHashTable* attributes =
+ atspi_accessible_get_attributes(event->source, &error);
+ std::string html_tag, html_class, html_id;
+ if (!error && attributes) {
+ if (char* tag = static_cast<char*>(g_hash_table_lookup(attributes, "tag")))
+ html_tag = tag;
+ if (char* id = static_cast<char*>(g_hash_table_lookup(attributes, "id")))
+ html_id = id;
+ if (char* class_chars =
+ static_cast<char*>(g_hash_table_lookup(attributes, "class")))
+ html_class = std::string(".") + class_chars;
+ g_hash_table_unref(attributes);
+ }
+ g_clear_error(&error);
+
+ if (!html_tag.empty())
+ output << "<" << html_tag << html_id << html_class << ">";
+
+ AtspiRole role = atspi_accessible_get_role(event->source, &error);
+ output << "role=";
+ if (!error)
+ output << ATSPIRoleToString(role);
+ else
+ output << "#error";
+ g_clear_error(&error);
+
+ char* name = atspi_accessible_get_name(event->source, &error);
+ output << " name=";
+ if (!error && name)
+ output << name;
+ else
+ output << "#error";
+ g_clear_error(&error);
+ free(name);
+
+ AtspiStateSet* atspi_states = atspi_accessible_get_state_set(event->source);
+ GArray* state_array = atspi_state_set_get_states(atspi_states);
+ std::vector<std::string> states;
+ for (unsigned i = 0; i < state_array->len; i++) {
+ AtspiStateType state_type = g_array_index(state_array, AtspiStateType, i);
+ states.push_back(ATSPIStateToString(state_type));
+ }
+ g_array_free(state_array, TRUE);
+ g_object_unref(atspi_states);
+ output << " ";
+ std::copy(states.begin(), states.end(),
+ std::ostream_iterator<std::string>(output, ", "));
+
+ OnEvent(output.str());
+}
+
+} // namespace content
diff --git a/chromium/content/browser/accessibility/accessibility_event_recorder_mac.mm b/chromium/content/browser/accessibility/accessibility_event_recorder_mac.mm
index 0245a037230..9b037b4b368 100644
--- a/chromium/content/browser/accessibility/accessibility_event_recorder_mac.mm
+++ b/chromium/content/browser/accessibility/accessibility_event_recorder_mac.mm
@@ -8,6 +8,7 @@
#include <string>
+#include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/strings/stringprintf.h"
@@ -20,15 +21,14 @@ namespace content {
// watch for NSAccessibility events.
class AccessibilityEventRecorderMac : public AccessibilityEventRecorder {
public:
+ AccessibilityEventRecorderMac(BrowserAccessibilityManager* manager,
+ base::ProcessId pid);
~AccessibilityEventRecorderMac() override;
// Callback executed every time we receive an event notification.
void EventReceived(AXUIElementRef element, CFStringRef notification);
private:
- AccessibilityEventRecorderMac(BrowserAccessibilityManager* manager,
- base::ProcessId pid);
-
// Add one notification to the list of notifications monitored by our
// observer.
void AddNotification(NSString* notification);
@@ -45,7 +45,6 @@ class AccessibilityEventRecorderMac : public AccessibilityEventRecorder {
base::ScopedCFTypeRef<AXObserverRef> observer_ref_;
CFRunLoopSourceRef observer_run_loop_source_;
- friend class base::NoDestructor<AccessibilityEventRecorderMac>;
DISALLOW_COPY_AND_ASSIGN(AccessibilityEventRecorderMac);
};
@@ -61,19 +60,23 @@ static void EventReceivedThunk(
}
// static
-AccessibilityEventRecorder& AccessibilityEventRecorder::GetInstance(
+std::unique_ptr<AccessibilityEventRecorder> AccessibilityEventRecorder::Create(
BrowserAccessibilityManager* manager,
- base::ProcessId pid) {
- static base::NoDestructor<AccessibilityEventRecorderMac> instance(manager,
- pid);
- return *instance;
+ base::ProcessId pid,
+ const base::StringPiece& application_name_match_pattern) {
+ if (!application_name_match_pattern.empty()) {
+ LOG(ERROR) << "Recording accessibility events from an application name "
+ "match pattern not supported on this platform yet.";
+ NOTREACHED();
+ }
+
+ return std::make_unique<AccessibilityEventRecorderMac>(manager, pid);
}
AccessibilityEventRecorderMac::AccessibilityEventRecorderMac(
BrowserAccessibilityManager* manager,
base::ProcessId pid)
- : AccessibilityEventRecorder(manager, pid),
- observer_run_loop_source_(NULL) {
+ : AccessibilityEventRecorder(manager), observer_run_loop_source_(NULL) {
if (kAXErrorSuccess != AXObserverCreate(pid, EventReceivedThunk,
observer_ref_.InitializeInto())) {
LOG(FATAL) << "Failed to create AXObserverRef";
diff --git a/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc b/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
index 07c26adb4c0..0f1c7120a37 100644
--- a/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
+++ b/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
@@ -75,6 +75,10 @@ std::string AccessibilityEventToStringUTF8(int32_t event_id) {
class AccessibilityEventRecorderWin : public AccessibilityEventRecorder {
public:
+ AccessibilityEventRecorderWin(
+ BrowserAccessibilityManager* manager,
+ base::ProcessId pid,
+ const base::StringPiece& application_name_match_pattern);
~AccessibilityEventRecorderWin() override;
// Callback registered by SetWinEventHook. Just calls OnWinEventHook.
@@ -87,9 +91,6 @@ class AccessibilityEventRecorderWin : public AccessibilityEventRecorder {
DWORD event_time);
private:
- AccessibilityEventRecorderWin(BrowserAccessibilityManager* manager,
- base::ProcessId pid);
-
// Called by the thunk registered by SetWinEventHook. Retrieves accessibility
// info about the node the event was fired on and appends a string to
// the event log.
@@ -107,18 +108,27 @@ class AccessibilityEventRecorderWin : public AccessibilityEventRecorder {
HWND hwnd, DWORD dwId, REFIID riid, void **ppvObject);
HWINEVENTHOOK win_event_hook_handle_;
+ static AccessibilityEventRecorderWin* instance_;
- friend class base::NoDestructor<AccessibilityEventRecorderWin>;
DISALLOW_COPY_AND_ASSIGN(AccessibilityEventRecorderWin);
};
// static
-AccessibilityEventRecorder& AccessibilityEventRecorder::GetInstance(
+AccessibilityEventRecorderWin* AccessibilityEventRecorderWin::instance_ =
+ nullptr;
+
+// static
+std::unique_ptr<AccessibilityEventRecorder> AccessibilityEventRecorder::Create(
BrowserAccessibilityManager* manager,
- base::ProcessId pid) {
- static base::NoDestructor<AccessibilityEventRecorderWin> instance(manager,
- pid);
- return *instance;
+ base::ProcessId pid,
+ const base::StringPiece& application_name_match_pattern) {
+ if (!application_name_match_pattern.empty()) {
+ LOG(FATAL) << "Recording accessibility events from an application name "
+ "match pattern not supported on this platform yet.";
+ }
+
+ return std::make_unique<AccessibilityEventRecorderWin>(
+ manager, pid, application_name_match_pattern);
}
// static
@@ -130,15 +140,19 @@ CALLBACK void AccessibilityEventRecorderWin::WinEventHookThunk(
LONG child_id,
DWORD event_thread,
DWORD event_time) {
- static_cast<AccessibilityEventRecorderWin&>(GetInstance())
- .OnWinEventHook(handle, event, hwnd, obj_id, child_id, event_thread,
- event_time);
+ if (instance_) {
+ instance_->OnWinEventHook(handle, event, hwnd, obj_id, child_id,
+ event_thread, event_time);
+ }
}
AccessibilityEventRecorderWin::AccessibilityEventRecorderWin(
BrowserAccessibilityManager* manager,
- base::ProcessId pid)
- : AccessibilityEventRecorder(manager, pid) {
+ base::ProcessId pid,
+ const base::StringPiece& application_name_match_pattern)
+ : AccessibilityEventRecorder(manager) {
+ CHECK(!instance_) << "There can be only one instance of"
+ << " AccessibilityEventRecorder at a time.";
// For now, just use out of context events when running as a utility to watch
// events (no BrowserAccessibilityManager), because otherwise Chrome events
// are not getting reported. Being in context is better so that for
@@ -151,10 +165,12 @@ AccessibilityEventRecorderWin::AccessibilityEventRecorderWin(
0, // Hook all threads
context);
CHECK(win_event_hook_handle_);
+ instance_ = this;
}
AccessibilityEventRecorderWin::~AccessibilityEventRecorderWin() {
UnhookWinEvent(win_event_hook_handle_);
+ instance_ = nullptr;
}
void AccessibilityEventRecorderWin::OnWinEventHook(
@@ -194,8 +210,33 @@ void AccessibilityEventRecorderWin::OnWinEventHook(
return;
}
+ std::string event_str = AccessibilityEventToStringUTF8(event);
+ if (event_str.empty()) {
+ VLOG(1) << "Ignoring event " << event;
+ return;
+ }
+
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ base::win::ScopedVariant role;
+ iaccessible->get_accRole(childid_self, role.Receive());
+ base::win::ScopedVariant state;
+ iaccessible->get_accState(childid_self, state.Receive());
+ int ia_state = V_I4(state.ptr());
+ std::string hwnd_class_name = base::UTF16ToUTF8(gfx::GetClassName(hwnd));
+
+ // Caret is special:
+ // Log all caret events that occur, with their window class, so that we can
+ // test to make sure they are only occurring on the desired window class.
+ if (ROLE_SYSTEM_CARET == V_I4(role.ptr())) {
+ base::string16 state_str = IAccessibleStateToString(ia_state);
+ std::string log = base::StringPrintf(
+ "%s role=ROLE_SYSTEM_CARET %ls window_class=%s", event_str.c_str(),
+ state_str.c_str(), hwnd_class_name.c_str());
+ OnEvent(log);
+ return;
+ }
+
if (only_web_events_) {
- std::string hwnd_class_name = base::UTF16ToUTF8(gfx::GetClassName(hwnd));
if (hwnd_class_name != "Chrome_RenderWidgetHostHWND")
return;
@@ -211,22 +252,10 @@ void AccessibilityEventRecorderWin::OnWinEventHook(
return;
}
- std::string event_str = AccessibilityEventToStringUTF8(event);
- if (event_str.empty()) {
- VLOG(1) << "Ignoring event " << event;
- return;
- }
-
- base::win::ScopedVariant childid_self(CHILDID_SELF);
- base::win::ScopedVariant role;
- iaccessible->get_accRole(childid_self, role.Receive());
base::win::ScopedBstr name_bstr;
iaccessible->get_accName(childid_self, name_bstr.Receive());
base::win::ScopedBstr value_bstr;
iaccessible->get_accValue(childid_self, value_bstr.Receive());
- base::win::ScopedVariant state;
- iaccessible->get_accState(childid_self, state.Receive());
- int ia_state = V_I4(state.ptr());
// Avoid flakiness. Events fired on a WINDOW are out of the control
// of a test.
diff --git a/chromium/content/browser/accessibility/accessibility_mode_browsertest.cc b/chromium/content/browser/accessibility/accessibility_mode_browsertest.cc
index 8bbb7346b01..c68ecf5396a 100644
--- a/chromium/content/browser/accessibility/accessibility_mode_browsertest.cc
+++ b/chromium/content/browser/accessibility/accessibility_mode_browsertest.cc
@@ -18,7 +18,7 @@
#include "content/shell/browser/shell.h"
#include "content/test/accessibility_browser_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
namespace content {
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter.h b/chromium/content/browser/accessibility/accessibility_tree_formatter.h
index 51b8bc52c6a..7dc41adf79c 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter.h
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter.h
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/process/process_handle.h"
#include "base/strings/string16.h"
+#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "content/browser/accessibility/browser_accessibility.h"
@@ -89,6 +90,11 @@ class CONTENT_EXPORT AccessibilityTreeFormatter {
virtual std::unique_ptr<base::DictionaryValue>
BuildAccessibilityTreeForWindow(gfx::AcceleratedWidget widget) = 0;
+ // Build an accessibility tree for an application with a name matching the
+ // given pattern.
+ virtual std::unique_ptr<base::DictionaryValue>
+ BuildAccessibilityTreeForPattern(const base::StringPiece& pattern) = 0;
+
// Returns a filtered accesibility tree using the current filters.
std::unique_ptr<base::DictionaryValue> FilterAccessibilityTree(
const base::DictionaryValue& dict);
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
index 596b7d7ebc6..91baaa6c28a 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_auralinux.cc
@@ -4,23 +4,31 @@
#include "content/browser/accessibility/accessibility_tree_formatter_browser.h"
+#include <atspi/atspi.h>
+#include <dbus/dbus.h>
+
+#include <iostream>
#include <utility>
#include "base/logging.h"
+#include "base/strings/pattern.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
+#include "content/browser/accessibility/accessibility_tree_formatter_utils_auralinux.h"
#include "content/browser/accessibility/browser_accessibility_auralinux.h"
#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
+#include "ui/base/x/x11_util.h"
+#include "ui/gfx/x/x11.h"
namespace content {
class AccessibilityTreeFormatterAuraLinux
: public AccessibilityTreeFormatterBrowser {
public:
- explicit AccessibilityTreeFormatterAuraLinux();
+ AccessibilityTreeFormatterAuraLinux();
~AccessibilityTreeFormatterAuraLinux() override;
private:
@@ -30,9 +38,24 @@ class AccessibilityTreeFormatterAuraLinux
const std::string GetDenyString() override;
void AddProperties(const BrowserAccessibility& node,
base::DictionaryValue* dict) override;
+
base::string16 ProcessTreeForOutput(
const base::DictionaryValue& node,
base::DictionaryValue* filtered_dict_result = nullptr) override;
+
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForProcess(
+ base::ProcessId pid) override;
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForWindow(
+ gfx::AcceleratedWidget hwnd) override;
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForPattern(
+ const base::StringPiece& pattern) override;
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeWithNode(
+ AtspiAccessible* node);
+
+ void RecursiveBuildAccessibilityTree(AtspiAccessible* node,
+ base::DictionaryValue* dict);
+ virtual void AddProperties(AtspiAccessible* node,
+ base::DictionaryValue* dict);
};
// static
@@ -46,16 +69,176 @@ AccessibilityTreeFormatterAuraLinux::AccessibilityTreeFormatterAuraLinux() {
AccessibilityTreeFormatterAuraLinux::~AccessibilityTreeFormatterAuraLinux() {
}
+std::unique_ptr<base::DictionaryValue>
+AccessibilityTreeFormatterAuraLinux::BuildAccessibilityTreeForPattern(
+ const base::StringPiece& pattern) {
+ // AT-SPI2 always expects the first parameter to this call to be zero.
+ AtspiAccessible* desktop = atspi_get_desktop(0);
+ CHECK(desktop);
+
+ GError* error = nullptr;
+ int child_count = atspi_accessible_get_child_count(desktop, &error);
+ if (error) {
+ LOG(ERROR) << "Failed to get children of root accessible object"
+ << error->message;
+ g_clear_error(&error);
+ return nullptr;
+ }
+
+ std::vector<std::pair<std::string, AtspiAccessible*>> matched_children;
+ for (int i = 0; i < child_count; i++) {
+ AtspiAccessible* child =
+ atspi_accessible_get_child_at_index(desktop, i, &error);
+ if (error) {
+ g_clear_error(&error);
+ continue;
+ }
+
+ char* name = atspi_accessible_get_name(child, &error);
+ if (!error && name && base::MatchPattern(name, pattern)) {
+ matched_children.push_back(std::make_pair(name, child));
+ }
+
+ free(name);
+ }
+
+ if (matched_children.size() == 1) {
+ return BuildAccessibilityTreeWithNode(matched_children[0].second);
+ }
+
+ if (matched_children.size()) {
+ LOG(ERROR) << "Matched more than one application. "
+ << "Try to make a more specific pattern.";
+ for (auto& match : matched_children) {
+ LOG(ERROR) << " * " << match.first;
+ }
+ }
+
+ return nullptr;
+}
+
+std::unique_ptr<base::DictionaryValue>
+AccessibilityTreeFormatterAuraLinux::BuildAccessibilityTreeForProcess(
+ base::ProcessId pid) {
+ LOG(ERROR) << "Aura Linux does not yet support building trees for processes";
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+std::unique_ptr<base::DictionaryValue>
+AccessibilityTreeFormatterAuraLinux::BuildAccessibilityTreeForWindow(
+ gfx::AcceleratedWidget window) {
+ LOG(ERROR) << "Aura Linux does not yet support building trees for window ids";
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+std::unique_ptr<base::DictionaryValue>
+AccessibilityTreeFormatterAuraLinux::BuildAccessibilityTreeWithNode(
+ AtspiAccessible* node) {
+ CHECK(node);
+
+ std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
+ RecursiveBuildAccessibilityTree(node, dict.get());
+
+ return dict;
+}
+
+void AccessibilityTreeFormatterAuraLinux::RecursiveBuildAccessibilityTree(
+ AtspiAccessible* node,
+ base::DictionaryValue* dict) {
+ AddProperties(node, dict);
+
+ GError* error = nullptr;
+ int child_count = atspi_accessible_get_child_count(node, &error);
+ if (error) {
+ g_clear_error(&error);
+ return;
+ }
+
+ if (child_count <= 0)
+ return;
+
+ auto children = std::make_unique<base::ListValue>();
+ for (int i = 0; i < child_count; i++) {
+ std::unique_ptr<base::DictionaryValue> child_dict(
+ new base::DictionaryValue);
+
+ AtspiAccessible* child =
+ atspi_accessible_get_child_at_index(node, i, &error);
+ if (error) {
+ child_dict->SetString("error", "[Error retrieving child]");
+ g_clear_error(&error);
+ continue;
+ }
+
+ CHECK(child);
+ RecursiveBuildAccessibilityTree(child, child_dict.get());
+ children->Append(std::move(child_dict));
+ }
+
+ dict->Set(kChildrenDictAttr, std::move(children));
+}
+
void AccessibilityTreeFormatterAuraLinux::AddProperties(
const BrowserAccessibility& node,
base::DictionaryValue* dict) {
dict->SetInteger("id", node.GetId());
BrowserAccessibilityAuraLinux* acc_obj =
ToBrowserAccessibilityAuraLinux(const_cast<BrowserAccessibility*>(&node));
-
acc_obj->GetNode()->AddAccessibilityTreeProperties(dict);
}
+void AccessibilityTreeFormatterAuraLinux::AddProperties(
+ AtspiAccessible* node,
+ base::DictionaryValue* dict) {
+ GError* error = nullptr;
+ char* role_name = atspi_accessible_get_role_name(node, &error);
+ if (!error)
+ dict->SetString("role", role_name);
+ g_clear_error(&error);
+ free(role_name);
+
+ char* name = atspi_accessible_get_name(node, &error);
+ if (!error)
+ dict->SetString("name", name);
+ g_clear_error(&error);
+ free(name);
+
+ error = nullptr;
+ char* description = atspi_accessible_get_description(node, &error);
+ if (!error)
+ dict->SetString("description", description);
+ g_clear_error(&error);
+ free(description);
+
+ error = nullptr;
+ GHashTable* attributes = atspi_accessible_get_attributes(node, &error);
+ if (!error) {
+ GHashTableIter i;
+ void* key = nullptr;
+ void* value = nullptr;
+
+ g_hash_table_iter_init(&i, attributes);
+ while (g_hash_table_iter_next(&i, &key, &value)) {
+ dict->SetString(static_cast<char*>(key), static_cast<char*>(value));
+ }
+ }
+ g_clear_error(&error);
+ g_hash_table_unref(attributes);
+
+ AtspiStateSet* atspi_states = atspi_accessible_get_state_set(node);
+ GArray* state_array = atspi_state_set_get_states(atspi_states);
+ auto states = std::make_unique<base::ListValue>();
+ for (unsigned i = 0; i < state_array->len; i++) {
+ AtspiStateType state_type = g_array_index(state_array, AtspiStateType, i);
+ states->AppendString(ATSPIStateToString(state_type));
+ }
+ dict->Set("states", std::move(states));
+ g_array_free(state_array, TRUE);
+ g_object_unref(atspi_states);
+}
+
const char* const ATK_OBJECT_ATTRIBUTES[] = {
"atomic",
"autocomplete",
@@ -120,8 +303,7 @@ base::string16 AccessibilityTreeFormatterAuraLinux::ProcessTreeForOutput(
const base::ListValue* states_value;
node.GetList("states", &states_value);
- for (base::ListValue::const_iterator it = states_value->begin();
- it != states_value->end(); ++it) {
+ for (auto it = states_value->begin(); it != states_value->end(); ++it) {
std::string state_value;
if (it->GetAsString(&state_value))
WriteAttribute(false, state_value, &line);
@@ -161,4 +343,4 @@ const std::string AccessibilityTreeFormatterAuraLinux::GetDenyString() {
return "@AURALINUX-DENY:";
}
-}
+} // namespace content
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc
index 50f1d01015b..69d5f617bae 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_blink.cc
@@ -35,7 +35,7 @@ const char* STATE_OFFSCREEN = "offscreen";
uint32_t AccessibilityTreeFormatterBlink::ChildCount(
const BrowserAccessibility& node) const {
- if (node.HasIntAttribute(ax::mojom::IntAttribute::kChildTreeId))
+ if (node.HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId))
return node.PlatformChildCount();
else
return node.InternalChildCount();
@@ -44,7 +44,7 @@ uint32_t AccessibilityTreeFormatterBlink::ChildCount(
BrowserAccessibility* AccessibilityTreeFormatterBlink::GetChild(
const BrowserAccessibility& node,
uint32_t i) const {
- if (node.HasIntAttribute(ax::mojom::IntAttribute::kChildTreeId))
+ if (node.HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId))
return node.PlatformGetChild(i);
else
return node.InternalGetChild(i);
@@ -92,7 +92,6 @@ std::string AccessibilityTreeFormatterBlink::IntAttrToString(
case ax::mojom::IntAttribute::kAriaColumnCount:
case ax::mojom::IntAttribute::kAriaRowCount:
case ax::mojom::IntAttribute::kBackgroundColor:
- case ax::mojom::IntAttribute::kChildTreeId:
case ax::mojom::IntAttribute::kColor:
case ax::mojom::IntAttribute::kColorValue:
case ax::mojom::IntAttribute::kDetailsId:
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.cc
index fa5142f04df..3157cc7050b 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.cc
@@ -30,6 +30,13 @@ AccessibilityTreeFormatterBrowser::BuildAccessibilityTreeForWindow(
return nullptr;
}
+std::unique_ptr<base::DictionaryValue>
+AccessibilityTreeFormatterBrowser::BuildAccessibilityTreeForPattern(
+ const base::StringPiece& pattern) {
+ NOTREACHED();
+ return nullptr;
+}
+
void AccessibilityTreeFormatterBrowser::RecursiveBuildAccessibilityTree(
const BrowserAccessibility& node,
base::DictionaryValue* dict) {
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.h b/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.h
index b91c9debdc3..c5713fd3367 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.h
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_browser.h
@@ -31,6 +31,9 @@ class CONTENT_EXPORT AccessibilityTreeFormatterBrowser
std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForWindow(
gfx::AcceleratedWidget widget) override;
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForPattern(
+ const base::StringPiece& pattern) override;
+
protected:
void RecursiveBuildAccessibilityTree(const BrowserAccessibility& node,
base::DictionaryValue* dict);
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm b/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm
index a63ae0b7b07..72b0c9164e8 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -143,72 +143,68 @@ std::unique_ptr<base::Value> PopulateObject(id value) {
SysNSStringToUTF16([NSString stringWithFormat:@"%@", value])));
}
-NSArray* BuildAllAttributesArray() {
- // Note: clang-format tries to put multiple attributes on one line,
- // but we prefer to have one per line for readability.
- // clang-format off
- NSArray* array = [NSArray arrayWithObjects:
- NSAccessibilityRoleDescriptionAttribute,
- NSAccessibilityTitleAttribute,
- NSAccessibilityValueAttribute,
- NSAccessibilityMinValueAttribute,
- NSAccessibilityMaxValueAttribute,
- NSAccessibilityValueDescriptionAttribute,
- NSAccessibilityDescriptionAttribute,
- NSAccessibilityHelpAttribute,
- @"AXInvalid",
- NSAccessibilityDisclosingAttribute,
- NSAccessibilityDisclosureLevelAttribute,
- @"AXAccessKey",
- @"AXARIAAtomic",
- @"AXARIABusy",
- @"AXARIAColumnCount",
- @"AXARIAColumnIndex",
- @"AXARIALive",
- @"AXARIARelevant",
- @"AXARIARowCount",
- @"AXARIARowIndex",
- @"AXARIASetSize",
- @"AXARIAPosInSet",
- @"AXAutocomplete",
- @"AXAutocompleteValue",
- NSAccessibilityColumnHeaderUIElementsAttribute,
- NSAccessibilityColumnIndexRangeAttribute,
- @"AXDOMIdentifier",
- @"AXDropEffects",
- @"AXEditableAncestor",
- NSAccessibilityEnabledAttribute,
- NSAccessibilityExpandedAttribute,
- @"AXFocusableAncestor",
- NSAccessibilityFocusedAttribute,
- @"AXGrabbed",
- NSAccessibilityHeaderAttribute,
- @"AXHasPopup",
- @"AXHasPopupValue",
- @"AXHighestEditableAncestor",
- NSAccessibilityIndexAttribute,
- @"AXLanguage",
- @"AXLoaded",
- @"AXLoadingProcess",
- NSAccessibilityNumberOfCharactersAttribute,
- NSAccessibilitySortDirectionAttribute,
- NSAccessibilityOrientationAttribute,
- NSAccessibilityPlaceholderValueAttribute,
- @"AXRequired",
- NSAccessibilityRowHeaderUIElementsAttribute,
- NSAccessibilityRowIndexRangeAttribute,
- NSAccessibilitySelectedAttribute,
- NSAccessibilitySelectedChildrenAttribute,
- NSAccessibilityTitleUIElementAttribute,
- NSAccessibilityURLAttribute,
- NSAccessibilityVisibleCharacterRangeAttribute,
- NSAccessibilityVisibleChildrenAttribute,
- @"AXVisited",
- @"AXLinkedUIElements",
- nil];
- // clang-format off
-
- return [array retain];
+NSArray* AllAttributesArray() {
+ static NSArray* all_attributes = [@[
+ NSAccessibilityRoleDescriptionAttribute,
+ NSAccessibilityTitleAttribute,
+ NSAccessibilityValueAttribute,
+ NSAccessibilityMinValueAttribute,
+ NSAccessibilityMaxValueAttribute,
+ NSAccessibilityValueDescriptionAttribute,
+ NSAccessibilityDescriptionAttribute,
+ NSAccessibilityHelpAttribute,
+ @"AXInvalid",
+ NSAccessibilityDisclosingAttribute,
+ NSAccessibilityDisclosureLevelAttribute,
+ @"AXAccessKey",
+ @"AXARIAAtomic",
+ @"AXARIABusy",
+ @"AXARIAColumnCount",
+ @"AXARIAColumnIndex",
+ @"AXARIALive",
+ @"AXARIARelevant",
+ @"AXARIARowCount",
+ @"AXARIARowIndex",
+ @"AXARIASetSize",
+ @"AXARIAPosInSet",
+ @"AXAutocomplete",
+ @"AXAutocompleteValue",
+ NSAccessibilityColumnHeaderUIElementsAttribute,
+ NSAccessibilityColumnIndexRangeAttribute,
+ @"AXDOMIdentifier",
+ @"AXDropEffects",
+ @"AXEditableAncestor",
+ NSAccessibilityEnabledAttribute,
+ NSAccessibilityExpandedAttribute,
+ @"AXFocusableAncestor",
+ NSAccessibilityFocusedAttribute,
+ @"AXGrabbed",
+ NSAccessibilityHeaderAttribute,
+ @"AXHasPopup",
+ @"AXHasPopupValue",
+ @"AXHighestEditableAncestor",
+ NSAccessibilityIndexAttribute,
+ @"AXLanguage",
+ @"AXLoaded",
+ @"AXLoadingProcess",
+ NSAccessibilityNumberOfCharactersAttribute,
+ NSAccessibilitySortDirectionAttribute,
+ NSAccessibilityOrientationAttribute,
+ NSAccessibilityPlaceholderValueAttribute,
+ @"AXRequired",
+ NSAccessibilityRowHeaderUIElementsAttribute,
+ NSAccessibilityRowIndexRangeAttribute,
+ NSAccessibilitySelectedAttribute,
+ NSAccessibilitySelectedChildrenAttribute,
+ NSAccessibilityTitleUIElementAttribute,
+ NSAccessibilityURLAttribute,
+ NSAccessibilityVisibleCharacterRangeAttribute,
+ NSAccessibilityVisibleChildrenAttribute,
+ @"AXVisited",
+ @"AXLinkedUIElements"
+ ] retain];
+
+ return all_attributes;
}
} // namespace
@@ -259,8 +255,7 @@ void AccessibilityTreeFormatterMac::AddProperties(
SysNSStringToUTF8(subrole));
}
- CR_DEFINE_STATIC_LOCAL(NSArray*, all_attributes, (BuildAllAttributesArray()));
- for (NSString* requestedAttribute in all_attributes) {
+ for (NSString* requestedAttribute in AllAttributesArray()) {
if (![supportedAttributes containsObject:requestedAttribute])
continue;
id value = [cocoa_node accessibilityAttributeValue:requestedAttribute];
@@ -307,8 +302,7 @@ base::string16 AccessibilityTreeFormatterMac::ProcessTreeForOutput(
&line);
}
- CR_DEFINE_STATIC_LOCAL(NSArray*, all_attributes, (BuildAllAttributesArray()));
- for (NSString* requestedAttribute in all_attributes) {
+ for (NSString* requestedAttribute in AllAttributesArray()) {
string requestedAttributeUTF8 = SysNSStringToUTF8(requestedAttribute);
if (dict.GetString(requestedAttributeUTF8, &s_value)) {
WriteAttribute([defaultAttributes containsObject:requestedAttribute],
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_auralinux.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_auralinux.cc
new file mode 100644
index 00000000000..976c1f8d26b
--- /dev/null
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_auralinux.cc
@@ -0,0 +1,238 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/accessibility/accessibility_tree_formatter_utils_auralinux.h"
+
+#include "base/stl_util.h"
+
+namespace content {
+namespace {
+struct PlatformConstantToNameEntry {
+ int32_t value;
+ const char* name;
+};
+
+const char* GetNameForPlatformConstant(
+ const PlatformConstantToNameEntry table[],
+ size_t table_size,
+ int32_t value) {
+ for (size_t i = 0; i < table_size; ++i) {
+ auto& entry = table[i];
+ if (entry.value == value)
+ return entry.name;
+ }
+ return "<unknown>";
+}
+} // namespace
+
+#define QUOTE(X) \
+ { X, #X }
+
+#define ATSPI_CHECK_VERSION(major, minor, micro) \
+ (major) < ATSPI_MAJOR_VERSION || \
+ ((major) == ATSPI_MAJOR_VERSION && (minor) < ATSPI_MINOR_VERSION) || \
+ ((major) == ATSPI_MAJOR_VERSION && (minor) == ATSPI_MINOR_VERSION && \
+ (micro) <= ATSPI_MICRO_VERSION)
+
+CONTENT_EXPORT const char* ATSPIStateToString(AtspiStateType state) {
+ // These roles are listed in the order they are defined in the enum so that
+ // we can more easily discard ones that are too new for the version of
+ // atspi2 that we are compiling against.
+ static const PlatformConstantToNameEntry state_table[] = {
+ QUOTE(ATSPI_STATE_INVALID),
+ QUOTE(ATSPI_STATE_ACTIVE),
+ QUOTE(ATSPI_STATE_ARMED),
+ QUOTE(ATSPI_STATE_BUSY),
+ QUOTE(ATSPI_STATE_CHECKED),
+ QUOTE(ATSPI_STATE_COLLAPSED),
+ QUOTE(ATSPI_STATE_DEFUNCT),
+ QUOTE(ATSPI_STATE_EDITABLE),
+ QUOTE(ATSPI_STATE_ENABLED),
+ QUOTE(ATSPI_STATE_EXPANDABLE),
+ QUOTE(ATSPI_STATE_EXPANDED),
+ QUOTE(ATSPI_STATE_FOCUSABLE),
+ QUOTE(ATSPI_STATE_FOCUSED),
+ QUOTE(ATSPI_STATE_HAS_TOOLTIP),
+ QUOTE(ATSPI_STATE_HORIZONTAL),
+ QUOTE(ATSPI_STATE_ICONIFIED),
+ QUOTE(ATSPI_STATE_MODAL),
+ QUOTE(ATSPI_STATE_MULTI_LINE),
+ QUOTE(ATSPI_STATE_MULTISELECTABLE),
+ QUOTE(ATSPI_STATE_OPAQUE),
+ QUOTE(ATSPI_STATE_PRESSED),
+ QUOTE(ATSPI_STATE_RESIZABLE),
+ QUOTE(ATSPI_STATE_SELECTABLE),
+ QUOTE(ATSPI_STATE_SELECTED),
+ QUOTE(ATSPI_STATE_SENSITIVE),
+ QUOTE(ATSPI_STATE_SHOWING),
+ QUOTE(ATSPI_STATE_SINGLE_LINE),
+ QUOTE(ATSPI_STATE_STALE),
+ QUOTE(ATSPI_STATE_TRANSIENT),
+ QUOTE(ATSPI_STATE_VERTICAL),
+ QUOTE(ATSPI_STATE_VISIBLE),
+ QUOTE(ATSPI_STATE_MANAGES_DESCENDANTS),
+ QUOTE(ATSPI_STATE_INDETERMINATE),
+ QUOTE(ATSPI_STATE_REQUIRED),
+ QUOTE(ATSPI_STATE_TRUNCATED),
+ QUOTE(ATSPI_STATE_ANIMATED),
+ QUOTE(ATSPI_STATE_INVALID_ENTRY),
+ QUOTE(ATSPI_STATE_SUPPORTS_AUTOCOMPLETION),
+ QUOTE(ATSPI_STATE_SELECTABLE_TEXT),
+ QUOTE(ATSPI_STATE_IS_DEFAULT),
+ QUOTE(ATSPI_STATE_VISITED),
+#if ATSPI_CHECK_VERSION(2, 12, 0)
+ QUOTE(ATSPI_STATE_CHECKABLE),
+ QUOTE(ATSPI_STATE_HAS_POPUP),
+#endif
+#if ATSPI_CHECK_VERSION(2, 16, 0)
+ QUOTE(ATSPI_STATE_READ_ONLY),
+#endif
+ };
+
+ return GetNameForPlatformConstant(state_table, base::size(state_table),
+ state);
+}
+
+CONTENT_EXPORT const char* ATSPIRoleToString(AtspiRole role) {
+ // These roles are listed in the order they are defined in the enum so that
+ // we can more easily discard ones that are too new for the version of
+ // atspi2 that we are compiling against.
+ static const PlatformConstantToNameEntry role_table[] = {
+ QUOTE(ATSPI_ROLE_INVALID),
+ QUOTE(ATSPI_ROLE_ACCELERATOR_LABEL),
+ QUOTE(ATSPI_ROLE_ALERT),
+ QUOTE(ATSPI_ROLE_ANIMATION),
+ QUOTE(ATSPI_ROLE_ARROW),
+ QUOTE(ATSPI_ROLE_CALENDAR),
+ QUOTE(ATSPI_ROLE_CANVAS),
+ QUOTE(ATSPI_ROLE_CHECK_BOX),
+ QUOTE(ATSPI_ROLE_CHECK_MENU_ITEM),
+ QUOTE(ATSPI_ROLE_COLOR_CHOOSER),
+ QUOTE(ATSPI_ROLE_COLUMN_HEADER),
+ QUOTE(ATSPI_ROLE_COMBO_BOX),
+ QUOTE(ATSPI_ROLE_DATE_EDITOR),
+ QUOTE(ATSPI_ROLE_DESKTOP_ICON),
+ QUOTE(ATSPI_ROLE_DESKTOP_FRAME),
+ QUOTE(ATSPI_ROLE_DIAL),
+ QUOTE(ATSPI_ROLE_DIALOG),
+ QUOTE(ATSPI_ROLE_DIRECTORY_PANE),
+ QUOTE(ATSPI_ROLE_DRAWING_AREA),
+ QUOTE(ATSPI_ROLE_FILE_CHOOSER),
+ QUOTE(ATSPI_ROLE_FILLER),
+ QUOTE(ATSPI_ROLE_FOCUS_TRAVERSABLE),
+ QUOTE(ATSPI_ROLE_FONT_CHOOSER),
+ QUOTE(ATSPI_ROLE_FRAME),
+ QUOTE(ATSPI_ROLE_GLASS_PANE),
+ QUOTE(ATSPI_ROLE_HTML_CONTAINER),
+ QUOTE(ATSPI_ROLE_ICON),
+ QUOTE(ATSPI_ROLE_IMAGE),
+ QUOTE(ATSPI_ROLE_INTERNAL_FRAME),
+ QUOTE(ATSPI_ROLE_LABEL),
+ QUOTE(ATSPI_ROLE_LAYERED_PANE),
+ QUOTE(ATSPI_ROLE_LIST),
+ QUOTE(ATSPI_ROLE_LIST_ITEM),
+ QUOTE(ATSPI_ROLE_MENU),
+ QUOTE(ATSPI_ROLE_MENU_BAR),
+ QUOTE(ATSPI_ROLE_MENU_ITEM),
+ QUOTE(ATSPI_ROLE_OPTION_PANE),
+ QUOTE(ATSPI_ROLE_PAGE_TAB),
+ QUOTE(ATSPI_ROLE_PAGE_TAB_LIST),
+ QUOTE(ATSPI_ROLE_PANEL),
+ QUOTE(ATSPI_ROLE_PASSWORD_TEXT),
+ QUOTE(ATSPI_ROLE_POPUP_MENU),
+ QUOTE(ATSPI_ROLE_PROGRESS_BAR),
+ QUOTE(ATSPI_ROLE_PUSH_BUTTON),
+ QUOTE(ATSPI_ROLE_RADIO_BUTTON),
+ QUOTE(ATSPI_ROLE_RADIO_MENU_ITEM),
+ QUOTE(ATSPI_ROLE_ROOT_PANE),
+ QUOTE(ATSPI_ROLE_ROW_HEADER),
+ QUOTE(ATSPI_ROLE_SCROLL_BAR),
+ QUOTE(ATSPI_ROLE_SCROLL_PANE),
+ QUOTE(ATSPI_ROLE_SEPARATOR),
+ QUOTE(ATSPI_ROLE_SLIDER),
+ QUOTE(ATSPI_ROLE_SPIN_BUTTON),
+ QUOTE(ATSPI_ROLE_SPLIT_PANE),
+ QUOTE(ATSPI_ROLE_STATUS_BAR),
+ QUOTE(ATSPI_ROLE_TABLE),
+ QUOTE(ATSPI_ROLE_TABLE_CELL),
+ QUOTE(ATSPI_ROLE_TABLE_COLUMN_HEADER),
+ QUOTE(ATSPI_ROLE_TABLE_ROW_HEADER),
+ QUOTE(ATSPI_ROLE_TEAROFF_MENU_ITEM),
+ QUOTE(ATSPI_ROLE_TERMINAL),
+ QUOTE(ATSPI_ROLE_TEXT),
+ QUOTE(ATSPI_ROLE_TOGGLE_BUTTON),
+ QUOTE(ATSPI_ROLE_TOOL_BAR),
+ QUOTE(ATSPI_ROLE_TOOL_TIP),
+ QUOTE(ATSPI_ROLE_TREE),
+ QUOTE(ATSPI_ROLE_TREE_TABLE),
+ QUOTE(ATSPI_ROLE_UNKNOWN),
+ QUOTE(ATSPI_ROLE_VIEWPORT),
+ QUOTE(ATSPI_ROLE_WINDOW),
+ QUOTE(ATSPI_ROLE_EXTENDED),
+ QUOTE(ATSPI_ROLE_HEADER),
+ QUOTE(ATSPI_ROLE_FOOTER),
+ QUOTE(ATSPI_ROLE_PARAGRAPH),
+ QUOTE(ATSPI_ROLE_RULER),
+ QUOTE(ATSPI_ROLE_APPLICATION),
+ QUOTE(ATSPI_ROLE_AUTOCOMPLETE),
+ QUOTE(ATSPI_ROLE_EDITBAR),
+ QUOTE(ATSPI_ROLE_EMBEDDED),
+ QUOTE(ATSPI_ROLE_ENTRY),
+ QUOTE(ATSPI_ROLE_CHART),
+ QUOTE(ATSPI_ROLE_CAPTION),
+ QUOTE(ATSPI_ROLE_DOCUMENT_FRAME),
+ QUOTE(ATSPI_ROLE_HEADING),
+ QUOTE(ATSPI_ROLE_PAGE),
+ QUOTE(ATSPI_ROLE_SECTION),
+ QUOTE(ATSPI_ROLE_REDUNDANT_OBJECT),
+ QUOTE(ATSPI_ROLE_FORM),
+ QUOTE(ATSPI_ROLE_LINK),
+ QUOTE(ATSPI_ROLE_INPUT_METHOD_WINDOW),
+ QUOTE(ATSPI_ROLE_TABLE_ROW),
+ QUOTE(ATSPI_ROLE_TREE_ITEM),
+ QUOTE(ATSPI_ROLE_DOCUMENT_SPREADSHEET),
+ QUOTE(ATSPI_ROLE_DOCUMENT_PRESENTATION),
+ QUOTE(ATSPI_ROLE_DOCUMENT_TEXT),
+ QUOTE(ATSPI_ROLE_DOCUMENT_WEB),
+ QUOTE(ATSPI_ROLE_DOCUMENT_EMAIL),
+ QUOTE(ATSPI_ROLE_COMMENT),
+ QUOTE(ATSPI_ROLE_LIST_BOX),
+ QUOTE(ATSPI_ROLE_GROUPING),
+ QUOTE(ATSPI_ROLE_IMAGE_MAP),
+ QUOTE(ATSPI_ROLE_NOTIFICATION),
+ QUOTE(ATSPI_ROLE_INFO_BAR),
+ QUOTE(ATSPI_ROLE_LEVEL_BAR),
+#if ATSPI_CHECK_VERSION(2, 12, 0)
+ QUOTE(ATSPI_ROLE_TITLE_BAR),
+ QUOTE(ATSPI_ROLE_BLOCK_QUOTE),
+ QUOTE(ATSPI_ROLE_AUDIO),
+ QUOTE(ATSPI_ROLE_VIDEO),
+ QUOTE(ATSPI_ROLE_DEFINITION),
+ QUOTE(ATSPI_ROLE_ARTICLE),
+ QUOTE(ATSPI_ROLE_LANDMARK),
+ QUOTE(ATSPI_ROLE_LOG),
+ QUOTE(ATSPI_ROLE_MARQUEE),
+ QUOTE(ATSPI_ROLE_MATH),
+ QUOTE(ATSPI_ROLE_RATING),
+ QUOTE(ATSPI_ROLE_TIMER),
+#endif
+#if ATSPI_CHECK_VERSION(2, 16, 0)
+ QUOTE(ATSPI_ROLE_STATIC),
+ QUOTE(ATSPI_ROLE_MATH_FRACTION),
+ QUOTE(ATSPI_ROLE_MATH_ROOT),
+ QUOTE(ATSPI_ROLE_SUBSCRIPT),
+ QUOTE(ATSPI_ROLE_SUPERSCRIPT),
+#endif
+#if ATSPI_CHECK_VERSION(2, 26, 0)
+ QUOTE(ATSPI_ROLE_DESCRIPTION_LIST),
+ QUOTE(ATSPI_ROLE_DESCRIPTION_TERM),
+ QUOTE(ATSPI_ROLE_DESCRIPTION_VALUE),
+ QUOTE(ATSPI_ROLE_FOOTNOTE),
+#endif
+ };
+
+ return GetNameForPlatformConstant(role_table, base::size(role_table), role);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_auralinux.h b/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_auralinux.h
new file mode 100644
index 00000000000..29dad1d2fea
--- /dev/null
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_auralinux.h
@@ -0,0 +1,19 @@
+// 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 CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_UTILS_AURALINUX_H_
+#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_UTILS_AURALINUX_H_
+
+#include <atspi/atspi.h>
+
+#include "content/common/content_export.h"
+
+namespace content {
+
+CONTENT_EXPORT const char* ATSPIStateToString(AtspiStateType state);
+CONTENT_EXPORT const char* ATSPIRoleToString(AtspiRole role);
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_UTILS_AURALINUX_H_
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc
index 20fd3b776fc..edcd636a3c3 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_win.cc
@@ -10,6 +10,7 @@
#include <stdint.h>
#include <wrl/client.h>
+#include <iostream>
#include <string>
#include <utility>
@@ -70,6 +71,8 @@ class AccessibilityTreeFormatterWin : public AccessibilityTreeFormatter {
gfx::AcceleratedWidget hwnd) override;
std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForProcess(
base::ProcessId pid) override;
+ std::unique_ptr<base::DictionaryValue> BuildAccessibilityTreeForPattern(
+ const base::StringPiece& pattern) override;
std::unique_ptr<base::DictionaryValue> BuildAccessibilityTree(
Microsoft::WRL::ComPtr<IAccessible> start,
LONG window_x = 0,
@@ -281,6 +284,14 @@ AccessibilityTreeFormatterWin::BuildAccessibilityTreeForProcess(
return BuildAccessibilityTreeForWindow(hwnd);
}
+std::unique_ptr<base::DictionaryValue>
+AccessibilityTreeFormatterWin::BuildAccessibilityTreeForPattern(
+ const base::StringPiece& pattern) {
+ LOG(ERROR) << "Windows does not yet support building accessibility trees for "
+ "patterns";
+ return nullptr;
+}
+
void AccessibilityTreeFormatterWin::RecursiveBuildAccessibilityTree(
const Microsoft::WRL::ComPtr<IAccessible> node,
base::DictionaryValue* dict,
diff --git a/chromium/content/browser/accessibility/accessibility_win_browsertest.cc b/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
index 9bb5760cfdb..1813c91433c 100644
--- a/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -76,6 +76,16 @@ class AccessibilityWinBrowserTest : public ContentBrowserTest {
void SetUpInputField(Microsoft::WRL::ComPtr<IAccessibleText>* input_text);
void SetUpScrollableInputField(
Microsoft::WRL::ComPtr<IAccessibleText>* input_text);
+ void SetUpSingleCharInputField(
+ Microsoft::WRL::ComPtr<IAccessibleText>* input_text);
+ void SetUpSingleCharInputFieldWithPlaceholder(
+ Microsoft::WRL::ComPtr<IAccessibleText>* input_text);
+ void SetUpSingleCharTextarea(
+ Microsoft::WRL::ComPtr<IAccessibleText>* input_text);
+ void SetUpSingleCharContenteditable(
+ Microsoft::WRL::ComPtr<IAccessibleText>* input_text);
+ void SetUpSingleCharRtlInputField(
+ Microsoft::WRL::ComPtr<IAccessibleText>* input_text);
void SetUpTextareaField(
Microsoft::WRL::ComPtr<IAccessibleText>* textarea_text);
void SetUpSampleParagraph(
@@ -201,6 +211,71 @@ void AccessibilityWinBrowserTest::SetUpScrollableInputField(
SetUpInputFieldHelper(input_text);
}
+// Loads a page with an input text field and places a single character in it.
+// Also tests with padding, in order to ensure character extent of empty field
+// does not erroneously include padding.
+void AccessibilityWinBrowserTest::SetUpSingleCharInputField(
+ Microsoft::WRL::ComPtr<IAccessibleText>* input_text) {
+ ASSERT_NE(nullptr, input_text);
+ LoadInitialAccessibilityTreeFromHtml(std::string(
+ R"HTML(<!DOCTYPE html>
+ <html>
+ <body>
+ <form>
+ <input type="text" value="x" style="padding:3px">
+ </form>
+ </body>
+ </html>)HTML"));
+ SetUpInputFieldHelper(input_text);
+}
+
+void AccessibilityWinBrowserTest::SetUpSingleCharInputFieldWithPlaceholder(
+ Microsoft::WRL::ComPtr<IAccessibleText>* input_text) {
+ ASSERT_NE(nullptr, input_text);
+ LoadInitialAccessibilityTreeFromHtml(std::string(
+ R"HTML(<!DOCTYPE html>
+ <html>
+ <body>
+ <form>
+ <input type="text" value="x" placeholder="placeholder">
+ </form>
+ </body>
+ </html>)HTML"));
+ SetUpInputFieldHelper(input_text);
+}
+
+void AccessibilityWinBrowserTest::SetUpSingleCharTextarea(
+ Microsoft::WRL::ComPtr<IAccessibleText>* input_text) {
+ ASSERT_NE(nullptr, input_text);
+ LoadInitialAccessibilityTreeFromHtml(std::string(
+ R"HTML(<!DOCTYPE html>
+ <html>
+ <body>
+ <form>
+ <textarea rows="3" cols="10">x</textarea>
+ </form>
+ </body>
+ </html>)HTML"));
+ SetUpInputFieldHelper(input_text);
+}
+
+// Loads a page with a right-to-left input text field and places a single
+// character in it.
+void AccessibilityWinBrowserTest::SetUpSingleCharRtlInputField(
+ Microsoft::WRL::ComPtr<IAccessibleText>* input_text) {
+ ASSERT_NE(nullptr, input_text);
+ LoadInitialAccessibilityTreeFromHtml(std::string(
+ R"HTML(<!DOCTYPE html>
+ <html>
+ <body>
+ <form>
+ <input type="text" id="textField" name="name" dir="rtl" value="x">
+ </form>
+ </body>
+ </html>)HTML"));
+ SetUpInputFieldHelper(input_text);
+}
+
void AccessibilityWinBrowserTest::SetUpInputFieldHelper(
Microsoft::WRL::ComPtr<IAccessibleText>* input_text) {
Microsoft::WRL::ComPtr<IAccessible> document(GetRendererAccessible());
@@ -237,12 +312,13 @@ void AccessibilityWinBrowserTest::SetUpInputFieldHelper(
ax::mojom::Event::kTextSelectionChanged);
std::wstring caret_offset = base::UTF16ToWide(
base::IntToString16(static_cast<int>(kContentsLength - 1)));
- ExecuteScript(std::wstring(L"let textField = document.querySelector('input');"
- L"textField.focus();"
- L"textField.setSelectionRange(") +
- caret_offset + L"," + caret_offset +
- L");"
- L"textField.scrollLeft = 1000;");
+ ExecuteScript(
+ std::wstring(L"let textField = document.querySelector('input,textarea');"
+ L"textField.focus();"
+ L"textField.setSelectionRange(") +
+ caret_offset + L"," + caret_offset +
+ L");"
+ L"textField.scrollLeft = 1000;");
waiter.WaitForNotification();
}
@@ -330,8 +406,9 @@ void AccessibilityWinBrowserTest::SetUpSampleParagraphInScrollableDocument(
LoadInitialAccessibilityTreeFromHtml(
R"HTML(<!DOCTYPE html>
<html>
- <body style="overflow: scroll; margin-top: 100vh">
- <p><b>Game theory</b> is "the study of
+ <body>
+ <p style="margin-top:50vh; margin-bottom:200vh">
+ <b>Game theory</b> is "the study of
<a href="" title="Mathematical model">mathematical models</a>
of conflict and<br>cooperation between intelligent rational
decision-makers."
@@ -771,10 +848,10 @@ class NativeWinEventWaiter {
NativeWinEventWaiter(BrowserAccessibilityManager* manager,
const std::string& match_pattern)
: event_recorder_(
- AccessibilityEventRecorder::GetInstance(manager,
- base::GetCurrentProcId())),
+ AccessibilityEventRecorder::Create(manager,
+ base::GetCurrentProcId())),
match_pattern_(match_pattern) {
- event_recorder_.ListenToEvents(base::BindRepeating(
+ event_recorder_->ListenToEvents(base::BindRepeating(
&NativeWinEventWaiter::OnEvent, base::Unretained(this)));
}
@@ -787,7 +864,7 @@ class NativeWinEventWaiter {
void Wait() { run_loop_.Run(); }
private:
- AccessibilityEventRecorder& event_recorder_;
+ std::unique_ptr<AccessibilityEventRecorder> event_recorder_;
std::string match_pattern_;
base::RunLoop run_loop_;
};
@@ -1244,6 +1321,15 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
EXPECT_LT(1, width) << "at offset " << offset;
EXPECT_EQ(previous_height, height) << "at offset " << offset;
}
+
+ // Past end of text.
+ EXPECT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
+ n_characters, coordinate_type, &x, &y, &width, &height));
+ EXPECT_LT(previous_x, x) << "at final offset " << n_characters;
+ EXPECT_EQ(previous_y, y) << "at final offset " << n_characters;
+ // Last character width past end should be 1, the width of a caret.
+ EXPECT_EQ(1, width) << "at final offset " << n_characters;
+ EXPECT_EQ(previous_height, height) << "at final offset " << n_characters;
}
}
@@ -1375,6 +1461,272 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
EXPECT_LT(1, width) << "at offset " << offset;
EXPECT_EQ(previous_height, height) << "at offset " << offset;
}
+ // Past end of text.
+ EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
+ n_characters, coordinate_type, &x, &y, &width, &height));
+ EXPECT_LT(previous_x, x) << "at final offset " << n_characters;
+ EXPECT_EQ(previous_y, y) << "at final offset " << n_characters;
+ // Last character width past end should be 1, the width of a caret.
+ EXPECT_EQ(1, width) << "at final offset " << n_characters;
+ EXPECT_EQ(previous_height, height) << "at final offset " << n_characters;
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
+ TestCharacterExtentsInEmptyInputField) {
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
+ SetUpSingleCharInputField(&input_text);
+
+ LONG n_characters;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
+ ASSERT_EQ(1, n_characters);
+
+ // Get the rect for the only character.
+ LONG prev_x, prev_y, prev_width, prev_height;
+ EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
+ 0, IA2_COORDTYPE_SCREEN_RELATIVE, &prev_x, &prev_y, &prev_width,
+ &prev_height));
+
+ EXPECT_LT(1, prev_width);
+ EXPECT_LT(1, prev_height);
+
+ base::win::ScopedBstr text0;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_text(0, -1, text0.Receive()));
+
+ // Delete the character in the input field.
+ AccessibilityNotificationWaiter waiter(
+ shell()->web_contents(), ui::kAXModeComplete,
+ ax::mojom::Event::kTextSelectionChanged);
+ ExecuteScript(std::wstring(L"document.querySelector('input').value='';"));
+ waiter.WaitForNotification();
+
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
+ ASSERT_EQ(0, n_characters);
+ LONG caret_offset;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_caretOffset(&caret_offset));
+ ASSERT_EQ(0, caret_offset);
+
+ base::win::ScopedBstr text;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_text(0, -1, text.Receive()));
+
+ // Now that input is completely empty, the position of the caret should be
+ // returned for character 0. The x,y position and height should be the same as
+ // it was as when there was single character, but the width should now be 1.
+ LONG x, y, width, height;
+ for (int offset = IA2_TEXT_OFFSET_CARET; offset <= 0; ++offset) {
+ EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
+ offset, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height));
+ EXPECT_EQ(prev_x, x);
+ EXPECT_EQ(prev_y, y);
+ EXPECT_EQ(1, width);
+ EXPECT_EQ(prev_height, height);
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
+ TestCharacterExtentsInEmptyInputFieldWithPlaceholder) {
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
+ SetUpSingleCharInputFieldWithPlaceholder(&input_text);
+
+ LONG n_characters;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
+ ASSERT_EQ(1, n_characters);
+
+ // Get the rect for the only character.
+ LONG prev_x, prev_y, prev_width, prev_height;
+ EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
+ 0, IA2_COORDTYPE_SCREEN_RELATIVE, &prev_x, &prev_y, &prev_width,
+ &prev_height));
+
+ EXPECT_LT(1, prev_width);
+ EXPECT_LT(1, prev_height);
+
+ base::win::ScopedBstr text0;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_text(0, -1, text0.Receive()));
+
+ // Delete the character in the input field.
+ AccessibilityNotificationWaiter waiter(
+ shell()->web_contents(), ui::kAXModeComplete,
+ ax::mojom::Event::kTextSelectionChanged);
+ ExecuteScript(std::wstring(L"document.querySelector('input').value='';"));
+ waiter.WaitForNotification();
+
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
+ ASSERT_EQ(0, n_characters);
+ LONG caret_offset;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_caretOffset(&caret_offset));
+ ASSERT_EQ(0, caret_offset);
+
+ base::win::ScopedBstr text;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_text(0, -1, text.Receive()));
+
+ // Now that input is completely empty, the position of the caret should be
+ // returned for character 0. The x,y position and height should be the same as
+ // it was as when there was single character, but the width should now be 1.
+ LONG x, y, width, height;
+ for (int offset = IA2_TEXT_OFFSET_CARET; offset <= 0; ++offset) {
+ EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
+ offset, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height));
+ EXPECT_EQ(prev_x, x);
+ EXPECT_EQ(prev_y, y);
+ EXPECT_EQ(1, width);
+ EXPECT_EQ(prev_height, height);
+ }
+}
+
+// TODO(accessibility) empty contenteditable gets height of entire
+// contenteditable instead of just 1 line. May be able to use the following
+// in Blink to get the height of a line -- it's at least close:
+// layout_object->Style()->GetFont().PrimaryFont()->GetFontMetrics().Height()
+IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
+ DISABLED_TestCharacterExtentsInEmptyContenteditable) {
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
+ SetUpSampleParagraphInScrollableEditable(&input_text);
+
+ LONG n_characters;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
+ ASSERT_LT(0, n_characters);
+
+ // Get the rect for the only character.
+ LONG prev_x, prev_y, prev_width, prev_height;
+ EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
+ 0, IA2_COORDTYPE_SCREEN_RELATIVE, &prev_x, &prev_y, &prev_width,
+ &prev_height));
+
+ EXPECT_LT(1, prev_width);
+ EXPECT_LT(1, prev_height);
+
+ base::win::ScopedBstr text0;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_text(0, -1, text0.Receive()));
+
+ // Delete the character in the input field.
+ AccessibilityNotificationWaiter waiter(shell()->web_contents(),
+ ui::kAXModeComplete,
+ ax::mojom::Event::kChildrenChanged);
+ ExecuteScript(std::wstring(
+ L"document.querySelector('[contenteditable]').innerText='';"));
+ waiter.WaitForNotification();
+
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
+ ASSERT_EQ(0, n_characters);
+ LONG caret_offset;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_caretOffset(&caret_offset));
+ ASSERT_EQ(0, caret_offset);
+
+ base::win::ScopedBstr text;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_text(0, -1, text.Receive()));
+
+ // Now that input is completely empty, the position of the caret should be
+ // returned for character 0. The x,y position and height should be the same as
+ // it was as when there was single character, but the width should now be 1.
+ LONG x, y, width, height;
+ for (int offset = IA2_TEXT_OFFSET_CARET; offset <= 0; ++offset) {
+ EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
+ offset, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height));
+ EXPECT_EQ(prev_x, x);
+ EXPECT_EQ(prev_y, y);
+ EXPECT_EQ(1, width);
+ EXPECT_EQ(prev_height, height);
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
+ TestCharacterExtentsInEmptyTextarea) {
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
+ SetUpSingleCharTextarea(&input_text);
+
+ LONG n_characters;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
+ ASSERT_EQ(1, n_characters);
+
+ // Get the rect for the only character.
+ LONG prev_x, prev_y, prev_width, prev_height;
+ EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
+ 0, IA2_COORDTYPE_SCREEN_RELATIVE, &prev_x, &prev_y, &prev_width,
+ &prev_height));
+
+ EXPECT_LT(1, prev_width);
+ EXPECT_LT(1, prev_height);
+
+ base::win::ScopedBstr text0;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_text(0, -1, text0.Receive()));
+
+ // Delete the character in the input field.
+ AccessibilityNotificationWaiter waiter(
+ shell()->web_contents(), ui::kAXModeComplete,
+ ax::mojom::Event::kTextSelectionChanged);
+ ExecuteScript(
+ std::wstring(L"document.querySelector('textarea').innerText='';"));
+ waiter.WaitForNotification();
+
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
+ ASSERT_EQ(0, n_characters);
+ LONG caret_offset;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_caretOffset(&caret_offset));
+ ASSERT_EQ(0, caret_offset);
+
+ base::win::ScopedBstr text;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_text(0, -1, text.Receive()));
+
+ // Now that input is completely empty, the position of the caret should be
+ // returned for character 0. The x,y position and height should be the same as
+ // it was as when there was single character, but the width should now be 1.
+ LONG x, y, width, height;
+ for (int offset = IA2_TEXT_OFFSET_CARET; offset <= 0; ++offset) {
+ EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
+ offset, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height));
+ EXPECT_EQ(prev_x, x);
+ EXPECT_EQ(prev_y, y);
+ EXPECT_EQ(1, width);
+ EXPECT_EQ(prev_height, height);
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
+ TestCharacterExtentsInEmptyRtlInputField) {
+ Microsoft::WRL::ComPtr<IAccessibleText> input_text;
+ SetUpSingleCharRtlInputField(&input_text);
+
+ LONG n_characters;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
+ ASSERT_EQ(1, n_characters);
+
+ // Get the rect for the only character.
+ LONG prev_x, prev_y, prev_width, prev_height;
+ EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
+ 0, IA2_COORDTYPE_SCREEN_RELATIVE, &prev_x, &prev_y, &prev_width,
+ &prev_height));
+
+ EXPECT_LT(1, prev_width);
+ EXPECT_LT(1, prev_height);
+
+ // Delete the character in the input field.
+ AccessibilityNotificationWaiter waiter(
+ shell()->web_contents(), ui::kAXModeComplete,
+ ax::mojom::Event::kTextSelectionChanged);
+ ExecuteScript(
+ std::wstring(L"const input = document.querySelector('input');"
+ "input.value='';"));
+ waiter.WaitForNotification();
+
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
+ ASSERT_EQ(0, n_characters);
+ LONG caret_offset;
+ ASSERT_HRESULT_SUCCEEDED(input_text->get_caretOffset(&caret_offset));
+ ASSERT_EQ(0, caret_offset);
+
+ // Now that input is completely empty, the position of the caret should be
+ // returned for character 0. The x,y position and height should be the same as
+ // it was as when there was single character, but the width should now be 1.
+ LONG x, y, width, height;
+ for (int offset = IA2_TEXT_OFFSET_CARET; offset <= 0; ++offset) {
+ EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
+ offset, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height));
+ // TODO(accessibility) Why do results keep changing on each run?
+ EXPECT_GE(prev_x + prev_width - 1, x);
+ EXPECT_EQ(prev_y, y);
+ EXPECT_EQ(1, width);
+ EXPECT_EQ(prev_height, height);
}
}
@@ -1433,15 +1785,55 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestScrollToPoint) {
EXPECT_EQ(prev_x, x);
EXPECT_GT(prev_y, y);
- prev_x = x;
- prev_y = y;
+ constexpr int kScrollToY = 0;
EXPECT_HRESULT_SUCCEEDED(
- paragraph->scrollToPoint(IA2_COORDTYPE_SCREEN_RELATIVE, 0, 0));
+ paragraph->scrollToPoint(IA2_COORDTYPE_SCREEN_RELATIVE, 0, kScrollToY));
location_changed_waiter.WaitForNotification();
ASSERT_HRESULT_SUCCEEDED(
paragraph->accLocation(&x, &y, &width, &height, childid_self));
- EXPECT_EQ(prev_x, x);
- EXPECT_EQ(prev_y, y);
+ EXPECT_EQ(kScrollToY, y);
+
+ constexpr int kScrollToY_2 = 243;
+ EXPECT_HRESULT_SUCCEEDED(
+ paragraph->scrollToPoint(IA2_COORDTYPE_SCREEN_RELATIVE, 0, kScrollToY_2));
+ location_changed_waiter.WaitForNotification();
+ ASSERT_HRESULT_SUCCEEDED(
+ paragraph->accLocation(&x, &y, &width, &height, childid_self));
+ EXPECT_EQ(kScrollToY_2, y);
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
+ TestScrollSubstringToPoint) {
+ Microsoft::WRL::ComPtr<IAccessibleText> paragraph_text;
+ SetUpSampleParagraphInScrollableDocument(&paragraph_text);
+ Microsoft::WRL::ComPtr<IAccessible2> paragraph;
+ ASSERT_HRESULT_SUCCEEDED(paragraph_text.CopyTo(IID_PPV_ARGS(&paragraph)));
+
+ LONG x, y, width, height;
+ base::win::ScopedVariant childid_self(CHILDID_SELF);
+ AccessibilityNotificationWaiter location_changed_waiter(
+ shell()->web_contents(), ui::kAXModeComplete,
+ ax::mojom::Event::kLocationChanged);
+
+ constexpr int kScrollToY = 187;
+ constexpr int kCharOffset = 10;
+ EXPECT_HRESULT_SUCCEEDED(paragraph_text->scrollSubstringToPoint(
+ kCharOffset, kCharOffset + 1, IA2_COORDTYPE_SCREEN_RELATIVE, 0,
+ kScrollToY));
+ location_changed_waiter.WaitForNotification();
+ ASSERT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
+ kCharOffset, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height));
+ EXPECT_EQ(kScrollToY, y);
+
+ constexpr int kScrollToY_2 = -133;
+ constexpr int kCharOffset_2 = 30;
+ EXPECT_HRESULT_SUCCEEDED(paragraph_text->scrollSubstringToPoint(
+ kCharOffset_2, kCharOffset_2 + 1, IA2_COORDTYPE_SCREEN_RELATIVE, 0,
+ kScrollToY_2));
+ location_changed_waiter.WaitForNotification();
+ ASSERT_HRESULT_SUCCEEDED(paragraph_text->get_characterExtents(
+ kCharOffset_2, IA2_COORDTYPE_SCREEN_RELATIVE, &x, &y, &width, &height));
+ EXPECT_EQ(kScrollToY_2, y);
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest, TestSetCaretOffset) {
diff --git a/chromium/content/browser/accessibility/browser_accessibility.cc b/chromium/content/browser/accessibility/browser_accessibility.cc
index 10485315e69..d8c0af5afcf 100644
--- a/chromium/content/browser/accessibility/browser_accessibility.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility.cc
@@ -10,6 +10,7 @@
#include <iterator>
#include "base/logging.h"
+#include "base/no_destructor.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
@@ -73,11 +74,17 @@ bool BrowserAccessibility::PlatformIsLeaf() const {
}
}
+bool BrowserAccessibility::CanFireEvents() const {
+ // Allow events unless this object would be trimmed away.
+ return !PlatformIsChildOfLeaf();
+}
+
uint32_t BrowserAccessibility::PlatformChildCount() const {
- if (HasIntAttribute(ax::mojom::IntAttribute::kChildTreeId)) {
+ if (HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId)) {
+ AXTreeID child_tree_id = AXTreeID::FromString(
+ GetStringAttribute(ax::mojom::StringAttribute::kChildTreeId));
BrowserAccessibilityManager* child_manager =
- BrowserAccessibilityManager::FromID(
- GetIntAttribute(ax::mojom::IntAttribute::kChildTreeId));
+ BrowserAccessibilityManager::FromID(child_tree_id);
if (child_manager && child_manager->GetRoot()->PlatformGetParent() == this)
return 1;
@@ -127,10 +134,11 @@ BrowserAccessibility* BrowserAccessibility::PlatformGetChild(
BrowserAccessibility* result = nullptr;
if (child_index == 0 &&
- HasIntAttribute(ax::mojom::IntAttribute::kChildTreeId)) {
+ HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId)) {
+ AXTreeID child_tree_id = AXTreeID::FromString(
+ GetStringAttribute(ax::mojom::StringAttribute::kChildTreeId));
BrowserAccessibilityManager* child_manager =
- BrowserAccessibilityManager::FromID(
- GetIntAttribute(ax::mojom::IntAttribute::kChildTreeId));
+ BrowserAccessibilityManager::FromID(child_tree_id);
if (child_manager && child_manager->GetRoot()->PlatformGetParent() == this)
result = child_manager->GetRoot();
} else {
@@ -380,7 +388,9 @@ gfx::Rect BrowserAccessibility::GetPageBoundsForRange(int start,
else
start = 0;
}
- return bounds;
+ // When past the end of text, the area will be 0.
+ // In this case, use bounds provided for the caret.
+ return bounds.IsEmpty() ? GetPageBoundsPastEndOfText() : bounds;
}
int end = start + len;
@@ -492,6 +502,53 @@ gfx::Rect BrowserAccessibility::GetScreenBoundsForRange(int start,
return bounds;
}
+// Get a rect for a 1-width character past the end of text. This is what ATs
+// expect when getting the character extents past the last character in a line,
+// and equals what the caret bounds would be when past the end of the text.
+gfx::Rect BrowserAccessibility::GetPageBoundsPastEndOfText() const {
+ // Step 1: get approximate caret bounds. The thickness may not yet be correct.
+ gfx::Rect bounds;
+ if (InternalChildCount() > 0) {
+ // When past the end of text, use bounds provided by a last child if
+ // available, and then correct for thickness of caret.
+ BrowserAccessibility* child = InternalGetChild(InternalChildCount() - 1);
+ int child_text_len = child->GetText().size();
+ bounds = child->GetPageBoundsForRange(child_text_len, child_text_len);
+ if (bounds.width() == 0 && bounds.height() == 0)
+ return bounds; // Inline text boxes info not yet available.
+ } else {
+ // Compute bounds of where caret would be, based on bounds of object.
+ bounds = GetPageBoundsRect();
+ }
+
+ // Step 2: correct for the thickness of the caret.
+ auto text_direction = static_cast<ax::mojom::TextDirection>(
+ GetIntAttribute(ax::mojom::IntAttribute::kTextDirection));
+ constexpr int kCaretThickness = 1;
+ switch (text_direction) {
+ case ax::mojom::TextDirection::kNone:
+ case ax::mojom::TextDirection::kLtr: {
+ bounds.set_width(kCaretThickness);
+ break;
+ }
+ case ax::mojom::TextDirection::kRtl: {
+ bounds.set_x(bounds.right() - kCaretThickness);
+ bounds.set_width(kCaretThickness);
+ break;
+ }
+ case ax::mojom::TextDirection::kTtb: {
+ bounds.set_height(kCaretThickness);
+ break;
+ }
+ case ax::mojom::TextDirection::kBtt: {
+ bounds.set_y(bounds.bottom() - kCaretThickness);
+ bounds.set_height(kCaretThickness);
+ break;
+ }
+ }
+ return bounds;
+}
+
base::string16 BrowserAccessibility::GetValue() const {
base::string16 value =
GetString16Attribute(ax::mojom::StringAttribute::kValue);
@@ -886,19 +943,19 @@ gfx::NativeViewAccessible BrowserAccessibility::GetNativeViewAccessible() {
// AXPlatformNodeDelegate.
//
const ui::AXNodeData& BrowserAccessibility::GetData() const {
- CR_DEFINE_STATIC_LOCAL(ui::AXNodeData, empty_data, ());
+ static base::NoDestructor<ui::AXNodeData> empty_data;
if (node_)
return node_->data();
else
- return empty_data;
+ return *empty_data;
}
const ui::AXTreeData& BrowserAccessibility::GetTreeData() const {
- CR_DEFINE_STATIC_LOCAL(ui::AXTreeData, empty_data, ());
+ static base::NoDestructor<ui::AXTreeData> empty_data;
if (manager())
return manager()->GetTreeData();
else
- return empty_data;
+ return *empty_data;
}
gfx::NativeWindow BrowserAccessibility::GetTopLevelWidget() {
diff --git a/chromium/content/browser/accessibility/browser_accessibility.h b/chromium/content/browser/accessibility/browser_accessibility.h
index b66d5e86384..89034481f8b 100644
--- a/chromium/content/browser/accessibility/browser_accessibility.h
+++ b/chromium/content/browser/accessibility/browser_accessibility.h
@@ -114,6 +114,9 @@ class CONTENT_EXPORT BrowserAccessibility : public ui::AXPlatformNodeDelegate {
// that might send notifications.
virtual bool PlatformIsLeaf() const;
+ // Returns true if this object can fire events.
+ virtual bool CanFireEvents() const;
+
// Returns the number of children of this object, or 0 if PlatformIsLeaf()
// returns true.
virtual uint32_t PlatformChildCount() const;
@@ -392,6 +395,8 @@ class CONTENT_EXPORT BrowserAccessibility : public ui::AXPlatformNodeDelegate {
// text, depending on the platform.
base::string16 GetInnerText() const;
+ gfx::Rect GetPageBoundsPastEndOfText() const;
+
// A unique ID, since node IDs are frame-local.
ui::AXUniqueId unique_id_;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_android.cc b/chromium/content/browser/accessibility/browser_accessibility_android.cc
index 95b60d9f0d0..7cc43690a3a 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_android.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_android.cc
@@ -163,6 +163,10 @@ bool BrowserAccessibilityAndroid::PlatformIsLeaf() const {
return false;
}
+bool BrowserAccessibilityAndroid::CanFireEvents() const {
+ return true;
+}
+
bool BrowserAccessibilityAndroid::IsCheckable() const {
return HasIntAttribute(ax::mojom::IntAttribute::kCheckedState);
}
diff --git a/chromium/content/browser/accessibility/browser_accessibility_android.h b/chromium/content/browser/accessibility/browser_accessibility_android.h
index a2c8b6cb973..e87b171f578 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_android.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_android.h
@@ -27,6 +27,8 @@ class CONTENT_EXPORT BrowserAccessibilityAndroid : public BrowserAccessibility {
base::string16 GetValue() const override;
bool PlatformIsLeaf() const override;
+ // Android needs events even on objects that are trimmed away.
+ bool CanFireEvents() const override;
bool IsCheckable() const;
bool IsChecked() const;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc b/chromium/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc
index 3d31036acac..40acf2141b1 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_auralinux_unittest.cc
@@ -113,6 +113,161 @@ TEST_F(BrowserAccessibilityAuraLinuxTest, TestCompositeAtkText) {
EXPECT_STREQ((text1_name + text2_name).c_str(), text);
g_free(text);
+ ASSERT_TRUE(ATK_IS_HYPERTEXT(root_atk_object));
+ AtkHypertext* atk_hypertext = ATK_HYPERTEXT(root_atk_object);
+
+ // There should be no hyperlinks in the node and trying to get one should
+ // always return -1.
+ EXPECT_EQ(0, atk_hypertext_get_n_links(atk_hypertext));
+ EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 0));
+ EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, -1));
+ EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 1));
+
+ g_object_unref(root_atk_object);
+
+ manager.reset();
+}
+
+TEST_F(BrowserAccessibilityAuraLinuxTest, TestComplexHypertext) {
+ const std::string text1_name = "One two three.";
+ const std::string combo_box_name = "City:";
+ const std::string combo_box_value = "Happyland";
+ const std::string text2_name = " Four five six.";
+ const std::string check_box_name = "I agree";
+ const std::string check_box_value = "Checked";
+ const std::string button_text_name = "Red";
+ const std::string link_text_name = "Blue";
+ // Each control (combo / check box, button and link) will be represented by an
+ // embedded object character.
+ const base::string16 string16_embed(
+ 1, ui::AXPlatformNodeAuraLinux::kEmbeddedCharacter);
+ const std::string embed = base::UTF16ToUTF8(string16_embed);
+ const std::string root_hypertext =
+ text1_name + embed + text2_name + embed + embed + embed;
+
+ ui::AXNodeData text1;
+ text1.id = 11;
+ text1.role = ax::mojom::Role::kStaticText;
+ text1.SetName(text1_name);
+
+ ui::AXNodeData combo_box;
+ combo_box.id = 12;
+ combo_box.role = ax::mojom::Role::kTextFieldWithComboBox;
+ combo_box.AddState(ax::mojom::State::kEditable);
+ combo_box.SetName(combo_box_name);
+ combo_box.SetValue(combo_box_value);
+
+ ui::AXNodeData text2;
+ text2.id = 13;
+ text2.role = ax::mojom::Role::kStaticText;
+ text2.SetName(text2_name);
+
+ ui::AXNodeData check_box;
+ check_box.id = 14;
+ check_box.role = ax::mojom::Role::kCheckBox;
+ check_box.SetCheckedState(ax::mojom::CheckedState::kTrue);
+ check_box.SetName(check_box_name);
+ check_box.SetValue(check_box_value);
+
+ ui::AXNodeData button, button_text;
+ button.id = 15;
+ button_text.id = 17;
+ button_text.SetName(button_text_name);
+ button.role = ax::mojom::Role::kButton;
+ button_text.role = ax::mojom::Role::kStaticText;
+ button.child_ids.push_back(button_text.id);
+
+ ui::AXNodeData link, link_text;
+ link.id = 16;
+ link_text.id = 18;
+ link_text.SetName(link_text_name);
+ link.role = ax::mojom::Role::kLink;
+ link_text.role = ax::mojom::Role::kStaticText;
+ link.child_ids.push_back(link_text.id);
+
+ ui::AXNodeData root;
+ root.id = 1;
+ root.role = ax::mojom::Role::kRootWebArea;
+ root.child_ids.push_back(text1.id);
+ root.child_ids.push_back(combo_box.id);
+ root.child_ids.push_back(text2.id);
+ root.child_ids.push_back(check_box.id);
+ root.child_ids.push_back(button.id);
+ root.child_ids.push_back(link.id);
+
+ std::unique_ptr<BrowserAccessibilityManager> manager(
+ BrowserAccessibilityManager::Create(
+ MakeAXTreeUpdate(root, text1, combo_box, text2, check_box, button,
+ button_text, link, link_text),
+ nullptr, new BrowserAccessibilityFactory()));
+
+ ui::AXPlatformNodeAuraLinux* root_obj =
+ ToBrowserAccessibilityAuraLinux(manager->GetRoot())->GetNode();
+ AtkObject* root_atk_object(root_obj->GetNativeViewAccessible());
+
+ ASSERT_TRUE(ATK_IS_OBJECT(root_atk_object));
+ ASSERT_TRUE(ATK_IS_TEXT(root_atk_object));
+ g_object_ref(root_atk_object);
+ AtkText* atk_text = ATK_TEXT(root_atk_object);
+
+ EXPECT_EQ(g_utf8_strlen(root_hypertext.c_str(), -1),
+ atk_text_get_character_count(atk_text));
+
+ gchar* text = atk_text_get_text(atk_text, 0, -1);
+ EXPECT_STREQ(root_hypertext.c_str(), text);
+ g_free(text);
+
+ ASSERT_TRUE(ATK_IS_HYPERTEXT(root_atk_object));
+ AtkHypertext* atk_hypertext = ATK_HYPERTEXT(root_atk_object);
+
+ EXPECT_EQ(4, atk_hypertext_get_n_links(atk_hypertext));
+
+ auto verify_atk_link_text = [&](const char* expected_text, int link_index,
+ int expected_start_index) {
+ AtkHyperlink* link = atk_hypertext_get_link(atk_hypertext, link_index);
+ ASSERT_NE(nullptr, link);
+ ASSERT_TRUE(ATK_IS_HYPERLINK(link));
+
+ ASSERT_EQ(atk_hyperlink_get_start_index(link), expected_start_index);
+ ASSERT_EQ(atk_hyperlink_get_end_index(link), expected_start_index + 1);
+
+ AtkObject* object = atk_hyperlink_get_object(link, 0);
+ ASSERT_TRUE(ATK_IS_TEXT(object));
+
+ char* text = atk_text_get_text(ATK_TEXT(object), 0, -1);
+ EXPECT_STREQ(expected_text, text);
+ g_free(text);
+ };
+
+ AtkHyperlink* combo_box_link = atk_hypertext_get_link(atk_hypertext, 0);
+ ASSERT_NE(nullptr, combo_box_link);
+ ASSERT_TRUE(ATK_IS_HYPERLINK(combo_box_link));
+
+ // Get the text of the combo box. It should be its value.
+ verify_atk_link_text(combo_box_value.c_str(), 0, 14);
+
+ // Get the text of the check box. It should be its name.
+ verify_atk_link_text(check_box_name.c_str(), 1, 30);
+
+ // Get the text of the button.
+ verify_atk_link_text(button_text_name.c_str(), 2, 31);
+
+ // Get the text of the link.
+ verify_atk_link_text(link_text_name.c_str(), 3, 32);
+
+ // Now test that all the object indices map back to the correct link indices.
+ EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, -1));
+ EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 0));
+ EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 1));
+ EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 5));
+ EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 13));
+ EXPECT_EQ(0, atk_hypertext_get_link_index(atk_hypertext, 14));
+ EXPECT_EQ(1, atk_hypertext_get_link_index(atk_hypertext, 30));
+ EXPECT_EQ(2, atk_hypertext_get_link_index(atk_hypertext, 31));
+ EXPECT_EQ(3, atk_hypertext_get_link_index(atk_hypertext, 32));
+ EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 33));
+ EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 34));
+
g_object_unref(root_atk_object);
manager.reset();
diff --git a/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm b/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
index 06db282cd74..ec60dd6b8f2 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -985,7 +985,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// Group, radiogroup etc.
if ([self shouldExposeNameInDescription]) {
return base::SysUTF8ToNSString(name);
- } else if (nameFrom == ax::mojom::NameFrom::kContents ||
+ } else if (nameFrom == ax::mojom::NameFrom::kCaption ||
+ nameFrom == ax::mojom::NameFrom::kContents ||
nameFrom == ax::mojom::NameFrom::kRelatedElement ||
nameFrom == ax::mojom::NameFrom::kValue) {
return @"";
@@ -1568,7 +1569,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
ax::mojom::NameFrom nameFrom = static_cast<ax::mojom::NameFrom>(
owner_->GetIntAttribute(ax::mojom::IntAttribute::kNameFrom));
- if (nameFrom != ax::mojom::NameFrom::kRelatedElement)
+ if (nameFrom != ax::mojom::NameFrom::kCaption &&
+ nameFrom != ax::mojom::NameFrom::kRelatedElement)
return false;
std::vector<int32_t> labelledby_ids =
@@ -2173,7 +2175,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// On Mac OS X, the accessible name of an object is exposed as its
// title if it comes from visible text, and as its description
// otherwise, but never both.
- if (nameFrom == ax::mojom::NameFrom::kContents ||
+ if (nameFrom == ax::mojom::NameFrom::kCaption ||
+ nameFrom == ax::mojom::NameFrom::kContents ||
nameFrom == ax::mojom::NameFrom::kRelatedElement ||
nameFrom == ax::mojom::NameFrom::kValue) {
return NSStringForStringAttribute(owner_,
@@ -2193,7 +2196,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
owner_->GetIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds);
ax::mojom::NameFrom nameFrom = static_cast<ax::mojom::NameFrom>(
owner_->GetIntAttribute(ax::mojom::IntAttribute::kNameFrom));
- if (nameFrom == ax::mojom::NameFrom::kRelatedElement &&
+ if ((nameFrom == ax::mojom::NameFrom::kCaption ||
+ nameFrom == ax::mojom::NameFrom::kRelatedElement) &&
labelledby_ids.size() == 1) {
BrowserAccessibility* titleElement =
owner_->manager()->GetFromID(labelledby_ids[0]);
@@ -2239,6 +2243,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return @"";
} else if (owner_->HasIntAttribute(ax::mojom::IntAttribute::kCheckedState) ||
[role isEqualToString:NSAccessibilityRadioButtonRole]) {
+ // On Mac, tabs are exposed as radio buttons, and are treated as checkable.
int value;
const auto checkedState = static_cast<ax::mojom::CheckedState>(
owner_->GetIntAttribute(ax::mojom::IntAttribute::kCheckedState));
diff --git a/chromium/content/browser/accessibility/browser_accessibility_com_win.cc b/chromium/content/browser/accessibility/browser_accessibility_com_win.cc
index c874c05dd94..edcd56cc1ba 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -20,7 +20,7 @@
#include "content/common/accessibility_messages.h"
#include "content/public/common/content_client.h"
#include "third_party/skia/include/core/SkColor.h"
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
#include "ui/accessibility/ax_role_properties.h"
#include "ui/accessibility/ax_text_utils.h"
#include "ui/base/win/accessibility_ids_win.h"
@@ -95,7 +95,8 @@ IFACEMETHODIMP BrowserAccessibilityComWin::get_appName(BSTR* app_name) {
std::vector<std::string> product_components =
base::SplitString(GetContentClient()->GetProduct(), "/",
base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- DCHECK_EQ(2U, product_components.size());
+ // |GetProduct| will return an empty string if we are running the content
+ // shell instead of Chrome.
if (product_components.size() != 2)
return E_FAIL;
*app_name = SysAllocString(base::UTF8ToUTF16(product_components[0]).c_str());
@@ -114,7 +115,8 @@ IFACEMETHODIMP BrowserAccessibilityComWin::get_appVersion(BSTR* app_version) {
std::vector<std::string> product_components =
base::SplitString(GetContentClient()->GetProduct(), "/",
base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- DCHECK_EQ(2U, product_components.size());
+ // |GetProduct| will return an empty string if we are running the content
+ // shell instead of Chrome.
if (product_components.size() != 2)
return E_FAIL;
*app_version =
diff --git a/chromium/content/browser/accessibility/browser_accessibility_mac.h b/chromium/content/browser/accessibility/browser_accessibility_mac.h
index d2cc8d75974..0e00dbdf874 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_mac.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_mac.h
@@ -38,11 +38,6 @@ class BrowserAccessibilityMac : public BrowserAccessibility {
return browser_accessibility_cocoa_;
}
- // Detach the BrowserAccessibilityCocoa object and then recreate it.
- // This is only used to work around VoiceOver bugs by forcing VoiceOver
- // to rebuild its internal state.
- void RecreateNativeObject();
-
private:
// This gives BrowserAccessibility::Create access to the class constructor.
friend class BrowserAccessibility;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_mac.mm b/chromium/content/browser/accessibility/browser_accessibility_mac.mm
index 1c5d9171a4f..ca5da8d26c8 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_mac.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_mac.mm
@@ -82,21 +82,6 @@ BrowserAccessibility* BrowserAccessibilityMac::PlatformGetChild(
return nullptr;
}
-void BrowserAccessibilityMac::RecreateNativeObject() {
- if (!browser_accessibility_cocoa_)
- return;
-
- // Preserve the children so that recreating the native object doesn't
- // end up recreating the whole subtree.
- base::scoped_nsobject<NSMutableArray> children;
- [browser_accessibility_cocoa_ swapChildren:&children];
- [browser_accessibility_cocoa_ detach];
- [browser_accessibility_cocoa_ release];
- browser_accessibility_cocoa_ = [[BrowserAccessibilityCocoa alloc]
- initWithObject:this];
- [browser_accessibility_cocoa_ swapChildren:&children];
-}
-
const BrowserAccessibilityCocoa*
ToBrowserAccessibilityCocoa(const BrowserAccessibility* obj) {
DCHECK(obj);
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager.cc b/chromium/content/browser/accessibility/browser_accessibility_manager.cc
index 3ab440e85ad..568883f0915 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager.cc
@@ -5,10 +5,12 @@
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include <stddef.h>
+#include <map>
#include <utility>
#include "base/debug/crash_logging.h"
#include "base/logging.h"
+#include "base/no_destructor.h"
#include "build/build_config.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/common/accessibility_messages.h"
@@ -21,8 +23,7 @@ namespace content {
namespace {
// Map from AXTreeID to BrowserAccessibilityManager
-using AXTreeIDMap = base::hash_map<ui::AXTreeIDRegistry::AXTreeID,
- BrowserAccessibilityManager*>;
+using AXTreeIDMap = std::map<ui::AXTreeID, BrowserAccessibilityManager*>;
base::LazyInstance<AXTreeIDMap>::Leaky g_ax_tree_id_map =
LAZY_INSTANCE_INITIALIZER;
@@ -45,13 +46,13 @@ ui::AXTreeUpdate MakeAXTreeUpdate(
const ui::AXNodeData& node10 /* = ui::AXNodeData() */,
const ui::AXNodeData& node11 /* = ui::AXNodeData() */,
const ui::AXNodeData& node12 /* = ui::AXNodeData() */) {
- CR_DEFINE_STATIC_LOCAL(ui::AXNodeData, empty_data, ());
- int32_t no_id = empty_data.id;
+ static base::NoDestructor<ui::AXNodeData> empty_data;
+ int32_t no_id = empty_data->id;
ui::AXTreeUpdate update;
ui::AXTreeData tree_data;
- tree_data.tree_id = 1;
- tree_data.focused_tree_id = 1;
+ tree_data.tree_id = ui::AXTreeID::FromString("1");
+ tree_data.focused_tree_id = ui::AXTreeID::FromString("1");
update.tree_data = tree_data;
update.has_tree_data = true;
update.root_id = node1.id;
@@ -106,7 +107,7 @@ BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::FromID(
- ui::AXTreeIDRegistry::AXTreeID ax_tree_id) {
+ ui::AXTreeID ax_tree_id) {
AXTreeIDMap* ax_tree_id_map = g_ax_tree_id_map.Pointer();
auto iter = ax_tree_id_map->find(ax_tree_id);
return iter == ax_tree_id_map->end() ? nullptr : iter->second;
@@ -123,7 +124,7 @@ BrowserAccessibilityManager::BrowserAccessibilityManager(
last_focused_node_(nullptr),
last_focused_manager_(nullptr),
connected_to_parent_tree_node_(false),
- ax_tree_id_(ui::AXTreeIDRegistry::kNoAXTreeID),
+ ax_tree_id_(ui::AXTreeIDUnknown()),
device_scale_factor_(1.0f),
use_custom_device_scale_factor_for_testing_(false) {
SetTree(tree_.get());
@@ -140,7 +141,7 @@ BrowserAccessibilityManager::BrowserAccessibilityManager(
user_is_navigating_away_(false),
last_focused_node_(nullptr),
last_focused_manager_(nullptr),
- ax_tree_id_(ui::AXTreeIDRegistry::kNoAXTreeID),
+ ax_tree_id_(ui::AXTreeIDUnknown()),
device_scale_factor_(1.0f),
use_custom_device_scale_factor_for_testing_(false) {
SetTree(tree_.get());
@@ -257,7 +258,7 @@ BrowserAccessibilityManager::GetParentNodeFromParentTree() {
if (!GetRoot())
return nullptr;
- int parent_tree_id = GetTreeData().parent_tree_id;
+ ui::AXTreeID parent_tree_id = GetTreeData().parent_tree_id;
BrowserAccessibilityManager* parent_manager =
BrowserAccessibilityManager::FromID(parent_tree_id);
if (!parent_manager)
@@ -274,8 +275,9 @@ BrowserAccessibilityManager::GetParentNodeFromParentTree() {
for (int32_t host_node_id : host_node_ids) {
BrowserAccessibility* parent_node = parent_manager->GetFromID(host_node_id);
if (parent_node) {
- DCHECK_EQ(ax_tree_id_, parent_node->GetIntAttribute(
- ax::mojom::IntAttribute::kChildTreeId));
+ DCHECK_EQ(ax_tree_id_,
+ AXTreeID::FromString(parent_node->GetStringAttribute(
+ ax::mojom::StringAttribute::kChildTreeId)));
return parent_node;
}
}
@@ -374,7 +376,7 @@ void BrowserAccessibilityManager::OnAccessibilityEvents(
// Fire any events related to changes to the tree.
for (auto targeted_event : *this) {
BrowserAccessibility* event_target = GetFromAXNode(targeted_event.node);
- if (!event_target)
+ if (!event_target || !event_target->CanFireEvents())
continue;
FireGeneratedEvent(targeted_event.event_params.event, event_target);
@@ -387,7 +389,7 @@ void BrowserAccessibilityManager::OnAccessibilityEvents(
// Fire the native event.
BrowserAccessibility* event_target = GetFromID(event.id);
- if (!event_target)
+ if (!event_target || !event_target->CanFireEvents())
return;
if (event.event_type == ax::mojom::Event::kHover)
@@ -499,10 +501,10 @@ BrowserAccessibility* BrowserAccessibilityManager::GetFocus() {
BrowserAccessibilityManager* root_manager = GetRootManager();
if (!root_manager)
root_manager = this;
- int32_t focused_tree_id = root_manager->GetTreeData().focused_tree_id;
+ ui::AXTreeID focused_tree_id = root_manager->GetTreeData().focused_tree_id;
BrowserAccessibilityManager* focused_manager = nullptr;
- if (focused_tree_id)
+ if (focused_tree_id != ui::AXTreeIDUnknown())
focused_manager = BrowserAccessibilityManager::FromID(focused_tree_id);
// BrowserAccessibilityManager::FromID(focused_tree_id) may return nullptr
@@ -520,10 +522,11 @@ BrowserAccessibilityManager::GetFocusFromThisOrDescendantFrame() {
if (!obj)
return GetRoot();
- if (obj->HasIntAttribute(ax::mojom::IntAttribute::kChildTreeId)) {
+ if (obj->HasStringAttribute(ax::mojom::StringAttribute::kChildTreeId)) {
+ AXTreeID child_tree_id = AXTreeID::FromString(
+ obj->GetStringAttribute(ax::mojom::StringAttribute::kChildTreeId));
BrowserAccessibilityManager* child_manager =
- BrowserAccessibilityManager::FromID(
- obj->GetIntAttribute(ax::mojom::IntAttribute::kChildTreeId));
+ BrowserAccessibilityManager::FromID(child_tree_id);
if (child_manager)
return child_manager->GetFocusFromThisOrDescendantFrame();
}
@@ -1115,7 +1118,8 @@ void BrowserAccessibilityManager::OnAtomicUpdateFinished(
const std::vector<ui::AXTreeDelegate::Change>& changes) {
AXEventGenerator::OnAtomicUpdateFinished(tree, root_changed, changes);
bool ax_tree_id_changed = false;
- if (GetTreeData().tree_id != -1 && GetTreeData().tree_id != ax_tree_id_) {
+ if (GetTreeData().tree_id != ui::AXTreeIDUnknown() &&
+ GetTreeData().tree_id != ax_tree_id_) {
g_ax_tree_id_map.Get().erase(ax_tree_id_);
ax_tree_id_ = GetTreeData().tree_id;
g_ax_tree_id_map.Get().insert(std::make_pair(ax_tree_id_, this));
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager.h b/chromium/content/browser/accessibility/browser_accessibility_manager.h
index 397df50cb4b..76aec4cef74 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager.h
@@ -120,8 +120,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXEventGenerator {
BrowserAccessibilityDelegate* delegate,
BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory());
- static BrowserAccessibilityManager* FromID(
- ui::AXTreeIDRegistry::AXTreeID ax_tree_id);
+ static BrowserAccessibilityManager* FromID(ui::AXTreeID ax_tree_id);
~BrowserAccessibilityManager() override;
@@ -340,7 +339,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXEventGenerator {
int end_offset);
// Accessors.
- ui::AXTreeIDRegistry::AXTreeID ax_tree_id() const { return ax_tree_id_; }
+ ui::AXTreeID ax_tree_id() const { return ax_tree_id_; }
float device_scale_factor() const { return device_scale_factor_; }
ui::AXTree* ax_tree() const { return tree_.get(); }
@@ -441,7 +440,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXEventGenerator {
// last object found by an asynchronous hit test. Subsequent hit test
// requests that remain within this object's bounds will return the same
// object, but will also trigger a new asynchronous hit test request.
- int last_hover_ax_tree_id_;
+ ui::AXTreeID last_hover_ax_tree_id_;
int last_hover_node_id_;
gfx::Rect last_hover_bounds_;
@@ -451,7 +450,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXEventGenerator {
bool connected_to_parent_tree_node_;
// The global ID of this accessibility tree.
- ui::AXTreeIDRegistry::AXTreeID ax_tree_id_;
+ ui::AXTreeID ax_tree_id_;
// The device scale factor for the view associated with this frame,
// cached each time there's any update to the accessibility tree.
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc
index f1ba43ffb36..ed8b663a4d7 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -205,6 +205,7 @@ void BrowserAccessibilityManagerAndroid::FireGeneratedEvent(
case Event::INVALID_STATUS_CHANGED:
case Event::LIVE_REGION_CHANGED:
case Event::LIVE_REGION_CREATED:
+ case Event::LOAD_START:
case Event::MENU_ITEM_SELECTED:
case Event::NAME_CHANGED:
case Event::OTHER_ATTRIBUTE_CHANGED:
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
index 1caa0621b77..74d1bd60af5 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
@@ -54,10 +54,55 @@ ui::AXTreeUpdate
void BrowserAccessibilityManagerAuraLinux::FireFocusEvent(
BrowserAccessibility* node) {
BrowserAccessibilityManager::FireFocusEvent(node);
- if (node->IsNative()) {
- ToBrowserAccessibilityAuraLinux(node)->GetNode()->NotifyAccessibilityEvent(
- ax::mojom::Event::kFocus);
- }
+ FireEvent(node, ax::mojom::Event::kFocus);
+}
+
+void BrowserAccessibilityManagerAuraLinux::FireSelectedEvent(
+ BrowserAccessibility* node) {
+ // Some browser UI widgets, such as the omnibox popup, only send notifications
+ // when they become selected. In contrast elements in a page, such as options
+ // in the select element, also send notifications when they become unselected.
+ // Since AXPlatformNodeAuraLinux must handle firing a platform event for the
+ // unselected case, we can safely ignore the unselected case for rendered
+ // elements.
+ if (!node->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
+ return;
+
+ FireEvent(node, ax::mojom::Event::kSelection);
+}
+
+void BrowserAccessibilityManagerAuraLinux::FireLoadingEvent(
+ BrowserAccessibility* node,
+ bool is_loading) {
+ if (!node->IsNative())
+ return;
+
+ gfx::NativeViewAccessible obj = node->GetNativeViewAccessible();
+ if (!ATK_IS_OBJECT(obj))
+ return;
+
+ atk_object_notify_state_change(obj, ATK_STATE_BUSY, is_loading);
+ if (!is_loading)
+ g_signal_emit_by_name(obj, "load_complete");
+}
+
+void BrowserAccessibilityManagerAuraLinux::FireExpandedEvent(
+ BrowserAccessibility* node,
+ bool is_expanded) {
+ if (!node->IsNative())
+ return;
+
+ ToBrowserAccessibilityAuraLinux(node)->GetNode()->OnExpandedStateChanged(
+ is_expanded);
+}
+
+void BrowserAccessibilityManagerAuraLinux::FireEvent(BrowserAccessibility* node,
+ ax::mojom::Event event) {
+ if (!node->IsNative())
+ return;
+
+ ToBrowserAccessibilityAuraLinux(node)->GetNode()->NotifyAccessibilityEvent(
+ event);
}
void BrowserAccessibilityManagerAuraLinux::FireBlinkEvent(
@@ -71,7 +116,34 @@ void BrowserAccessibilityManagerAuraLinux::FireGeneratedEvent(
AXEventGenerator::Event event_type,
BrowserAccessibility* node) {
BrowserAccessibilityManager::FireGeneratedEvent(event_type, node);
- // Need to implement.
+
+ switch (event_type) {
+ case Event::CHECKED_STATE_CHANGED:
+ FireEvent(node, ax::mojom::Event::kCheckedStateChanged);
+ break;
+ case Event::COLLAPSED:
+ FireExpandedEvent(node, false);
+ break;
+ case Event::EXPANDED:
+ FireExpandedEvent(node, true);
+ break;
+ case Event::LOAD_COMPLETE:
+ FireLoadingEvent(node, false);
+ break;
+ case Event::LOAD_START:
+ FireLoadingEvent(node, true);
+ break;
+ case Event::MENU_ITEM_SELECTED:
+ case Event::SELECTED_CHANGED:
+ FireSelectedEvent(node);
+ break;
+ case Event::VALUE_CHANGED:
+ FireEvent(node, ax::mojom::Event::kValueChanged);
+ break;
+ default:
+ // Need to implement.
+ break;
+ }
}
void BrowserAccessibilityManagerAuraLinux::OnAtomicUpdateFinished(
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h
index 7de682076c4..a6e857981fc 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_auralinux.h
@@ -34,6 +34,10 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAuraLinux
void FireGeneratedEvent(AXEventGenerator::Event event_type,
BrowserAccessibility* node) override;
+ void FireSelectedEvent(BrowserAccessibility* node);
+ void FireExpandedEvent(BrowserAccessibility* node, bool is_expanded);
+ void FireLoadingEvent(BrowserAccessibility* node, bool is_loading);
+
AtkObject* parent_object() { return parent_object_; }
protected:
@@ -44,6 +48,8 @@ class CONTENT_EXPORT BrowserAccessibilityManagerAuraLinux
const std::vector<ui::AXTreeDelegate::Change>& changes) override;
private:
+ void FireEvent(BrowserAccessibility* node, ax::mojom::Event event);
+
AtkObject* parent_object_;
// Give BrowserAccessibilityManager::Create access to our constructor.
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
index 09cb7f8a55d..ace4792b686 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -12,10 +12,12 @@
#import "base/mac/sdk_forward_declarations.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#import "content/browser/accessibility/browser_accessibility_cocoa.h"
#import "content/browser/accessibility/browser_accessibility_mac.h"
#include "content/common/accessibility_messages.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#include "ui/accessibility/ax_role_properties.h"
@@ -337,8 +339,8 @@ void BrowserAccessibilityManagerMac::FireGeneratedEvent(
// Use native VoiceOver support for live regions.
base::scoped_nsobject<BrowserAccessibilityCocoa> retained_node(
[native_node retain]);
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(
[](base::scoped_nsobject<BrowserAccessibilityCocoa> node) {
if (node && [node instanceActive]) {
@@ -376,6 +378,7 @@ void BrowserAccessibilityManagerMac::FireGeneratedEvent(
case Event::DESCRIPTION_CHANGED:
case Event::DOCUMENT_TITLE_CHANGED:
case Event::LIVE_REGION_NODE_CHANGED:
+ case Event::LOAD_START:
case Event::NAME_CHANGED:
case Event::OTHER_ATTRIBUTE_CHANGED:
case Event::RELATED_NODE_CHANGED:
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
index 1a3eecf5de2..166426aed7e 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -19,10 +19,6 @@
namespace content {
-// See OnScreenReaderHoneyPotQueried, below.
-bool g_screen_reader_honeypot_queried = false;
-bool g_acc_name_called = false;
-
// static
BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
const ui::AXTreeUpdate& initial_tree,
@@ -44,7 +40,6 @@ BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin(
load_complete_pending_(false) {
ui::win::CreateATLModuleIfNeeded();
Initialize(initial_tree);
- ui::GetIAccessible2UsageObserverList().AddObserver(this);
}
BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
@@ -52,7 +47,6 @@ BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() {
// destructor, otherwise our overrides of functions like
// OnNodeWillBeDeleted won't be called.
tree_.reset(NULL);
- ui::GetIAccessible2UsageObserverList().RemoveObserver(this);
}
// static
@@ -76,38 +70,6 @@ HWND BrowserAccessibilityManagerWin::GetParentHWND() {
return delegate->AccessibilityGetAcceleratedWidget();
}
-void BrowserAccessibilityManagerWin::OnIAccessible2Used() {
- // When IAccessible2 APIs have been used elsewhere in the codebase,
- // enable basic web accessibility support. (Full screen reader support is
- // detected later when specific more advanced APIs are accessed.)
- BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
- ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
-}
-
-void BrowserAccessibilityManagerWin::OnScreenReaderHoneyPotQueried() {
- // We used to trust this as a signal that a screen reader is running,
- // but it's been abused. Now only enable accessibility if we also
- // detect a call to get_accName.
- if (g_screen_reader_honeypot_queried)
- return;
- g_screen_reader_honeypot_queried = true;
- if (g_acc_name_called) {
- BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
- ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
- }
-}
-
-void BrowserAccessibilityManagerWin::OnAccNameCalled() {
- // See OnScreenReaderHoneyPotQueried, above.
- if (g_acc_name_called)
- return;
- g_acc_name_called = true;
- if (g_screen_reader_honeypot_queried) {
- BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
- ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
- }
-}
-
void BrowserAccessibilityManagerWin::UserIsReloading() {
if (GetRoot())
FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_RELOAD, GetRoot());
@@ -217,6 +179,7 @@ void BrowserAccessibilityManagerWin::FireGeneratedEvent(
case Event::INVALID_STATUS_CHANGED:
case Event::LIVE_REGION_CREATED:
case Event::LIVE_REGION_NODE_CHANGED:
+ case Event::LOAD_START:
case Event::MENU_ITEM_SELECTED:
case Event::NAME_CHANGED:
case Event::OTHER_ATTRIBUTE_CHANGED:
@@ -235,6 +198,9 @@ void BrowserAccessibilityManagerWin::FireGeneratedEvent(
void BrowserAccessibilityManagerWin::FireWinAccessibilityEvent(
LONG win_event_type,
BrowserAccessibility* node) {
+ if (!node->CanFireEvents())
+ return;
+
// If there's no root delegate, this may be a new frame that hasn't
// yet been swapped in or added to the frame tree. Suppress firing events
// until then.
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_win.h b/chromium/content/browser/accessibility/browser_accessibility_manager_win.h
index 76d343421cc..88fd18b431d 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_win.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -18,8 +18,7 @@ class BrowserAccessibilityWin;
// Manages a tree of BrowserAccessibilityWin objects.
class CONTENT_EXPORT BrowserAccessibilityManagerWin
- : public BrowserAccessibilityManager,
- public ui::IAccessible2UsageObserver {
+ : public BrowserAccessibilityManager {
public:
BrowserAccessibilityManagerWin(
const ui::AXTreeUpdate& initial_tree,
@@ -33,11 +32,6 @@ class CONTENT_EXPORT BrowserAccessibilityManagerWin
// Get the closest containing HWND.
HWND GetParentHWND();
- // IAccessible2UsageObserver
- void OnIAccessible2Used() override;
- void OnScreenReaderHoneyPotQueried() override;
- void OnAccNameCalled() override;
-
// BrowserAccessibilityManager methods
void UserIsReloading() override;
BrowserAccessibility* GetFocus() override;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_position.cc b/chromium/content/browser/accessibility/browser_accessibility_position.cc
index 74ba6636e49..8d11df28630 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_position.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_position.cc
@@ -36,7 +36,7 @@ void BrowserAccessibilityPosition::AnchorChild(int child_index,
DCHECK(child_id);
if (!GetAnchor() || child_index < 0 || child_index >= AnchorChildCount()) {
- *tree_id = INVALID_TREE_ID;
+ *tree_id = ui::AXTreeIDUnknown();
*child_id = INVALID_ANCHOR_ID;
return;
}
@@ -74,7 +74,7 @@ void BrowserAccessibilityPosition::AnchorParent(AXTreeID* tree_id,
DCHECK(parent_id);
if (!GetAnchor() || !GetAnchor()->PlatformGetParent()) {
- *tree_id = AXPosition::INVALID_TREE_ID;
+ *tree_id = ui::AXTreeIDUnknown();
*parent_id = AXPosition::INVALID_ANCHOR_ID;
return;
}
@@ -87,7 +87,7 @@ void BrowserAccessibilityPosition::AnchorParent(AXTreeID* tree_id,
BrowserAccessibility* BrowserAccessibilityPosition::GetNodeInTree(
AXTreeID tree_id,
int32_t node_id) const {
- if (tree_id == AXPosition::INVALID_TREE_ID ||
+ if (tree_id == ui::AXTreeIDUnknown() ||
node_id == AXPosition::INVALID_ANCHOR_ID) {
return nullptr;
}
diff --git a/chromium/content/browser/accessibility/browser_accessibility_position.h b/chromium/content/browser/accessibility/browser_accessibility_position.h
index 89ea6d8e407..d5a7a684dab 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_position.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_position.h
@@ -17,7 +17,7 @@ namespace content {
class BrowserAccessibility;
-using AXTreeID = ui::AXTreeIDRegistry::AXTreeID;
+using AXTreeID = ui::AXTreeID;
class BrowserAccessibilityPosition
: public ui::AXPosition<BrowserAccessibilityPosition,
diff --git a/chromium/content/browser/accessibility/browser_accessibility_state_impl.cc b/chromium/content/browser/accessibility/browser_accessibility_state_impl.cc
index 15faf68df8a..2c185d0ad17 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_state_impl.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_state_impl.cc
@@ -12,6 +12,7 @@
#include "build/build_config.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "ui/accessibility/platform/ax_platform_node.h"
@@ -67,6 +68,9 @@ BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl()
// Hook ourselves up to observe ax mode changes.
ui::AXPlatformNode::AddAXModeObserver(this);
+ // Let each platform do its own initialization.
+ PlatformInitialize();
+
#if defined(OS_WIN)
// The delay is necessary because assistive technology sometimes isn't
// detected until after the user interacts in some way, so a reasonable delay
@@ -78,8 +82,8 @@ BrowserAccessibilityStateImpl::BrowserAccessibilityStateImpl()
#else
// On all other platforms, UpdateHistograms should be called on the UI
// thread because it needs to be able to access PrefService.
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&BrowserAccessibilityStateImpl::UpdateHistograms, this),
base::TimeDelta::FromSeconds(ACCESSIBILITY_HISTOGRAM_DELAY_SECS));
#endif
@@ -167,6 +171,8 @@ ui::AXMode BrowserAccessibilityStateImpl::GetAccessibilityMode() const {
}
#if !defined(OS_WIN) && !defined(OS_MACOSX)
+void BrowserAccessibilityStateImpl::PlatformInitialize() {}
+
void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
}
#endif
diff --git a/chromium/content/browser/accessibility/browser_accessibility_state_impl.h b/chromium/content/browser/accessibility/browser_accessibility_state_impl.h
index 9b57bbd68d8..1b592367cb8 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_state_impl.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_state_impl.h
@@ -11,8 +11,8 @@
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "content/public/browser/browser_accessibility_state.h"
+#include "ui/accessibility/ax_mode.h"
#include "ui/accessibility/ax_mode_observer.h"
-#include "ui/accessibility/ax_modes.h"
namespace content {
@@ -84,6 +84,7 @@ class CONTENT_EXPORT BrowserAccessibilityStateImpl
// Leaky singleton, destructor generally won't be called.
~BrowserAccessibilityStateImpl() override;
+ void PlatformInitialize();
void UpdatePlatformSpecificHistograms();
ui::AXMode accessibility_mode_;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_state_impl_mac.mm b/chromium/content/browser/accessibility/browser_accessibility_state_impl_mac.mm
index e3a743e11a9..262083f1234 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_state_impl_mac.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_state_impl_mac.mm
@@ -18,6 +18,8 @@
namespace content {
+void BrowserAccessibilityStateImpl::PlatformInitialize() {}
+
void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
// NOTE: This function is running on the file thread.
NSWorkspace* workspace = [NSWorkspace sharedWorkspace];
diff --git a/chromium/content/browser/accessibility/browser_accessibility_state_impl_win.cc b/chromium/content/browser/accessibility/browser_accessibility_state_impl_win.cc
index df3b54be3ca..16314d71645 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_state_impl_win.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_state_impl_win.cc
@@ -15,9 +15,65 @@
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
+#include "ui/accessibility/platform/ax_platform_node_win.h"
namespace content {
+namespace {
+
+// Enables accessibility based on three possible clues that indicate
+// accessibility API usage.
+//
+// TODO(dmazzoni): Rename IAccessible2UsageObserver to something more general.
+class WindowsAccessibilityEnabler : public ui::IAccessible2UsageObserver {
+ public:
+ WindowsAccessibilityEnabler() {}
+
+ private:
+ // IAccessible2UsageObserver
+ void OnIAccessible2Used() override {
+ // When IAccessible2 APIs have been used elsewhere in the codebase,
+ // enable basic web accessibility support. (Full screen reader support is
+ // detected later when specific more advanced APIs are accessed.)
+ BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
+ ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
+ }
+
+ void OnScreenReaderHoneyPotQueried() override {
+ // We used to trust this as a signal that a screen reader is running,
+ // but it's been abused. Now only enable accessibility if we also
+ // detect a call to get_accName.
+ if (screen_reader_honeypot_queried_)
+ return;
+ screen_reader_honeypot_queried_ = true;
+ if (acc_name_called_) {
+ BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
+ ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
+ }
+ }
+
+ void OnAccNameCalled() override {
+ // See OnScreenReaderHoneyPotQueried, above.
+ if (acc_name_called_)
+ return;
+ acc_name_called_ = true;
+ if (screen_reader_honeypot_queried_) {
+ BrowserAccessibilityStateImpl::GetInstance()->AddAccessibilityModeFlags(
+ ui::AXMode::kNativeAPIs | ui::AXMode::kWebContents);
+ }
+ }
+
+ bool screen_reader_honeypot_queried_ = false;
+ bool acc_name_called_ = false;
+};
+
+} // namespace
+
+void BrowserAccessibilityStateImpl::PlatformInitialize() {
+ ui::GetIAccessible2UsageObserverList().AddObserver(
+ new WindowsAccessibilityEnabler());
+}
+
void BrowserAccessibilityStateImpl::UpdatePlatformSpecificHistograms() {
// NOTE: this method is run from the file thread to reduce jank, since
// there's no guarantee these system calls will return quickly. Be careful
diff --git a/chromium/content/browser/accessibility/browser_accessibility_unittest.cc b/chromium/content/browser/accessibility/browser_accessibility_unittest.cc
new file mode 100644
index 00000000000..af607ed106c
--- /dev/null
+++ b/chromium/content/browser/accessibility/browser_accessibility_unittest.cc
@@ -0,0 +1,66 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/accessibility/browser_accessibility.h"
+
+#include "build/build_config.h"
+#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class BrowserAccessibilityTest : public testing::Test {
+ public:
+ BrowserAccessibilityTest();
+ ~BrowserAccessibilityTest() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityTest);
+};
+
+BrowserAccessibilityTest::BrowserAccessibilityTest() {}
+
+BrowserAccessibilityTest::~BrowserAccessibilityTest() {}
+
+TEST_F(BrowserAccessibilityTest, TestCanFireEvents) {
+ ui::AXNodeData text1;
+ text1.id = 111;
+ text1.role = ax::mojom::Role::kStaticText;
+ text1.SetName("One two three.");
+
+ ui::AXNodeData para1;
+ para1.id = 11;
+ para1.role = ax::mojom::Role::kParagraph;
+ para1.child_ids.push_back(text1.id);
+
+ ui::AXNodeData root;
+ root.id = 1;
+ root.role = ax::mojom::Role::kRootWebArea;
+ root.child_ids.push_back(para1.id);
+
+ std::unique_ptr<BrowserAccessibilityManager> manager(
+ BrowserAccessibilityManager::Create(MakeAXTreeUpdate(root, para1, text1),
+ nullptr,
+ new BrowserAccessibilityFactory()));
+
+ BrowserAccessibility* root_obj = manager->GetRoot();
+ EXPECT_FALSE(root_obj->PlatformIsLeaf());
+ EXPECT_TRUE(root_obj->CanFireEvents());
+
+ BrowserAccessibility* para_obj = root_obj->PlatformGetChild(0);
+ EXPECT_TRUE(para_obj->CanFireEvents());
+#if defined(OS_ANDROID)
+ EXPECT_TRUE(para_obj->PlatformIsLeaf());
+#else
+ EXPECT_FALSE(para_obj->PlatformIsLeaf());
+#endif
+
+ BrowserAccessibility* text_obj = manager->GetFromID(111);
+ EXPECT_TRUE(text_obj->PlatformIsLeaf());
+ EXPECT_TRUE(text_obj->CanFireEvents());
+
+ manager.reset();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.cc
index 76f0ccee205..77b9831fee4 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.cc
+++ b/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -142,7 +142,8 @@ std::vector<int> DumpAccessibilityTestBase::DiffLines(
void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives(
const std::string& test_html,
std::vector<Filter>* filters,
- std::vector<std::string>* wait_for) {
+ std::vector<std::string>* wait_for,
+ std::vector<std::string>* run_until) {
for (const std::string& line :
base::SplitString(test_html, "\n", base::TRIM_WHITESPACE,
base::SPLIT_WANT_ALL)) {
@@ -150,6 +151,7 @@ void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives(
const std::string& allow_str = formatter_->GetAllowString();
const std::string& deny_str = formatter_->GetDenyString();
const std::string& wait_str = "@WAIT-FOR:";
+ const std::string& until_str = "@RUN-UNTIL-EVENT:";
if (base::StartsWith(line, allow_empty_str,
base::CompareCase::SENSITIVE)) {
filters->push_back(
@@ -168,6 +170,9 @@ void DumpAccessibilityTestBase::ParseHtmlForExtraDirectives(
} else if (base::StartsWith(line, wait_str,
base::CompareCase::SENSITIVE)) {
wait_for->push_back(line.substr(wait_str.size()));
+ } else if (base::StartsWith(line, until_str,
+ base::CompareCase::SENSITIVE)) {
+ run_until->push_back(line.substr(until_str.size()));
}
}
}
@@ -254,9 +259,10 @@ void DumpAccessibilityTestBase::RunTestForPlatform(
// Parse filters and other directives in the test file.
std::vector<std::string> wait_for;
+ std::vector<std::string> run_until;
filters_.clear();
AddDefaultFilters(&filters_);
- ParseHtmlForExtraDirectives(html_contents, &filters_, &wait_for);
+ ParseHtmlForExtraDirectives(html_contents, &filters_, &wait_for, &run_until);
// Get the test URL.
GURL url(embedded_test_server()->GetURL(
@@ -354,7 +360,7 @@ void DumpAccessibilityTestBase::RunTestForPlatform(
}
// Call the subclass to dump the output.
- std::vector<std::string> actual_lines = Dump();
+ std::vector<std::string> actual_lines = Dump(run_until);
std::string actual_contents_for_output =
base::JoinString(actual_lines, "\n") + "\n";
diff --git a/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h b/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h
index 0dfb953b1a4..35a8e57b8be 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h
+++ b/chromium/content/browser/accessibility/dump_accessibility_browsertest_base.h
@@ -47,7 +47,8 @@ class DumpAccessibilityTestBase : public ContentBrowserTest {
// including the load complete accessibility event. The subclass should
// dump whatever that specific test wants to dump, returning the result
// as a sequence of strings.
- virtual std::vector<std::string> Dump() = 0;
+ virtual std::vector<std::string> Dump(
+ std::vector<std::string>& run_until) = 0;
// Add the default filters that are applied to all tests.
virtual void AddDefaultFilters(
@@ -92,7 +93,8 @@ class DumpAccessibilityTestBase : public ContentBrowserTest {
void ParseHtmlForExtraDirectives(
const std::string& test_html,
std::vector<AccessibilityTreeFormatter::Filter>* filters,
- std::vector<std::string>* wait_for);
+ std::vector<std::string>* wait_for,
+ std::vector<std::string>* run_until);
// Create the right AccessibilityTreeFormatter subclass.
AccessibilityTreeFormatter* CreateAccessibilityTreeFormatter();
diff --git a/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index b914cec0d63..b5d3af0d4b5 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -69,7 +69,7 @@ class DumpAccessibilityEventsTest : public DumpAccessibilityTestBase {
base::ASCIIToUTF16("EVENT_OBJECT_FOCUS*DOCUMENT*"), Filter::DENY));
}
- std::vector<std::string> Dump() override;
+ std::vector<std::string> Dump(std::vector<std::string>& run_until) override;
void OnDiffFailed() override;
void RunEventTest(const base::FilePath::CharType* file_path);
@@ -79,13 +79,31 @@ class DumpAccessibilityEventsTest : public DumpAccessibilityTestBase {
base::string16 final_tree_;
};
-std::vector<std::string> DumpAccessibilityEventsTest::Dump() {
+bool IsRecordingComplete(AccessibilityEventRecorder& event_recorder,
+ std::vector<std::string>& run_until) {
+ // If no @RUN-UNTIL-EVENT directives, then having any events is enough.
+ if (run_until.empty())
+ return true;
+
+ std::vector<std::string> event_logs = event_recorder.event_logs();
+
+ for (size_t i = 0; i < event_logs.size(); ++i)
+ for (size_t j = 0; j < run_until.size(); ++j)
+ if (event_logs[i].find(run_until[j]) != std::string::npos)
+ return true;
+
+ return false;
+}
+
+std::vector<std::string> DumpAccessibilityEventsTest::Dump(
+ std::vector<std::string>& run_until) {
WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
shell()->web_contents());
base::ProcessId pid = base::GetCurrentProcId();
- auto& event_recorder = AccessibilityEventRecorder::GetInstance(
- web_contents->GetRootBrowserAccessibilityManager(), pid);
- event_recorder.set_only_web_events(true);
+ std::unique_ptr<AccessibilityEventRecorder> event_recorder(
+ AccessibilityEventRecorder::Create(
+ web_contents->GetRootBrowserAccessibilityManager(), pid));
+ event_recorder->set_only_web_events(true);
// Save a copy of the accessibility tree (as a text dump); we'll
// log this for the user later if the test fails.
@@ -102,9 +120,11 @@ std::vector<std::string> DumpAccessibilityEventsTest::Dump() {
web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
base::ASCIIToUTF16("go()"));
- // Wait for at least one accessibility event generated in response to
- // that function.
- waiter->WaitForNotification();
+ for (;;) {
+ waiter->WaitForNotification(); // Run at least once.
+ if (IsRecordingComplete(*event_recorder, run_until))
+ break;
+ }
// More than one accessibility event could have been generated.
// To make sure we've received all accessibility events, add a
@@ -123,7 +143,7 @@ std::vector<std::string> DumpAccessibilityEventsTest::Dump() {
// Dump the event logs, running them through any filters specified
// in the HTML file.
- std::vector<std::string> event_logs = event_recorder.event_logs();
+ std::vector<std::string> event_logs = event_recorder->event_logs();
std::vector<std::string> result;
for (size_t i = 0; i < event_logs.size(); ++i) {
if (AccessibilityTreeFormatter::MatchesFilters(
@@ -268,6 +288,18 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
RunEventTest(FILE_PATH_LITERAL("checked-state-changed.html"));
}
+// http:/crbug.com/889013
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
+ DISABLED_AccessibilityEventsCaretHide) {
+ RunEventTest(FILE_PATH_LITERAL("caret-hide.html"));
+}
+
+// http:/crbug.com/889013
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
+ DISABLED_AccessibilityEventsCaretMove) {
+ RunEventTest(FILE_PATH_LITERAL("caret-move.html"));
+}
+
IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
AccessibilityEventsCSSDisplay) {
RunEventTest(FILE_PATH_LITERAL("css-display.html"));
@@ -423,4 +455,14 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
RunEventTest(FILE_PATH_LITERAL("text-changed.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
+ AccessibilityEventsAriaCheckedChanged) {
+ RunEventTest(FILE_PATH_LITERAL("aria-checked-changed.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
+ AccessibilityEventsAriaPressedChanged) {
+ RunEventTest(FILE_PATH_LITERAL("aria-pressed-changed.html"));
+}
+
} // namespace content
diff --git a/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 6de78219107..10e4d014626 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -125,7 +125,7 @@ class DumpAccessibilityTreeTest : public DumpAccessibilityTestBase {
RunTest(test_file, "accessibility/regression");
}
- std::vector<std::string> Dump() override {
+ std::vector<std::string> Dump(std::vector<std::string>& unused) override {
std::unique_ptr<AccessibilityTreeFormatter> formatter(
CreateAccessibilityTreeFormatter());
formatter->SetFilters(filters_);
@@ -514,6 +514,10 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaDropEffect) {
RunAriaTest(FILE_PATH_LITERAL("aria-dropeffect.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaEditable) {
+ RunAriaTest(FILE_PATH_LITERAL("aria-editable.html"));
+}
+
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
AccessibilityAriaErrorMessage) {
RunAriaTest(FILE_PATH_LITERAL("aria-errormessage.html"));
@@ -967,6 +971,11 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
RunAriaTest(FILE_PATH_LITERAL("table-column-hidden.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityLabelWithSelectedAriaOption) {
+ RunAriaTest(FILE_PATH_LITERAL("label-with-selected-option.html"));
+}
+
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityArticle) {
RunHtmlTest(FILE_PATH_LITERAL("article.html"));
}
@@ -1835,6 +1844,26 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
RunHtmlTest(FILE_PATH_LITERAL("window-crops-items.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityInputInsideLabel) {
+ RunHtmlTest(FILE_PATH_LITERAL("input-inside-label.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityInputImageWithTitle) {
+ RunHtmlTest(FILE_PATH_LITERAL("input-image-with-title.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityLabelWithSelectedOption) {
+ RunHtmlTest(FILE_PATH_LITERAL("label-with-selected-option.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityLabelWithPresentationalChild) {
+ RunHtmlTest(FILE_PATH_LITERAL("label-with-presentational-child.html"));
+}
+
//
// Regression tests. These don't test a specific web platform feature,
// they test a specific web page that crashed or had some bad behavior
diff --git a/chromium/content/browser/android/app_web_message_port.cc b/chromium/content/browser/android/app_web_message_port.cc
index ec7b9ba9fdf..ac0b990d8fd 100644
--- a/chromium/content/browser/android/app_web_message_port.cc
+++ b/chromium/content/browser/android/app_web_message_port.cc
@@ -10,7 +10,7 @@
#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "jni/AppWebMessagePort_jni.h"
-#include "third_party/blink/public/common/message_port/string_message_codec.h"
+#include "third_party/blink/public/common/messaging/string_message_codec.h"
using blink::MessagePortChannel;
diff --git a/chromium/content/browser/android/app_web_message_port.h b/chromium/content/browser/android/app_web_message_port.h
index 2dd94028094..2d1f3a4d712 100644
--- a/chromium/content/browser/android/app_web_message_port.h
+++ b/chromium/content/browser/android/app_web_message_port.h
@@ -6,7 +6,7 @@
#define CONTENT_BROWSER_ANDROID_APP_WEB_MESSAGE_PORT_H_
#include "base/android/jni_weak_ref.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
namespace content {
diff --git a/chromium/content/browser/android/background_sync_network_observer_android.cc b/chromium/content/browser/android/background_sync_network_observer_android.cc
index c1c514c7f4b..77844478b8d 100644
--- a/chromium/content/browser/android/background_sync_network_observer_android.cc
+++ b/chromium/content/browser/android/background_sync_network_observer_android.cc
@@ -4,6 +4,8 @@
#include "content/browser/android/background_sync_network_observer_android.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "jni/BackgroundSyncNetworkObserver_jni.h"
using base::android::JavaParamRef;
@@ -13,12 +15,12 @@ namespace content {
// static
scoped_refptr<BackgroundSyncNetworkObserverAndroid::Observer>
BackgroundSyncNetworkObserverAndroid::Observer::Create(
- base::Callback<void(net::NetworkChangeNotifier::ConnectionType)> callback) {
+ base::Callback<void(network::mojom::ConnectionType)> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
scoped_refptr<BackgroundSyncNetworkObserverAndroid::Observer> observer(
new BackgroundSyncNetworkObserverAndroid::Observer(callback));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&BackgroundSyncNetworkObserverAndroid::Observer::Init,
observer));
return observer;
@@ -48,15 +50,14 @@ void BackgroundSyncNetworkObserverAndroid::Observer::
const JavaParamRef<jobject>& jcaller,
jint new_connection_type) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(callback_,
- static_cast<net::NetworkChangeNotifier::ConnectionType>(
- new_connection_type)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::Bind(callback_, static_cast<network::mojom::ConnectionType>(
+ new_connection_type)));
}
BackgroundSyncNetworkObserverAndroid::Observer::Observer(
- base::Callback<void(net::NetworkChangeNotifier::ConnectionType)> callback)
+ base::Callback<void(network::mojom::ConnectionType)> callback)
: callback_(callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
@@ -67,15 +68,16 @@ BackgroundSyncNetworkObserverAndroid::BackgroundSyncNetworkObserverAndroid(
weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // Remove the observer attached by the NetworkObserver constructor
- net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
-
observer_ = Observer::Create(
- base::Bind(&BackgroundSyncNetworkObserverAndroid::OnNetworkChanged,
+ base::Bind(&BackgroundSyncNetworkObserverAndroid::OnConnectionChanged,
weak_ptr_factory_.GetWeakPtr()));
}
BackgroundSyncNetworkObserverAndroid::~BackgroundSyncNetworkObserverAndroid() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
+
+void BackgroundSyncNetworkObserverAndroid::RegisterWithNetworkConnectionTracker(
+ network::NetworkConnectionTracker* network_connection_tracker) {}
+
} // namespace content
diff --git a/chromium/content/browser/android/background_sync_network_observer_android.h b/chromium/content/browser/android/background_sync_network_observer_android.h
index ace3b9b4f17..85f93c2d603 100644
--- a/chromium/content/browser/android/background_sync_network_observer_android.h
+++ b/chromium/content/browser/android/background_sync_network_observer_android.h
@@ -15,9 +15,9 @@
namespace content {
// BackgroundSyncNetworkObserverAndroid is a specialized
-// BackgroundSyncNetworkObserver which is backed by a NetworkChangeNotifier
+// BackgroundSyncNetworkObserver which is backed by a NetworkConnectionTracker
// that listens for network events even when the browser is paused, unlike the
-// standard NetworkChangeNotifier. This ensures that sync events can be fired
+// standard NetworkConnectionTracker. This ensures that sync events can be fired
// even when the browser is backgrounded, and other network observers are
// disabled.
class BackgroundSyncNetworkObserverAndroid
@@ -38,8 +38,7 @@ class BackgroundSyncNetworkObserverAndroid
content::BrowserThread::DeleteOnUIThread> {
public:
static scoped_refptr<BackgroundSyncNetworkObserverAndroid::Observer> Create(
- base::Callback<void(net::NetworkChangeNotifier::ConnectionType)>
- callback);
+ base::Callback<void(network::mojom::ConnectionType)> callback);
// Called from BackgroundSyncNetworkObserver.java over JNI whenever the
// connection type changes. This updates the current connection type seen by
@@ -55,20 +54,22 @@ class BackgroundSyncNetworkObserverAndroid
friend class base::DeleteHelper<
BackgroundSyncNetworkObserverAndroid::Observer>;
- Observer(base::Callback<void(net::NetworkChangeNotifier::ConnectionType)>
- callback);
+ Observer(base::Callback<void(network::mojom::ConnectionType)> callback);
void Init();
~Observer();
// This callback is to be run on the IO thread whenever the connection type
// changes.
- base::Callback<void(net::NetworkChangeNotifier::ConnectionType)> callback_;
+ base::Callback<void(network::mojom::ConnectionType)> callback_;
base::android::ScopedJavaGlobalRef<jobject> j_observer_;
DISALLOW_COPY_AND_ASSIGN(Observer);
};
private:
+ void RegisterWithNetworkConnectionTracker(
+ network::NetworkConnectionTracker* network_connection_tracker) override;
+
// Accessed on UI Thread
scoped_refptr<Observer> observer_;
diff --git a/chromium/content/browser/android/content_url_loader_factory.cc b/chromium/content/browser/android/content_url_loader_factory.cc
new file mode 100644
index 00000000000..25cc7e7006a
--- /dev/null
+++ b/chromium/content/browser/android/content_url_loader_factory.cc
@@ -0,0 +1,261 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/android/content_url_loader_factory.h"
+
+#include <string>
+#include <vector>
+
+#include "base/android/content_uri_utils.h"
+#include "base/bind.h"
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/file_url_loader.h"
+#include "content/public/common/content_client.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/file_data_pipe_producer.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_byte_range.h"
+#include "net/http/http_util.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
+
+// TODO(eroman): Add unit-tests for "X-Chrome-intent-type"
+// (see url_request_content_job_unittest.cc).
+// TODO(eroman): Remove duplication with file_url_loader_factory.cc (notably
+// Range header parsing).
+
+namespace content {
+namespace {
+
+constexpr size_t kDefaultContentUrlPipeSize = 65536;
+
+// Assigns the byte range that has been requested based on the Range header.
+// This assumes the simplest form of the Range header using a single range.
+// If no byte range was specified, the output range will cover the entire file.
+bool GetRequestedByteRange(const network::ResourceRequest& request,
+ size_t content_size,
+ size_t* first_byte_to_send,
+ size_t* total_bytes_to_send) {
+ *first_byte_to_send = 0;
+ *total_bytes_to_send = content_size;
+
+ std::string range_header;
+ std::vector<net::HttpByteRange> ranges;
+
+ if (!request.headers.GetHeader(net::HttpRequestHeaders::kRange,
+ &range_header) ||
+ !net::HttpUtil::ParseRangeHeader(range_header, &ranges)) {
+ return true;
+ }
+
+ // Only handle a simple Range header for a single range.
+ net::HttpByteRange byte_range = ranges[0];
+ if (ranges.size() != 1 || !byte_range.ComputeBounds(content_size))
+ return false;
+
+ *first_byte_to_send = static_cast<size_t>(byte_range.first_byte_position());
+ *total_bytes_to_send = static_cast<size_t>(byte_range.last_byte_position()) -
+ *first_byte_to_send + 1;
+ return true;
+}
+
+// Gets the mimetype for |content_path| either by asking the content provider,
+// or by using the special Chrome request header X-Chrome-intent-type.
+void GetMimeType(const network::ResourceRequest& request,
+ const base::FilePath& content_path,
+ std::string* out_mime_type) {
+ out_mime_type->clear();
+
+ std::string intent_type_header;
+ if ((request.resource_type == content::RESOURCE_TYPE_MAIN_FRAME) &&
+ request.headers.GetHeader("X-Chrome-intent-type", &intent_type_header)) {
+ *out_mime_type = intent_type_header;
+ }
+
+ if (out_mime_type->empty())
+ *out_mime_type = base::GetContentUriMimeType(content_path);
+}
+
+class ContentURLLoader : public network::mojom::URLLoader {
+ public:
+ static void CreateAndStart(
+ const network::ResourceRequest& request,
+ network::mojom::URLLoaderRequest loader,
+ network::mojom::URLLoaderClientPtrInfo client_info) {
+ // Owns itself. Will live as long as its URLLoader and URLLoaderClientPtr
+ // bindings are alive - essentially until either the client gives up or all
+ // file data has been sent to it.
+ auto* content_url_loader = new ContentURLLoader;
+ content_url_loader->Start(request, std::move(loader),
+ std::move(client_info));
+ }
+
+ // network::mojom::URLLoader:
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) override {}
+ void ProceedWithResponse() override {}
+ void SetPriority(net::RequestPriority priority,
+ int32_t intra_priority_value) override {}
+ void PauseReadingBodyFromNet() override {}
+ void ResumeReadingBodyFromNet() override {}
+
+ private:
+ ContentURLLoader() : binding_(this) {}
+ ~ContentURLLoader() override = default;
+
+ void Start(const network::ResourceRequest& request,
+ network::mojom::URLLoaderRequest loader,
+ network::mojom::URLLoaderClientPtrInfo client_info) {
+ network::ResourceResponseHead head;
+ head.request_start = head.response_start = base::TimeTicks::Now();
+ binding_.Bind(std::move(loader));
+ binding_.set_connection_error_handler(base::BindOnce(
+ &ContentURLLoader::OnConnectionError, base::Unretained(this)));
+
+ network::mojom::URLLoaderClientPtr client;
+ client.Bind(std::move(client_info));
+
+ DCHECK(request.url.SchemeIs("content"));
+ base::FilePath path = base::FilePath(request.url.spec());
+
+ // Get the file length.
+ base::File::Info info;
+ if (!base::GetFileInfo(path, &info))
+ return CompleteWithFailure(std::move(client), net::ERR_FILE_NOT_FOUND);
+
+ size_t first_byte_to_send;
+ size_t total_bytes_to_send;
+ if (!GetRequestedByteRange(request, info.size, &first_byte_to_send,
+ &total_bytes_to_send)) {
+ return CompleteWithFailure(std::move(client),
+ net::ERR_REQUEST_RANGE_NOT_SATISFIABLE);
+ }
+
+ mojo::DataPipe pipe(kDefaultContentUrlPipeSize);
+ if (!pipe.consumer_handle.is_valid()) {
+ return CompleteWithFailure(std::move(client), net::ERR_FAILED);
+ }
+
+ base::File file = base::OpenContentUriForRead(path);
+ if (!file.IsValid()) {
+ return CompleteWithFailure(
+ std::move(client), net::FileErrorToNetError(file.error_details()));
+ return;
+ }
+
+ total_bytes_written_ = total_bytes_to_send;
+ head.content_length = base::saturated_cast<int64_t>(total_bytes_to_send);
+
+ // Set the mimetype of the response.
+ GetMimeType(request, path, &head.mime_type);
+ if (!head.mime_type.empty() && head.headers) {
+ head.headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
+ head.headers->AddHeader(
+ base::StringPrintf("%s: %s", net::HttpRequestHeaders::kContentType,
+ head.mime_type.c_str()));
+ }
+
+ client->OnReceiveResponse(head);
+ client->OnStartLoadingResponseBody(std::move(pipe.consumer_handle));
+ client_ = std::move(client);
+
+ if (total_bytes_to_send == 0) {
+ // There's no more data, so we're already done.
+ OnFileWritten(MOJO_RESULT_OK);
+ return;
+ }
+
+ // In case of a range request, seek to the appropriate position before
+ // sending the remaining bytes asynchronously. Under normal conditions
+ // (i.e., no range request) this Seek is effectively a no-op.
+ file.Seek(base::File::FROM_BEGIN, static_cast<int64_t>(first_byte_to_send));
+
+ data_producer_ = std::make_unique<mojo::FileDataPipeProducer>(
+ std::move(pipe.producer_handle), /*observer=*/nullptr);
+ data_producer_->WriteFromFile(
+ std::move(file), total_bytes_to_send,
+ base::BindOnce(&ContentURLLoader::OnFileWritten,
+ base::Unretained(this)));
+ }
+
+ void CompleteWithFailure(network::mojom::URLLoaderClientPtr client,
+ net::Error net_error) {
+ client->OnComplete(network::URLLoaderCompletionStatus(net_error));
+ MaybeDeleteSelf();
+ }
+
+ void OnConnectionError() {
+ binding_.Close();
+ MaybeDeleteSelf();
+ }
+
+ void MaybeDeleteSelf() {
+ if (!binding_.is_bound() && !client_.is_bound())
+ delete this;
+ }
+
+ void OnFileWritten(MojoResult result) {
+ // All the data has been written now. Close the data pipe. The consumer will
+ // be notified that there will be no more data to read from now.
+ data_producer_.reset();
+
+ if (result == MOJO_RESULT_OK) {
+ network::URLLoaderCompletionStatus status(net::OK);
+ status.encoded_data_length = total_bytes_written_;
+ status.encoded_body_length = total_bytes_written_;
+ status.decoded_body_length = total_bytes_written_;
+ client_->OnComplete(status);
+ } else {
+ client_->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
+ }
+ client_.reset();
+ MaybeDeleteSelf();
+ }
+
+ std::unique_ptr<mojo::FileDataPipeProducer> data_producer_;
+ mojo::Binding<network::mojom::URLLoader> binding_;
+ network::mojom::URLLoaderClientPtr client_;
+
+ // In case of successful loads, this holds the total of bytes written.
+ // It is used to set some of the URLLoaderCompletionStatus data passed back
+ // to the URLLoaderClients (eg SimpleURLLoader).
+ size_t total_bytes_written_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentURLLoader);
+};
+
+} // namespace
+
+ContentURLLoaderFactory::ContentURLLoaderFactory(
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
+ : task_runner_(std::move(task_runner)) {}
+
+ContentURLLoaderFactory::~ContentURLLoaderFactory() = default;
+
+void ContentURLLoaderFactory::CreateLoaderAndStart(
+ network::mojom::URLLoaderRequest loader,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const network::ResourceRequest& request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
+ task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&ContentURLLoader::CreateAndStart, request,
+ std::move(loader), client.PassInterface()));
+}
+
+void ContentURLLoaderFactory::Clone(
+ network::mojom::URLLoaderFactoryRequest loader) {
+ bindings_.AddBinding(this, std::move(loader));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/android/content_url_loader_factory.h b/chromium/content/browser/android/content_url_loader_factory.h
new file mode 100644
index 00000000000..8cbe8c63054
--- /dev/null
+++ b/chromium/content/browser/android/content_url_loader_factory.h
@@ -0,0 +1,47 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ANDROID_CONTENT_URL_LOADER_FACTORY_H_
+#define CONTENT_BROWSER_ANDROID_CONTENT_URL_LOADER_FACTORY_H_
+
+#include "base/macros.h"
+#include "base/sequenced_task_runner.h"
+#include "content/common/content_export.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+
+namespace content {
+
+// A URLLoaderFactory used for the content:// scheme used when Network Service
+// is enabled.
+class CONTENT_EXPORT ContentURLLoaderFactory
+ : public network::mojom::URLLoaderFactory {
+ public:
+ // SequencedTaskRunner must be allowed to block and should have background
+ // priority since it will be used to schedule synchronous file I/O tasks.
+ explicit ContentURLLoaderFactory(
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
+ ~ContentURLLoaderFactory() override;
+
+ private:
+ // network::mojom::URLLoaderFactory:
+ void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const network::ResourceRequest& request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag&
+ traffic_annotation) override;
+ void Clone(network::mojom::URLLoaderFactoryRequest loader) override;
+
+ const scoped_refptr<base::SequencedTaskRunner> task_runner_;
+ mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentURLLoaderFactory);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_ANDROID_CONTENT_URL_LOADER_FACTORY_H_
diff --git a/chromium/content/browser/android/dialog_overlay_impl.cc b/chromium/content/browser/android/dialog_overlay_impl.cc
index 70457ba7490..a6a952bd31f 100644
--- a/chromium/content/browser/android/dialog_overlay_impl.cc
+++ b/chromium/content/browser/android/dialog_overlay_impl.cc
@@ -71,7 +71,8 @@ DialogOverlayImpl::DialogOverlayImpl(const JavaParamRef<jobject>& obj,
bool power_efficient)
: WebContentsObserver(web_contents),
rfhi_(rfhi),
- power_efficient_(power_efficient) {
+ power_efficient_(power_efficient),
+ observed_window_android_(false) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(rfhi_);
@@ -105,9 +106,11 @@ void DialogOverlayImpl::CompleteInit(JNIEnv* env,
// Send the initial token, if there is one. The observer will notify us about
// changes only.
if (auto* window = web_contents()->GetNativeView()->GetWindowAndroid()) {
+ RegisterWindowObserverIfNeeded(window);
ScopedJavaLocalRef<jobject> token = window->GetWindowToken();
- if (!token.is_null())
+ if (!token.is_null()) {
Java_DialogOverlayImpl_onWindowToken(env, obj, token);
+ }
// else we will send one if we get a callback from ViewAndroid.
}
}
@@ -117,7 +120,7 @@ DialogOverlayImpl::~DialogOverlayImpl() {
}
void DialogOverlayImpl::Stop() {
- UnregisterForTokensIfNeeded();
+ UnregisterCallbacksIfNeeded();
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = obj_.get(env);
@@ -129,7 +132,7 @@ void DialogOverlayImpl::Stop() {
void DialogOverlayImpl::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- UnregisterForTokensIfNeeded();
+ UnregisterCallbacksIfNeeded();
// We delete soon since this might be part of an onDismissed callback.
BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this);
}
@@ -145,7 +148,7 @@ void DialogOverlayImpl::GetCompositorOffset(
point.y());
}
-void DialogOverlayImpl::UnregisterForTokensIfNeeded() {
+void DialogOverlayImpl::UnregisterCallbacksIfNeeded() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!rfhi_)
@@ -157,7 +160,12 @@ void DialogOverlayImpl::UnregisterForTokensIfNeeded() {
WebContentsDelegate* delegate = web_contents()->GetDelegate();
if (delegate)
delegate->SetOverlayMode(false);
-
+ if (observed_window_android_) {
+ auto* window_android = web_contents()->GetNativeView()->GetWindowAndroid();
+ if (window_android)
+ window_android->RemoveObserver(this);
+ observed_window_android_ = false;
+ }
web_contents()->GetNativeView()->RemoveObserver(this);
rfhi_ = nullptr;
}
@@ -187,6 +195,11 @@ void DialogOverlayImpl::OnVisibilityChanged(content::Visibility visibility) {
Stop();
}
+void DialogOverlayImpl::OnRootWindowVisibilityChanged(bool visible) {
+ if (!visible)
+ Stop();
+}
+
void DialogOverlayImpl::WebContentsDestroyed() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
Stop();
@@ -213,9 +226,10 @@ void DialogOverlayImpl::OnAttachedToWindow() {
ScopedJavaLocalRef<jobject> token;
- if (auto* window = web_contents()->GetNativeView()->GetWindowAndroid())
+ if (auto* window = web_contents()->GetNativeView()->GetWindowAndroid()) {
+ RegisterWindowObserverIfNeeded(window);
token = window->GetWindowToken();
-
+ }
ScopedJavaLocalRef<jobject> obj = obj_.get(env);
if (!obj.is_null())
Java_DialogOverlayImpl_onWindowToken(env, obj, token);
@@ -226,6 +240,15 @@ void DialogOverlayImpl::OnDetachedFromWindow() {
ScopedJavaLocalRef<jobject> obj = obj_.get(env);
if (!obj.is_null())
Java_DialogOverlayImpl_onWindowToken(env, obj, nullptr);
+ Stop();
+}
+
+void DialogOverlayImpl::RegisterWindowObserverIfNeeded(
+ ui::WindowAndroid* window) {
+ if (!observed_window_android_) {
+ observed_window_android_ = true;
+ window->AddObserver(this);
+ }
}
static jint JNI_DialogOverlayImpl_RegisterSurface(
diff --git a/chromium/content/browser/android/dialog_overlay_impl.h b/chromium/content/browser/android/dialog_overlay_impl.h
index 4cb4cbef524..1e955a8c085 100644
--- a/chromium/content/browser/android/dialog_overlay_impl.h
+++ b/chromium/content/browser/android/dialog_overlay_impl.h
@@ -12,6 +12,8 @@
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/android/view_android_observer.h"
+#include "ui/android/window_android.h"
+#include "ui/android/window_android_observer.h"
namespace content {
@@ -20,6 +22,7 @@ namespace content {
// detached from a WindowAndroid, we get the Android window token and notify the
// java side.
class DialogOverlayImpl : public ui::ViewAndroidObserver,
+ public ui::WindowAndroidObserver,
public WebContentsObserver {
public:
// This may not call back into |obj| directly, but must post. This is because
@@ -59,12 +62,21 @@ class DialogOverlayImpl : public ui::ViewAndroidObserver,
void RenderFrameHostChanged(RenderFrameHost* old_host,
RenderFrameHost* new_host) override;
- // Unregister for tokens if we're registered.
- void UnregisterForTokensIfNeeded();
+ // Unregister callbacks if previously registered.
+ void UnregisterCallbacksIfNeeded();
+
+ // WindowAndroidObserver
+ void OnRootWindowVisibilityChanged(bool visible) override;
+ void OnCompositingDidCommit() override {}
+ void OnAttachCompositor() override {}
+ void OnDetachCompositor() override {}
+ void OnActivityStopped() override {}
+ void OnActivityStarted() override {}
private:
// Signals the overlay should be cleaned up and no longer used.
void Stop();
+ void RegisterWindowObserverIfNeeded(ui::WindowAndroid* window);
// Java object that owns us.
JavaObjectWeakGlobalRef obj_;
@@ -74,6 +86,9 @@ class DialogOverlayImpl : public ui::ViewAndroidObserver,
// Do we care about power efficiency?
bool power_efficient_;
+
+ // Whether we added ourselves as an observer through WindowAndroid.
+ bool observed_window_android_;
};
} // namespace content
diff --git a/chromium/content/browser/android/gesture_listener_manager.cc b/chromium/content/browser/android/gesture_listener_manager.cc
index 676329795a4..4d03f78eec8 100644
--- a/chromium/content/browser/android/gesture_listener_manager.cc
+++ b/chromium/content/browser/android/gesture_listener_manager.cc
@@ -111,7 +111,7 @@ GestureListenerManager::~GestureListenerManager() {
ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
if (j_obj.is_null())
return;
- Java_GestureListenerManagerImpl_onDestroy(env, j_obj);
+ Java_GestureListenerManagerImpl_onNativeDestroyed(env, j_obj);
}
void GestureListenerManager::ResetGestureDetection(
diff --git a/chromium/content/browser/android/ime_adapter_android.cc b/chromium/content/browser/android/ime_adapter_android.cc
index 6bb9735fc5b..cdc5d3255cb 100644
--- a/chromium/content/browser/android/ime_adapter_android.cc
+++ b/chromium/content/browser/android/ime_adapter_android.cc
@@ -14,6 +14,7 @@
#include "base/android/scoped_java_ref.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "content/browser/android/text_suggestion_host_android.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -144,13 +145,17 @@ ImeAdapterAndroid::ImeAdapterAndroid(JNIEnv* env,
WebContents* web_contents)
: RenderWidgetHostConnector(web_contents), rwhva_(nullptr) {
java_ime_adapter_ = JavaObjectWeakGlobalRef(env, obj);
+
+ // Set up mojo client for TextSuggestionHost in advance. Java side is
+ // initialized lazily right before showing the menu first time.
+ TextSuggestionHostAndroid::Create(env, web_contents);
}
ImeAdapterAndroid::~ImeAdapterAndroid() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_ime_adapter_.get(env);
if (!obj.is_null())
- Java_ImeAdapterImpl_destroy(env, obj);
+ Java_ImeAdapterImpl_onNativeDestroyed(env, obj);
}
void ImeAdapterAndroid::UpdateRenderProcessConnection(
diff --git a/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.h b/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.h
index 8e55c6434e9..db327b40960 100644
--- a/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.h
+++ b/chromium/content/browser/android/java/gin_java_bridge_dispatcher_host.h
@@ -15,6 +15,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
#include "content/browser/android/java/gin_java_bound_object.h"
#include "content/browser/android/java/gin_java_method_invocation_helper.h"
#include "content/public/browser/web_contents_observer.h"
@@ -95,9 +96,9 @@ class GinJavaBridgeDispatcherHost
bool FindObjectId(const base::android::JavaRef<jobject>& object,
GinJavaBoundObject::ObjectID* object_id);
void RemoveFromRetainedObjectSetLocked(const JavaObjectWeakGlobalRef& ref);
- JavaObjectWeakGlobalRef RemoveHolderLocked(
- int32_t holder,
- ObjectMap::iterator* iter_ptr);
+ JavaObjectWeakGlobalRef RemoveHolderLocked(int32_t holder,
+ ObjectMap::iterator* iter_ptr)
+ EXCLUSIVE_LOCKS_REQUIRED(objects_lock_);
// The following objects are used only on the UI thread.
@@ -116,7 +117,7 @@ class GinJavaBridgeDispatcherHost
JavaObjectWeakGlobalRef retained_object_set_;
// Note that retained_object_set_ does not need to be consistent
// with objects_.
- ObjectMap objects_;
+ ObjectMap objects_ GUARDED_BY(objects_lock_);
base::Lock objects_lock_;
// The following objects are only used on the background thread.
diff --git a/chromium/content/browser/android/java/gin_java_bridge_message_filter.cc b/chromium/content/browser/android/java/gin_java_bridge_message_filter.cc
index 9c2feb1a847..2a3872237b2 100644
--- a/chromium/content/browser/android/java/gin_java_bridge_message_filter.cc
+++ b/chromium/content/browser/android/java/gin_java_bridge_message_filter.cc
@@ -84,6 +84,21 @@ void GinJavaBridgeMessageFilter::RemoveHost(GinJavaBridgeDispatcherHost* host) {
}
}
+void GinJavaBridgeMessageFilter::RenderProcessExited(
+ RenderProcessHost* rph,
+ const ChildProcessTerminationInfo& info) {
+#if DCHECK_IS_ON()
+ {
+ scoped_refptr<GinJavaBridgeMessageFilter> filter =
+ base::UserDataAdapter<GinJavaBridgeMessageFilter>::Get(
+ rph, kGinJavaBridgeMessageFilterKey);
+ DCHECK_EQ(this, filter.get());
+ }
+#endif
+ rph->RemoveObserver(this);
+ rph->RemoveUserData(kGinJavaBridgeMessageFilterKey);
+}
+
// static
scoped_refptr<GinJavaBridgeMessageFilter> GinJavaBridgeMessageFilter::FromHost(
GinJavaBridgeDispatcherHost* host, bool create_if_not_exists) {
@@ -94,6 +109,8 @@ scoped_refptr<GinJavaBridgeMessageFilter> GinJavaBridgeMessageFilter::FromHost(
if (!filter && create_if_not_exists) {
filter = new GinJavaBridgeMessageFilter();
rph->AddFilter(filter.get());
+ rph->AddObserver(filter.get());
+
rph->SetUserData(
kGinJavaBridgeMessageFilterKey,
std::make_unique<base::UserDataAdapter<GinJavaBridgeMessageFilter>>(
diff --git a/chromium/content/browser/android/java/gin_java_bridge_message_filter.h b/chromium/content/browser/android/java/gin_java_bridge_message_filter.h
index b117d2d5d53..c15bc707920 100644
--- a/chromium/content/browser/android/java/gin_java_bridge_message_filter.h
+++ b/chromium/content/browser/android/java/gin_java_bridge_message_filter.h
@@ -12,9 +12,11 @@
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
#include "content/browser/android/java/gin_java_bound_object.h"
#include "content/common/android/gin_java_bridge_errors.h"
#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/render_process_host_observer.h"
namespace base {
class ListValue;
@@ -29,7 +31,8 @@ namespace content {
class GinJavaBridgeDispatcherHost;
class RenderFrameHost;
-class GinJavaBridgeMessageFilter : public BrowserMessageFilter {
+class GinJavaBridgeMessageFilter : public BrowserMessageFilter,
+ public RenderProcessHostObserver {
public:
// BrowserMessageFilter
void OnDestruct() const override;
@@ -37,6 +40,10 @@ class GinJavaBridgeMessageFilter : public BrowserMessageFilter {
base::TaskRunner* OverrideTaskRunnerForMessage(
const IPC::Message& message) override;
+ // RenderProcessHostObserver
+ void RenderProcessExited(RenderProcessHost* rph,
+ const ChildProcessTerminationInfo& info) override;
+
// Called on the UI thread.
void AddRoutingIdForHost(GinJavaBridgeDispatcherHost* host,
RenderFrameHost* render_frame_host);
@@ -81,7 +88,7 @@ class GinJavaBridgeMessageFilter : public BrowserMessageFilter {
void OnObjectWrapperDeleted(GinJavaBoundObject::ObjectID object_id);
// Accessed both from UI and background threads.
- HostMap hosts_;
+ HostMap hosts_ GUARDED_BY(hosts_lock_);
base::Lock hosts_lock_;
// The routing id of the RenderFrameHost whose request we are processing.
diff --git a/chromium/content/browser/android/java/jni_reflect.cc b/chromium/content/browser/android/java/jni_reflect.cc
new file mode 100644
index 00000000000..cc2ef8b6cde
--- /dev/null
+++ b/chromium/content/browser/android/java/jni_reflect.cc
@@ -0,0 +1,63 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/android/java/jni_reflect.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+
+#include "jni/AccessibleObject_jni.h"
+#include "jni/Class_jni.h"
+#include "jni/Method_jni.h"
+#include "jni/Modifier_jni.h"
+
+using base::android::ConvertJavaStringToUTF8;
+using base::android::JavaRef;
+using base::android::ScopedJavaLocalRef;
+
+namespace content {
+
+std::string GetClassName(JNIEnv* env, const JavaRef<jclass>& clazz) {
+ return ConvertJavaStringToUTF8(JNI_Class::Java_Class_getName(env, clazz));
+}
+
+ScopedJavaLocalRef<jobjectArray> GetClassMethods(JNIEnv* env,
+ const JavaRef<jclass>& clazz) {
+ return JNI_Class::Java_Class_getMethods(env, clazz);
+}
+
+std::string GetMethodName(JNIEnv* env, const JavaRef<jobject>& method) {
+ return ConvertJavaStringToUTF8(JNI_Method::Java_Method_getName(env, method));
+}
+
+ScopedJavaLocalRef<jobjectArray> GetMethodParameterTypes(
+ JNIEnv* env,
+ const JavaRef<jobject>& method) {
+ return JNI_Method::Java_Method_getParameterTypes(env, method);
+}
+
+ScopedJavaLocalRef<jclass> GetMethodReturnType(JNIEnv* env,
+ const JavaRef<jobject>& method) {
+ return JNI_Method::Java_Method_getReturnType(env, method);
+}
+
+ScopedJavaLocalRef<jclass> GetMethodDeclaringClass(
+ JNIEnv* env,
+ const JavaRef<jobject>& method) {
+ return JNI_Method::Java_Method_getDeclaringClass(env, method);
+}
+
+bool IsMethodStatic(JNIEnv* env, const JavaRef<jobject>& method) {
+ jint modifiers = JNI_Method::Java_Method_getModifiers(env, method);
+ return JNI_Modifier::Java_Modifier_isStatic(env, modifiers);
+}
+
+bool IsAnnotationPresent(JNIEnv* env,
+ const JavaRef<jobject>& obj,
+ const JavaRef<jclass>& annotation_clazz) {
+ return JNI_AccessibleObject::Java_AccessibleObject_isAnnotationPresent(
+ env, obj, annotation_clazz);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/android/java/jni_reflect.h b/chromium/content/browser/android/java/jni_reflect.h
new file mode 100644
index 00000000000..b7455fd4dcd
--- /dev/null
+++ b/chromium/content/browser/android/java/jni_reflect.h
@@ -0,0 +1,55 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_ANDROID_JAVA_JNI_REFLECT_H_
+#define CONTENT_BROWSER_ANDROID_JAVA_JNI_REFLECT_H_
+
+#include <jni.h>
+#include <string>
+
+#include "base/android/scoped_java_ref.h"
+
+namespace content {
+
+// Return the class's name.
+std::string GetClassName(JNIEnv* env,
+ const base::android::JavaRef<jclass>& clazz);
+
+// Return an array of Method objects for the public methods of clazz.
+base::android::ScopedJavaLocalRef<jobjectArray> GetClassMethods(
+ JNIEnv* env,
+ const base::android::JavaRef<jclass>& clazz);
+
+// Return the method's name.
+std::string GetMethodName(JNIEnv* env,
+ const base::android::JavaRef<jobject>& method);
+
+// Return an array listing the method's parameter types.
+base::android::ScopedJavaLocalRef<jobjectArray> GetMethodParameterTypes(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& method);
+
+// Return the method's return type.
+base::android::ScopedJavaLocalRef<jclass> GetMethodReturnType(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& method);
+
+// Return the method's declaring class.
+base::android::ScopedJavaLocalRef<jclass> GetMethodDeclaringClass(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& method);
+
+// Check if the method is static.
+bool IsMethodStatic(JNIEnv* env, const base::android::JavaRef<jobject>& method);
+
+// Check if the annotation identified by annotation_clazz is present on the
+// object obj.
+bool IsAnnotationPresent(
+ JNIEnv* env,
+ const base::android::JavaRef<jobject>& obj,
+ const base::android::JavaRef<jclass>& annotation_clazz);
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_ANDROID_JAVA_JNI_REFLECT_H_
diff --git a/chromium/content/browser/android/scoped_surface_request_manager.cc b/chromium/content/browser/android/scoped_surface_request_manager.cc
index 6d67c9f810d..d37d66eb3e7 100644
--- a/chromium/content/browser/android/scoped_surface_request_manager.cc
+++ b/chromium/content/browser/android/scoped_surface_request_manager.cc
@@ -4,6 +4,8 @@
#include "content/browser/android/scoped_surface_request_manager.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@@ -64,8 +66,8 @@ void ScopedSurfaceRequestManager::FulfillScopedSurfaceRequest(
gl::ScopedJavaSurface surface) {
// base::Unretained is safe because the lifetime of this object is tied to
// the lifetime of the browser process.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&ScopedSurfaceRequestManager::CompleteRequestOnUiThread,
base::Unretained(this), request_token,
base::Passed(&surface)));
diff --git a/chromium/content/browser/android/select_popup.cc b/chromium/content/browser/android/select_popup.cc
index 44d187ced2e..404e2194a4a 100644
--- a/chromium/content/browser/android/select_popup.cc
+++ b/chromium/content/browser/android/select_popup.cc
@@ -53,7 +53,7 @@ SelectPopup::~SelectPopup() {
ScopedJavaLocalRef<jobject> j_obj = java_obj_.get(env);
if (j_obj.is_null())
return;
- Java_SelectPopup_destroy(env, j_obj);
+ Java_SelectPopup_onNativeDestroyed(env, j_obj);
}
void SelectPopup::ShowMenu(RenderFrameHost* frame,
diff --git a/chromium/content/browser/android/synchronous_compositor_host.cc b/chromium/content/browser/android/synchronous_compositor_host.cc
index 58d7822c4aa..ff49053fcc2 100644
--- a/chromium/content/browser/android/synchronous_compositor_host.cc
+++ b/chromium/content/browser/android/synchronous_compositor_host.cc
@@ -11,6 +11,7 @@
#include "base/containers/hash_tables.h"
#include "base/memory/ptr_util.h"
#include "base/memory/shared_memory.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/trace_event_argument.h"
#include "content/browser/android/synchronous_compositor_sync_call_bridge.h"
@@ -20,6 +21,7 @@
#include "content/common/android/sync_compositor_statics.h"
#include "content/common/input/sync_compositor_messages.h"
#include "content/public/browser/android/synchronous_compositor_client.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/common/content_features.h"
@@ -53,8 +55,8 @@ class SynchronousCompositorControlHost
scoped_refptr<SynchronousCompositorSyncCallBridge> bridge,
int process_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CreateOnIOThread, std::move(request), std::move(bridge),
process_id));
}
diff --git a/chromium/content/browser/android/synchronous_compositor_sync_call_bridge.cc b/chromium/content/browser/android/synchronous_compositor_sync_call_bridge.cc
index 1f560661134..5a312ae3381 100644
--- a/chromium/content/browser/android/synchronous_compositor_sync_call_bridge.cc
+++ b/chromium/content/browser/android/synchronous_compositor_sync_call_bridge.cc
@@ -4,8 +4,10 @@
#include "content/browser/android/synchronous_compositor_sync_call_bridge.h"
+#include "base/task/post_task.h"
#include "content/browser/android/synchronous_compositor_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
#include "ui/android/window_android.h"
@@ -54,8 +56,8 @@ bool SynchronousCompositorSyncCallBridge::ReceiveFrameOnIOThread(
frame_futures_.pop_front();
if (compositor_frame) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SynchronousCompositorSyncCallBridge::
ProcessFrameMetadataOnUIThread,
this, metadata_version,
@@ -85,7 +87,7 @@ bool SynchronousCompositorSyncCallBridge::WaitAfterVSyncOnUIThread(
base::AutoLock lock(lock_);
if (remote_state_ != RemoteState::READY)
return false;
- DCHECK(!begin_frame_response_valid_);
+ CHECK(!begin_frame_response_valid_);
if (window_android_in_vsync_) {
DCHECK_EQ(window_android_in_vsync_, window_android);
return true;
diff --git a/chromium/content/browser/android/synchronous_compositor_sync_call_bridge.h b/chromium/content/browser/android/synchronous_compositor_sync_call_bridge.h
index 36dc19df4ad..1b833f9b6e4 100644
--- a/chromium/content/browser/android/synchronous_compositor_sync_call_bridge.h
+++ b/chromium/content/browser/android/synchronous_compositor_sync_call_bridge.h
@@ -8,6 +8,7 @@
#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/thread_annotations.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "content/common/input/sync_compositor_messages.h"
#include "content/public/browser/android/synchronous_compositor.h"
@@ -114,7 +115,8 @@ class SynchronousCompositorSyncCallBridge
viz::CompositorFrameMetadata metadata);
// Signal all waiters for closure. Callee must host a lock to |lock_|.
- void SignalRemoteClosedToAllWaitersOnIOThread();
+ void SignalRemoteClosedToAllWaitersOnIOThread()
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
using FrameFutureQueue =
base::circular_deque<scoped_refptr<SynchronousCompositor::FrameFuture>>;
@@ -129,11 +131,11 @@ class SynchronousCompositorSyncCallBridge
// Shared variables between the IO thread and UI thread.
base::Lock lock_;
- FrameFutureQueue frame_futures_;
- bool begin_frame_response_valid_ = false;
- SyncCompositorCommonRendererParams last_render_params_;
- base::ConditionVariable begin_frame_condition_;
- RemoteState remote_state_ = RemoteState::INIT;
+ FrameFutureQueue frame_futures_ GUARDED_BY(lock_);
+ bool begin_frame_response_valid_ GUARDED_BY(lock_) = false;
+ SyncCompositorCommonRendererParams last_render_params_ GUARDED_BY(lock_);
+ base::ConditionVariable begin_frame_condition_ GUARDED_BY(lock_);
+ RemoteState remote_state_ GUARDED_BY(lock_) = RemoteState::INIT;
DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorSyncCallBridge);
};
diff --git a/chromium/content/browser/android/text_suggestion_host_android.cc b/chromium/content/browser/android/text_suggestion_host_android.cc
index ac308472dda..c571a952c47 100644
--- a/chromium/content/browser/android/text_suggestion_host_android.cc
+++ b/chromium/content/browser/android/text_suggestion_host_android.cc
@@ -34,25 +34,17 @@ const size_t kMaxNumberOfSuggestions = 5;
} // namespace
-jlong JNI_TextSuggestionHost_Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jweb_contents) {
- WebContents* web_contents = WebContents::FromJavaWebContents(jweb_contents);
- DCHECK(web_contents);
- auto* text_suggestion_host =
- new TextSuggestionHostAndroid(env, obj, web_contents);
+void TextSuggestionHostAndroid::Create(JNIEnv* env, WebContents* web_contents) {
+ auto* text_suggestion_host = new TextSuggestionHostAndroid(env, web_contents);
text_suggestion_host->Initialize();
- return reinterpret_cast<intptr_t>(text_suggestion_host);
}
TextSuggestionHostAndroid::TextSuggestionHostAndroid(
JNIEnv* env,
- const JavaParamRef<jobject>& obj,
WebContents* web_contents)
: RenderWidgetHostConnector(web_contents),
WebContentsObserver(web_contents),
rwhva_(nullptr),
- java_text_suggestion_host_(JavaObjectWeakGlobalRef(env, obj)),
suggestion_menu_timeout_(
base::Bind(&TextSuggestionHostAndroid::OnSuggestionMenuTimeout,
base::Unretained(this))) {
@@ -64,7 +56,7 @@ TextSuggestionHostAndroid::~TextSuggestionHostAndroid() {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> obj = java_text_suggestion_host_.get(env);
if (!obj.is_null())
- Java_TextSuggestionHost_destroy(env, obj);
+ Java_TextSuggestionHost_onNativeDestroyed(env, obj);
}
void TextSuggestionHostAndroid::UpdateRenderProcessConnection(
@@ -144,6 +136,19 @@ double TextSuggestionHostAndroid::DpToPxIfNeeded(double value) {
return value;
}
+ScopedJavaLocalRef<jobject>
+TextSuggestionHostAndroid::GetJavaTextSuggestionHost() {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_text_suggestion_host_.get(env);
+ if (obj.is_null()) {
+ obj = Java_TextSuggestionHost_create(
+ env, WebContentsObserver::web_contents()->GetJavaWebContents(),
+ reinterpret_cast<intptr_t>(this));
+ java_text_suggestion_host_ = JavaObjectWeakGlobalRef(env, obj);
+ }
+ return obj;
+}
+
void TextSuggestionHostAndroid::ShowSpellCheckSuggestionMenu(
double caret_x,
double caret_y,
@@ -155,7 +160,7 @@ void TextSuggestionHostAndroid::ShowSpellCheckSuggestionMenu(
for (size_t i = 0; i < suggestions.size() && i < kMaxNumberOfSuggestions; ++i)
suggestion_strings.push_back(suggestions[i]->suggestion);
JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_text_suggestion_host_.get(env);
+ ScopedJavaLocalRef<jobject> obj = GetJavaTextSuggestionHost();
if (obj.is_null())
return;
@@ -173,7 +178,9 @@ void TextSuggestionHostAndroid::ShowTextSuggestionMenu(
const std::string& marked_text,
const std::vector<blink::mojom::TextSuggestionPtr>& suggestions) {
JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_text_suggestion_host_.get(env);
+ ScopedJavaLocalRef<jobject> obj = GetJavaTextSuggestionHost();
+ if (obj.is_null())
+ return;
// Enforce kMaxNumberOfSuggestions here in case the renderer is hijacked and
// tries to send bad input.
diff --git a/chromium/content/browser/android/text_suggestion_host_android.h b/chromium/content/browser/android/text_suggestion_host_android.h
index af220c331ff..e2b690a252f 100644
--- a/chromium/content/browser/android/text_suggestion_host_android.h
+++ b/chromium/content/browser/android/text_suggestion_host_android.h
@@ -18,13 +18,13 @@ namespace content {
// misspelled word. This class creates the Android implementation of
// mojom::TextSuggestionHost, which is used to communicate back-and-forth with
// Blink side code (these are separate classes due to lifecycle considerations;
-// this class needs to be constructed from Java code, but Mojo code wants to
-// take ownership of mojom::TextSuggestionHost).
+// this class is created by ImeAdapterAndroid ctor and destroyed together with
+// WebContents. Mojo code takes ownership of mojom::TextSuggestionHost).
class TextSuggestionHostAndroid : public RenderWidgetHostConnector,
public WebContentsObserver {
public:
+ static void Create(JNIEnv* env, WebContents* web_contents);
TextSuggestionHostAndroid(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
WebContents* web_contents);
~TextSuggestionHostAndroid() override;
@@ -95,6 +95,7 @@ class TextSuggestionHostAndroid : public RenderWidgetHostConnector,
private:
RenderFrameHost* GetFocusedFrame();
+ base::android::ScopedJavaLocalRef<jobject> GetJavaTextSuggestionHost();
const blink::mojom::TextSuggestionBackendPtr& GetTextSuggestionBackend();
// Used by the spell check menu timer to notify Blink that the timer has
// expired.
diff --git a/chromium/content/browser/android/url_request_content_job.h b/chromium/content/browser/android/url_request_content_job.h
index 40a97470a83..e389fdd3073 100644
--- a/chromium/content/browser/android/url_request_content_job.h
+++ b/chromium/content/browser/android/url_request_content_job.h
@@ -31,6 +31,9 @@ class FileStream;
namespace content {
// A request job that handles reading content URIs
+//
+// Note that when the Network Service is enabled, ContentUrlLoaderFactory is
+// used instead.
class CONTENT_EXPORT URLRequestContentJob : public net::URLRequestJob {
public:
URLRequestContentJob(
diff --git a/chromium/content/browser/android/web_contents_observer_proxy.cc b/chromium/content/browser/android/web_contents_observer_proxy.cc
index 988ede89422..84b5241b810 100644
--- a/chromium/content/browser/android/web_contents_observer_proxy.cc
+++ b/chromium/content/browser/android/web_contents_observer_proxy.cc
@@ -138,8 +138,13 @@ void WebContentsObserverProxy::DidStartNavigation(
void WebContentsObserverProxy::DidFinishNavigation(
NavigationHandle* navigation_handle) {
JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jstring> jstring_url(
- ConvertUTF8ToJavaString(env, navigation_handle->GetURL().spec()));
+ // Matches logic in
+ // components/navigation_interception/navigation_params_android.cc
+ ScopedJavaLocalRef<jstring> jstring_url(ConvertUTF8ToJavaString(
+ env,
+ navigation_handle->GetBaseURLForDataURL().is_empty()
+ ? navigation_handle->GetURL().spec()
+ : navigation_handle->GetBaseURLForDataURL().possibly_invalid_spec()));
bool is_fragment_navigation = navigation_handle->IsSameDocument();
@@ -161,6 +166,7 @@ void WebContentsObserverProxy::DidFinishNavigation(
env, java_observer_, jstring_url, navigation_handle->IsInMainFrame(),
navigation_handle->IsErrorPage(), navigation_handle->HasCommitted(),
navigation_handle->IsSameDocument(), is_fragment_navigation,
+ navigation_handle->IsRendererInitiated(), navigation_handle->IsDownload(),
navigation_handle->HasCommitted() ? navigation_handle->GetPageTransition()
: -1,
navigation_handle->GetNetErrorCode(), jerror_description,
@@ -277,4 +283,9 @@ void WebContentsObserverProxy::ViewportFitChanged(
env, java_observer_, as_jint(static_cast<int>(value)));
}
+void WebContentsObserverProxy::DidReloadLoFiImages() {
+ JNIEnv* env = AttachCurrentThread();
+ Java_WebContentsObserverProxy_didReloadLoFiImages(env, java_observer_);
+}
+
} // namespace content
diff --git a/chromium/content/browser/android/web_contents_observer_proxy.h b/chromium/content/browser/android/web_contents_observer_proxy.h
index e79ad3edb59..ccc54e0a776 100644
--- a/chromium/content/browser/android/web_contents_observer_proxy.h
+++ b/chromium/content/browser/android/web_contents_observer_proxy.h
@@ -59,6 +59,7 @@ class WebContentsObserverProxy : public WebContentsObserver {
void MediaEffectivelyFullscreenChanged(bool is_fullscreen) override;
void SetToBaseURLForDataURLIfNeeded(std::string* url);
void ViewportFitChanged(blink::mojom::ViewportFit value) override;
+ void DidReloadLoFiImages() override;
base::android::ScopedJavaGlobalRef<jobject> java_observer_;
GURL base_url_of_last_started_data_url_;
diff --git a/chromium/content/browser/appcache/appcache.cc b/chromium/content/browser/appcache/appcache.cc
index 5390894d2ed..0dc8369a996 100644
--- a/chromium/content/browser/appcache/appcache.cc
+++ b/chromium/content/browser/appcache/appcache.cc
@@ -61,14 +61,14 @@ bool AppCache::AddOrModifyEntry(const GURL& url, const AppCacheEntry& entry) {
}
void AppCache::RemoveEntry(const GURL& url) {
- EntryMap::iterator found = entries_.find(url);
+ auto found = entries_.find(url);
DCHECK(found != entries_.end());
cache_size_ -= found->second.response_size();
entries_.erase(found);
}
AppCacheEntry* AppCache::GetEntry(const GURL& url) {
- EntryMap::iterator it = entries_.find(url);
+ auto it = entries_.find(url);
return (it != entries_.end()) ? &(it->second) : nullptr;
}
diff --git a/chromium/content/browser/appcache/appcache_database.cc b/chromium/content/browser/appcache/appcache_database.cc
index e3d373be53a..96ae9e4c8d4 100644
--- a/chromium/content/browser/appcache/appcache_database.cc
+++ b/chromium/content/browser/appcache/appcache_database.cc
@@ -24,6 +24,20 @@ namespace content {
// Schema -------------------------------------------------------------------
namespace {
+// Version number of the database.
+//
+// We support migrating the database schema from versions that are at most 2
+// years old. Older versions are unsupported, and will cause the database to get
+// nuked.
+//
+// Version 0 - 2009-12-28 - https://crrev.com/501033 (unsupported)
+// Version 1 - 2010-01-20 - https://crrev.com/554008 (unsupported)
+// Version 2 - 2010-02-23 - https://crrev.com/630009 (unsupported)
+// Version 3 - 2010-03-17 - https://crrev.com/886003 (unsupported)
+// Version 4 - 2011-12-12 - https://crrev.com/8396013 (unsupported)
+// Version 5 - 2013-03-29 - https://crrev.com/12628006 (unsupported)
+// Version 6 - 2013-09-20 - https://crrev.com/23503069 (unsupported)
+// Version 7 - 2015-07-09 - https://crrev.com/879393002
const int kCurrentVersion = 7;
const int kCompatibleVersion = 7;
const bool kCreateIfNeeded = true;
@@ -1141,117 +1155,7 @@ bool AppCacheDatabase::CreateSchema() {
}
bool AppCacheDatabase::UpgradeSchema() {
-#if defined(APPCACHE_USE_SIMPLE_CACHE)
- if (meta_table_->GetVersionNumber() < 6)
- return DeleteExistingAndCreateNewDatabase();
-#endif
- if (meta_table_->GetVersionNumber() == 3) {
- // version 3 was pre 12/17/2011
- DCHECK_EQ(strcmp(kNamespacesTable, kTables[3].table_name), 0);
- DCHECK_EQ(strcmp(kNamespacesTable, kIndexes[6].table_name), 0);
- DCHECK_EQ(strcmp(kNamespacesTable, kIndexes[7].table_name), 0);
- DCHECK_EQ(strcmp(kNamespacesTable, kIndexes[8].table_name), 0);
-
- const TableInfo kNamespaceTable_v4 = {
- kNamespacesTable,
- "(cache_id INTEGER,"
- " origin TEXT," // intentionally not normalized
- " type INTEGER,"
- " namespace_url TEXT,"
- " target_url TEXT)"
- };
-
- // Migrate from the old FallbackNameSpaces to the newer Namespaces table,
- // but without the is_pattern column added in v5.
- sql::Transaction transaction(db_.get());
- if (!transaction.Begin() ||
- !CreateTable(db_.get(), kNamespaceTable_v4)) {
- return false;
- }
-
- // Move data from the old table to the new table, setting the
- // 'type' for all current records to the value for
- // APPCACHE_FALLBACK_NAMESPACE.
- DCHECK_EQ(0, static_cast<int>(APPCACHE_FALLBACK_NAMESPACE));
- if (!db_->Execute(
- "INSERT INTO Namespaces"
- " SELECT cache_id, origin, 0, namespace_url, fallback_entry_url"
- " FROM FallbackNameSpaces")) {
- return false;
- }
-
- // Drop the old table, indexes on that table are also removed by this.
- if (!db_->Execute("DROP TABLE FallbackNameSpaces"))
- return false;
-
- // Create new indexes.
- if (!CreateIndex(db_.get(), kIndexes[6]) ||
- !CreateIndex(db_.get(), kIndexes[7]) ||
- !CreateIndex(db_.get(), kIndexes[8])) {
- return false;
- }
-
- meta_table_->SetVersionNumber(4);
- meta_table_->SetCompatibleVersionNumber(4);
- if (!transaction.Commit())
- return false;
- }
-
- if (meta_table_->GetVersionNumber() == 4) {
- // version 4 pre 3/30/2013
- // Add the is_pattern column to the Namespaces and OnlineWhitelists tables.
- DCHECK_EQ(strcmp(kNamespacesTable, "Namespaces"), 0);
- sql::Transaction transaction(db_.get());
- if (!transaction.Begin())
- return false;
- if (!db_->Execute(
- "ALTER TABLE Namespaces ADD COLUMN"
- " is_pattern INTEGER CHECK(is_pattern IN (0, 1))")) {
- return false;
- }
- if (!db_->Execute(
- "ALTER TABLE OnlineWhitelists ADD COLUMN"
- " is_pattern INTEGER CHECK(is_pattern IN (0, 1))")) {
- return false;
- }
- meta_table_->SetVersionNumber(5);
- meta_table_->SetCompatibleVersionNumber(5);
- if (!transaction.Commit())
- return false;
- }
-
-#if defined(APPCACHE_USE_SIMPLE_CACHE)
- // The schema version number was increased to 6 when we switched to the
- // SimpleCache for Android, but the SQL part of the schema is identical
- // to v5 on desktop chrome.
- if (meta_table_->GetVersionNumber() == 6) {
-#else
- if (meta_table_->GetVersionNumber() == 5) {
-#endif
- // Versions 5 and 6 were pre-July 2015.
- // Version 7 adds support for expiring caches that are failing to update.
- sql::Transaction transaction(db_.get());
- if (!transaction.Begin() ||
- !db_->Execute(
- "ALTER TABLE Groups ADD COLUMN"
- " last_full_update_check_time INTEGER") ||
- !db_->Execute(
- "ALTER TABLE Groups ADD COLUMN"
- " first_evictable_error_time INTEGER") ||
- !db_->Execute(
- "UPDATE Groups"
- " SET last_full_update_check_time ="
- " (SELECT update_time FROM Caches"
- " WHERE Caches.group_id = Groups.group_id)")) {
- return false;
- }
- meta_table_->SetVersionNumber(7);
- meta_table_->SetCompatibleVersionNumber(7);
- return transaction.Commit();
- }
-
- // If there is no upgrade path for the version on disk to the current
- // version, nuke everything and start over.
+ // The version on disk is deprecated.
return DeleteExistingAndCreateNewDatabase();
}
diff --git a/chromium/content/browser/appcache/appcache_database.h b/chromium/content/browser/appcache/appcache_database.h
index fe3e144e8ca..5aecf70ec3f 100644
--- a/chromium/content/browser/appcache/appcache_database.h
+++ b/chromium/content/browser/appcache/appcache_database.h
@@ -41,9 +41,7 @@ FORWARD_DECLARE_TEST(AppCacheDatabaseTest, OnlineWhiteListRecords);
FORWARD_DECLARE_TEST(AppCacheDatabaseTest, ReCreate);
FORWARD_DECLARE_TEST(AppCacheDatabaseTest, DeletableResponseIds);
FORWARD_DECLARE_TEST(AppCacheDatabaseTest, OriginUsage);
-FORWARD_DECLARE_TEST(AppCacheDatabaseTest, UpgradeSchema3to7);
-FORWARD_DECLARE_TEST(AppCacheDatabaseTest, UpgradeSchema4to7);
-FORWARD_DECLARE_TEST(AppCacheDatabaseTest, UpgradeSchema5or6to7);
+FORWARD_DECLARE_TEST(AppCacheDatabaseTest, UpgradeSchemaNukesDeprecatedVersion);
FORWARD_DECLARE_TEST(AppCacheDatabaseTest, WasCorrutionDetected);
class AppCacheDatabaseTest;
class AppCacheStorageImplTest;
@@ -258,9 +256,8 @@ class CONTENT_EXPORT AppCacheDatabase {
FRIEND_TEST_ALL_PREFIXES(content::AppCacheDatabaseTest, ReCreate);
FRIEND_TEST_ALL_PREFIXES(content::AppCacheDatabaseTest, DeletableResponseIds);
FRIEND_TEST_ALL_PREFIXES(content::AppCacheDatabaseTest, OriginUsage);
- FRIEND_TEST_ALL_PREFIXES(content::AppCacheDatabaseTest, UpgradeSchema3to7);
- FRIEND_TEST_ALL_PREFIXES(content::AppCacheDatabaseTest, UpgradeSchema4to7);
- FRIEND_TEST_ALL_PREFIXES(content::AppCacheDatabaseTest, UpgradeSchema5or6to7);
+ FRIEND_TEST_ALL_PREFIXES(content::AppCacheDatabaseTest,
+ UpgradeSchemaNukesDeprecatedVersion);
FRIEND_TEST_ALL_PREFIXES(content::AppCacheDatabaseTest, WasCorrutionDetected);
DISALLOW_COPY_AND_ASSIGN(AppCacheDatabase);
diff --git a/chromium/content/browser/appcache/appcache_database_unittest.cc b/chromium/content/browser/appcache/appcache_database_unittest.cc
index 53b5e2e317f..4145ded8318 100644
--- a/chromium/content/browser/appcache/appcache_database_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_database_unittest.cc
@@ -826,481 +826,38 @@ TEST(AppCacheDatabaseTest, OriginUsage) {
EXPECT_EQ(5000, usage_map[kOtherOrigin]);
}
-#if defined(APPCACHE_USE_SIMPLE_CACHE)
-// There is no such upgrade path in this case.
-#else
-TEST(AppCacheDatabaseTest, UpgradeSchema4to7) {
+TEST(AppCacheDatabaseTest, UpgradeSchemaNukesDeprecatedVersion) {
// Real file on disk for this test.
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- const base::FilePath kDbFile = temp_dir.GetPath().AppendASCII("upgrade4.db");
-
- const GURL kMockOrigin("http://mockorigin/");
- const char kNamespaceUrlFormat[] = "namespace%d";
- const char kWhitelistUrlFormat[] = "whitelist%d";
- const char kTargetUrlFormat[] = "target%d";
- const int kNumNamespaces = 10;
- const int kWhitelistCacheId = 1;
+ const base::FilePath kDbFile =
+ temp_dir.GetPath().AppendASCII("deprecated.db");
- // Create a v4 schema based database containing some fallback records.
+ // Create a database with a table name that does not show up in the AppCache
+ // schema. This table would not be touched by any migration, so its existence
+ // indicates that the database was not nuked.
{
- const int kVersion4 = 4;
- const char kGroupsTable[] = "Groups";
- const char kCachesTable[] = "Caches";
- const char kEntriesTable[] = "Entries";
- const char kNamespacesTable[] = "Namespaces";
- const char kOnlineWhiteListsTable[] = "OnlineWhiteLists";
- const char kDeletableResponseIdsTable[] = "DeletableResponseIds";
-
- struct TableInfo {
- const char* table_name;
- const char* columns;
- };
-
- struct IndexInfo {
- const char* index_name;
- const char* table_name;
- const char* columns;
- bool unique;
- };
-
- const TableInfo kTables4[] = {
- { kGroupsTable,
- "(group_id INTEGER PRIMARY KEY,"
- " origin TEXT,"
- " manifest_url TEXT,"
- " creation_time INTEGER,"
- " last_access_time INTEGER)" },
-
- { kCachesTable,
- "(cache_id INTEGER PRIMARY KEY,"
- " group_id INTEGER,"
- " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1)),"
- " update_time INTEGER,"
- " cache_size INTEGER)" }, // intentionally not normalized
-
- { kEntriesTable,
- "(cache_id INTEGER,"
- " url TEXT,"
- " flags INTEGER,"
- " response_id INTEGER,"
- " response_size INTEGER)" },
-
- { kNamespacesTable,
- "(cache_id INTEGER,"
- " origin TEXT," // intentionally not normalized
- " type INTEGER,"
- " namespace_url TEXT,"
- " target_url TEXT)" },
-
- { kOnlineWhiteListsTable,
- "(cache_id INTEGER,"
- " namespace_url TEXT)" },
-
- { kDeletableResponseIdsTable,
- "(response_id INTEGER NOT NULL)" },
- };
-
- const IndexInfo kIndexes4[] = {
- { "GroupsOriginIndex",
- kGroupsTable,
- "(origin)",
- false },
-
- { "GroupsManifestIndex",
- kGroupsTable,
- "(manifest_url)",
- true },
-
- { "CachesGroupIndex",
- kCachesTable,
- "(group_id)",
- false },
-
- { "EntriesCacheIndex",
- kEntriesTable,
- "(cache_id)",
- false },
-
- { "EntriesCacheAndUrlIndex",
- kEntriesTable,
- "(cache_id, url)",
- true },
-
- { "EntriesResponseIdIndex",
- kEntriesTable,
- "(response_id)",
- true },
-
- { "NamespacesCacheIndex",
- kNamespacesTable,
- "(cache_id)",
- false },
-
- { "NamespacesOriginIndex",
- kNamespacesTable,
- "(origin)",
- false },
-
- { "NamespacesCacheAndUrlIndex",
- kNamespacesTable,
- "(cache_id, namespace_url)",
- true },
-
- { "OnlineWhiteListCacheIndex",
- kOnlineWhiteListsTable,
- "(cache_id)",
- false },
-
- { "DeletableResponsesIdIndex",
- kDeletableResponseIdsTable,
- "(response_id)",
- true },
- };
-
- const int kTableCount4 = arraysize(kTables4);
- const int kIndexCount4 = arraysize(kIndexes4);
-
- sql::Database connection;
- EXPECT_TRUE(connection.Open(kDbFile));
-
- sql::Transaction transaction(&connection);
- EXPECT_TRUE(transaction.Begin());
+ sql::Database db;
+ EXPECT_TRUE(db.Open(kDbFile));
sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&connection, kVersion4, kVersion4));
-
- for (int i = 0; i < kTableCount4; ++i) {
- std::string sql("CREATE TABLE ");
- sql += kTables4[i].table_name;
- sql += kTables4[i].columns;
- EXPECT_TRUE(connection.Execute(sql.c_str()));
- }
-
- for (int i = 0; i < kIndexCount4; ++i) {
- std::string sql;
- if (kIndexes4[i].unique)
- sql += "CREATE UNIQUE INDEX ";
- else
- sql += "CREATE INDEX ";
- sql += kIndexes4[i].index_name;
- sql += " ON ";
- sql += kIndexes4[i].table_name;
- sql += kIndexes4[i].columns;
- EXPECT_TRUE(connection.Execute(sql.c_str()));
- }
-
- const char* kNamespacesSql =
- "INSERT INTO Namespaces"
- " (cache_id, origin, type, namespace_url, target_url)"
- " VALUES (?, ?, ?, ?, ?)";
- sql::Statement statement;
- statement.Assign(connection.GetUniqueStatement(kNamespacesSql));
- EXPECT_TRUE(statement.is_valid());
- for (int i = 0; i < kNumNamespaces; ++i) {
- GURL namespace_url(
- kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i)));
- GURL target_url(
- kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i)));
- statement.BindInt64(0, i);
- statement.BindString(1, kMockOrigin.spec().c_str());
- statement.BindInt(2, APPCACHE_FALLBACK_NAMESPACE);
- statement.BindString(3, namespace_url.spec().c_str());
- statement.BindString(4, target_url.spec().c_str());
- ASSERT_TRUE(statement.Run());
- statement.Reset(true);
- }
-
- const char* kWhitelistsSql =
- "INSERT INTO OnlineWhiteLists"
- " (cache_id, namespace_url)"
- " VALUES (?, ?)";
- statement.Assign(connection.GetUniqueStatement(kWhitelistsSql));
- EXPECT_TRUE(statement.is_valid());
- for (int i = 0; i < kNumNamespaces; ++i) {
- GURL namespace_url(
- kMockOrigin.Resolve(base::StringPrintf(kWhitelistUrlFormat, i)));
- statement.BindInt64(0, kWhitelistCacheId);
- statement.BindString(1, namespace_url.spec().c_str());
- ASSERT_TRUE(statement.Run());
- statement.Reset(true);
- }
-
- EXPECT_TRUE(transaction.Commit());
- }
+ EXPECT_TRUE(meta_table.Init(&db, 6, 6));
- // Open that database and verify that it got upgraded to v7.
- AppCacheDatabase db(kDbFile);
- EXPECT_TRUE(db.LazyOpen(true));
- EXPECT_TRUE(db.db_->DoesColumnExist("Namespaces", "is_pattern"));
- EXPECT_TRUE(db.db_->DoesColumnExist("OnlineWhiteLists", "is_pattern"));
- EXPECT_TRUE(db.db_->DoesColumnExist("Groups",
- "last_full_update_check_time"));
- EXPECT_TRUE(db.db_->DoesColumnExist("Groups",
- "first_evictable_error_time"));
- EXPECT_EQ(7, db.meta_table_->GetVersionNumber());
- EXPECT_EQ(7, db.meta_table_->GetCompatibleVersionNumber());
+ static const char kSchemaSql[] =
+ "CREATE TABLE Unused(id INTEGER PRIMARY KEY)";
+ EXPECT_TRUE(db.Execute(kSchemaSql));
- std::vector<AppCacheDatabase::NamespaceRecord> intercepts;
- std::vector<AppCacheDatabase::NamespaceRecord> fallbacks;
- EXPECT_TRUE(db.FindNamespacesForOrigin(url::Origin::Create(kMockOrigin),
- &intercepts, &fallbacks));
- EXPECT_TRUE(intercepts.empty());
- EXPECT_EQ(kNumNamespaces, static_cast<int>(fallbacks.size()));
-
- std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists;
- EXPECT_TRUE(db.FindOnlineWhiteListForCache(kWhitelistCacheId, &whitelists));
- EXPECT_EQ(kNumNamespaces, static_cast<int>(whitelists.size()));
-
- for (int i = 0; i < kNumNamespaces; ++i) {
- GURL expected_namespace_url(
- kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i)));
- GURL expected_target_url(
- kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i)));
- GURL expected_whitelist_url(
- kMockOrigin.Resolve(base::StringPrintf(kWhitelistUrlFormat, i)));
-
- EXPECT_EQ(i, fallbacks[i].cache_id);
- EXPECT_EQ(APPCACHE_FALLBACK_NAMESPACE, fallbacks[i].namespace_.type);
- EXPECT_EQ(url::Origin::Create(kMockOrigin), fallbacks[i].origin);
- EXPECT_EQ(expected_namespace_url, fallbacks[i].namespace_.namespace_url);
- EXPECT_EQ(expected_target_url, fallbacks[i].namespace_.target_url);
- EXPECT_FALSE(fallbacks[i].namespace_.is_pattern);
- EXPECT_EQ(expected_whitelist_url, whitelists[i].namespace_url);
- EXPECT_FALSE(whitelists[i].is_pattern);
+ EXPECT_TRUE(db.DoesColumnExist("Unused", "id"));
}
-}
-#endif // !APPCACHE_USE_SIMPLE_CACHE
-// Verify last_full_update_check_time and first_evictable_error_time.
-TEST(AppCacheDatabaseTest, UpgradeSchema5or6to7) {
- // Real file on disk for this test.
- base::ScopedTempDir temp_dir;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- const base::FilePath kDbFile =
- temp_dir.GetPath().AppendASCII("upgrade5or6to7.db");
-
- const GURL kMockOrigin("http://mockorigin/");
- const base::Time kMockTime = base::Time::Now();
-
- // Create a v5or6 schema based database containing two groups, one
- // that has an associated cache as expected, and one which erroneously
- // is missing its cache record.
- {
- // The SQL schema is the same in these two cases.
-#if defined(APPCACHE_USE_SIMPLE_CACHE)
- const int kVersionN = 6;
-#else
- const int kVersionN = 5;
-#endif // !APPCACHE_USE_SIMPLE_CACHE
-
- const char kGroupsTable[] = "Groups";
- const char kCachesTable[] = "Caches";
- const char kEntriesTable[] = "Entries";
- const char kNamespacesTable[] = "Namespaces";
- const char kOnlineWhiteListsTable[] = "OnlineWhiteLists";
- const char kDeletableResponseIdsTable[] = "DeletableResponseIds";
-
- struct TableInfo {
- const char* table_name;
- const char* columns;
- };
-
- struct IndexInfo {
- const char* index_name;
- const char* table_name;
- const char* columns;
- bool unique;
- };
-
- const TableInfo kTables5[] = {
- { kGroupsTable,
- "(group_id INTEGER PRIMARY KEY,"
- " origin TEXT,"
- " manifest_url TEXT,"
- " creation_time INTEGER,"
- " last_access_time INTEGER)" },
-
- { kCachesTable,
- "(cache_id INTEGER PRIMARY KEY,"
- " group_id INTEGER,"
- " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1)),"
- " update_time INTEGER,"
- " cache_size INTEGER)" }, // intentionally not normalized
-
- { kEntriesTable,
- "(cache_id INTEGER,"
- " url TEXT,"
- " flags INTEGER,"
- " response_id INTEGER,"
- " response_size INTEGER)" },
-
- { kNamespacesTable,
- "(cache_id INTEGER,"
- " origin TEXT," // intentionally not normalized
- " type INTEGER,"
- " namespace_url TEXT,"
- " target_url TEXT,"
- " is_pattern INTEGER CHECK(is_pattern IN (0, 1)))" },
-
- { kOnlineWhiteListsTable,
- "(cache_id INTEGER,"
- " namespace_url TEXT,"
- " is_pattern INTEGER CHECK(is_pattern IN (0, 1)))" },
-
- { kDeletableResponseIdsTable,
- "(response_id INTEGER NOT NULL)" },
- };
-
- const IndexInfo kIndexes5[] = {
- { "GroupsOriginIndex",
- kGroupsTable,
- "(origin)",
- false },
-
- { "GroupsManifestIndex",
- kGroupsTable,
- "(manifest_url)",
- true },
-
- { "CachesGroupIndex",
- kCachesTable,
- "(group_id)",
- false },
-
- { "EntriesCacheIndex",
- kEntriesTable,
- "(cache_id)",
- false },
-
- { "EntriesCacheAndUrlIndex",
- kEntriesTable,
- "(cache_id, url)",
- true },
-
- { "EntriesResponseIdIndex",
- kEntriesTable,
- "(response_id)",
- true },
-
- { "NamespacesCacheIndex",
- kNamespacesTable,
- "(cache_id)",
- false },
-
- { "NamespacesOriginIndex",
- kNamespacesTable,
- "(origin)",
- false },
-
- { "NamespacesCacheAndUrlIndex",
- kNamespacesTable,
- "(cache_id, namespace_url)",
- true },
-
- { "OnlineWhiteListCacheIndex",
- kOnlineWhiteListsTable,
- "(cache_id)",
- false },
-
- { "DeletableResponsesIdIndex",
- kDeletableResponseIdsTable,
- "(response_id)",
- true },
- };
-
- const int kTableCount5 = arraysize(kTables5);
- const int kIndexCount5 = arraysize(kIndexes5);
-
- sql::Database connection;
- EXPECT_TRUE(connection.Open(kDbFile));
-
- sql::Transaction transaction(&connection);
- EXPECT_TRUE(transaction.Begin());
-
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&connection, kVersionN, kVersionN));
-
- for (int i = 0; i < kTableCount5; ++i) {
- std::string sql("CREATE TABLE ");
- sql += kTables5[i].table_name;
- sql += kTables5[i].columns;
- EXPECT_TRUE(connection.Execute(sql.c_str()));
- }
-
- for (int i = 0; i < kIndexCount5; ++i) {
- std::string sql;
- if (kIndexes5[i].unique)
- sql += "CREATE UNIQUE INDEX ";
- else
- sql += "CREATE INDEX ";
- sql += kIndexes5[i].index_name;
- sql += " ON ";
- sql += kIndexes5[i].table_name;
- sql += kIndexes5[i].columns;
- EXPECT_TRUE(connection.Execute(sql.c_str()));
- }
-
- sql::Statement statement;
-
- const GURL kMockManifestUrl(kMockOrigin.Resolve("mockmanifest"));
- const GURL kMockManifest2Url(kMockOrigin.Resolve("mockmanifest2"));
-
- const char* kInsertGroup =
- "INSERT INTO Groups"
- " (group_id, origin, manifest_url, creation_time, last_access_time)"
- " VALUES (?, ?, ?, ?, ?)";
- statement.Assign(connection.GetUniqueStatement(kInsertGroup));
- EXPECT_TRUE(statement.is_valid());
- statement.BindInt64(0, 1);
- statement.BindString(1, kMockOrigin.spec().c_str());
- statement.BindString(2, kMockManifestUrl.spec().c_str());
- statement.BindInt64(3, kMockTime.ToInternalValue());
- statement.BindInt64(4, kMockTime.ToInternalValue());
- ASSERT_TRUE(statement.Run());
- statement.Reset(true);
- statement.BindInt64(0, 2);
- statement.BindString(1, kMockOrigin.spec().c_str());
- statement.BindString(2, kMockManifest2Url.spec().c_str());
- statement.BindInt64(3, kMockTime.ToInternalValue());
- statement.BindInt64(4, kMockTime.ToInternalValue());
- ASSERT_TRUE(statement.Run());
- statement.Reset(true);
-
- const char* kInsertCache =
- "INSERT INTO Caches"
- " (cache_id, group_id, online_wildcard, update_time, cache_size)"
- " VALUES (?, ?, ?, ?, ?)";
- statement.Assign(connection.GetUniqueStatement(kInsertCache));
- EXPECT_TRUE(statement.is_valid());
- statement.BindInt64(0, 1);
- statement.BindInt64(1, 1);
- statement.BindInt(2, 0);
- statement.BindInt64(3, kMockTime.ToInternalValue());
- statement.BindInt64(4, 1000);
- ASSERT_TRUE(statement.Run());
- statement.Reset(true);
-
- EXPECT_TRUE(transaction.Commit());
- }
-
- // Open that database and verify that it got upgraded to v7.
+ // Open that database and verify that it got nuked.
AppCacheDatabase db(kDbFile);
- EXPECT_TRUE(db.LazyOpen(true));
+ EXPECT_TRUE(db.LazyOpen(/*create_if_needed=*/false));
+ EXPECT_FALSE(db.db_->DoesColumnExist("Unused", "id"));
EXPECT_TRUE(db.db_->DoesColumnExist("Groups",
"last_full_update_check_time"));
- EXPECT_TRUE(db.db_->DoesColumnExist("Groups",
- "first_evictable_error_time"));
EXPECT_EQ(7, db.meta_table_->GetVersionNumber());
EXPECT_EQ(7, db.meta_table_->GetCompatibleVersionNumber());
-
- AppCacheDatabase::GroupRecord group;
- EXPECT_TRUE(db.FindGroup(1, &group));
- EXPECT_EQ(kMockTime, group.last_full_update_check_time);
- EXPECT_EQ(kZeroTime, group.first_evictable_error_time);
- EXPECT_TRUE(db.FindGroup(2, &group));
- EXPECT_EQ(kZeroTime, group.last_full_update_check_time);
- EXPECT_EQ(kZeroTime, group.first_evictable_error_time);
}
} // namespace content
diff --git a/chromium/content/browser/appcache/appcache_disk_cache.cc b/chromium/content/browser/appcache/appcache_disk_cache.cc
index c7018934cb2..242bf8c88f1 100644
--- a/chromium/content/browser/appcache/appcache_disk_cache.cc
+++ b/chromium/content/browser/appcache/appcache_disk_cache.cc
@@ -34,9 +34,9 @@ class AppCacheDiskCache::CreateBackendCallbackShim
void Cancel() { appcache_diskcache_ = nullptr; }
- void Callback(int rv) {
+ void Callback(int return_value) {
if (appcache_diskcache_)
- appcache_diskcache_->OnCreateBackendComplete(rv);
+ appcache_diskcache_->OnCreateBackendComplete(return_value);
}
std::unique_ptr<disk_cache::Backend> backend_ptr_; // Accessed directly.
@@ -50,118 +50,108 @@ class AppCacheDiskCache::CreateBackendCallbackShim
AppCacheDiskCache* appcache_diskcache_; // Unowned pointer.
};
-// An implementation of AppCacheDiskCacheInterface::Entry that's a thin
-// wrapper around disk_cache::Entry.
-class AppCacheDiskCache::EntryImpl : public Entry {
- public:
- EntryImpl(disk_cache::Entry* disk_cache_entry,
- AppCacheDiskCache* owner)
- : disk_cache_entry_(disk_cache_entry), owner_(owner) {
- DCHECK(disk_cache_entry);
- DCHECK(owner);
- owner_->AddOpenEntry(this);
- }
+AppCacheDiskCacheEntry::AppCacheDiskCacheEntry(
+ disk_cache::Entry* disk_cache_entry,
+ AppCacheDiskCache* cache)
+ : disk_cache_entry_(disk_cache_entry), cache_(cache) {
+ DCHECK(disk_cache_entry);
+ DCHECK(cache);
+ cache_->AddOpenEntry(this);
+}
- // Entry implementation.
- int Read(int index,
- int64_t offset,
- net::IOBuffer* buf,
- int buf_len,
- net::CompletionOnceCallback callback) override {
- if (offset < 0 || offset > std::numeric_limits<int32_t>::max())
- return net::ERR_INVALID_ARGUMENT;
- if (!disk_cache_entry_)
- return net::ERR_ABORTED;
- return disk_cache_entry_->ReadData(index, static_cast<int>(offset), buf,
- buf_len, std::move(callback));
- }
+AppCacheDiskCacheEntry::~AppCacheDiskCacheEntry() {
+ if (cache_)
+ cache_->RemoveOpenEntry(this);
+}
- int Write(int index,
- int64_t offset,
- net::IOBuffer* buf,
- int buf_len,
- net::CompletionOnceCallback callback) override {
- if (offset < 0 || offset > std::numeric_limits<int32_t>::max())
- return net::ERR_INVALID_ARGUMENT;
- if (!disk_cache_entry_)
- return net::ERR_ABORTED;
- const bool kTruncate = true;
- return disk_cache_entry_->WriteData(index, static_cast<int>(offset), buf,
- buf_len, std::move(callback),
- kTruncate);
- }
+int AppCacheDiskCacheEntry::Read(int index,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ net::CompletionOnceCallback callback) {
+ if (offset < 0 || offset > std::numeric_limits<int32_t>::max())
+ return net::ERR_INVALID_ARGUMENT;
+ if (!disk_cache_entry_)
+ return net::ERR_ABORTED;
+ return disk_cache_entry_->ReadData(index, static_cast<int>(offset), buf,
+ buf_len, std::move(callback));
+}
- int64_t GetSize(int index) override {
- return disk_cache_entry_ ? disk_cache_entry_->GetDataSize(index) : 0L;
- }
+int AppCacheDiskCacheEntry::Write(int index,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ net::CompletionOnceCallback callback) {
+ if (offset < 0 || offset > std::numeric_limits<int32_t>::max())
+ return net::ERR_INVALID_ARGUMENT;
+ if (!disk_cache_entry_)
+ return net::ERR_ABORTED;
+ const bool kTruncate = true;
+ return disk_cache_entry_->WriteData(index, static_cast<int>(offset), buf,
+ buf_len, std::move(callback), kTruncate);
+}
- void Close() override {
- if (disk_cache_entry_)
- disk_cache_entry_->Close();
- delete this;
- }
+int64_t AppCacheDiskCacheEntry::GetSize(int index) {
+ return disk_cache_entry_ ? disk_cache_entry_->GetDataSize(index) : 0L;
+}
- void Abandon() {
- owner_ = nullptr;
+void AppCacheDiskCacheEntry::Close() {
+ if (disk_cache_entry_)
disk_cache_entry_->Close();
- disk_cache_entry_ = nullptr;
- }
-
- private:
- ~EntryImpl() override {
- if (owner_)
- owner_->RemoveOpenEntry(this);
- }
+ delete this;
+}
- disk_cache::Entry* disk_cache_entry_;
- AppCacheDiskCache* owner_;
-};
+void AppCacheDiskCacheEntry::Abandon() {
+ cache_ = nullptr;
+ disk_cache_entry_->Close();
+ disk_cache_entry_ = nullptr;
+}
// Separate object to hold state for each Create, Delete, or Doom call
// while the call is in-flight and to produce an EntryImpl upon completion.
class AppCacheDiskCache::ActiveCall
: public base::RefCounted<AppCacheDiskCache::ActiveCall> {
public:
- static int CreateEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
- int64_t key,
- Entry** entry,
- net::CompletionOnceCallback callback) {
+ static net::Error CreateEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
+ int64_t key,
+ AppCacheDiskCacheEntry** entry,
+ net::CompletionOnceCallback callback) {
scoped_refptr<ActiveCall> active_call(
new ActiveCall(owner, entry, std::move(callback)));
- int rv = owner->disk_cache()->CreateEntry(
+ net::Error return_value = owner->disk_cache()->CreateEntry(
base::Int64ToString(key), net::HIGHEST, &active_call->entry_ptr_,
base::BindOnce(&ActiveCall::OnAsyncCompletion, active_call));
- return active_call->HandleImmediateReturnValue(rv);
+ return active_call->HandleImmediateReturnValue(return_value);
}
- static int OpenEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
- int64_t key,
- Entry** entry,
- net::CompletionOnceCallback callback) {
+ static net::Error OpenEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
+ int64_t key,
+ AppCacheDiskCacheEntry** entry,
+ net::CompletionOnceCallback callback) {
scoped_refptr<ActiveCall> active_call(
new ActiveCall(owner, entry, std::move(callback)));
- int rv = owner->disk_cache()->OpenEntry(
+ net::Error return_value = owner->disk_cache()->OpenEntry(
base::Int64ToString(key), net::HIGHEST, &active_call->entry_ptr_,
base::BindOnce(&ActiveCall::OnAsyncCompletion, active_call));
- return active_call->HandleImmediateReturnValue(rv);
+ return active_call->HandleImmediateReturnValue(return_value);
}
- static int DoomEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
- int64_t key,
- net::CompletionOnceCallback callback) {
+ static net::Error DoomEntry(const base::WeakPtr<AppCacheDiskCache>& owner,
+ int64_t key,
+ net::CompletionOnceCallback callback) {
scoped_refptr<ActiveCall> active_call(
new ActiveCall(owner, nullptr, std::move(callback)));
- int rv = owner->disk_cache()->DoomEntry(
+ net::Error return_value = owner->disk_cache()->DoomEntry(
base::Int64ToString(key), net::HIGHEST,
base::BindOnce(&ActiveCall::OnAsyncCompletion, active_call));
- return active_call->HandleImmediateReturnValue(rv);
+ return active_call->HandleImmediateReturnValue(return_value);
}
private:
friend class base::RefCounted<AppCacheDiskCache::ActiveCall>;
ActiveCall(const base::WeakPtr<AppCacheDiskCache>& owner,
- Entry** entry,
+ AppCacheDiskCacheEntry** entry,
net::CompletionOnceCallback callback)
: owner_(owner),
entry_(entry),
@@ -172,7 +162,7 @@ class AppCacheDiskCache::ActiveCall
~ActiveCall() {}
- int HandleImmediateReturnValue(int rv) {
+ net::Error HandleImmediateReturnValue(net::Error rv) {
if (rv == net::ERR_IO_PENDING) {
// OnAsyncCompletion will be called later.
return rv;
@@ -180,7 +170,7 @@ class AppCacheDiskCache::ActiveCall
if (rv == net::OK && entry_) {
DCHECK(entry_ptr_);
- *entry_ = new EntryImpl(entry_ptr_, owner_.get());
+ *entry_ = new AppCacheDiskCacheEntry(entry_ptr_, owner_.get());
}
return rv;
}
@@ -189,7 +179,7 @@ class AppCacheDiskCache::ActiveCall
if (rv == net::OK && entry_) {
DCHECK(entry_ptr_);
if (owner_) {
- *entry_ = new EntryImpl(entry_ptr_, owner_.get());
+ *entry_ = new AppCacheDiskCacheEntry(entry_ptr_, owner_.get());
} else {
entry_ptr_->Close();
rv = net::ERR_ABORTED;
@@ -199,16 +189,16 @@ class AppCacheDiskCache::ActiveCall
}
base::WeakPtr<AppCacheDiskCache> owner_;
- Entry** entry_;
+ AppCacheDiskCacheEntry** entry_;
net::CompletionOnceCallback callback_;
disk_cache::Entry* entry_ptr_;
};
AppCacheDiskCache::AppCacheDiskCache()
#if defined(APPCACHE_USE_SIMPLE_CACHE)
- : AppCacheDiskCache(true)
+ : AppCacheDiskCache("DiskCache.AppCache", true)
#else
- : AppCacheDiskCache(false)
+ : AppCacheDiskCache("DiskCache.AppCache", false)
#endif
{
}
@@ -217,7 +207,7 @@ AppCacheDiskCache::~AppCacheDiskCache() {
Disable();
}
-int AppCacheDiskCache::InitWithDiskBackend(
+net::Error AppCacheDiskCache::InitWithDiskBackend(
const base::FilePath& disk_cache_directory,
int disk_cache_size,
bool force,
@@ -227,7 +217,7 @@ int AppCacheDiskCache::InitWithDiskBackend(
std::move(post_cleanup_callback), std::move(callback));
}
-int AppCacheDiskCache::InitWithMemBackend(
+net::Error AppCacheDiskCache::InitWithMemBackend(
int mem_cache_size,
net::CompletionOnceCallback callback) {
return Init(net::MEMORY_CACHE, base::FilePath(), mem_cache_size, false,
@@ -249,16 +239,17 @@ void AppCacheDiskCache::Disable() {
// We need to close open file handles in order to reinitalize the
// appcache system on the fly. File handles held in both entries and in
// the main disk_cache::Backend class need to be released.
- for (EntryImpl* entry : open_entries_) {
+ for (AppCacheDiskCacheEntry* entry : open_entries_) {
entry->Abandon();
}
open_entries_.clear();
disk_cache_.reset();
}
-int AppCacheDiskCache::CreateEntry(int64_t key,
- Entry** entry,
- net::CompletionOnceCallback callback) {
+net::Error AppCacheDiskCache::CreateEntry(
+ int64_t key,
+ AppCacheDiskCacheEntry** entry,
+ net::CompletionOnceCallback callback) {
DCHECK(entry);
DCHECK(!callback.is_null());
if (is_disabled_)
@@ -277,9 +268,9 @@ int AppCacheDiskCache::CreateEntry(int64_t key,
std::move(callback));
}
-int AppCacheDiskCache::OpenEntry(int64_t key,
- Entry** entry,
- net::CompletionOnceCallback callback) {
+net::Error AppCacheDiskCache::OpenEntry(int64_t key,
+ AppCacheDiskCacheEntry** entry,
+ net::CompletionOnceCallback callback) {
DCHECK(entry);
DCHECK(!callback.is_null());
if (is_disabled_)
@@ -298,8 +289,8 @@ int AppCacheDiskCache::OpenEntry(int64_t key,
std::move(callback));
}
-int AppCacheDiskCache::DoomEntry(int64_t key,
- net::CompletionOnceCallback callback) {
+net::Error AppCacheDiskCache::DoomEntry(int64_t key,
+ net::CompletionOnceCallback callback) {
DCHECK(!callback.is_null());
if (is_disabled_)
return net::ERR_ABORTED;
@@ -317,11 +308,16 @@ int AppCacheDiskCache::DoomEntry(int64_t key,
std::move(callback));
}
-AppCacheDiskCache::AppCacheDiskCache(bool use_simple_cache)
- : AppCacheDiskCacheInterface("DiskCache.AppCache"),
- use_simple_cache_(use_simple_cache),
+base::WeakPtr<AppCacheDiskCache> AppCacheDiskCache::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
+AppCacheDiskCache::AppCacheDiskCache(const char* uma_name,
+ bool use_simple_cache)
+ : use_simple_cache_(use_simple_cache),
is_disabled_(false),
is_waiting_to_initialize_(false),
+ uma_name_(uma_name),
weak_factory_(this) {}
AppCacheDiskCache::PendingCall::PendingCall()
@@ -330,7 +326,7 @@ AppCacheDiskCache::PendingCall::PendingCall()
AppCacheDiskCache::PendingCall::PendingCall(
PendingCallType call_type,
int64_t key,
- Entry** entry,
+ AppCacheDiskCacheEntry** entry,
net::CompletionOnceCallback callback)
: call_type(call_type),
key(key),
@@ -339,19 +335,19 @@ AppCacheDiskCache::PendingCall::PendingCall(
AppCacheDiskCache::PendingCall::PendingCall(PendingCall&& other) = default;
-AppCacheDiskCache::PendingCall::~PendingCall() {}
+AppCacheDiskCache::PendingCall::~PendingCall() = default;
-int AppCacheDiskCache::Init(net::CacheType cache_type,
- const base::FilePath& cache_directory,
- int cache_size,
- bool force,
- base::OnceClosure post_cleanup_callback,
- net::CompletionOnceCallback callback) {
+net::Error AppCacheDiskCache::Init(net::CacheType cache_type,
+ const base::FilePath& cache_directory,
+ int cache_size,
+ bool force,
+ base::OnceClosure post_cleanup_callback,
+ net::CompletionOnceCallback callback) {
DCHECK(!is_initializing_or_waiting_to_initialize() && !disk_cache_.get());
is_disabled_ = false;
create_backend_callback_ = new CreateBackendCallbackShim(this);
- int rv = disk_cache::CreateCacheBackend(
+ net::Error return_value = disk_cache::CreateCacheBackend(
cache_type,
use_simple_cache_ ? net::CACHE_BACKEND_SIMPLE
: net::CACHE_BACKEND_DEFAULT,
@@ -360,22 +356,22 @@ int AppCacheDiskCache::Init(net::CacheType cache_type,
std::move(post_cleanup_callback),
base::BindOnce(&CreateBackendCallbackShim::Callback,
create_backend_callback_));
- if (rv == net::ERR_IO_PENDING)
+ if (return_value == net::ERR_IO_PENDING)
init_callback_ = std::move(callback);
else
- OnCreateBackendComplete(rv);
- return rv;
+ OnCreateBackendComplete(return_value);
+ return return_value;
}
-void AppCacheDiskCache::OnCreateBackendComplete(int rv) {
- if (rv == net::OK) {
+void AppCacheDiskCache::OnCreateBackendComplete(int return_value) {
+ if (return_value == net::OK) {
disk_cache_ = std::move(create_backend_callback_->backend_ptr_);
}
create_backend_callback_ = nullptr;
// Invoke our clients callback function.
if (!init_callback_.is_null()) {
- std::move(init_callback_).Run(rv);
+ std::move(init_callback_).Run(return_value);
}
// Service pending calls that were queued up while we were initializing.
@@ -383,23 +379,20 @@ void AppCacheDiskCache::OnCreateBackendComplete(int rv) {
// This is safe, because the callback will only be called once.
net::CompletionRepeatingCallback copyable_callback =
base::AdaptCallbackForRepeating(std::move(call.callback));
- rv = net::ERR_FAILED;
+ return_value = net::ERR_FAILED;
switch (call.call_type) {
case CREATE:
- rv = CreateEntry(call.key, call.entry, copyable_callback);
+ return_value = CreateEntry(call.key, call.entry, copyable_callback);
break;
case OPEN:
- rv = OpenEntry(call.key, call.entry, copyable_callback);
+ return_value = OpenEntry(call.key, call.entry, copyable_callback);
break;
case DOOM:
- rv = DoomEntry(call.key, copyable_callback);
- break;
- default:
- NOTREACHED();
+ return_value = DoomEntry(call.key, copyable_callback);
break;
}
- if (rv != net::ERR_IO_PENDING)
- copyable_callback.Run(rv);
+ if (return_value != net::ERR_IO_PENDING)
+ copyable_callback.Run(return_value);
}
pending_calls_.clear();
}
diff --git a/chromium/content/browser/appcache/appcache_disk_cache.h b/chromium/content/browser/appcache/appcache_disk_cache.h
index 73bccf9d2f9..82309a1502f 100644
--- a/chromium/content/browser/appcache/appcache_disk_cache.h
+++ b/chromium/content/browser/appcache/appcache_disk_cache.h
@@ -13,55 +13,96 @@
#include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
-#include "content/browser/appcache/appcache_response.h"
#include "content/common/content_export.h"
#include "net/base/completion_once_callback.h"
#include "net/disk_cache/disk_cache.h"
namespace content {
-// An implementation of AppCacheDiskCacheInterface that
+class AppCacheDiskCache;
+
+// Thin wrapper around disk_cache::Entry.
+class CONTENT_EXPORT AppCacheDiskCacheEntry {
+ public:
+ // The newly created entry takes ownership of |disk_cache_entry| and closes it
+ // on destruction. |cache| must outlive the newly created entry.
+ AppCacheDiskCacheEntry(disk_cache::Entry* disk_cache_entry,
+ AppCacheDiskCache* cache);
+
+ int Read(int index,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ net::CompletionOnceCallback callback);
+
+ int Write(int index,
+ int64_t offset,
+ net::IOBuffer* buf,
+ int buf_len,
+ net::CompletionOnceCallback callback);
+ int64_t GetSize(int index);
+ void Close();
+
+ // Should only be called by AppCacheDiskCache.
+ void Abandon();
+
+ private:
+ // Call Close() instead of calling this directly.
+ ~AppCacheDiskCacheEntry();
+
+ // The disk_cache::Entry is owned by this entry and closed on destruction.
+ disk_cache::Entry* disk_cache_entry_;
+
+ // The cache that this entry belongs to.
+ AppCacheDiskCache* cache_;
+};
+
+// An implementation of AppCacheDiskCache that
// uses net::DiskCache as the backing store.
-class CONTENT_EXPORT AppCacheDiskCache
- : public AppCacheDiskCacheInterface {
+class CONTENT_EXPORT AppCacheDiskCache {
public:
AppCacheDiskCache();
- ~AppCacheDiskCache() override;
+ virtual ~AppCacheDiskCache();
// Initializes the object to use disk backed storage.
- int InitWithDiskBackend(const base::FilePath& disk_cache_directory,
- int disk_cache_size,
- bool force,
- base::OnceClosure post_cleanup_callback,
- net::CompletionOnceCallback callback);
+ net::Error InitWithDiskBackend(const base::FilePath& disk_cache_directory,
+ int disk_cache_size,
+ bool force,
+ base::OnceClosure post_cleanup_callback,
+ net::CompletionOnceCallback callback);
// Initializes the object to use memory only storage.
// This is used for Chrome's incognito browsing.
- int InitWithMemBackend(int disk_cache_size,
- net::CompletionOnceCallback callback);
+ net::Error InitWithMemBackend(int disk_cache_size,
+ net::CompletionOnceCallback callback);
void Disable();
bool is_disabled() const { return is_disabled_; }
- int CreateEntry(int64_t key,
- Entry** entry,
- net::CompletionOnceCallback callback) override;
- int OpenEntry(int64_t key,
- Entry** entry,
- net::CompletionOnceCallback callback) override;
- int DoomEntry(int64_t key, net::CompletionOnceCallback callback) override;
+ net::Error CreateEntry(int64_t key,
+ AppCacheDiskCacheEntry** entry,
+ net::CompletionOnceCallback callback);
+ net::Error OpenEntry(int64_t key,
+ AppCacheDiskCacheEntry** entry,
+ net::CompletionOnceCallback callback);
+ net::Error DoomEntry(int64_t key, net::CompletionOnceCallback callback);
+
+ base::WeakPtr<AppCacheDiskCache> GetWeakPtr();
void set_is_waiting_to_initialize(bool is_waiting_to_initialize) {
is_waiting_to_initialize_ = is_waiting_to_initialize;
}
+ const char* uma_name() { return uma_name_; }
+
protected:
- explicit AppCacheDiskCache(bool use_simple_cache);
+ // |uma_name| must remain valid for the life of the object.
+ explicit AppCacheDiskCache(const char* uma_name, bool use_simple_cache);
disk_cache::Backend* disk_cache() { return disk_cache_.get(); }
private:
class CreateBackendCallbackShim;
- class EntryImpl;
+ friend class AppCacheDiskCacheEntry;
// PendingCalls allow CreateEntry, OpenEntry, and DoomEntry to be called
// immediately after construction, without waiting for the
@@ -77,7 +118,7 @@ class CONTENT_EXPORT AppCacheDiskCache
PendingCall();
PendingCall(PendingCallType call_type,
int64_t key,
- Entry** entry,
+ AppCacheDiskCacheEntry** entry,
net::CompletionOnceCallback callback);
PendingCall(PendingCall&& other);
@@ -85,28 +126,35 @@ class CONTENT_EXPORT AppCacheDiskCache
PendingCallType call_type;
int64_t key;
- Entry** entry;
+ AppCacheDiskCacheEntry** entry;
net::CompletionOnceCallback callback;
};
using PendingCalls = std::vector<PendingCall>;
class ActiveCall;
using ActiveCalls = std::set<ActiveCall*>;
- using OpenEntries = std::set<EntryImpl*>;
+ using OpenEntries = std::set<AppCacheDiskCacheEntry*>;
bool is_initializing_or_waiting_to_initialize() const {
return create_backend_callback_.get() != NULL || is_waiting_to_initialize_;
}
- int Init(net::CacheType cache_type,
- const base::FilePath& directory,
- int cache_size,
- bool force,
- base::OnceClosure post_cleanup_callback,
- net::CompletionOnceCallback callback);
- void OnCreateBackendComplete(int rv);
- void AddOpenEntry(EntryImpl* entry) { open_entries_.insert(entry); }
- void RemoveOpenEntry(EntryImpl* entry) { open_entries_.erase(entry); }
+ net::Error Init(net::CacheType cache_type,
+ const base::FilePath& directory,
+ int cache_size,
+ bool force,
+ base::OnceClosure post_cleanup_callback,
+ net::CompletionOnceCallback callback);
+ void OnCreateBackendComplete(int return_value);
+
+ // Called by AppCacheDiskCacheEntry constructor.
+ void AddOpenEntry(AppCacheDiskCacheEntry* entry) {
+ open_entries_.insert(entry);
+ }
+ // Called by AppCacheDiskCacheEntry destructor.
+ void RemoveOpenEntry(AppCacheDiskCacheEntry* entry) {
+ open_entries_.erase(entry);
+ }
bool use_simple_cache_;
bool is_disabled_;
@@ -116,6 +164,7 @@ class CONTENT_EXPORT AppCacheDiskCache
PendingCalls pending_calls_;
OpenEntries open_entries_;
std::unique_ptr<disk_cache::Backend> disk_cache_;
+ const char* const uma_name_;
base::WeakPtrFactory<AppCacheDiskCache> weak_factory_;
};
diff --git a/chromium/content/browser/appcache/appcache_disk_cache_unittest.cc b/chromium/content/browser/appcache/appcache_disk_cache_unittest.cc
index f6e4cf492d9..8f382da2538 100644
--- a/chromium/content/browser/appcache/appcache_disk_cache_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_disk_cache_unittest.cc
@@ -49,7 +49,7 @@ class AppCacheDiskCacheTest : public testing::Test {
};
TEST_F(AppCacheDiskCacheTest, DisablePriorToInitCompletion) {
- AppCacheDiskCache::Entry* entry = nullptr;
+ AppCacheDiskCacheEntry* entry = nullptr;
// Create an instance and start it initializing, queue up
// one of each kind of "entry" function.
@@ -103,7 +103,7 @@ TEST_F(AppCacheDiskCacheTest, DisableAfterInitted) {
// Methods should return immediately when disabled and not invoke
// the callback at all.
- AppCacheDiskCache::Entry* entry = nullptr;
+ AppCacheDiskCacheEntry* entry = nullptr;
completion_results_.clear();
EXPECT_EQ(net::ERR_ABORTED,
disk_cache->CreateEntry(1, &entry, completion_callback_));
@@ -135,8 +135,8 @@ TEST_F(AppCacheDiskCacheTest, DISABLED_DisableWithEntriesOpen) {
// and we do have expectations about that.
// Create/open some entries.
- AppCacheDiskCache::Entry* entry1 = nullptr;
- AppCacheDiskCache::Entry* entry2 = nullptr;
+ AppCacheDiskCacheEntry* entry1 = nullptr;
+ AppCacheDiskCacheEntry* entry2 = nullptr;
disk_cache->CreateEntry(1, &entry1, completion_callback_);
disk_cache->CreateEntry(2, &entry2, completion_callback_);
FlushCacheTasks();
@@ -146,12 +146,14 @@ TEST_F(AppCacheDiskCacheTest, DISABLED_DisableWithEntriesOpen) {
// Write something to one of the entries and flush it.
const char* kData = "Hello";
const int kDataLen = strlen(kData) + 1;
- scoped_refptr<net::IOBuffer> write_buf(new net::WrappedIOBuffer(kData));
+ scoped_refptr<net::IOBuffer> write_buf =
+ base::MakeRefCounted<net::WrappedIOBuffer>(kData);
entry1->Write(0, 0, write_buf.get(), kDataLen, completion_callback_);
FlushCacheTasks();
// Queue up a read and a write.
- scoped_refptr<net::IOBuffer> read_buf = new net::IOBuffer(kDataLen);
+ scoped_refptr<net::IOBuffer> read_buf =
+ base::MakeRefCounted<net::IOBuffer>(kDataLen);
entry1->Read(0, 0, read_buf.get(), kDataLen, completion_callback_);
entry2->Write(0, 0, write_buf.get(), kDataLen, completion_callback_);
diff --git a/chromium/content/browser/appcache/appcache_frontend_proxy.cc b/chromium/content/browser/appcache/appcache_frontend_proxy.cc
index 47b80b9ace4..d9eb816c963 100644
--- a/chromium/content/browser/appcache/appcache_frontend_proxy.cc
+++ b/chromium/content/browser/appcache/appcache_frontend_proxy.cc
@@ -4,7 +4,9 @@
#include "content/browser/appcache/appcache_frontend_proxy.h"
+#include "base/task/post_task.h"
#include "content/common/appcache.mojom.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/bind_interface_helpers.h"
@@ -26,8 +28,8 @@ void BindOnUIThread(int process_id, mojom::AppCacheFrontendRequest request) {
mojom::AppCacheFrontend* AppCacheFrontendProxy::GetAppCacheFrontend() {
if (!app_cache_renderer_ptr_) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&BindOnUIThread, process_id_,
mojo::MakeRequest(&app_cache_renderer_ptr_)));
}
diff --git a/chromium/content/browser/appcache/appcache_group.cc b/chromium/content/browser/appcache/appcache_group.cc
index 6a83480f298..42a94cca7d5 100644
--- a/chromium/content/browser/appcache/appcache_group.cc
+++ b/chromium/content/browser/appcache/appcache_group.cc
@@ -100,8 +100,7 @@ void AppCacheGroup::AddCache(AppCache* complete_cache) {
// Update hosts of older caches to add a reference to the newest cache.
// (This loop mutates |old_caches_| so a range-based for-loop cannot be
// used, because it caches the end iterator.)
- for (Caches::iterator it = old_caches_.begin(); it != old_caches_.end();
- ++it) {
+ for (auto it = old_caches_.begin(); it != old_caches_.end(); ++it) {
AppCache* cache = *it;
for (AppCacheHost* host : cache->associated_hosts())
host->SetSwappableCache(this);
@@ -121,8 +120,7 @@ void AppCacheGroup::RemoveCache(AppCache* cache) {
} else {
scoped_refptr<AppCacheGroup> protect(this);
- Caches::iterator it =
- std::find(old_caches_.begin(), old_caches_.end(), cache);
+ auto it = std::find(old_caches_.begin(), old_caches_.end(), cache);
if (it != old_caches_.end()) {
AppCache* tmp_cache = *it;
old_caches_.erase(it);
diff --git a/chromium/content/browser/appcache/appcache_host.cc b/chromium/content/browser/appcache/appcache_host.cc
index f82d1f76585..bbc891b3d8b 100644
--- a/chromium/content/browser/appcache/appcache_host.cc
+++ b/chromium/content/browser/appcache/appcache_host.cc
@@ -83,7 +83,7 @@ AppCacheHost::~AppCacheHost() {
if (group_being_updated_.get())
group_being_updated_->RemoveUpdateObserver(this);
storage()->CancelDelegateCallbacks(this);
- if (service()->quota_manager_proxy() && !origin_in_use_.unique())
+ if (service()->quota_manager_proxy() && !origin_in_use_.opaque())
service()->quota_manager_proxy()->NotifyOriginNoLongerInUse(origin_in_use_);
}
@@ -113,7 +113,7 @@ bool AppCacheHost::SelectCache(const GURL& document_url,
}
origin_in_use_ = url::Origin::Create(document_url);
- if (service()->quota_manager_proxy() && !origin_in_use_.unique())
+ if (service()->quota_manager_proxy() && !origin_in_use_.opaque())
service()->quota_manager_proxy()->NotifyOriginInUse(origin_in_use_);
if (main_resource_blocked_)
diff --git a/chromium/content/browser/appcache/appcache_internals_ui.cc b/chromium/content/browser/appcache/appcache_internals_ui.cc
index d95dcaf3494..6256cd8b4f9 100644
--- a/chromium/content/browser/appcache/appcache_internals_ui.cc
+++ b/chromium/content/browser/appcache/appcache_internals_ui.cc
@@ -13,6 +13,7 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/threading/platform_thread.h"
#include "base/values.h"
#include "content/browser/appcache/appcache.h"
@@ -20,6 +21,7 @@
#include "content/browser/storage_partition_impl.h"
#include "content/grit/content_resources.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
@@ -145,8 +147,8 @@ AppCacheInternalsUI::Proxy::Proxy(
void AppCacheInternalsUI::Proxy::Initialize(
const scoped_refptr<ChromeAppCacheService>& chrome_appcache_service) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&Proxy::Initialize, this, chrome_appcache_service));
return;
}
@@ -161,8 +163,8 @@ AppCacheInternalsUI::Proxy::~Proxy() {
void AppCacheInternalsUI::Proxy::Shutdown() {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&Proxy::Shutdown, this));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&Proxy::Shutdown, this));
return;
}
shutdown_called_ = true;
@@ -175,8 +177,8 @@ void AppCacheInternalsUI::Proxy::Shutdown() {
void AppCacheInternalsUI::Proxy::RequestAllAppCacheInfo() {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&Proxy::RequestAllAppCacheInfo, this));
return;
}
@@ -192,8 +194,8 @@ void AppCacheInternalsUI::Proxy::RequestAllAppCacheInfo() {
void AppCacheInternalsUI::Proxy::OnAllAppCacheInfoReady(
scoped_refptr<AppCacheInfoCollection> collection,
int net_result_code) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&AppCacheInternalsUI::OnAllAppCacheInfoReady,
appcache_internals_ui_, collection, partition_path_));
}
@@ -201,8 +203,8 @@ void AppCacheInternalsUI::Proxy::OnAllAppCacheInfoReady(
void AppCacheInternalsUI::Proxy::DeleteAppCache(
const std::string& manifest_url) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&Proxy::DeleteAppCache, this, manifest_url));
return;
}
@@ -216,8 +218,8 @@ void AppCacheInternalsUI::Proxy::DeleteAppCache(
void AppCacheInternalsUI::Proxy::OnAppCacheInfoDeleted(
const std::string& manifest_url,
int net_result_code) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&AppCacheInternalsUI::OnAppCacheInfoDeleted,
appcache_internals_ui_, partition_path_, manifest_url,
net_result_code == net::OK));
@@ -226,8 +228,8 @@ void AppCacheInternalsUI::Proxy::OnAppCacheInfoDeleted(
void AppCacheInternalsUI::Proxy::RequestAppCacheDetails(
const std::string& manifest_url) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&Proxy::RequestAppCacheDetails, this, manifest_url));
return;
}
@@ -246,8 +248,8 @@ void AppCacheInternalsUI::Proxy::OnGroupLoaded(AppCacheGroup* appcache_group,
std::sort(resource_info_vector->begin(), resource_info_vector->end(),
SortByResourceUrl);
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&AppCacheInternalsUI::OnAppCacheDetailsReady,
appcache_internals_ui_, partition_path_,
manifest_gurl.spec(), std::move(resource_info_vector)));
@@ -256,8 +258,8 @@ void AppCacheInternalsUI::Proxy::OnGroupLoaded(AppCacheGroup* appcache_group,
void AppCacheInternalsUI::Proxy::RequestFileDetails(
const ResponseEnquiry& response_enquiry) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&Proxy::RequestFileDetails, this, response_enquiry));
return;
}
@@ -289,11 +291,12 @@ void AppCacheInternalsUI::Proxy::OnResponseInfoLoaded(
const int64_t kLimit = 100 * 1000;
int64_t amount_to_read =
std::min(kLimit, response_info->response_data_size());
- scoped_refptr<net::IOBuffer> response_data(
- new net::IOBuffer(base::checked_cast<size_t>(amount_to_read)));
- std::unique_ptr<AppCacheResponseReader> reader(
+ scoped_refptr<net::IOBuffer> response_data =
+ base::MakeRefCounted<net::IOBuffer>(
+ base::checked_cast<size_t>(amount_to_read));
+ std::unique_ptr<AppCacheResponseReader> reader =
appcache_service_->storage()->CreateResponseReader(
- GURL(response_enquiry.manifest_url), response_enquiry.response_id));
+ GURL(response_enquiry.manifest_url), response_enquiry.response_id);
reader->ReadData(response_data.get(), amount_to_read,
base::BindOnce(&Proxy::OnResponseDataReadComplete, this,
@@ -313,14 +316,14 @@ void AppCacheInternalsUI::Proxy::OnResponseDataReadComplete(
if (shutdown_called_)
return;
if (!response_info || net_result_code < 0) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&AppCacheInternalsUI::OnFileDetailsFailed,
appcache_internals_ui_, response_enquiry,
net_result_code));
} else {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&AppCacheInternalsUI::OnFileDetailsReady,
appcache_internals_ui_, response_enquiry, response_info,
response_data, net_result_code));
diff --git a/chromium/content/browser/appcache/appcache_job.cc b/chromium/content/browser/appcache/appcache_job.cc
index 20fcaed3a65..e5575b2bc5c 100644
--- a/chromium/content/browser/appcache/appcache_job.cc
+++ b/chromium/content/browser/appcache/appcache_job.cc
@@ -20,26 +20,6 @@ AppCacheJob::~AppCacheJob() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
-bool AppCacheJob::IsWaiting() const {
- return delivery_type_ == AWAITING_DELIVERY_ORDERS;
-}
-
-bool AppCacheJob::IsDeliveringAppCacheResponse() const {
- return delivery_type_ == APPCACHED_DELIVERY;
-}
-
-bool AppCacheJob::IsDeliveringNetworkResponse() const {
- return delivery_type_ == NETWORK_DELIVERY;
-}
-
-bool AppCacheJob::IsDeliveringErrorResponse() const {
- return delivery_type_ == ERROR_DELIVERY;
-}
-
-bool AppCacheJob::IsCacheEntryNotFound() const {
- return cache_entry_not_found_;
-}
-
AppCacheURLRequestJob* AppCacheJob::AsURLRequestJob() {
return nullptr;
}
@@ -49,7 +29,8 @@ AppCacheURLLoaderJob* AppCacheJob::AsURLLoaderJob() {
}
AppCacheJob::AppCacheJob()
- : cache_entry_not_found_(false), delivery_type_(AWAITING_DELIVERY_ORDERS) {}
+ : cache_entry_not_found_(false),
+ delivery_type_(DeliveryType::kAwaitingDeliverCall) {}
void AppCacheJob::InitializeRangeRequestInfo(
const net::HttpRequestHeaders& headers) {
diff --git a/chromium/content/browser/appcache/appcache_job.h b/chromium/content/browser/appcache/appcache_job.h
index 47d80378f29..cf18a72fcc7 100644
--- a/chromium/content/browser/appcache/appcache_job.h
+++ b/chromium/content/browser/appcache/appcache_job.h
@@ -36,32 +36,40 @@ class AppCacheURLRequestJob;
// of the AppCache code.
class CONTENT_EXPORT AppCacheJob {
public:
- enum DeliveryType {
- AWAITING_DELIVERY_ORDERS,
- APPCACHED_DELIVERY,
- NETWORK_DELIVERY,
- ERROR_DELIVERY
+ enum class DeliveryType {
+ kAwaitingDeliverCall,
+ kAppCached,
+ kNetwork,
+ kError,
};
virtual ~AppCacheJob();
- // Returns true if the job was started.
+ // True if the job was started.
virtual bool IsStarted() const = 0;
- // Returns true if the job is waiting for instructions.
- virtual bool IsWaiting() const;
+ // True if the job is waiting for instructions.
+ bool IsWaiting() const {
+ return delivery_type_ == DeliveryType::kAwaitingDeliverCall;
+ }
- // Returns true if the job is delivering a response from the cache.
- virtual bool IsDeliveringAppCacheResponse() const;
+ // True if the job is delivering a response from the cache.
+ bool IsDeliveringAppCacheResponse() const {
+ return delivery_type_ == DeliveryType::kAppCached;
+ }
// Returns true if the job is delivering a response from the network.
- virtual bool IsDeliveringNetworkResponse() const;
+ bool IsDeliveringNetworkResponse() const {
+ return delivery_type_ == DeliveryType::kNetwork;
+ }
// Returns true if the job is delivering an error response.
- virtual bool IsDeliveringErrorResponse() const;
+ bool IsDeliveringErrorResponse() const {
+ return delivery_type_ == DeliveryType::kError;
+ }
// Returns true if the cache entry was not found in the cache.
- virtual bool IsCacheEntryNotFound() const;
+ bool IsCacheEntryNotFound() const { return cache_entry_not_found_; }
// Informs the job of what response it should deliver. Only one of these
// methods should be called, and only once per job. A job will sit idle and
diff --git a/chromium/content/browser/appcache/appcache_manifest_parser.cc b/chromium/content/browser/appcache/appcache_manifest_parser.cc
index 88ab907592f..d07cabf28fb 100644
--- a/chromium/content/browser/appcache/appcache_manifest_parser.cc
+++ b/chromium/content/browser/appcache/appcache_manifest_parser.cc
@@ -33,11 +33,11 @@
#include <stddef.h>
-#include "base/command_line.h"
-#include "base/i18n/icu_string_conversions.h"
+#include <tuple>
+#include <utility>
+
#include "base/logging.h"
-#include "base/macros.h"
-#include "base/strings/string_util.h"
+#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
#include "url/gurl.h"
@@ -45,17 +45,176 @@ namespace content {
namespace {
-// Helper function used to identify 'isPattern' annotations.
-bool HasPatternMatchingAnnotation(const wchar_t* line_p,
- const wchar_t* line_end) {
- // Skip whitespace separating the resource url from the annotation.
- // Note: trailing whitespace has already been trimmed from the line.
- while (line_p < line_end && (*line_p == '\t' || *line_p == ' '))
- ++line_p;
- if (line_p == line_end)
+// Values for the mode in the AppCache manifest parsing algorithm specification.
+enum class Mode {
+ kExplicit, // In the CACHE: section.
+ kIntercept, // In the CHROMIUM-INTERCEPT: section. (non-standard)
+ kFallback, // In the FALLBACK: section.
+ kOnlineSafelist, // In the NETWORK: section.
+ kUnknown, // Sections that are not covered by the spec.
+};
+
+// AppCache defines whitespace as CR / LF / space (0x20) / tab (0x09).
+constexpr bool IsWhiteSpace(char character) {
+ return (character == ' ') || (character == '\t') || (character == '\n') ||
+ (character == '\r');
+}
+
+// AppCache defines newline characters as CR or LF.
+constexpr bool IsNewLine(char character) {
+ return (character == '\n') || (character == '\r');
+}
+
+// AppCache defines token separators as space (0x20) or tab (0x09).
+constexpr bool IsTokenSeparator(char character) {
+ return (character == ' ') || (character == '\t');
+}
+
+// Removes the characters at the beginning of the string up to a newline.
+base::StringPiece TrimToFirstNewLine(base::StringPiece data) {
+ size_t skip = 0;
+ while (skip < data.length() && !IsNewLine(data[skip]))
+ ++skip;
+ return data.substr(skip);
+}
+
+// Removes whitespace characters at the beginning of the string.
+base::StringPiece TrimStartingWhiteSpace(base::StringPiece data) {
+ size_t skip = 0;
+ while (skip < data.length() && IsWhiteSpace(data[skip]))
+ ++skip;
+ return data.substr(skip);
+}
+
+// Removes whitespace characters at the end of the string.
+base::StringPiece TrimTrailingWhiteSpace(base::StringPiece data) {
+ size_t length = data.size();
+
+ while (length != 0) {
+ --length;
+ if (!IsWhiteSpace(data[length])) {
+ ++length;
+ break;
+ }
+ }
+ return data.substr(0, length);
+}
+
+// Splits a string at the first occurrence of a newline.
+//
+// Returns the first line, which is guaranteed not to include a newline, and the
+// rest of the string, which may be empty.
+std::pair<base::StringPiece, base::StringPiece> SplitOnNewLine(
+ base::StringPiece data) {
+ size_t split = 0;
+ while (split < data.length() && !IsNewLine(data[split]))
+ ++split;
+ return {data.substr(0, split), data.substr(split)};
+}
+
+// True if the string does not contain any newline character.
+bool IsSingleLine(base::StringPiece maybe_line) {
+ return !std::any_of(maybe_line.begin(), maybe_line.end(), &IsNewLine);
+}
+
+// Splits a token out of a manifest line.
+//
+// Tokens are separated by space (0x20) or tab (0x09) characters.
+//
+// The line must not start with a whitespace character.
+//
+// Returns the token and the rest of the line. Consumes the whitespace after the
+// returned token -- the rest of the line will not start with whitespace.
+std::pair<base::StringPiece, base::StringPiece> SplitLineToken(
+ base::StringPiece line) {
+ DCHECK(IsSingleLine(line));
+ DCHECK(line.empty() || !IsWhiteSpace(line[0]));
+
+ size_t token_end = 0;
+ while (token_end < line.length() && !IsTokenSeparator(line[token_end]))
+ ++token_end;
+
+ size_t split = token_end;
+ while (split < line.length() && IsTokenSeparator(line[split]))
+ ++split;
+
+ return {line.substr(0, token_end), line.substr(split)};
+}
+
+// True if the given line is a mode-setting line.
+//
+// In the AppCache parsing algorithm, the mode only changes when processing a
+// line that ends with ':' (colon) after whitespace removal.
+//
+// The given string must have had whitespace stripped at both ends.
+bool IsModeSettingLine(base::StringPiece line) {
+ DCHECK(IsSingleLine(line));
+
+ if (line.empty())
return false;
- std::wstring annotation(line_p, line_end - line_p);
- return annotation == L"isPattern";
+
+ DCHECK(!IsWhiteSpace(line[0])) << "line starts with whitespace";
+
+ const auto last_character = line[line.length() - 1];
+ DCHECK(!IsWhiteSpace(last_character)) << "line ends with whitespace";
+
+ return last_character == ':';
+}
+
+// The mode that the AppCache parsing algorithm will be switched to.
+//
+// The given string must be a mode-setting line.
+Mode ParseModeSettingLine(base::StringPiece line) {
+ DCHECK(IsModeSettingLine(line));
+
+ static constexpr base::StringPiece kCacheLine("CACHE:");
+ if (line == kCacheLine)
+ return Mode::kExplicit;
+
+ static constexpr base::StringPiece kFallbackLine("FALLBACK:");
+ if (line == kFallbackLine)
+ return Mode::kFallback;
+
+ static constexpr base::StringPiece kNetworkLine("NETWORK:");
+ if (line == kNetworkLine)
+ return Mode::kOnlineSafelist;
+
+ static constexpr base::StringPiece kInterceptLine("CHROMIUM-INTERCEPT:");
+ if (line == kInterceptLine)
+ return Mode::kIntercept;
+
+ return Mode::kUnknown;
+}
+
+// True if the next token in the manifest line is the pattern indicator flag.
+//
+// Pattern URLs are a non-standard feature.
+bool NextTokenIsPatternMatchingFlag(base::StringPiece line) {
+ base::StringPiece is_pattern_token;
+ std::tie(is_pattern_token, line) = SplitLineToken(line);
+
+ static constexpr base::StringPiece kPatternFlag("isPattern");
+ return is_pattern_token == kPatternFlag;
+}
+
+// Parses a URL token in an AppCache manifest.
+//
+// The returned URL may not be valid, if the token does not represent a valid
+// URL.
+//
+// Per the AppCache specification, the URL is resolved relative to the manifest
+// URL, and stripped of any fragment.
+GURL ParseUrlToken(base::StringPiece url_token, const GURL& manifest_url) {
+ GURL url = manifest_url.Resolve(url_token);
+ if (!url.is_valid())
+ return url;
+
+ if (url.has_ref()) {
+ GURL::Replacements replacements;
+ replacements.ClearRef();
+ url = url.ReplaceComponents(replacements);
+ }
+ return url;
}
bool ScopeMatches(const GURL& manifest_url, const GURL& namespace_url) {
@@ -66,37 +225,17 @@ bool ScopeMatches(const GURL& manifest_url, const GURL& namespace_url) {
} // namespace
-enum Mode {
- EXPLICIT,
- INTERCEPT,
- FALLBACK,
- ONLINE_WHITELIST,
- UNKNOWN_MODE,
-};
-
-enum InterceptVerb {
- RETURN,
- EXECUTE,
- UNKNOWN_VERB,
-};
-
-AppCacheManifest::AppCacheManifest() {}
-
-AppCacheManifest::~AppCacheManifest() {}
+AppCacheManifest::AppCacheManifest() = default;
-bool ParseManifest(const GURL& manifest_url, const char* data, int length,
- ParseMode parse_mode, AppCacheManifest& manifest) {
- // This is an implementation of the parsing algorithm specified in
- // the HTML5 offline web application docs:
- // http://www.w3.org/TR/html5/offline.html
- // Do not modify it without consulting those docs.
- // Though you might be tempted to convert these wstrings to UTF-8 or
- // base::string16, this implementation seems simpler given the constraints.
+AppCacheManifest::~AppCacheManifest() = default;
- const wchar_t kSignature[] = L"CACHE MANIFEST";
- const size_t kSignatureLength = arraysize(kSignature) - 1;
- const wchar_t kChromiumSignature[] = L"CHROMIUM CACHE MANIFEST";
- const size_t kChromiumSignatureLength = arraysize(kChromiumSignature) - 1;
+bool ParseManifest(const GURL& manifest_url,
+ const char* manifest_bytes,
+ int manifest_size,
+ ParseMode parse_mode,
+ AppCacheManifest& manifest) {
+ // The parsing algorithm is specified at
+ // https://html.spec.whatwg.org/multipage/offline.html
DCHECK(manifest.explicit_urls.empty());
DCHECK(manifest.fallback_namespaces.empty());
@@ -105,233 +244,168 @@ bool ParseManifest(const GURL& manifest_url, const char* data, int length,
DCHECK(!manifest.did_ignore_intercept_namespaces);
DCHECK(!manifest.did_ignore_fallback_namespaces);
- Mode mode = EXPLICIT;
-
- std::wstring data_string;
- base::UTF8ToWide(data, length, &data_string);
- const wchar_t* p = data_string.c_str();
- const wchar_t* end = p + data_string.length();
-
- // Look for the magic signature: "^\xFEFF?CACHE MANIFEST[ \t]?"
- // Example: "CACHE MANIFEST #comment" is a valid signature.
- // Example: "CACHE MANIFEST;V2" is not.
-
- // When the input data starts with a UTF-8 Byte-Order-Mark
- // (0xEF, 0xBB, 0xBF), the UTF8ToWide() function converts it to a
- // Unicode BOM (U+FEFF). Skip a converted Unicode BOM if it exists.
- int bom_offset = 0;
- if (!data_string.empty() && data_string[0] == 0xFEFF) {
- bom_offset = 1;
- ++p;
- }
-
- if (p >= end)
- return false;
-
- // Check for a supported signature and skip p past it.
- if (0 == data_string.compare(bom_offset, kSignatureLength,
- kSignature)) {
- p += kSignatureLength;
- } else if (0 == data_string.compare(bom_offset, kChromiumSignatureLength,
- kChromiumSignature)) {
- p += kChromiumSignatureLength;
+ Mode mode = Mode::kExplicit;
+
+ // The specification requires UTF-8-decoding the manifest, which replaces
+ // invalid UTF-8 characters with placeholders. It would be nice if
+ // utf_string_conversions included a UTF-8 to UTF-8 conversion for this
+ // purpose, but AppCache isn't important enough to add conversion code just
+ // to accelerate manifest decoding.
+ DCHECK_GE(manifest_size, 0);
+ base::string16 wide_manifest_bytes =
+ base::UTF8ToUTF16(base::StringPiece(manifest_bytes, manifest_size));
+ std::string decoded_manifest_bytes = base::UTF16ToUTF8(wide_manifest_bytes);
+
+ // The bytes of the manifest that haven't been consumed yet.
+ base::StringPiece data(decoded_manifest_bytes);
+
+ // Discard a leading UTF-8 Byte-Order-Mark (BOM) (0xEF, 0xBB, 0xBF);
+ static constexpr base::StringPiece kUtf8Bom("\xEF\xBB\xBF");
+ if (data.starts_with(kUtf8Bom))
+ data = data.substr(kUtf8Bom.length());
+
+ // The manifest has to start with a well-defined signature.
+ static constexpr base::StringPiece kSignature("CACHE MANIFEST");
+ static constexpr base::StringPiece kChromiumSignature(
+ "CHROMIUM CACHE MANIFEST");
+ if (data.starts_with(kSignature)) {
+ data = data.substr(kSignature.length());
+ } else if (data.starts_with(kChromiumSignature)) {
+ // Chrome recognizes a separate signature, CHROMIUM CACHE MANIFEST. This was
+ // built so that manifests that use the Chrome-only feature
+ // CHROMIUM-INTERCEPT will be ignored by other browsers.
+ // See https://crbug.com/101565
+
+ // TODO(pwnall): Add a UMA metric to see if we can remove support for this
+ // non-standard signature.
+ data = data.substr(kChromiumSignature.length());
} else {
return false;
}
- // Character after "CACHE MANIFEST" must be whitespace.
- if (p < end && *p != ' ' && *p != '\t' && *p != '\n' && *p != '\r')
+ // The character after "CACHE MANIFEST" must be a whitespace character.
+ if (!data.empty() && !IsWhiteSpace(data[0]))
return false;
- // Skip to the end of the line.
- while (p < end && *p != '\r' && *p != '\n')
- ++p;
+ // The spec requires ignoring any characters on the first line after the
+ // signature and its following whitespace.
+ data = TrimToFirstNewLine(data);
- while (1) {
- // Skip whitespace
- while (p < end && (*p == '\n' || *p == '\r' || *p == ' ' || *p == '\t'))
- ++p;
-
- if (p == end)
+ while (true) {
+ data = TrimStartingWhiteSpace(data);
+ if (data.empty())
break;
- const wchar_t* line_start = p;
+ base::StringPiece line;
+ std::tie(line, data) = SplitOnNewLine(data);
- // Find the end of the line
- while (p < end && *p != '\r' && *p != '\n')
- ++p;
+ // The checks above guarantee that the input to SplitOnNewLine() starts with
+ // a non-whitespace character.
+ DCHECK(!line.empty());
- // Check if we have a comment
- if (*line_start == '#')
+ if (line[0] == '#') // Lines starting with # are comments.
continue;
- // Get rid of trailing whitespace
- const wchar_t* tmp = p - 1;
- while (tmp > line_start && (*tmp == ' ' || *tmp == '\t'))
- --tmp;
-
- std::wstring line(line_start, tmp - line_start + 1);
-
- if (line == L"CACHE:") {
- mode = EXPLICIT;
- } else if (line == L"FALLBACK:") {
- mode = FALLBACK;
- } else if (line == L"NETWORK:") {
- mode = ONLINE_WHITELIST;
- } else if (line == L"CHROMIUM-INTERCEPT:") {
- mode = INTERCEPT;
- } else if (*(line.end() - 1) == ':') {
- mode = UNKNOWN_MODE;
- } else if (mode == UNKNOWN_MODE) {
+ line = TrimTrailingWhiteSpace(line);
+
+ // Handle all the steps checking for lines that end with ":".
+ if (IsModeSettingLine(line)) {
+ mode = ParseModeSettingLine(line);
+ continue;
+ }
+
+ if (mode == Mode::kUnknown)
continue;
- } else if (line == L"*" && mode == ONLINE_WHITELIST) {
+
+ static constexpr base::StringPiece kOnlineSafelistWildcard("*");
+ if (mode == Mode::kOnlineSafelist && line == kOnlineSafelistWildcard) {
manifest.online_whitelist_all = true;
continue;
- } else if (mode == EXPLICIT || mode == ONLINE_WHITELIST) {
- const wchar_t *line_p = line.c_str();
- const wchar_t *line_end = line_p + line.length();
-
- // Look for whitespace separating the URL from subsequent ignored tokens.
- while (line_p < line_end && *line_p != '\t' && *line_p != ' ')
- ++line_p;
-
- base::string16 url16;
- base::WideToUTF16(line.c_str(), line_p - line.c_str(), &url16);
- GURL url = manifest_url.Resolve(url16);
- if (!url.is_valid())
- continue;
- if (url.has_ref()) {
- GURL::Replacements replacements;
- replacements.ClearRef();
- url = url.ReplaceComponents(replacements);
- }
+ }
+
+ // Chrome does not implement the SETTINGS: section. If we ever decided to do
+ // so, the implementation would go here.
+
+ // Common code for the following sections: explicit (CACHE:),
+ // fallback (FALLBACK:), online safelist (NETWORK:) and intercept
+ // (CHROMIUM-INTERCEPT:). All these sections start by parsing a URL token.
+ base::StringPiece namespace_url_token;
+ std::tie(namespace_url_token, line) = SplitLineToken(line);
+ GURL namespace_url = ParseUrlToken(namespace_url_token, manifest_url);
+ if (!namespace_url.is_valid())
+ continue;
+ if (mode == Mode::kExplicit || mode == Mode::kOnlineSafelist) {
// Scheme component must be the same as the manifest URL's.
- if (url.scheme() != manifest_url.scheme()) {
+ if (namespace_url.scheme() != manifest_url.scheme()) {
continue;
}
- // See http://code.google.com/p/chromium/issues/detail?id=69594
- // We willfully violate the HTML5 spec at this point in order
- // to support the appcaching of cross-origin HTTPS resources.
- // Per the spec, EXPLICIT cross-origin HTTS resources should be
- // ignored here. We've opted for a milder constraint and allow
- // caching unless the resource has a "no-store" header. That
- // condition is enforced in AppCacheUpdateJob.
+ // Deviate from the HTML5 spec by supporting the caching of cross-origin
+ // HTTPS resources. See https://crbug.com/69594
+ //
+ // Per the spec, explicit (CACHE:) cross-origin HTTPS resources should be
+ // ignored here. We've opted for a milder constraint and allow caching
+ // unless the resource has a "no-store" header. That condition is enforced
+ // in AppCacheUpdateJob.
- if (mode == EXPLICIT) {
- manifest.explicit_urls.insert(url.spec());
+ if (mode == Mode::kExplicit) {
+ manifest.explicit_urls.insert(namespace_url.spec());
} else {
- bool is_pattern = HasPatternMatchingAnnotation(line_p, line_end);
- manifest.online_whitelist_namespaces.push_back(
- AppCacheNamespace(APPCACHE_NETWORK_NAMESPACE, url, GURL(),
- is_pattern));
+ // Chrome supports URL patterns in manifests. This is not standardized.
+ // An URL record followed by the "isPattern" token is considered a
+ // pattern.
+
+ // TODO(pwnall): Add a UMA metric to see if we can remove this feature.
+ bool is_pattern = NextTokenIsPatternMatchingFlag(line);
+ manifest.online_whitelist_namespaces.emplace_back(AppCacheNamespace(
+ APPCACHE_NETWORK_NAMESPACE, namespace_url, GURL(), is_pattern));
}
- } else if (mode == INTERCEPT) {
- if (parse_mode != PARSE_MANIFEST_ALLOWING_DANGEROUS_FEATURES) {
- manifest.did_ignore_intercept_namespaces = true;
- continue;
- }
-
- // Lines of the form,
- // <urlnamespace> <intercept_type> <targeturl>
- const wchar_t* line_p = line.c_str();
- const wchar_t* line_end = line_p + line.length();
-
- // Look for first whitespace separating the url namespace from
- // the intercept type.
- while (line_p < line_end && *line_p != '\t' && *line_p != ' ')
- ++line_p;
+ continue;
+ }
- if (line_p == line_end)
- continue; // There was no whitespace separating the URLs.
+ if (mode == Mode::kIntercept) {
+ // Chrome supports a CHROMIUM-INTERCEPT section. https://crbug.com/101565
+ //
+ // This section consists of entries of the form:
+ // namespace_url verb url_target
- base::string16 namespace_url16;
- base::WideToUTF16(line.c_str(), line_p - line.c_str(), &namespace_url16);
- GURL namespace_url = manifest_url.Resolve(namespace_url16);
- if (!namespace_url.is_valid())
+ if (parse_mode != PARSE_MANIFEST_ALLOWING_DANGEROUS_FEATURES) {
+ manifest.did_ignore_intercept_namespaces = true;
continue;
- if (namespace_url.has_ref()) {
- GURL::Replacements replacements;
- replacements.ClearRef();
- namespace_url = namespace_url.ReplaceComponents(replacements);
}
- // The namespace URL must have the same scheme, host and port
- // as the manifest's URL.
if (manifest_url.GetOrigin() != namespace_url.GetOrigin())
continue;
- // Skip whitespace separating namespace from the type.
- while (line_p < line_end && (*line_p == '\t' || *line_p == ' '))
- ++line_p;
-
- // Look for whitespace separating the type from the target url.
- const wchar_t* type_start = line_p;
- while (line_p < line_end && *line_p != '\t' && *line_p != ' ')
- ++line_p;
-
- // Look for a type value we understand, otherwise skip the line.
- std::wstring type(type_start, line_p - type_start);
- if (type != L"return")
+ // The only supported verb is "return".
+ base::StringPiece verb_token;
+ std::tie(verb_token, line) = SplitLineToken(line);
+ static constexpr base::StringPiece kReturnVerb("return");
+ if (verb_token != kReturnVerb)
continue;
- // Skip whitespace separating type from the target_url.
- while (line_p < line_end && (*line_p == '\t' || *line_p == ' '))
- ++line_p;
-
- // Look for whitespace separating the URL from subsequent ignored tokens.
- const wchar_t* target_url_start = line_p;
- while (line_p < line_end && *line_p != '\t' && *line_p != ' ')
- ++line_p;
-
- base::string16 target_url16;
- base::WideToUTF16(target_url_start, line_p - target_url_start,
- &target_url16);
- GURL target_url = manifest_url.Resolve(target_url16);
+ base::StringPiece target_url_token;
+ std::tie(target_url_token, line) = SplitLineToken(line);
+ if (target_url_token.empty())
+ continue;
+ GURL target_url = ParseUrlToken(target_url_token, manifest_url);
if (!target_url.is_valid())
continue;
- if (target_url.has_ref()) {
- GURL::Replacements replacements;
- replacements.ClearRef();
- target_url = target_url.ReplaceComponents(replacements);
- }
if (manifest_url.GetOrigin() != target_url.GetOrigin())
continue;
- bool is_pattern = HasPatternMatchingAnnotation(line_p, line_end);
- manifest.intercept_namespaces.push_back(AppCacheNamespace(
- APPCACHE_INTERCEPT_NAMESPACE, namespace_url, target_url, is_pattern));
- } else if (mode == FALLBACK) {
- const wchar_t* line_p = line.c_str();
- const wchar_t* line_end = line_p + line.length();
-
- // Look for whitespace separating the two URLs
- while (line_p < line_end && *line_p != '\t' && *line_p != ' ')
- ++line_p;
-
- if (line_p == line_end) {
- // There was no whitespace separating the URLs.
- continue;
- }
-
- base::string16 namespace_url16;
- base::WideToUTF16(line.c_str(), line_p - line.c_str(), &namespace_url16);
- GURL namespace_url = manifest_url.Resolve(namespace_url16);
- if (!namespace_url.is_valid())
- continue;
- if (namespace_url.has_ref()) {
- GURL::Replacements replacements;
- replacements.ClearRef();
- namespace_url = namespace_url.ReplaceComponents(replacements);
- }
+ // TODO(pwnall): Add a UMA metric to see if we can remove this feature.
+ bool is_pattern = NextTokenIsPatternMatchingFlag(line);
+ manifest.intercept_namespaces.emplace_back(
+ APPCACHE_INTERCEPT_NAMESPACE, namespace_url, target_url, is_pattern);
+ continue;
+ }
- // Fallback namespace URL must have the same scheme, host and port
- // as the manifest's URL.
- if (manifest_url.GetOrigin() != namespace_url.GetOrigin()) {
+ if (mode == Mode::kFallback) {
+ if (manifest_url.GetOrigin() != namespace_url.GetOrigin())
continue;
- }
if (parse_mode != PARSE_MANIFEST_ALLOWING_DANGEROUS_FEATURES) {
if (!ScopeMatches(manifest_url, namespace_url)) {
@@ -340,43 +414,29 @@ bool ParseManifest(const GURL& manifest_url, const char* data, int length,
}
}
- // Skip whitespace separating fallback namespace from URL.
- while (line_p < line_end && (*line_p == '\t' || *line_p == ' '))
- ++line_p;
-
- // Look for whitespace separating the URL from subsequent ignored tokens.
- const wchar_t* fallback_start = line_p;
- while (line_p < line_end && *line_p != '\t' && *line_p != ' ')
- ++line_p;
-
- base::string16 fallback_url16;
- base::WideToUTF16(fallback_start, line_p - fallback_start,
- &fallback_url16);
- GURL fallback_url = manifest_url.Resolve(fallback_url16);
+ base::StringPiece fallback_url_token;
+ std::tie(fallback_url_token, line) = SplitLineToken(line);
+ if (fallback_url_token.empty())
+ continue;
+ GURL fallback_url = ParseUrlToken(fallback_url_token, manifest_url);
if (!fallback_url.is_valid())
continue;
- if (fallback_url.has_ref()) {
- GURL::Replacements replacements;
- replacements.ClearRef();
- fallback_url = fallback_url.ReplaceComponents(replacements);
- }
- // Fallback entry URL must have the same scheme, host and port
- // as the manifest's URL.
- if (manifest_url.GetOrigin() != fallback_url.GetOrigin()) {
+ if (manifest_url.GetOrigin() != fallback_url.GetOrigin())
continue;
- }
- bool is_pattern = HasPatternMatchingAnnotation(line_p, line_end);
+ // TODO(pwnall): Add a UMA metric to see if we can remove this feature.
+ bool is_pattern = NextTokenIsPatternMatchingFlag(line);
- // Store regardless of duplicate namespace URL. Only first match
- // will ever be used.
- manifest.fallback_namespaces.push_back(
+ // Store regardless of duplicate namespace URL. Only the first match will
+ // ever be used.
+ manifest.fallback_namespaces.emplace_back(
AppCacheNamespace(APPCACHE_FALLBACK_NAMESPACE, namespace_url,
- fallback_url, is_pattern));
- } else {
- NOTREACHED();
+ fallback_url, is_pattern));
+ continue;
}
+
+ NOTREACHED() << "Unimplemented AppCache manifest parser mode";
}
return true;
diff --git a/chromium/content/browser/appcache/appcache_manifest_parser.h b/chromium/content/browser/appcache/appcache_manifest_parser.h
index 016655b25e9..6312d4fa08d 100644
--- a/chromium/content/browser/appcache/appcache_manifest_parser.h
+++ b/chromium/content/browser/appcache/appcache_manifest_parser.h
@@ -61,12 +61,11 @@ enum ParseMode {
PARSE_MANIFEST_ALLOWING_DANGEROUS_FEATURES
};
-CONTENT_EXPORT bool ParseManifest(
- const GURL& manifest_url,
- const char* data,
- int length,
- ParseMode parse_mode,
- AppCacheManifest& manifest);
+CONTENT_EXPORT bool ParseManifest(const GURL& manifest_url,
+ const char* manifest_bytes,
+ int manifest_size,
+ ParseMode parse_mode,
+ AppCacheManifest& manifest);
} // namespace content
diff --git a/chromium/content/browser/appcache/appcache_manifest_parser_unittest.cc b/chromium/content/browser/appcache/appcache_manifest_parser_unittest.cc
index 5ca2d3ac9e1..07f005be838 100644
--- a/chromium/content/browser/appcache/appcache_manifest_parser_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_manifest_parser_unittest.cc
@@ -447,7 +447,8 @@ TEST(AppCacheManifestParserTest, UnusualUtf8) {
PARSE_MANIFEST_ALLOWING_DANGEROUS_FEATURES,
manifest));
base::hash_set<std::string> urls = manifest.explicit_urls;
- EXPECT_TRUE(urls.find("http://bad.com/%EF%BF%BDinvalidutf8") != urls.end());
+ EXPECT_TRUE(urls.find("http://bad.com/%EF%BF%BDinvalidutf8") != urls.end())
+ << "manifest byte stream was passed through, not UTF-8-decoded";
EXPECT_TRUE(urls.find("http://bad.com/nonbmp%F1%84%AB%BC") != urls.end());
}
diff --git a/chromium/content/browser/appcache/appcache_navigation_handle.cc b/chromium/content/browser/appcache/appcache_navigation_handle.cc
index b6bf5de3d8f..005f258bb32 100644
--- a/chromium/content/browser/appcache/appcache_navigation_handle.cc
+++ b/chromium/content/browser/appcache/appcache_navigation_handle.cc
@@ -5,8 +5,10 @@
#include "content/browser/appcache/appcache_navigation_handle.h"
#include "base/bind.h"
+#include "base/task/post_task.h"
#include "content/browser/appcache/appcache_navigation_handle_core.h"
#include "content/browser/appcache/chrome_appcache_service.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace {
@@ -23,8 +25,8 @@ AppCacheNavigationHandle::AppCacheNavigationHandle(
core_(std::make_unique<AppCacheNavigationHandleCore>(appcache_service,
appcache_host_id_)) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AppCacheNavigationHandleCore::Initialize,
base::Unretained(core_.get())));
}
diff --git a/chromium/content/browser/appcache/appcache_request_handler.cc b/chromium/content/browser/appcache/appcache_request_handler.cc
index 459c79ab482..42578121c1d 100644
--- a/chromium/content/browser/appcache/appcache_request_handler.cc
+++ b/chromium/content/browser/appcache/appcache_request_handler.cc
@@ -573,7 +573,8 @@ bool AppCacheRequestHandler::MaybeCreateLoaderForResponse(
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr* loader,
network::mojom::URLLoaderClientRequest* client_request,
- ThrottlingURLLoader* url_loader) {
+ ThrottlingURLLoader* url_loader,
+ bool* skip_other_interceptors) {
// The sync interface of this method is inherited from the
// NavigationLoaderInterceptor class. The LoaderCallback created here is
// invoked synchronously in fallback cases, and only when there really is
@@ -600,6 +601,8 @@ bool AppCacheRequestHandler::MaybeCreateLoaderForResponse(
return false;
}
DCHECK(was_called);
+ if (IsMainResourceType(resource_type_))
+ should_create_subresource_loader_ = true;
return true;
}
diff --git a/chromium/content/browser/appcache/appcache_request_handler.h b/chromium/content/browser/appcache/appcache_request_handler.h
index 57362f43c43..40249b7ee04 100644
--- a/chromium/content/browser/appcache/appcache_request_handler.h
+++ b/chromium/content/browser/appcache/appcache_request_handler.h
@@ -84,7 +84,8 @@ class CONTENT_EXPORT AppCacheRequestHandler
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr* loader,
network::mojom::URLLoaderClientRequest* client_request,
- ThrottlingURLLoader* url_loader) override;
+ ThrottlingURLLoader* url_loader,
+ bool* skip_other_interceptors) override;
base::Optional<SubresourceLoaderParams> MaybeCreateSubresourceLoaderParams()
override;
diff --git a/chromium/content/browser/appcache/appcache_request_handler_unittest.cc b/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
index bd3494c4aa9..0ed52f25f1a 100644
--- a/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
@@ -21,6 +21,7 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -33,6 +34,7 @@
#include "content/browser/appcache/appcache_url_request_job.h"
#include "content/browser/appcache/mock_appcache_policy.h"
#include "content/browser/appcache/mock_appcache_service.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
@@ -204,7 +206,8 @@ class AppCacheRequestHandlerTest
static void SetUpTestCase() {
thread_bundle_.reset(
new TestBrowserThreadBundle(TestBrowserThreadBundle::REAL_IO_THREAD));
- io_task_runner_ = BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+ io_task_runner_ =
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
}
static void TearDownTestCase() {
diff --git a/chromium/content/browser/appcache/appcache_response.cc b/chromium/content/browser/appcache/appcache_response.cc
index 15bb71504fb..04515fc6118 100644
--- a/chromium/content/browser/appcache/appcache_response.cc
+++ b/chromium/content/browser/appcache/appcache_response.cc
@@ -18,6 +18,7 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "content/browser/appcache/appcache_disk_cache.h"
#include "content/browser/appcache/appcache_storage.h"
#include "net/base/completion_once_callback.h"
#include "net/base/io_buffer.h"
@@ -82,23 +83,11 @@ HttpResponseInfoIOBuffer::HttpResponseInfoIOBuffer(
HttpResponseInfoIOBuffer::~HttpResponseInfoIOBuffer() = default;
-// AppCacheDiskCacheInterface ----------------------------------------
-
-AppCacheDiskCacheInterface::AppCacheDiskCacheInterface(const char* uma_name)
- : uma_name_(uma_name), weak_factory_(this) {}
-
-base::WeakPtr<AppCacheDiskCacheInterface>
-AppCacheDiskCacheInterface::GetWeakPtr() {
- return weak_factory_.GetWeakPtr();
-}
-
-AppCacheDiskCacheInterface::~AppCacheDiskCacheInterface() {}
-
// AppCacheResponseIO ----------------------------------------------
AppCacheResponseIO::AppCacheResponseIO(
int64_t response_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache)
+ base::WeakPtr<AppCacheDiskCache> disk_cache)
: response_id_(response_id),
disk_cache_(std::move(disk_cache)),
entry_(nullptr),
@@ -152,13 +141,13 @@ void AppCacheResponseIO::OnRawIOComplete(int result) {
void AppCacheResponseIO::OpenEntryIfNeeded() {
int rv;
- AppCacheDiskCacheInterface::Entry** entry_ptr = nullptr;
+ AppCacheDiskCacheEntry** entry_ptr = nullptr;
if (entry_) {
rv = net::OK;
} else if (!disk_cache_) {
rv = net::ERR_FAILED;
} else {
- entry_ptr = new AppCacheDiskCacheInterface::Entry*;
+ entry_ptr = new AppCacheDiskCacheEntry*;
rv = disk_cache_->OpenEntry(
response_id_, entry_ptr,
base::BindOnce(&AppCacheResponseIO::OpenEntryCallback, GetWeakPtr(),
@@ -172,7 +161,7 @@ void AppCacheResponseIO::OpenEntryIfNeeded() {
// static
void AppCacheResponseIO::OpenEntryCallback(
base::WeakPtr<AppCacheResponseIO> response,
- AppCacheDiskCacheInterface::Entry** entry,
+ AppCacheDiskCacheEntry** entry,
int rv) {
if (!response) {
delete entry;
@@ -194,7 +183,7 @@ void AppCacheResponseIO::OpenEntryCallback(
AppCacheResponseReader::AppCacheResponseReader(
int64_t response_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache)
+ base::WeakPtr<AppCacheDiskCache> disk_cache)
: AppCacheResponseIO(response_id, std::move(disk_cache)),
range_offset_(0),
range_length_(std::numeric_limits<int32_t>::max()),
@@ -225,7 +214,7 @@ void AppCacheResponseReader::ContinueReadInfo() {
return;
}
- buffer_ = new net::IOBuffer(size);
+ buffer_ = base::MakeRefCounted<net::IOBuffer>(size);
ReadRaw(kResponseInfoIndex, 0, buffer_.get(), size);
}
@@ -290,8 +279,9 @@ void AppCacheResponseReader::OnIOComplete(int result) {
int64_t metadata_size = entry_->GetSize(kResponseMetadataIndex);
if (metadata_size > 0) {
reading_metadata_size_ = metadata_size;
- info_buffer_->http_info->metadata = new net::IOBufferWithSize(
- base::checked_cast<size_t>(metadata_size));
+ info_buffer_->http_info->metadata =
+ base::MakeRefCounted<net::IOBufferWithSize>(
+ base::checked_cast<size_t>(metadata_size));
ReadRaw(kResponseMetadataIndex, 0,
info_buffer_->http_info->metadata.get(), metadata_size);
return;
@@ -325,7 +315,7 @@ base::WeakPtr<AppCacheResponseIO> AppCacheResponseReader::GetWeakPtr() {
AppCacheResponseWriter::AppCacheResponseWriter(
int64_t response_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache)
+ base::WeakPtr<AppCacheDiskCache> disk_cache)
: AppCacheResponseIO(response_id, std::move(disk_cache)),
info_size_(0),
write_position_(0),
@@ -407,7 +397,7 @@ void AppCacheResponseWriter::OnIOComplete(int result) {
void AppCacheResponseWriter::CreateEntryIfNeededAndContinue() {
int rv;
- AppCacheDiskCacheInterface::Entry** entry_ptr = nullptr;
+ AppCacheDiskCacheEntry** entry_ptr = nullptr;
if (entry_) {
creation_phase_ = NO_ATTEMPT;
rv = net::OK;
@@ -416,7 +406,7 @@ void AppCacheResponseWriter::CreateEntryIfNeededAndContinue() {
rv = net::ERR_FAILED;
} else {
creation_phase_ = INITIAL_ATTEMPT;
- entry_ptr = new AppCacheDiskCacheInterface::Entry*;
+ entry_ptr = new AppCacheDiskCacheEntry*;
rv = disk_cache_->CreateEntry(
response_id_, entry_ptr,
base::BindOnce(&AppCacheResponseWriter::OnCreateEntryComplete,
@@ -429,7 +419,7 @@ void AppCacheResponseWriter::CreateEntryIfNeededAndContinue() {
// static
void AppCacheResponseWriter::OnCreateEntryComplete(
base::WeakPtr<AppCacheResponseWriter> writer,
- AppCacheDiskCacheInterface::Entry** entry,
+ AppCacheDiskCacheEntry** entry,
int rv) {
if (!writer) {
if (entry) {
@@ -462,8 +452,7 @@ void AppCacheResponseWriter::OnCreateEntryComplete(
} else if (writer->creation_phase_ == DOOM_EXISTING) {
DCHECK_EQ(nullptr, entry);
writer->creation_phase_ = SECOND_ATTEMPT;
- AppCacheDiskCacheInterface::Entry** entry_ptr =
- new AppCacheDiskCacheInterface::Entry*;
+ AppCacheDiskCacheEntry** entry_ptr = new AppCacheDiskCacheEntry*;
rv = writer->disk_cache_->CreateEntry(
writer->response_id_, entry_ptr,
base::BindOnce(&AppCacheResponseWriter::OnCreateEntryComplete, writer,
@@ -494,7 +483,7 @@ base::WeakPtr<AppCacheResponseIO> AppCacheResponseWriter::GetWeakPtr() {
AppCacheResponseMetadataWriter::AppCacheResponseMetadataWriter(
int64_t response_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache)
+ base::WeakPtr<AppCacheDiskCache> disk_cache)
: AppCacheResponseIO(response_id, std::move(disk_cache)),
write_amount_(0),
weak_factory_(this) {}
diff --git a/chromium/content/browser/appcache/appcache_response.h b/chromium/content/browser/appcache/appcache_response.h
index de0663e162e..3f22f716a64 100644
--- a/chromium/content/browser/appcache/appcache_response.h
+++ b/chromium/content/browser/appcache/appcache_response.h
@@ -23,6 +23,8 @@ class IOBuffer;
}
namespace content {
+class AppCacheDiskCache;
+class AppCacheDiskCacheEntry;
class AppCacheStorage;
class MockAppCacheStorage;
@@ -75,48 +77,6 @@ struct CONTENT_EXPORT HttpResponseInfoIOBuffer
~HttpResponseInfoIOBuffer();
};
-// Low level storage API used by the response reader and writer.
-class CONTENT_EXPORT AppCacheDiskCacheInterface {
- public:
- class Entry {
- public:
- virtual int Read(int index,
- int64_t offset,
- net::IOBuffer* buf,
- int buf_len,
- net::CompletionOnceCallback callback) = 0;
- virtual int Write(int index,
- int64_t offset,
- net::IOBuffer* buf,
- int buf_len,
- net::CompletionOnceCallback callback) = 0;
- virtual int64_t GetSize(int index) = 0;
- virtual void Close() = 0;
- protected:
- virtual ~Entry() = default;
- };
-
- // The uma_name pointer must remain valid for the life of the object.
- AppCacheDiskCacheInterface(const char* uma_name);
-
- virtual int CreateEntry(int64_t key,
- Entry** entry,
- net::CompletionOnceCallback callback) = 0;
- virtual int OpenEntry(int64_t key,
- Entry** entry,
- net::CompletionOnceCallback callback) = 0;
- virtual int DoomEntry(int64_t key, net::CompletionOnceCallback callback) = 0;
-
- const char* uma_name() const { return uma_name_; }
- base::WeakPtr<AppCacheDiskCacheInterface> GetWeakPtr();
-
- protected:
- virtual ~AppCacheDiskCacheInterface();
-
- const char* uma_name_;
- base::WeakPtrFactory<AppCacheDiskCacheInterface> weak_factory_;
-};
-
// Common base class for response reader and writer.
class CONTENT_EXPORT AppCacheResponseIO {
public:
@@ -125,7 +85,7 @@ class CONTENT_EXPORT AppCacheResponseIO {
protected:
AppCacheResponseIO(int64_t response_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache);
+ base::WeakPtr<AppCacheDiskCache> disk_cache);
virtual void OnIOComplete(int result) = 0;
virtual void OnOpenEntryComplete() {}
@@ -142,8 +102,8 @@ class CONTENT_EXPORT AppCacheResponseIO {
virtual base::WeakPtr<AppCacheResponseIO> GetWeakPtr() = 0;
const int64_t response_id_;
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache_;
- AppCacheDiskCacheInterface::Entry* entry_;
+ base::WeakPtr<AppCacheDiskCache> disk_cache_;
+ AppCacheDiskCacheEntry* entry_;
scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_;
scoped_refptr<net::IOBuffer> buffer_;
int buffer_len_;
@@ -153,7 +113,7 @@ class CONTENT_EXPORT AppCacheResponseIO {
private:
void OnRawIOComplete(int result);
static void OpenEntryCallback(base::WeakPtr<AppCacheResponseIO> response,
- AppCacheDiskCacheInterface::Entry** entry,
+ AppCacheDiskCacheEntry** entry,
int rv);
};
@@ -202,9 +162,9 @@ class CONTENT_EXPORT AppCacheResponseReader : public AppCacheResponseIO {
friend class AppCacheStorageImpl;
friend class content::MockAppCacheStorage;
- // Should only be constructed by the storage class and derivatives.
+ // Use AppCacheStorage::CreateResponse() instead of calling directly.
AppCacheResponseReader(int64_t response_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache);
+ base::WeakPtr<AppCacheDiskCache> disk_cache);
void OnIOComplete(int result) override;
void OnOpenEntryComplete() override;
@@ -262,7 +222,7 @@ class CONTENT_EXPORT AppCacheResponseWriter : public AppCacheResponseIO {
protected:
// Should only be constructed by the storage class and derivatives.
AppCacheResponseWriter(int64_t response_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache);
+ base::WeakPtr<AppCacheDiskCache> disk_cache);
private:
friend class AppCacheStorageImpl;
@@ -283,7 +243,7 @@ class CONTENT_EXPORT AppCacheResponseWriter : public AppCacheResponseIO {
void CreateEntryIfNeededAndContinue();
static void OnCreateEntryComplete(
base::WeakPtr<AppCacheResponseWriter> writer,
- AppCacheDiskCacheInterface::Entry** entry,
+ AppCacheDiskCacheEntry** entry,
int rv);
int info_size_;
@@ -323,9 +283,8 @@ class CONTENT_EXPORT AppCacheResponseMetadataWriter
friend class content::MockAppCacheStorage;
// Should only be constructed by the storage class and derivatives.
- AppCacheResponseMetadataWriter(
- int64_t response_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache);
+ AppCacheResponseMetadataWriter(int64_t response_id,
+ base::WeakPtr<AppCacheDiskCache> disk_cache);
private:
void OnIOComplete(int result) override;
diff --git a/chromium/content/browser/appcache/appcache_response_unittest.cc b/chromium/content/browser/appcache/appcache_response_unittest.cc
index 799c9133b52..5cde7376907 100644
--- a/chromium/content/browser/appcache/appcache_response_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_response_unittest.cc
@@ -169,7 +169,8 @@ class AppCacheResponseTest : public testing::Test {
static const char kHttpHeaders[] =
"HTTP/1.0 200 OK\0Content-Length: 5\0\0";
static const char kHttpBody[] = "Hello";
- scoped_refptr<IOBuffer> body(new WrappedIOBuffer(kHttpBody));
+ scoped_refptr<IOBuffer> body =
+ base::MakeRefCounted<WrappedIOBuffer>(kHttpBody);
std::string raw_headers(kHttpHeaders, arraysize(kHttpHeaders));
WriteResponse(
MakeHttpResponseInfo(raw_headers), body.get(), strlen(kHttpBody));
@@ -326,8 +327,8 @@ class AppCacheResponseTest : public testing::Test {
// 1. Attempt to ReadInfo
// 2. Attempt to ReadData
- reader_.reset(
- service_->storage()->CreateResponseReader(GURL(), kNoSuchResponseId));
+ reader_ =
+ service_->storage()->CreateResponseReader(GURL(), kNoSuchResponseId);
// Push tasks in reverse order
PushNextTask(base::BindOnce(&AppCacheResponseTest::ReadNonExistentData,
@@ -349,7 +350,7 @@ class AppCacheResponseTest : public testing::Test {
void ReadNonExistentData() {
EXPECT_FALSE(reader_->IsReadPending());
- read_buffer_ = new IOBuffer(kBlockSize);
+ read_buffer_ = base::MakeRefCounted<IOBuffer>(kBlockSize);
reader_->ReadData(read_buffer_.get(), kBlockSize,
base::BindOnce(&AppCacheResponseTest::OnReadComplete,
base::Unretained(this)));
@@ -382,7 +383,7 @@ class AppCacheResponseTest : public testing::Test {
PushNextTask(
base::BindOnce(&AppCacheResponseTest::LoadResponseInfo_Hit_Step2,
base::Unretained(this)));
- writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
+ writer_ = service_->storage()->CreateResponseWriter(GURL());
written_response_id_ = writer_->response_id();
WriteBasicResponse();
}
@@ -444,7 +445,7 @@ class AppCacheResponseTest : public testing::Test {
base::Unretained(this), "Metadata First"));
PushNextTask(base::BindOnce(&AppCacheResponseTest::Metadata_ResetWriter,
base::Unretained(this)));
- writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
+ writer_ = service_->storage()->CreateResponseWriter(GURL());
written_response_id_ = writer_->response_id();
WriteBasicResponse();
}
@@ -455,9 +456,10 @@ class AppCacheResponseTest : public testing::Test {
}
void Metadata_WriteMetadata(const char* metadata) {
- metadata_writer_.reset(service_->storage()->CreateResponseMetadataWriter(
- written_response_id_));
- scoped_refptr<IOBuffer> buffer(new WrappedIOBuffer(metadata));
+ metadata_writer_ =
+ service_->storage()->CreateResponseMetadataWriter(written_response_id_);
+ scoped_refptr<IOBuffer> buffer =
+ base::MakeRefCounted<WrappedIOBuffer>(metadata);
WriteResponseMetadata(buffer.get(), strlen(metadata));
}
@@ -510,7 +512,7 @@ class AppCacheResponseTest : public testing::Test {
PushNextTask(base::BindOnce(&AppCacheResponseTest::WriteResponseHead,
base::Unretained(this), std::move(head)));
- writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
+ writer_ = service_->storage()->CreateResponseWriter(GURL());
written_response_id_ = writer_->response_id();
ScheduleNextTask();
}
@@ -557,7 +559,7 @@ class AppCacheResponseTest : public testing::Test {
}
void WriteOutBlocks() {
- writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
+ writer_ = service_->storage()->CreateResponseWriter(GURL());
written_response_id_ = writer_->response_id();
for (int i = 0; i < kNumBlocks; ++i) {
PushNextTask(base::BindOnce(&AppCacheResponseTest::WriteOneBlock,
@@ -567,16 +569,16 @@ class AppCacheResponseTest : public testing::Test {
}
void WriteOneBlock(int block_number) {
- scoped_refptr<IOBuffer> io_buffer(
- new IOBuffer(kBlockSize));
+ scoped_refptr<IOBuffer> io_buffer =
+ base::MakeRefCounted<IOBuffer>(kBlockSize);
FillData(block_number, io_buffer->data(), kBlockSize);
WriteResponseBody(io_buffer, kBlockSize);
}
void ReadInBlocks() {
writer_.reset();
- reader_.reset(service_->storage()->CreateResponseReader(
- GURL(), written_response_id_));
+ reader_ =
+ service_->storage()->CreateResponseReader(GURL(), written_response_id_);
for (int i = 0; i < kNumBlocks; ++i) {
PushNextTask(base::BindOnce(&AppCacheResponseTest::ReadOneBlock,
base::Unretained(this), kNumBlocks - i));
@@ -587,7 +589,7 @@ class AppCacheResponseTest : public testing::Test {
void ReadOneBlock(int block_number) {
PushNextTask(base::BindOnce(&AppCacheResponseTest::VerifyOneBlock,
base::Unretained(this), block_number));
- ReadResponseBody(new IOBuffer(kBlockSize), kBlockSize);
+ ReadResponseBody(base::MakeRefCounted<IOBuffer>(kBlockSize), kBlockSize);
}
void VerifyOneBlock(int block_number) {
@@ -598,10 +600,10 @@ class AppCacheResponseTest : public testing::Test {
void ReadAllAtOnce() {
PushNextTask(base::BindOnce(&AppCacheResponseTest::VerifyAllAtOnce,
base::Unretained(this)));
- reader_.reset(service_->storage()->CreateResponseReader(
- GURL(), written_response_id_));
+ reader_ =
+ service_->storage()->CreateResponseReader(GURL(), written_response_id_);
int big_size = kNumBlocks * kBlockSize;
- ReadResponseBody(new IOBuffer(big_size), big_size);
+ ReadResponseBody(base::MakeRefCounted<IOBuffer>(big_size), big_size);
}
void VerifyAllAtOnce() {
@@ -613,7 +615,7 @@ class AppCacheResponseTest : public testing::Test {
void ReadPastEOF() {
EXPECT_FALSE(reader_->IsReadPending());
- read_buffer_ = new IOBuffer(kBlockSize);
+ read_buffer_ = base::MakeRefCounted<IOBuffer>(kBlockSize);
expected_read_result_ = 0;
reader_->ReadData(read_buffer_.get(), kBlockSize,
base::BindOnce(&AppCacheResponseTest::OnReadComplete,
@@ -623,10 +625,10 @@ class AppCacheResponseTest : public testing::Test {
void ReadRange() {
PushNextTask(base::BindOnce(&AppCacheResponseTest::VerifyRange,
base::Unretained(this)));
- reader_.reset(service_->storage()->CreateResponseReader(
- GURL(), written_response_id_));
+ reader_ =
+ service_->storage()->CreateResponseReader(GURL(), written_response_id_);
reader_->SetReadRange(kBlockSize, kBlockSize);
- ReadResponseBody(new IOBuffer(kBlockSize), kBlockSize);
+ ReadResponseBody(base::MakeRefCounted<IOBuffer>(kBlockSize), kBlockSize);
}
void VerifyRange() {
@@ -637,10 +639,10 @@ class AppCacheResponseTest : public testing::Test {
void ReadRangePartiallyBeyondEOF() {
PushNextTask(base::BindOnce(&AppCacheResponseTest::VerifyRangeBeyondEOF,
base::Unretained(this)));
- reader_.reset(service_->storage()->CreateResponseReader(
- GURL(), written_response_id_));
+ reader_ =
+ service_->storage()->CreateResponseReader(GURL(), written_response_id_);
reader_->SetReadRange(kBlockSize, kNumBlocks * kBlockSize);
- ReadResponseBody(new IOBuffer(kNumBlocks * kBlockSize),
+ ReadResponseBody(base::MakeRefCounted<IOBuffer>(kNumBlocks * kBlockSize),
kNumBlocks * kBlockSize);
expected_read_result_ = (kNumBlocks - 1) * kBlockSize;
}
@@ -651,10 +653,10 @@ class AppCacheResponseTest : public testing::Test {
}
void ReadRangeFullyBeyondEOF() {
- reader_.reset(service_->storage()->CreateResponseReader(
- GURL(), written_response_id_));
+ reader_ =
+ service_->storage()->CreateResponseReader(GURL(), written_response_id_);
reader_->SetReadRange((kNumBlocks * kBlockSize) + 1, kBlockSize);
- ReadResponseBody(new IOBuffer(kBlockSize), kBlockSize);
+ ReadResponseBody(base::MakeRefCounted<IOBuffer>(kBlockSize), kBlockSize);
expected_read_result_ = 0;
}
@@ -677,7 +679,7 @@ class AppCacheResponseTest : public testing::Test {
}
void WriteOutBlocksImmediately() {
- writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
+ writer_ = service_->storage()->CreateResponseWriter(GURL());
written_response_id_ = writer_->response_id();
for (int i = 0; i < kNumBlocks; ++i) {
PushNextTaskAsImmediate(
@@ -689,8 +691,8 @@ class AppCacheResponseTest : public testing::Test {
void ReadInBlocksImmediately() {
writer_.reset();
- reader_.reset(service_->storage()->CreateResponseReader(
- GURL(), written_response_id_));
+ reader_ =
+ service_->storage()->CreateResponseReader(GURL(), written_response_id_);
for (int i = 0; i < kNumBlocks; ++i) {
PushNextTaskAsImmediate(
base::BindOnce(&AppCacheResponseTest::ReadOneBlockImmediately,
@@ -703,7 +705,7 @@ class AppCacheResponseTest : public testing::Test {
PushNextTaskAsImmediate(
base::BindOnce(&AppCacheResponseTest::VerifyOneBlock,
base::Unretained(this), block_number));
- ReadResponseBody(new IOBuffer(kBlockSize), kBlockSize);
+ ReadResponseBody(base::MakeRefCounted<IOBuffer>(kBlockSize), kBlockSize);
}
// DeleteWithinCallbacks -------------------------------------------
@@ -749,9 +751,9 @@ class AppCacheResponseTest : public testing::Test {
void ReadThenDelete() {
read_callback_was_called_ = false;
- reader_.reset(service_->storage()->CreateResponseReader(
- GURL(), written_response_id_));
- ReadResponseBody(new IOBuffer(kBlockSize), kBlockSize);
+ reader_ =
+ service_->storage()->CreateResponseReader(GURL(), written_response_id_);
+ ReadResponseBody(base::MakeRefCounted<IOBuffer>(kBlockSize), kBlockSize);
EXPECT_TRUE(reader_->IsReadPending());
reader_.reset();
diff --git a/chromium/content/browser/appcache/appcache_service_impl.cc b/chromium/content/browser/appcache/appcache_service_impl.cc
index 513eef22af8..b95cb20d688 100644
--- a/chromium/content/browser/appcache/appcache_service_impl.cc
+++ b/chromium/content/browser/appcache/appcache_service_impl.cc
@@ -321,8 +321,8 @@ void AppCacheServiceImpl::CheckResponseHelper::OnGroupLoaded(
// Verify that we can read the response info and data.
expected_total_size_ = entry->response_size();
- response_reader_.reset(
- service_->storage()->CreateResponseReader(manifest_url_, response_id_));
+ response_reader_ =
+ service_->storage()->CreateResponseReader(manifest_url_, response_id_);
info_buffer_ = new HttpResponseInfoIOBuffer();
response_reader_->ReadInfo(
info_buffer_.get(),
@@ -341,7 +341,7 @@ void AppCacheServiceImpl::CheckResponseHelper::OnReadInfoComplete(int result) {
amount_headers_read_ = result;
// Start reading the data.
- data_buffer_ = new net::IOBuffer(kIOBufferSize);
+ data_buffer_ = base::MakeRefCounted<net::IOBuffer>(kIOBufferSize);
response_reader_->ReadData(
data_buffer_.get(), kIOBufferSize,
base::BindOnce(&CheckResponseHelper::OnReadDataComplete,
diff --git a/chromium/content/browser/appcache/appcache_service_unittest.cc b/chromium/content/browser/appcache/appcache_service_unittest.cc
index 50a7421ae9c..a50ce5ca7fc 100644
--- a/chromium/content/browser/appcache/appcache_service_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_service_unittest.cc
@@ -43,8 +43,7 @@ class MockResponseReader : public AppCacheResponseReader {
int info_size,
const char* data,
int data_size)
- : AppCacheResponseReader(response_id,
- base::WeakPtr<AppCacheDiskCacheInterface>()),
+ : AppCacheResponseReader(response_id, /*disk_cache=*/nullptr),
info_(info),
info_size_(info_size),
data_(data),
diff --git a/chromium/content/browser/appcache/appcache_storage.cc b/chromium/content/browser/appcache/appcache_storage.cc
index 3be839ed241..c927a8f5d7c 100644
--- a/chromium/content/browser/appcache/appcache_storage.cc
+++ b/chromium/content/browser/appcache/appcache_storage.cc
@@ -60,7 +60,7 @@ AppCacheStorage::ResponseInfoLoadTask::~ResponseInfoLoadTask() {
void AppCacheStorage::ResponseInfoLoadTask::StartIfNeeded() {
if (reader_)
return;
- reader_.reset(storage_->CreateResponseReader(manifest_url_, response_id_));
+ reader_ = storage_->CreateResponseReader(manifest_url_, response_id_);
reader_->ReadInfo(info_buffer_.get(),
base::BindOnce(&ResponseInfoLoadTask::OnReadComplete,
base::Unretained(this)));
diff --git a/chromium/content/browser/appcache/appcache_storage.h b/chromium/content/browser/appcache/appcache_storage.h
index 5e49a2760a2..79da21bb9e6 100644
--- a/chromium/content/browser/appcache/appcache_storage.h
+++ b/chromium/content/browser/appcache/appcache_storage.h
@@ -176,17 +176,18 @@ class CONTENT_EXPORT AppCacheStorage {
}
// Creates a reader to read a response from storage.
- virtual AppCacheResponseReader* CreateResponseReader(const GURL& manifest_url,
- int64_t response_id) = 0;
+ virtual std::unique_ptr<AppCacheResponseReader> CreateResponseReader(
+ const GURL& manifest_url,
+ int64_t response_id) = 0;
// Creates a writer to write a new response to storage. This call
// establishes a new response id.
- virtual AppCacheResponseWriter* CreateResponseWriter(
+ virtual std::unique_ptr<AppCacheResponseWriter> CreateResponseWriter(
const GURL& manifest_url) = 0;
// Creates a metadata writer to write metadata of response to storage.
- virtual AppCacheResponseMetadataWriter* CreateResponseMetadataWriter(
- int64_t response_id) = 0;
+ virtual std::unique_ptr<AppCacheResponseMetadataWriter>
+ CreateResponseMetadataWriter(int64_t response_id) = 0;
// Schedules the lazy deletion of responses and saves the ids
// persistently such that the responses will be deleted upon restart
diff --git a/chromium/content/browser/appcache/appcache_storage_impl.cc b/chromium/content/browser/appcache/appcache_storage_impl.cc
index 7ca367b82d4..35e3764b735 100644
--- a/chromium/content/browser/appcache/appcache_storage_impl.cc
+++ b/chromium/content/browser/appcache/appcache_storage_impl.cc
@@ -14,13 +14,11 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
-#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
@@ -32,7 +30,6 @@
#include "content/browser/appcache/appcache_quota_client.h"
#include "content/browser/appcache/appcache_response.h"
#include "content/browser/appcache/appcache_service_impl.h"
-#include "content/public/common/content_switches.h"
#include "net/base/cache_type.h"
#include "net/base/net_errors.h"
#include "sql/database.h"
@@ -46,13 +43,11 @@ namespace content {
namespace {
-constexpr const int kMB = 1024 * 1024;
-
// Hard coded default when not using quota management.
-constexpr const int kDefaultQuota = 5 * kMB;
+constexpr const int kDefaultQuota = 5 * 1024 * 1024;
-constexpr const int kMaxAppCacheDiskCacheSize = 250 * kMB;
-constexpr const int kMaxAppCacheMemDiskCacheSize = 10 * kMB;
+constexpr const int kMaxAppCacheDiskCacheSize = 250 * 1024 * 1024;
+constexpr const int kMaxAppCacheMemDiskCacheSize = 10 * 1024 * 1024;
constexpr base::FilePath::CharType kDiskCacheDirectoryName[] =
FILE_PATH_LITERAL("Cache");
@@ -620,22 +615,14 @@ class AppCacheStorageImpl::StoreGroupAndCacheTask : public StoreOrLoadTask {
bool would_exceed_quota_;
int64_t space_available_;
int64_t new_origin_usage_;
- int64_t max_appcache_origin_cache_size_;
std::vector<int64_t> newly_deletable_response_ids_;
};
AppCacheStorageImpl::StoreGroupAndCacheTask::StoreGroupAndCacheTask(
- AppCacheStorageImpl* storage,
- AppCacheGroup* group,
- AppCache* newest_cache)
- : StoreOrLoadTask(storage),
- group_(group),
- cache_(newest_cache),
- success_(false),
- would_exceed_quota_(false),
- space_available_(-1),
- new_origin_usage_(-1),
- max_appcache_origin_cache_size_(kDefaultQuota) {
+ AppCacheStorageImpl* storage, AppCacheGroup* group, AppCache* newest_cache)
+ : StoreOrLoadTask(storage), group_(group), cache_(newest_cache),
+ success_(false), would_exceed_quota_(false),
+ space_available_(-1), new_origin_usage_(-1) {
group_record_.group_id = group->group_id();
group_record_.manifest_url = group->manifest_url();
group_record_.origin = url::Origin::Create(group_record_.manifest_url);
@@ -649,15 +636,6 @@ AppCacheStorageImpl::StoreGroupAndCacheTask::StoreGroupAndCacheTask(
&intercept_namespace_records_,
&fallback_namespace_records_,
&online_whitelist_records_);
-
- base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kMaxAppCacheOriginCacheSizeMb)) {
- if (base::StringToInt64(command_line.GetSwitchValueASCII(
- switches::kMaxAppCacheOriginCacheSizeMb),
- &max_appcache_origin_cache_size_)) {
- max_appcache_origin_cache_size_ *= kMB;
- }
- }
}
void AppCacheStorageImpl::StoreGroupAndCacheTask::GetQuotaThenSchedule() {
@@ -684,7 +662,7 @@ void AppCacheStorageImpl::StoreGroupAndCacheTask::GetQuotaThenSchedule() {
// We have to ask the quota manager for the value.
storage_->pending_quota_queries_.insert(this);
quota_manager->GetUsageAndQuota(
- group_record_.origin.GetURL(), blink::mojom::StorageType::kTemporary,
+ group_record_.origin, blink::mojom::StorageType::kTemporary,
base::BindOnce(&StoreGroupAndCacheTask::OnQuotaCallback, this));
}
@@ -779,10 +757,9 @@ void AppCacheStorageImpl::StoreGroupAndCacheTask::Run() {
return;
}
- // Use a user defined value or a simple hard-coded value when not using quota
- // management.
+ // Use a simple hard-coded value when not using quota management.
if (space_available_ == -1) {
- if (new_origin_usage_ > max_appcache_origin_cache_size_) {
+ if (new_origin_usage_ > kDefaultQuota) {
would_exceed_quota_ = true;
success_ = false;
return;
@@ -1567,8 +1544,7 @@ void AppCacheStorageImpl::FindResponseForMainRequest(
working_set()->GetGroupsInOrigin(origin);
if (groups_in_use) {
if (!preferred_manifest_url.is_empty()) {
- AppCacheWorkingSet::GroupMap::const_iterator found =
- groups_in_use->find(preferred_manifest_url);
+ auto found = groups_in_use->find(preferred_manifest_url);
if (found != groups_in_use->end() &&
FindResponseForMainRequestInGroup(
found->second, *url_ptr, delegate)) {
@@ -1710,23 +1686,26 @@ void AppCacheStorageImpl::StoreEvictionTimes(AppCacheGroup* group) {
task->Schedule();
}
-AppCacheResponseReader* AppCacheStorageImpl::CreateResponseReader(
- const GURL& manifest_url,
- int64_t response_id) {
- return new AppCacheResponseReader(
- response_id, is_disabled_ ? nullptr : disk_cache()->GetWeakPtr());
+std::unique_ptr<AppCacheResponseReader>
+AppCacheStorageImpl::CreateResponseReader(const GURL& manifest_url,
+ int64_t response_id) {
+ // base::WrapUnique needed due to non-public constructor.
+ return base::WrapUnique(new AppCacheResponseReader(
+ response_id, is_disabled_ ? nullptr : disk_cache()->GetWeakPtr()));
}
-AppCacheResponseWriter* AppCacheStorageImpl::CreateResponseWriter(
- const GURL& manifest_url) {
- return new AppCacheResponseWriter(
- NewResponseId(), is_disabled_ ? nullptr : disk_cache()->GetWeakPtr());
+std::unique_ptr<AppCacheResponseWriter>
+AppCacheStorageImpl::CreateResponseWriter(const GURL& manifest_url) {
+ // base::WrapUnique needed due to non-public constructor.
+ return base::WrapUnique(new AppCacheResponseWriter(
+ NewResponseId(), is_disabled_ ? nullptr : disk_cache()->GetWeakPtr()));
}
-AppCacheResponseMetadataWriter*
+std::unique_ptr<AppCacheResponseMetadataWriter>
AppCacheStorageImpl::CreateResponseMetadataWriter(int64_t response_id) {
- return new AppCacheResponseMetadataWriter(
- response_id, is_disabled_ ? nullptr : disk_cache()->GetWeakPtr());
+ // base::WrapUnique needed due to non-public constructor.
+ return base::WrapUnique(new AppCacheResponseMetadataWriter(
+ response_id, is_disabled_ ? nullptr : disk_cache()->GetWeakPtr()));
}
void AppCacheStorageImpl::DoomResponses(
@@ -1843,7 +1822,7 @@ void AppCacheStorageImpl::OnDeletedOneResponse(int rv) {
AppCacheStorageImpl::CacheLoadTask*
AppCacheStorageImpl::GetPendingCacheLoadTask(int64_t cache_id) {
- PendingCacheLoads::iterator found = pending_cache_loads_.find(cache_id);
+ auto found = pending_cache_loads_.find(cache_id);
if (found != pending_cache_loads_.end())
return found->second;
return nullptr;
@@ -1851,7 +1830,7 @@ AppCacheStorageImpl::GetPendingCacheLoadTask(int64_t cache_id) {
AppCacheStorageImpl::GroupLoadTask*
AppCacheStorageImpl::GetPendingGroupLoadTask(const GURL& manifest_url) {
- PendingGroupLoads::iterator found = pending_group_loads_.find(manifest_url);
+ auto found = pending_group_loads_.find(manifest_url);
if (found != pending_group_loads_.end())
return found->second;
return nullptr;
@@ -1895,21 +1874,9 @@ AppCacheDiskCache* AppCacheStorageImpl::disk_cache() {
base::Unretained(this)));
} else {
expecting_cleanup_complete_on_disable_ = true;
-
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- unsigned int max_appcache_disk_cache_size = kMaxAppCacheDiskCacheSize;
- if (command_line.HasSwitch(switches::kMaxAppCacheDiskCacheSizeMb)) {
- if (base::StringToUint(command_line.GetSwitchValueASCII(
- switches::kMaxAppCacheDiskCacheSizeMb),
- &max_appcache_disk_cache_size)) {
- max_appcache_disk_cache_size *= kMB;
- }
- }
-
rv = disk_cache_->InitWithDiskBackend(
cache_directory_.Append(kDiskCacheDirectoryName),
- max_appcache_disk_cache_size, false,
+ kMaxAppCacheDiskCacheSize, false,
base::BindOnce(&AppCacheStorageImpl::OnDiskCacheCleanupComplete,
weak_factory_.GetWeakPtr()),
base::Bind(&AppCacheStorageImpl::OnDiskCacheInitialized,
diff --git a/chromium/content/browser/appcache/appcache_storage_impl.h b/chromium/content/browser/appcache/appcache_storage_impl.h
index 51b0bb1c093..c7b389b1932 100644
--- a/chromium/content/browser/appcache/appcache_storage_impl.h
+++ b/chromium/content/browser/appcache/appcache_storage_impl.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <map>
+#include <memory>
#include <set>
#include <utility>
#include <vector>
@@ -63,11 +64,12 @@ class AppCacheStorageImpl : public AppCacheStorage {
Delegate* delegate,
int response_code) override;
void StoreEvictionTimes(AppCacheGroup* group) override;
- AppCacheResponseReader* CreateResponseReader(const GURL& manifest_url,
- int64_t response_id) override;
- AppCacheResponseWriter* CreateResponseWriter(
+ std::unique_ptr<AppCacheResponseReader> CreateResponseReader(
+ const GURL& manifest_url,
+ int64_t response_id) override;
+ std::unique_ptr<AppCacheResponseWriter> CreateResponseWriter(
const GURL& manifest_url) override;
- AppCacheResponseMetadataWriter* CreateResponseMetadataWriter(
+ std::unique_ptr<AppCacheResponseMetadataWriter> CreateResponseMetadataWriter(
int64_t response_id) override;
void DoomResponses(const GURL& manifest_url,
const std::vector<int64_t>& response_ids) override;
diff --git a/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc b/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
index 03237c227d3..8fe734648c3 100644
--- a/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
@@ -254,7 +254,7 @@ class AppCacheStorageImplTest : public testing::Test {
storage::GetQuotaSettingsFunc()),
async_(false) {}
- void GetUsageAndQuota(const GURL& origin,
+ void GetUsageAndQuota(const url::Origin& /* origin */,
StorageType type,
UsageAndQuotaCallback callback) override {
EXPECT_EQ(StorageType::kTemporary, type);
diff --git a/chromium/content/browser/appcache/appcache_update_job.cc b/chromium/content/browser/appcache/appcache_update_job.cc
index 32be530befe..46f01ad46d2 100644
--- a/chromium/content/browser/appcache/appcache_update_job.cc
+++ b/chromium/content/browser/appcache/appcache_update_job.cc
@@ -271,8 +271,9 @@ void AppCacheUpdateJob::StartUpdate(AppCacheHost* host,
weak_factory_.GetWeakPtr(), true));
}
-AppCacheResponseWriter* AppCacheUpdateJob::CreateResponseWriter() {
- AppCacheResponseWriter* writer =
+std::unique_ptr<AppCacheResponseWriter>
+AppCacheUpdateJob::CreateResponseWriter() {
+ std::unique_ptr<AppCacheResponseWriter> writer =
storage_->CreateResponseWriter(manifest_url_);
stored_response_ids_.push_back(writer->response_id());
return writer;
@@ -598,7 +599,7 @@ void AppCacheUpdateJob::HandleMasterEntryFetchCompleted(URLFetcher* fetcher,
int response_code = net_error == net::OK ? request->GetResponseCode() : -1;
- PendingMasters::iterator found = pending_master_entries_.find(url);
+ auto found = pending_master_entries_.find(url);
DCHECK(found != pending_master_entries_.end());
PendingHosts& hosts = found->second;
@@ -687,7 +688,7 @@ void AppCacheUpdateJob::HandleManifestRefetchCompleted(URLFetcher* fetcher,
entry->add_types(AppCacheEntry::MANIFEST);
StoreGroupAndCache();
} else {
- manifest_response_writer_.reset(CreateResponseWriter());
+ manifest_response_writer_ = CreateResponseWriter();
scoped_refptr<HttpResponseInfoIOBuffer> io_buffer =
base::MakeRefCounted<HttpResponseInfoIOBuffer>(
std::move(manifest_response_info_));
@@ -721,8 +722,8 @@ void AppCacheUpdateJob::HandleManifestRefetchCompleted(URLFetcher* fetcher,
void AppCacheUpdateJob::OnManifestInfoWriteComplete(int result) {
if (result > 0) {
- scoped_refptr<net::StringIOBuffer> io_buffer(
- new net::StringIOBuffer(manifest_data_));
+ scoped_refptr<net::StringIOBuffer> io_buffer =
+ base::MakeRefCounted<net::StringIOBuffer>(manifest_data_);
manifest_response_writer_->WriteData(
io_buffer.get(), manifest_data_.length(),
base::BindOnce(&AppCacheUpdateJob::OnManifestDataWriteComplete,
@@ -860,11 +861,10 @@ void AppCacheUpdateJob::AddAllAssociatedHostsToNotifier(
void AppCacheUpdateJob::OnDestructionImminent(AppCacheHost* host) {
// The host is about to be deleted; remove from our collection.
- PendingMasters::iterator found =
- pending_master_entries_.find(host->pending_master_entry_url());
+ auto found = pending_master_entries_.find(host->pending_master_entry_url());
CHECK(found != pending_master_entries_.end());
PendingHosts& hosts = found->second;
- PendingHosts::iterator it = std::find(hosts.begin(), hosts.end(), host);
+ auto it = std::find(hosts.begin(), hosts.end(), host);
CHECK(it != hosts.end());
hosts.erase(it);
}
@@ -901,10 +901,10 @@ void AppCacheUpdateJob::CheckIfManifestChanged() {
}
// Load manifest data from storage to compare against fetched manifest.
- manifest_response_reader_.reset(
- storage_->CreateResponseReader(manifest_url_,
- entry->response_id()));
- read_manifest_buffer_ = new net::IOBuffer(kAppCacheFetchBufferSize);
+ manifest_response_reader_ =
+ storage_->CreateResponseReader(manifest_url_, entry->response_id());
+ read_manifest_buffer_ =
+ base::MakeRefCounted<net::IOBuffer>(kAppCacheFetchBufferSize);
manifest_response_reader_->ReadData(
read_manifest_buffer_.get(), kAppCacheFetchBufferSize,
base::BindOnce(&AppCacheUpdateJob::OnManifestDataReadComplete,
@@ -967,7 +967,7 @@ void AppCacheUpdateJob::FetchUrls() {
UrlToFetch url_to_fetch = urls_to_fetch_.front();
urls_to_fetch_.pop_front();
- AppCache::EntryMap::iterator it = url_file_list_.find(url_to_fetch.url);
+ auto it = url_file_list_.find(url_to_fetch.url);
DCHECK(it != url_file_list_.end());
AppCacheEntry& entry = it->second;
if (ShouldSkipUrlFetch(entry)) {
@@ -1093,7 +1093,7 @@ void AppCacheUpdateJob::FetchMasterEntries() {
// TODO(michaeln): defer until the updated cache has been stored.
DCHECK(!inprogress_cache_.get());
AppCache* cache = group_->newest_complete_cache();
- PendingMasters::iterator found = pending_master_entries_.find(url);
+ auto found = pending_master_entries_.find(url);
DCHECK(found != pending_master_entries_.end());
PendingHosts& hosts = found->second;
for (AppCacheHost* host : hosts)
@@ -1132,7 +1132,7 @@ void AppCacheUpdateJob::CancelAllMasterEntryFetches(
HostNotifier host_notifier;
while (!master_entries_to_fetch_.empty()) {
const GURL& url = *master_entries_to_fetch_.begin();
- PendingMasters::iterator found = pending_master_entries_.find(url);
+ auto found = pending_master_entries_.find(url);
DCHECK(found != pending_master_entries_.end());
PendingHosts& hosts = found->second;
for (AppCacheHost* host : hosts) {
@@ -1180,7 +1180,7 @@ void AppCacheUpdateJob::OnResponseInfoLoaded(
return;
}
- LoadingResponses::iterator found = loading_responses_.find(response_id);
+ auto found = loading_responses_.find(response_id);
DCHECK(found != loading_responses_.end());
const GURL& url = found->second;
@@ -1194,7 +1194,7 @@ void AppCacheUpdateJob::OnResponseInfoLoaded(
DCHECK(copy_me);
DCHECK_EQ(copy_me->response_id(), response_id);
- AppCache::EntryMap::iterator it = url_file_list_.find(url);
+ auto it = url_file_list_.find(url);
DCHECK(it != url_file_list_.end());
AppCacheEntry& entry = it->second;
entry.set_response_id(response_id);
diff --git a/chromium/content/browser/appcache/appcache_update_job.h b/chromium/content/browser/appcache/appcache_update_job.h
index 79eabef47b1..5a5f05c4860 100644
--- a/chromium/content/browser/appcache/appcache_update_job.h
+++ b/chromium/content/browser/appcache/appcache_update_job.h
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -116,7 +117,7 @@ class CONTENT_EXPORT AppCacheUpdateJob
scoped_refptr<AppCacheResponseInfo> existing_response_info;
};
- AppCacheResponseWriter* CreateResponseWriter();
+ std::unique_ptr<AppCacheResponseWriter> CreateResponseWriter();
// Methods for AppCacheStorage::Delegate.
void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
diff --git a/chromium/content/browser/appcache/appcache_update_job_unittest.cc b/chromium/content/browser/appcache/appcache_update_job_unittest.cc
index 6cb4ce06c35..53aecac2c24 100644
--- a/chromium/content/browser/appcache/appcache_update_job_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_update_job_unittest.cc
@@ -20,6 +20,7 @@
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -29,6 +30,7 @@
#include "content/browser/appcache/appcache_update_url_loader_request.h"
#include "content/browser/appcache/mock_appcache_service.h"
#include "content/browser/url_loader_factory_getter.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/data_pipe.h"
@@ -705,15 +707,15 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
tested_manifest_path_override_(nullptr),
request_handler_type_(GetParam()),
thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThread::Init, base::Unretained(io_thread_.get())));
if (request_handler_type_ == URLLOADER) {
loader_factory_getter_ = new URLLoaderFactoryGetter();
feature_list_.InitAndEnableFeature(network::features::kNetworkService);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AppCacheUpdateJobTest::InitializeFactory,
base::Unretained(this)));
}
@@ -724,8 +726,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
// The TestBrowserThreadBundle dtor guarantees that all posted tasks are
// executed before the IO thread shuts down. It is safe to use the
// Unretained pointer here.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThread::CleanUp, base::Unretained(io_thread_.get())));
}
@@ -737,8 +739,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED));
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(method, base::Unretained(this)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(method, base::Unretained(this)));
// Wait until task is done before exiting the test.
event_->Wait();
@@ -752,7 +754,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void StartCacheAttemptTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(), GURL("http://failme"),
@@ -787,7 +789,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void StartUpgradeAttemptTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
{
MakeService();
@@ -853,7 +855,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void CacheAttemptFetchManifestFailTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(), GURL("http://failme"),
@@ -877,7 +879,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeFetchManifestFailTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(),
@@ -918,7 +920,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void ManifestRedirectTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
if (request_handler_type_ == URLREQUEST) {
net::URLRequestJobFactoryImpl* new_factory(
@@ -950,7 +952,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void ManifestMissingMimeTypeTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -990,7 +992,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void ManifestNotFoundTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -1026,7 +1028,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void ManifestGoneTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -1051,7 +1053,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void CacheAttemptNotModifiedTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -1076,7 +1078,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeNotModifiedTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -1120,7 +1122,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeManifestDataUnchangedTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -1131,8 +1133,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
group_->update_job_ = update;
// Create response writer to get a response id.
- response_writer_.reset(
- service_->storage()->CreateResponseWriter(group_->manifest_url()));
+ response_writer_ =
+ service_->storage()->CreateResponseWriter(group_->manifest_url());
AppCache* cache = MakeCacheForGroup(1, response_writer_->response_id());
MockFrontend* frontend1 = MakeMockFrontend();
@@ -1158,8 +1160,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
// Seed storage with expected manifest data.
const std::string seed_data(kManifest1Contents);
- scoped_refptr<net::StringIOBuffer> io_buffer(
- new net::StringIOBuffer(seed_data));
+ scoped_refptr<net::StringIOBuffer> io_buffer =
+ base::MakeRefCounted<net::StringIOBuffer>(seed_data);
response_writer_->WriteData(
io_buffer.get(), seed_data.length(),
base::BindOnce(
@@ -1171,7 +1173,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
// See http://code.google.com/p/chromium/issues/detail?id=95101
void Bug95101Test() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -1215,7 +1217,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void BasicCacheAttemptSuccessTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
GURL manifest_url = MockHttpServer::GetMockUrl("files/manifest1");
@@ -1246,7 +1248,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
void DownloadInterceptEntriesTest() {
// Ensures we download intercept entries too.
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
GURL manifest_url =
MockHttpServer::GetMockUrl("files/manifest-with-intercept");
MakeService();
@@ -1273,7 +1275,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void BasicUpgradeSuccessTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -1284,8 +1286,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
group_->update_job_ = update;
// Create a response writer to get a response id.
- response_writer_.reset(
- service_->storage()->CreateResponseWriter(group_->manifest_url()));
+ response_writer_ =
+ service_->storage()->CreateResponseWriter(group_->manifest_url());
AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(),
response_writer_->response_id());
@@ -1330,8 +1332,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
// Seed storage with expected manifest data different from manifest1.
const std::string seed_data("different");
- scoped_refptr<net::StringIOBuffer> io_buffer(
- new net::StringIOBuffer(seed_data));
+ scoped_refptr<net::StringIOBuffer> io_buffer =
+ base::MakeRefCounted<net::StringIOBuffer>(seed_data);
response_writer_->WriteData(
io_buffer.get(), seed_data.length(),
base::BindOnce(
@@ -1342,7 +1344,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeLoadFromNewestCacheTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -1358,8 +1360,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
host->AssociateCompleteCache(cache);
// Give the newest cache an entry that is in storage.
- response_writer_.reset(
- service_->storage()->CreateResponseWriter(group_->manifest_url()));
+ response_writer_ =
+ service_->storage()->CreateResponseWriter(group_->manifest_url());
cache->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"),
AppCacheEntry(AppCacheEntry::EXPLICIT,
response_writer_->response_id()));
@@ -1410,7 +1412,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeNoLoadFromNewestCacheTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -1426,8 +1428,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
host->AssociateCompleteCache(cache);
// Give the newest cache an entry that is in storage.
- response_writer_.reset(
- service_->storage()->CreateResponseWriter(group_->manifest_url()));
+ response_writer_ =
+ service_->storage()->CreateResponseWriter(group_->manifest_url());
cache->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"),
AppCacheEntry(AppCacheEntry::EXPLICIT,
response_writer_->response_id()));
@@ -1476,7 +1478,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeLoadFromNewestCacheVaryHeaderTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -1492,8 +1494,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
host->AssociateCompleteCache(cache);
// Give the newest cache an entry that is in storage.
- response_writer_.reset(
- service_->storage()->CreateResponseWriter(group_->manifest_url()));
+ response_writer_ =
+ service_->storage()->CreateResponseWriter(group_->manifest_url());
cache->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"),
AppCacheEntry(AppCacheEntry::EXPLICIT,
response_writer_->response_id()));
@@ -1542,7 +1544,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeLoadFromNewestCacheReuseVaryHeaderTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(),
@@ -1558,8 +1560,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
host->AssociateCompleteCache(cache);
// Give the newest cache an entry that is in storage.
- response_writer_.reset(
- service_->storage()->CreateResponseWriter(group_->manifest_url()));
+ response_writer_ =
+ service_->storage()->CreateResponseWriter(group_->manifest_url());
cache->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"),
AppCacheEntry(AppCacheEntry::EXPLICIT,
response_writer_->response_id()));
@@ -1612,7 +1614,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeSuccessMergedTypesTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(),
@@ -1670,7 +1672,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void CacheAttemptFailUrlFetchTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(),
@@ -1695,7 +1697,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeFailUrlFetchTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(),
@@ -1740,7 +1742,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeFailMasterUrlFetchTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
tested_manifest_path_override_ = "files/manifest1-with-notmodified";
@@ -1853,7 +1855,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void EmptyManifestTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -1902,7 +1904,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void EmptyFileTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(),
@@ -1939,7 +1941,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void RetryRequestTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
// Set some large number of times to return retry.
// Expect 1 manifest fetch and 3 retries.
@@ -1976,7 +1978,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void RetryNoRetryAfterTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
// Set some large number of times to return retry.
// Expect 1 manifest fetch and 0 retries.
@@ -2013,7 +2015,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void RetryNonzeroRetryAfterTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
// Set some large number of times to return retry.
// Expect 1 request and 0 retry attempts.
@@ -2051,7 +2053,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void RetrySuccessTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
// Set 2 as the retry limit (does not exceed the max).
// Expect 1 manifest fetch, 2 retries, 1 url fetch, 1 manifest refetch.
@@ -2088,7 +2090,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void RetryUrlTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
// Set 1 as the retry limit (does not exceed the max).
// Expect 1 manifest fetch, 1 url fetch, 1 url retry, 1 manifest refetch.
@@ -2125,7 +2127,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void FailStoreNewestCacheTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
MockAppCacheStorage* storage =
@@ -2154,7 +2156,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeFailStoreNewestCacheTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
MockAppCacheStorage* storage =
@@ -2202,7 +2204,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void MasterEntryFailStoreNewestCacheTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
MockAppCacheStorage* storage =
@@ -2252,7 +2254,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeFailMakeGroupObsoleteTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
MockAppCacheStorage* storage =
@@ -2292,7 +2294,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void MasterEntryFetchManifestFailTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(), GURL("http://failme"), 111);
@@ -2317,7 +2319,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void MasterEntryBadManifestTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(),
@@ -2343,7 +2345,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void MasterEntryManifestNotFoundTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -2372,7 +2374,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void MasterEntryFailUrlFetchTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(),
@@ -2403,7 +2405,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void MasterEntryAllFailTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -2447,7 +2449,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeMasterEntryAllFailTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -2507,7 +2509,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void MasterEntrySomeFailTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -2558,7 +2560,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void UpgradeMasterEntrySomeFailTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -2625,7 +2627,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void MasterEntryNoUpdateTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(service_->storage(),
@@ -2681,7 +2683,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void StartUpdateMidCacheAttemptTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -2776,7 +2778,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void StartUpdateMidNoUpdateTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -2861,7 +2863,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void StartUpdateMidDownloadTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -2960,7 +2962,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void QueueMasterEntryTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
MakeService();
group_ = new AppCacheGroup(
@@ -3018,7 +3020,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void IfModifiedSinceTestCache() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
if (request_handler_type_ == URLREQUEST) {
net::URLRequestJobFactoryImpl* new_factory(
@@ -3059,7 +3061,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void IfModifiedTestRefetch() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
if (request_handler_type_ == URLREQUEST) {
net::URLRequestJobFactoryImpl* new_factory(
@@ -3110,7 +3112,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void IfModifiedTestLastModified() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
if (request_handler_type_ == URLREQUEST) {
net::URLRequestJobFactoryImpl* new_factory(
@@ -3162,7 +3164,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void IfModifiedSinceUpgradeTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
HttpHeadersRequestTestJob::Initialize("Sat, 29 Oct 1994 19:43:31 GMT",
std::string());
@@ -3185,8 +3187,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
group_->update_job_ = update;
// Give the newest cache a manifest enry that is in storage.
- response_writer_.reset(
- service_->storage()->CreateResponseWriter(group_->manifest_url()));
+ response_writer_ =
+ service_->storage()->CreateResponseWriter(group_->manifest_url());
AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(),
response_writer_->response_id());
@@ -3236,7 +3238,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void IfNoneMatchUpgradeTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
HttpHeadersRequestTestJob::Initialize(std::string(), "\"LadeDade\"");
@@ -3258,8 +3260,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
group_->update_job_ = update;
// Give the newest cache a manifest enry that is in storage.
- response_writer_.reset(
- service_->storage()->CreateResponseWriter(group_->manifest_url()));
+ response_writer_ =
+ service_->storage()->CreateResponseWriter(group_->manifest_url());
AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(),
response_writer_->response_id());
@@ -3309,7 +3311,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void IfNoneMatchRefetchTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
HttpHeadersRequestTestJob::Initialize(std::string(), "\"LadeDade\"");
@@ -3360,7 +3362,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void MultipleHeadersRefetchTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
// Verify that code is correct when building multiple extra headers.
HttpHeadersRequestTestJob::Initialize(
@@ -3414,7 +3416,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void CrossOriginHttpsSuccessTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
GURL manifest_url = MockHttpServer::GetMockHttpsUrl(
"files/valid_cross_origin_https_manifest");
@@ -3443,7 +3445,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
}
void CrossOriginHttpsDeniedTest() {
- ASSERT_TRUE(base::MessageLoopForIO::IsCurrent());
+ ASSERT_TRUE(base::MessageLoopCurrentForIO::IsSet());
GURL manifest_url = MockHttpServer::GetMockHttpsUrl(
"files/invalid_cross_origin_https_manifest");
@@ -3628,8 +3630,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
// Check that any copied entries have the expected response id
// and that entries that are not copied have a different response id.
- std::map<GURL, int64_t>::iterator found =
- expect_response_ids_.find(pair.first);
+ auto found = expect_response_ids_.find(pair.first);
if (found != expect_response_ids_.end()) {
EXPECT_EQ(found->second, pair.second.response_id());
} else if (expect_old_cache_) {
diff --git a/chromium/content/browser/appcache/appcache_update_url_fetcher.cc b/chromium/content/browser/appcache/appcache_update_url_fetcher.cc
index e9652f899a3..924a76cd237 100644
--- a/chromium/content/browser/appcache/appcache_update_url_fetcher.cc
+++ b/chromium/content/browser/appcache/appcache_update_url_fetcher.cc
@@ -106,7 +106,7 @@ void AppCacheUpdateJob::URLFetcher::OnResponseStarted(int net_error) {
// Write response info to storage for URL fetches. Wait for async write
// completion before reading any response data.
if (fetch_type_ == URL_FETCH || fetch_type_ == MASTER_ENTRY_FETCH) {
- response_writer_.reset(job_->CreateResponseWriter());
+ response_writer_ = job_->CreateResponseWriter();
scoped_refptr<HttpResponseInfoIOBuffer> io_buffer =
base::MakeRefCounted<HttpResponseInfoIOBuffer>(
std::make_unique<net::HttpResponseInfo>(
diff --git a/chromium/content/browser/appcache/appcache_update_url_request.cc b/chromium/content/browser/appcache/appcache_update_url_request.cc
index d2c28d702af..7448503af5b 100644
--- a/chromium/content/browser/appcache/appcache_update_url_request.cc
+++ b/chromium/content/browser/appcache/appcache_update_url_request.cc
@@ -119,7 +119,7 @@ AppCacheUpdateJob::UpdateURLRequest::UpdateURLRequest(
this,
GetTrafficAnnotation())),
fetcher_(fetcher),
- buffer_(new net::IOBuffer(buffer_size)),
+ buffer_(base::MakeRefCounted<net::IOBuffer>(buffer_size)),
buffer_size_(buffer_size),
weak_factory_(this) {}
diff --git a/chromium/content/browser/appcache/appcache_url_loader_job.cc b/chromium/content/browser/appcache/appcache_url_loader_job.cc
index e4245c4861f..43c10be404f 100644
--- a/chromium/content/browser/appcache/appcache_url_loader_job.cc
+++ b/chromium/content/browser/appcache/appcache_url_loader_job.cc
@@ -22,8 +22,8 @@ AppCacheURLLoaderJob::~AppCacheURLLoaderJob() {
}
bool AppCacheURLLoaderJob::IsStarted() const {
- return delivery_type_ != AWAITING_DELIVERY_ORDERS &&
- delivery_type_ != NETWORK_DELIVERY;
+ return delivery_type_ != DeliveryType::kAwaitingDeliverCall &&
+ delivery_type_ != DeliveryType::kNetwork;
}
void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url,
@@ -35,7 +35,7 @@ void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url,
return;
}
- delivery_type_ = APPCACHED_DELIVERY;
+ delivery_type_ = DeliveryType::kAppCached;
// In tests we only care about the delivery_type_ state.
if (AppCacheRequestHandler::IsRunningInTests())
@@ -57,7 +57,7 @@ void AppCacheURLLoaderJob::DeliverAppCachedResponse(const GURL& manifest_url,
}
void AppCacheURLLoaderJob::DeliverNetworkResponse() {
- delivery_type_ = NETWORK_DELIVERY;
+ delivery_type_ = DeliveryType::kNetwork;
// In tests we only care about the delivery_type_ state.
if (AppCacheRequestHandler::IsRunningInTests())
@@ -71,7 +71,7 @@ void AppCacheURLLoaderJob::DeliverNetworkResponse() {
}
void AppCacheURLLoaderJob::DeliverErrorResponse() {
- delivery_type_ = ERROR_DELIVERY;
+ delivery_type_ = DeliveryType::kError;
// In tests we only care about the delivery_type_ state.
if (AppCacheRequestHandler::IsRunningInTests())
@@ -190,8 +190,8 @@ void AppCacheURLLoaderJob::OnResponseInfoLoaded(
}
info_ = response_info;
- reader_.reset(
- storage_->CreateResponseReader(manifest_url_, entry_.response_id()));
+ reader_ =
+ storage_->CreateResponseReader(manifest_url_, entry_.response_id());
if (is_range_request())
SetupRangeResponse();
@@ -353,7 +353,7 @@ void AppCacheURLLoaderJob::NotifyCompleted(int error_code) {
}
client_->OnComplete(status);
- if (delivery_type_ == APPCACHED_DELIVERY) {
+ if (delivery_type_ == DeliveryType::kAppCached) {
AppCacheHistograms::CountResponseRetrieval(
error_code == 0, is_main_resource_load_,
url::Origin::Create(manifest_url_));
diff --git a/chromium/content/browser/appcache/appcache_url_request_job.cc b/chromium/content/browser/appcache/appcache_url_request_job.cc
index d0c16f3b250..cd1ab22e37f 100644
--- a/chromium/content/browser/appcache/appcache_url_request_job.cc
+++ b/chromium/content/browser/appcache/appcache_url_request_job.cc
@@ -65,7 +65,7 @@ void AppCacheURLRequestJob::DeliverAppCachedResponse(const GURL& manifest_url,
bool is_fallback) {
DCHECK(!has_delivery_orders());
DCHECK(entry.has_response_id());
- delivery_type_ = APPCACHED_DELIVERY;
+ delivery_type_ = DeliveryType::kAppCached;
manifest_url_ = manifest_url;
cache_id_ = cache_id;
entry_ = entry;
@@ -75,14 +75,14 @@ void AppCacheURLRequestJob::DeliverAppCachedResponse(const GURL& manifest_url,
void AppCacheURLRequestJob::DeliverNetworkResponse() {
DCHECK(!has_delivery_orders());
- delivery_type_ = NETWORK_DELIVERY;
+ delivery_type_ = DeliveryType::kNetwork;
storage_ = nullptr; // not needed
MaybeBeginDelivery();
}
void AppCacheURLRequestJob::DeliverErrorResponse() {
DCHECK(!has_delivery_orders());
- delivery_type_ = ERROR_DELIVERY;
+ delivery_type_ = DeliveryType::kError;
storage_ = nullptr; // not needed
MaybeBeginDelivery();
}
@@ -137,7 +137,7 @@ void AppCacheURLRequestJob::BeginDelivery() {
return;
switch (delivery_type_) {
- case NETWORK_DELIVERY:
+ case DeliveryType::kNetwork:
// To fallthru to the network, we restart the request which will
// cause a new job to be created to retrieve the resource from the
// network. Our caller is responsible for arranging to not re-intercept
@@ -145,14 +145,14 @@ void AppCacheURLRequestJob::BeginDelivery() {
NotifyRestartRequired();
break;
- case ERROR_DELIVERY:
+ case DeliveryType::kError:
request()->net_log().AddEvent(
net::NetLogEventType::APPCACHE_DELIVERING_ERROR_RESPONSE);
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
net::ERR_FAILED));
break;
- case APPCACHED_DELIVERY:
+ case DeliveryType::kAppCached:
request()->net_log().AddEvent(
is_fallback_
? net::NetLogEventType::APPCACHE_DELIVERING_FALLBACK_RESPONSE
@@ -170,7 +170,7 @@ void AppCacheURLRequestJob::BeginErrorDelivery(const char* message) {
if (host_)
host_->frontend()->OnLogMessage(host_->host_id(), APPCACHE_LOG_ERROR,
message);
- delivery_type_ = ERROR_DELIVERY;
+ delivery_type_ = DeliveryType::kError;
storage_ = nullptr;
BeginDelivery();
}
@@ -181,8 +181,8 @@ void AppCacheURLRequestJob::OnResponseInfoLoaded(
DCHECK(IsDeliveringAppCacheResponse());
if (response_info) {
info_ = response_info;
- reader_.reset(
- storage_->CreateResponseReader(manifest_url_, entry_.response_id()));
+ reader_ =
+ storage_->CreateResponseReader(manifest_url_, entry_.response_id());
if (is_range_request())
SetupRangeResponse();
@@ -249,7 +249,7 @@ net::LoadState AppCacheURLRequestJob::GetLoadState() const {
return net::LOAD_STATE_IDLE;
if (!has_delivery_orders())
return net::LOAD_STATE_WAITING_FOR_APPCACHE;
- if (delivery_type_ != APPCACHED_DELIVERY)
+ if (delivery_type_ != DeliveryType::kAppCached)
return net::LOAD_STATE_IDLE;
if (!info_.get())
return net::LOAD_STATE_WAITING_FOR_APPCACHE;
diff --git a/chromium/content/browser/appcache/appcache_url_request_job_unittest.cc b/chromium/content/browser/appcache/appcache_url_request_job_unittest.cc
index 266c8173551..a373b78fac1 100644
--- a/chromium/content/browser/appcache/appcache_url_request_job_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_url_request_job_unittest.cc
@@ -147,7 +147,8 @@ class AppCacheURLRequestJobTest : public testing::Test {
public:
explicit MockURLRequestDelegate(AppCacheURLRequestJobTest* test)
: test_(test),
- received_data_(new net::IOBuffer(kNumBlocks * kBlockSize)),
+ received_data_(
+ base::MakeRefCounted<net::IOBuffer>(kNumBlocks * kBlockSize)),
did_receive_headers_(false),
amount_received_(0),
kill_after_amount_received_(0),
@@ -197,8 +198,9 @@ class AppCacheURLRequestJobTest : public testing::Test {
void ReadSome(net::URLRequest* request) {
DCHECK(amount_received_ + kBlockSize <= kNumBlocks * kBlockSize);
- scoped_refptr<IOBuffer> wrapped_buffer(
- new net::WrappedIOBuffer(received_data_->data() + amount_received_));
+ scoped_refptr<IOBuffer> wrapped_buffer =
+ base::MakeRefCounted<net::WrappedIOBuffer>(received_data_->data() +
+ amount_received_);
EXPECT_EQ(net::ERR_IO_PENDING,
request->Read(wrapped_buffer.get(), kBlockSize));
}
@@ -620,7 +622,7 @@ class AppCacheURLRequestJobTest : public testing::Test {
base::BindOnce(&AppCacheURLRequestJobTest::RequestAppCachedResource,
base::Unretained(this), false));
- writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
+ writer_ = service_->storage()->CreateResponseWriter(GURL());
written_response_id_ = writer_->response_id();
WriteBasicResponse();
// Continues async
@@ -692,7 +694,7 @@ class AppCacheURLRequestJobTest : public testing::Test {
base::BindOnce(&AppCacheURLRequestJobTest::RequestAppCachedResource,
base::Unretained(this), true));
- writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
+ writer_ = service_->storage()->CreateResponseWriter(GURL());
written_response_id_ = writer_->response_id();
WriteLargeResponse();
// Continues async
@@ -702,7 +704,8 @@ class AppCacheURLRequestJobTest : public testing::Test {
// 3, 1k blocks
static const char kHttpHeaders[] =
"HTTP/1.0 200 OK\0Content-Length: 3072\0\0";
- scoped_refptr<IOBuffer> body(new IOBuffer(kBlockSize * 3));
+ scoped_refptr<IOBuffer> body =
+ base::MakeRefCounted<IOBuffer>(kBlockSize * 3);
char* p = body->data();
for (int i = 0; i < 3; ++i, p += kBlockSize)
FillData(i + 1, p, kBlockSize);
@@ -734,7 +737,7 @@ class AppCacheURLRequestJobTest : public testing::Test {
base::Unretained(this)));
PushNextTask(base::BindOnce(&AppCacheURLRequestJobTest::MakeRangeRequest,
base::Unretained(this)));
- writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
+ writer_ = service_->storage()->CreateResponseWriter(GURL());
written_response_id_ = writer_->response_id();
WriteBasicResponse();
// Continues async
@@ -801,7 +804,7 @@ class AppCacheURLRequestJobTest : public testing::Test {
base::BindOnce(&AppCacheURLRequestJobTest::RequestAppCachedResource,
base::Unretained(this), true));
- writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
+ writer_ = service_->storage()->CreateResponseWriter(GURL());
written_response_id_ = writer_->response_id();
WriteLargeResponse();
@@ -829,7 +832,7 @@ class AppCacheURLRequestJobTest : public testing::Test {
base::BindOnce(&AppCacheURLRequestJobTest::RequestAppCachedResource,
base::Unretained(this), true));
- writer_.reset(service_->storage()->CreateResponseWriter(GURL()));
+ writer_ = service_->storage()->CreateResponseWriter(GURL());
written_response_id_ = writer_->response_id();
WriteLargeResponse();
diff --git a/chromium/content/browser/appcache/chrome_appcache_service_unittest.cc b/chromium/content/browser/appcache/chrome_appcache_service_unittest.cc
index 1e5688dadd6..9a28416f758 100644
--- a/chromium/content/browser/appcache/chrome_appcache_service_unittest.cc
+++ b/chromium/content/browser/appcache/chrome_appcache_service_unittest.cc
@@ -11,11 +11,13 @@
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/appcache/appcache_database.h"
#include "content/browser/appcache/appcache_storage_impl.h"
#include "content/browser/appcache/chrome_appcache_service.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_context.h"
#include "content/public/test/test_browser_context.h"
@@ -103,8 +105,8 @@ ChromeAppCacheServiceTest::CreateAppCacheServiceImpl(
new MockURLRequestContextGetter(
browser_context_.GetResourceContext()->GetRequestContext(),
base::ThreadTaskRunnerHandle::Get());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ChromeAppCacheService::InitializeOnIOThread, appcache_service,
appcache_path, browser_context_.GetResourceContext(),
diff --git a/chromium/content/browser/appcache/mock_appcache_storage.cc b/chromium/content/browser/appcache/mock_appcache_storage.cc
index 79bf39b087e..30d7d9a5a5e 100644
--- a/chromium/content/browser/appcache/mock_appcache_storage.cc
+++ b/chromium/content/browser/appcache/mock_appcache_storage.cc
@@ -46,8 +46,7 @@ MockAppCacheStorage::MockAppCacheStorage(AppCacheServiceImpl* service)
last_response_id_ = 0;
}
-MockAppCacheStorage::~MockAppCacheStorage() {
-}
+MockAppCacheStorage::~MockAppCacheStorage() = default;
void MockAppCacheStorage::GetAllInfo(Delegate* delegate) {
ScheduleTask(base::BindOnce(
@@ -160,24 +159,29 @@ void MockAppCacheStorage::StoreEvictionTimes(AppCacheGroup* group) {
group->first_evictable_error_time());
}
-AppCacheResponseReader* MockAppCacheStorage::CreateResponseReader(
- const GURL& manifest_url,
- int64_t response_id) {
+std::unique_ptr<AppCacheResponseReader>
+MockAppCacheStorage::CreateResponseReader(const GURL& manifest_url,
+ int64_t response_id) {
if (simulated_reader_)
- return simulated_reader_.release();
- return new AppCacheResponseReader(response_id, disk_cache()->GetWeakPtr());
+ return std::move(simulated_reader_);
+
+ // base::WrapUnique needed due to non-public constructor.
+ return base::WrapUnique(
+ new AppCacheResponseReader(response_id, disk_cache()->GetWeakPtr()));
}
-AppCacheResponseWriter* MockAppCacheStorage::CreateResponseWriter(
- const GURL& manifest_url) {
- return new AppCacheResponseWriter(NewResponseId(),
- disk_cache()->GetWeakPtr());
+std::unique_ptr<AppCacheResponseWriter>
+MockAppCacheStorage::CreateResponseWriter(const GURL& manifest_url) {
+ // base::WrapUnique needed due to non-public constructor.
+ return base::WrapUnique(
+ new AppCacheResponseWriter(NewResponseId(), disk_cache()->GetWeakPtr()));
}
-AppCacheResponseMetadataWriter*
+std::unique_ptr<AppCacheResponseMetadataWriter>
MockAppCacheStorage::CreateResponseMetadataWriter(int64_t response_id) {
- return new AppCacheResponseMetadataWriter(response_id,
- disk_cache()->GetWeakPtr());
+ // base::WrapUnique needed due to non-public constructor.
+ return base::WrapUnique(new AppCacheResponseMetadataWriter(
+ response_id, disk_cache()->GetWeakPtr()));
}
void MockAppCacheStorage::DoomResponses(
diff --git a/chromium/content/browser/appcache/mock_appcache_storage.h b/chromium/content/browser/appcache/mock_appcache_storage.h
index 4823ff0523f..0a4fcb75cc1 100644
--- a/chromium/content/browser/appcache/mock_appcache_storage.h
+++ b/chromium/content/browser/appcache/mock_appcache_storage.h
@@ -75,11 +75,12 @@ class MockAppCacheStorage : public AppCacheStorage {
Delegate* delegate,
int response_code) override;
void StoreEvictionTimes(AppCacheGroup* group) override;
- AppCacheResponseReader* CreateResponseReader(const GURL& manifest_url,
- int64_t response_id) override;
- AppCacheResponseWriter* CreateResponseWriter(
+ std::unique_ptr<AppCacheResponseReader> CreateResponseReader(
+ const GURL& manifest_url,
+ int64_t response_id) override;
+ std::unique_ptr<AppCacheResponseWriter> CreateResponseWriter(
const GURL& manifest_url) override;
- AppCacheResponseMetadataWriter* CreateResponseMetadataWriter(
+ std::unique_ptr<AppCacheResponseMetadataWriter> CreateResponseMetadataWriter(
int64_t response_id) override;
void DoomResponses(const GURL& manifest_url,
const std::vector<int64_t>& response_ids) override;
diff --git a/chromium/content/browser/background_fetch/background_fetch.proto b/chromium/content/browser/background_fetch/background_fetch.proto
index d1cef4f3bfd..c88966804ed 100644
--- a/chromium/content/browser/background_fetch/background_fetch.proto
+++ b/chromium/content/browser/background_fetch/background_fetch.proto
@@ -13,8 +13,8 @@ package content.proto;
//
// Next Tag: 9
message BackgroundFetchRegistration {
- enum BackgroundFetchState {
- PENDING = 0; // Default value.
+ enum BackgroundFetchResult {
+ UNSET = 0; // Default value.
FAILURE = 1;
SUCCESS = 2;
}
@@ -41,7 +41,7 @@ message BackgroundFetchRegistration {
optional uint64 uploaded = 4;
optional uint64 download_total = 5;
optional uint64 downloaded = 6;
- optional BackgroundFetchState state = 7;
+ optional BackgroundFetchResult result = 7;
optional BackgroundFetchFailureReason failure_reason = 8;
}
diff --git a/chromium/content/browser/background_fetch/background_fetch_context.cc b/chromium/content/browser/background_fetch/background_fetch_context.cc
index 13f6f472b29..340d9d0eb87 100644
--- a/chromium/content/browser/background_fetch/background_fetch_context.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_context.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/bind_helpers.h"
+#include "base/task/post_task.h"
#include "content/browser/background_fetch/background_fetch_data_manager.h"
#include "content/browser/background_fetch/background_fetch_job_controller.h"
#include "content/browser/background_fetch/background_fetch_metrics.h"
@@ -17,6 +18,7 @@
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/background_fetch_delegate.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "net/url_request/url_request_context_getter.h"
@@ -25,6 +27,8 @@
namespace content {
+using FailureReason = blink::mojom::BackgroundFetchFailureReason;
+
BackgroundFetchContext::BackgroundFetchContext(
BrowserContext* browser_context,
const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context,
@@ -72,15 +76,16 @@ void BackgroundFetchContext::DidGetInitializationData(
blink::mojom::BackgroundFetchError error,
std::vector<background_fetch::BackgroundFetchInitializationData>
initialization_data) {
- if (error != blink::mojom::BackgroundFetchError::NONE) {
- // TODO(crbug.com/780025): Log failures to UMA.
+ if (error != blink::mojom::BackgroundFetchError::NONE)
return;
- }
+
+ background_fetch::RecordRegistrationsOnStartup(initialization_data.size());
for (auto& data : initialization_data) {
CreateController(data.registration_id, data.registration, data.options,
data.icon, data.ui_title, data.num_completed_requests,
- data.num_requests, std::move(data.active_fetch_requests));
+ data.num_requests, std::move(data.active_fetch_requests),
+ /* start_paused = */ false);
}
}
@@ -133,6 +138,7 @@ void BackgroundFetchContext::StartFetch(
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
+ blink::mojom::BackgroundFetchUkmDataPtr ukm_data,
RenderFrameHost* render_frame_host,
blink::mojom::BackgroundFetchService::FetchCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -143,23 +149,14 @@ void BackgroundFetchContext::StartFetch(
// operator uses.
DCHECK_EQ(0u, fetch_callbacks_.count(registration_id));
fetch_callbacks_[registration_id] = std::move(callback);
-
- // |data_manager| is guaranteed to outlive |this|. |create_registration| is
- // passed to `DidGetPermission`, which is tied to |weak_factory_|. That means
- // that if |create_registration| runs, |this| is still alive, as is
- // |data_manager| (a pointer owned by |this|).
- auto create_registration = base::BindOnce(
- &BackgroundFetchDataManager::CreateRegistration,
- base::Unretained(data_manager_.get()), registration_id, requests, options,
- icon,
- base::BindOnce(&BackgroundFetchContext::DidCreateRegistration,
- weak_factory_.GetWeakPtr(), registration_id));
+ int frame_tree_node_id =
+ render_frame_host ? render_frame_host->GetFrameTreeNodeId() : 0;
GetPermissionForOrigin(
registration_id.origin(), render_frame_host,
base::BindOnce(&BackgroundFetchContext::DidGetPermission,
- weak_factory_.GetWeakPtr(), std::move(create_registration),
- registration_id));
+ weak_factory_.GetWeakPtr(), registration_id, requests,
+ options, icon, std::move(ukm_data), frame_tree_node_id));
}
void BackgroundFetchContext::GetPermissionForOrigin(
@@ -167,7 +164,6 @@ void BackgroundFetchContext::GetPermissionForOrigin(
RenderFrameHost* render_frame_host,
GetPermissionCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
ResourceRequestInfo::WebContentsGetter wc_getter = base::NullCallback();
// Permissions need to go through the DownloadRequestLimiter if the fetch
@@ -182,11 +178,28 @@ void BackgroundFetchContext::GetPermissionForOrigin(
}
void BackgroundFetchContext::DidGetPermission(
- base::OnceClosure permission_closure,
const BackgroundFetchRegistrationId& registration_id,
- bool has_permission) {
- if (has_permission) {
- std::move(permission_closure).Run();
+ const std::vector<ServiceWorkerFetchRequest>& requests,
+ const BackgroundFetchOptions& options,
+ const SkBitmap& icon,
+ blink::mojom::BackgroundFetchUkmDataPtr ukm_data,
+ int frame_tree_node_id,
+ BackgroundFetchPermission permission) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&background_fetch::RecordBackgroundFetchUkmEvent,
+ registration_id.origin(), requests, options, icon,
+ std::move(ukm_data), frame_tree_node_id, permission));
+
+ if (permission != BackgroundFetchPermission::BLOCKED) {
+ // TODO(crbug.com/886896): Passed paused flag to CreateRegistration.
+ data_manager_->BackgroundFetchDataManager::CreateRegistration(
+ registration_id, requests, options, icon,
+ permission == BackgroundFetchPermission::ASK /* start_paused */,
+ base::BindOnce(&BackgroundFetchContext::DidCreateRegistration,
+ weak_factory_.GetWeakPtr(), registration_id));
return;
}
@@ -201,7 +214,6 @@ void BackgroundFetchContext::DidGetPermission(
void BackgroundFetchContext::GetIconDisplaySize(
blink::mojom::BackgroundFetchService::GetIconDisplaySizeCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
delegate_proxy_.GetIconDisplaySize(std::move(callback));
}
@@ -261,7 +273,7 @@ void BackgroundFetchContext::OnQuotaExceeded(
const BackgroundFetchRegistrationId& registration_id) {
auto job_it = job_controllers_.find(registration_id.unique_id());
if (job_it != job_controllers_.end() && job_it->second)
- job_it->second->Abort(BackgroundFetchReasonToAbort::QUOTA_EXCEEDED);
+ job_it->second->Abort(FailureReason::QUOTA_EXCEEDED);
}
void BackgroundFetchContext::AbandonFetches(
@@ -281,8 +293,7 @@ void BackgroundFetchContext::AbandonFetches(
service_worker_registration_id) {
DCHECK(saved_iter->second);
- saved_iter->second->Abort(
- BackgroundFetchReasonToAbort::SERVICE_WORKER_UNAVAILABLE);
+ saved_iter->second->Abort(FailureReason::SERVICE_WORKER_UNAVAILABLE);
}
}
@@ -307,7 +318,8 @@ void BackgroundFetchContext::OnRegistrationCreated(
const BackgroundFetchRegistration& registration,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
- int num_requests) {
+ int num_requests,
+ bool start_paused) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (hang_registration_creation_for_testing_) {
@@ -322,7 +334,7 @@ void BackgroundFetchContext::OnRegistrationCreated(
CreateController(registration_id, registration, options, icon, options.title,
0u /* num_completed_requests */, num_requests,
- {} /* active_fetch_requests */);
+ {} /* active_fetch_requests */, start_paused);
}
void BackgroundFetchContext::OnUpdatedUI(
@@ -348,6 +360,15 @@ void BackgroundFetchContext::OnStorageWiped() {
AbandonFetches(blink::mojom::kInvalidServiceWorkerRegistrationId);
}
+void BackgroundFetchContext::OnFetchStorageError(
+ const BackgroundFetchRegistrationId& registration_id) {
+ auto controllers_iter = job_controllers_.find(registration_id.unique_id());
+ if (controllers_iter == job_controllers_.end())
+ return;
+
+ controllers_iter->second->Abort(FailureReason::SERVICE_WORKER_UNAVAILABLE);
+}
+
void BackgroundFetchContext::CreateController(
const BackgroundFetchRegistrationId& registration_id,
const BackgroundFetchRegistration& registration,
@@ -357,7 +378,8 @@ void BackgroundFetchContext::CreateController(
size_t num_completed_requests,
size_t num_requests,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
- active_fetch_requests) {
+ active_fetch_requests,
+ bool start_paused) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
auto controller = std::make_unique<BackgroundFetchJobController>(
@@ -372,7 +394,7 @@ void BackgroundFetchContext::CreateController(
controller->InitializeRequestStatus(num_completed_requests, num_requests,
std::move(active_fetch_requests),
- ui_title);
+ ui_title, start_paused);
scheduler_->AddJobController(controller.get());
job_controllers_.emplace(registration_id.unique_id(), std::move(controller));
}
@@ -382,28 +404,36 @@ void BackgroundFetchContext::Abort(
blink::mojom::BackgroundFetchService::AbortCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ auto controllers_iter = job_controllers_.find(registration_id.unique_id());
+ if (controllers_iter == job_controllers_.end()) {
+ std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_ID);
+ return;
+ }
+
+ controllers_iter->second->Abort(FailureReason::CANCELLED_BY_DEVELOPER);
+
DidFinishJob(std::move(callback), registration_id,
- BackgroundFetchReasonToAbort::ABORTED_BY_DEVELOPER);
+ FailureReason::CANCELLED_BY_DEVELOPER);
}
void BackgroundFetchContext::DidFinishJob(
base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback,
const BackgroundFetchRegistrationId& registration_id,
- BackgroundFetchReasonToAbort reason_to_abort) {
+ FailureReason failure_reason) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // If |aborted| is true, this will also propagate the event to any active
- // JobController for the registration, to terminate in-progress requests.
+ // If the registration was aborted, this will also propagate the event to any
+ // active JobController, to terminate in-progress requests.
data_manager_->MarkRegistrationForDeletion(
registration_id,
base::BindOnce(&BackgroundFetchContext::DidMarkForDeletion,
weak_factory_.GetWeakPtr(), registration_id,
- reason_to_abort, std::move(callback)));
+ failure_reason, std::move(callback)));
}
void BackgroundFetchContext::DidMarkForDeletion(
const BackgroundFetchRegistrationId& registration_id,
- BackgroundFetchReasonToAbort reason_to_abort,
+ FailureReason failure_reason,
base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback,
blink::mojom::BackgroundFetchError error) {
DCHECK(callback);
@@ -412,109 +442,109 @@ void BackgroundFetchContext::DidMarkForDeletion(
// It's normal to get INVALID_ID errors here - it means the registration was
// already inactive (marked for deletion). This happens when an abort (from
// developer or from user) races with the download completing/failing, or even
- // when two aborts race. TODO(johnme): Log STORAGE_ERRORs to UMA though.
+ // when two aborts race.
if (error != blink::mojom::BackgroundFetchError::NONE)
return;
- auto controllers_iter = job_controllers_.find(registration_id.unique_id());
-
- if (reason_to_abort == BackgroundFetchReasonToAbort::ABORTED_BY_DEVELOPER) {
- DCHECK(controllers_iter != job_controllers_.end());
- controllers_iter->second->Abort(reason_to_abort);
+ if (failure_reason == FailureReason::NONE) {
+ // As far as we know the fetch was successful, go over the entries in the
+ // cache and make sure all the responses are there and successful.
+ data_manager_->GetSettledFetchesForRegistration(
+ registration_id, std::make_unique<BackgroundFetchRequestMatchParams>(),
+ base::BindOnce(&BackgroundFetchContext::DidGetSettledFetches,
+ weak_factory_.GetWeakPtr(), registration_id));
+ return;
}
- auto registration = controllers_iter->second->NewRegistration(
- blink::mojom::BackgroundFetchState::FAILURE);
- switch (reason_to_abort) {
- case BackgroundFetchReasonToAbort::ABORTED_BY_DEVELOPER:
- case BackgroundFetchReasonToAbort::CANCELLED_FROM_UI:
- CleanupRegistration(registration_id, {},
- blink::mojom::BackgroundFetchState::FAILURE);
- event_dispatcher_.DispatchBackgroundFetchAbortEvent(
- registration_id, std::move(registration), base::DoNothing());
- return;
- case BackgroundFetchReasonToAbort::TOTAL_DOWNLOAD_SIZE_EXCEEDED:
- case BackgroundFetchReasonToAbort::SERVICE_WORKER_UNAVAILABLE:
- case BackgroundFetchReasonToAbort::QUOTA_EXCEEDED:
- case BackgroundFetchReasonToAbort::NONE:
- // This will send a BackgroundFetchFetched or BackgroundFetchFail event.
- // We still need this to figure out which event to send.
- // TODO(crbug.com/699957, crbug.com/874092): Add a method to only return
- // the information needed to dispatch these events, instead of settled
- // fetches.
- data_manager_->GetSettledFetchesForRegistration(
- registration_id,
- std::make_unique<BackgroundFetchRequestMatchParams>(),
- base::BindOnce(&BackgroundFetchContext::DidGetSettledFetches,
- weak_factory_.GetWeakPtr(), registration_id,
- std::move(registration)));
- return;
- }
+ // The fetch failed, dispatch an appropriate event.
+ auto controllers_iter = job_controllers_.find(registration_id.unique_id());
+ DCHECK(controllers_iter != job_controllers_.end());
+ auto registration = controllers_iter->second->NewRegistration(
+ blink::mojom::BackgroundFetchResult::FAILURE);
+ DispatchCompletionEvent(registration_id, std::move(registration));
}
void BackgroundFetchContext::DidGetSettledFetches(
const BackgroundFetchRegistrationId& registration_id,
- std::unique_ptr<BackgroundFetchRegistration> registration,
blink::mojom::BackgroundFetchError error,
- bool background_fetch_succeeded,
+ FailureReason failure_reason,
std::vector<BackgroundFetchSettledFetch> settled_fetches,
std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(failure_reason == FailureReason::NONE ||
+ failure_reason == FailureReason::FETCH_ERROR ||
+ failure_reason == FailureReason::SERVICE_WORKER_UNAVAILABLE ||
+ failure_reason == FailureReason::BAD_STATUS);
- if (error != blink::mojom::BackgroundFetchError::NONE) {
- CleanupRegistration(registration_id, {} /* fetches */,
- blink::mojom::BackgroundFetchState::FAILURE,
- true /* preserve_info_to_dispatch_click_event */);
- return;
- }
+ auto controllers_iter = job_controllers_.find(registration_id.unique_id());
+ DCHECK(controllers_iter != job_controllers_.end());
+ failure_reason = controllers_iter->second->MergeFailureReason(failure_reason);
- DCHECK(job_controllers_.count(registration_id.unique_id()));
+ blink::mojom::BackgroundFetchResult result =
+ failure_reason == FailureReason::NONE
+ ? blink::mojom::BackgroundFetchResult::SUCCESS
+ : blink::mojom::BackgroundFetchResult::FAILURE;
- if (job_controllers_[registration_id.unique_id()]->total_downloads() !=
- static_cast<int>(settled_fetches.size())) {
- // Something went wrong, and some information was lost.
- background_fetch_succeeded = false;
- }
+ auto registration = controllers_iter->second->NewRegistration(result);
+ DispatchCompletionEvent(registration_id, std::move(registration));
+}
+
+void BackgroundFetchContext::DispatchCompletionEvent(
+ const BackgroundFetchRegistrationId& registration_id,
+ std::unique_ptr<BackgroundFetchRegistration> registration) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ registration_notifier_->Notify(*registration);
- // The `backgroundfetchsuccess` event will be invoked when all requests in the
- // registration have completed successfully. In all other cases, the
- // `backgroundfetchfail` event will be invoked instead.
- if (background_fetch_succeeded) {
- registration->state = blink::mojom::BackgroundFetchState::SUCCESS;
- event_dispatcher_.DispatchBackgroundFetchSuccessEvent(
- registration_id, std::move(registration),
- base::BindOnce(
- &BackgroundFetchContext::CleanupRegistration,
- weak_factory_.GetWeakPtr(), registration_id,
- // The blob uuid is sent as part of |settled_fetches|. Bind
- // |blob_data_handles| to the callback to keep them alive
- // until the waitUntil event is resolved.
- std::move(blob_data_handles),
- blink::mojom::BackgroundFetchState::SUCCESS,
- true /* preserve_info_to_dispatch_click_event */));
- } else {
- registration->state = blink::mojom::BackgroundFetchState::FAILURE;
- event_dispatcher_.DispatchBackgroundFetchFailEvent(
- registration_id, std::move(registration),
- base::BindOnce(
- &BackgroundFetchContext::CleanupRegistration,
- weak_factory_.GetWeakPtr(), registration_id,
- // The blob uuid is sent as part of |settled_fetches|. Bind
- // |blob_data_handles| to the callback to keep them alive
- // until the waitUntil event is resolved.
- std::move(blob_data_handles),
- blink::mojom::BackgroundFetchState::FAILURE,
- true /* preserve_info_to_dispatch_click_event */));
+ switch (registration->failure_reason) {
+ case FailureReason::NONE:
+ DCHECK_EQ(registration->result,
+ blink::mojom::BackgroundFetchResult::SUCCESS);
+ event_dispatcher_.DispatchBackgroundFetchSuccessEvent(
+ registration_id, std::move(registration),
+ base::BindOnce(&BackgroundFetchContext::CleanupRegistration,
+ weak_factory_.GetWeakPtr(), registration_id,
+ blink::mojom::BackgroundFetchResult::SUCCESS,
+ /* preserve_info_to_dispatch_click_event= */ true));
+ return;
+ case FailureReason::CANCELLED_FROM_UI:
+ case FailureReason::CANCELLED_BY_DEVELOPER:
+ DCHECK_EQ(registration->result,
+ blink::mojom::BackgroundFetchResult::FAILURE);
+ event_dispatcher_.DispatchBackgroundFetchAbortEvent(
+ registration_id, std::move(registration),
+ base::BindOnce(&BackgroundFetchContext::CleanupRegistration,
+ weak_factory_.GetWeakPtr(), registration_id,
+ blink::mojom::BackgroundFetchResult::FAILURE,
+ /* preserve_info_to_dispatch_click_event= */ false));
+ return;
+ case FailureReason::BAD_STATUS:
+ case FailureReason::FETCH_ERROR:
+ case FailureReason::SERVICE_WORKER_UNAVAILABLE:
+ case FailureReason::QUOTA_EXCEEDED:
+ case FailureReason::TOTAL_DOWNLOAD_SIZE_EXCEEDED:
+ DCHECK_EQ(registration->result,
+ blink::mojom::BackgroundFetchResult::FAILURE);
+ event_dispatcher_.DispatchBackgroundFetchFailEvent(
+ registration_id, std::move(registration),
+ base::BindOnce(&BackgroundFetchContext::CleanupRegistration,
+ weak_factory_.GetWeakPtr(), registration_id,
+ blink::mojom::BackgroundFetchResult::FAILURE,
+ /* preserve_info_to_dispatch_click_event= */ true));
+ return;
}
}
void BackgroundFetchContext::CleanupRegistration(
const BackgroundFetchRegistrationId& registration_id,
- const std::vector<std::unique_ptr<storage::BlobDataHandle>>& blob_handles,
- blink::mojom::BackgroundFetchState background_fetch_state,
+ blink::mojom::BackgroundFetchResult background_fetch_result,
bool preserve_info_to_dispatch_click_event) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // Indicate to the renderer that the records for this fetch are no longer
+ // available.
+ registration_notifier_->NotifyRecordsUnavailable(registration_id.unique_id());
+
// If we had an active JobController, it is no longer necessary, as the
// notification's UI can no longer be updated after the fetch is aborted, or
// after the waitUntil promise of the
@@ -526,22 +556,16 @@ void BackgroundFetchContext::CleanupRegistration(
if (preserve_info_to_dispatch_click_event) {
completed_fetches_[registration_id.unique_id()] = std::make_pair(
registration_id,
- controllers_iter->second->NewRegistration(background_fetch_state));
+ controllers_iter->second->NewRegistration(background_fetch_result));
}
job_controllers_.erase(registration_id.unique_id());
- // At this point, JavaScript can no longer obtain BackgroundFetchRegistration
- // objects for this registration, and those objects are the only thing that
- // requires us to keep the registration's data around. So once the
- // RegistrationNotifier informs us that all existing observers (and hence
- // BackgroundFetchRegistration objects) have been garbage collected, it'll be
- // safe to delete the registration. This callback doesn't run if the browser
- // is shutdown before that happens - BackgroundFetchDataManager::Cleanup acts
- // as a fallback in that case, and deletes the registration on next startup.
- registration_notifier_->AddGarbageCollectionCallback(
- registration_id.unique_id(),
- base::BindOnce(&BackgroundFetchContext::LastObserverGarbageCollected,
- weak_factory_.GetWeakPtr(), registration_id));
+ // Delete the data associated with this fetch. Cache storage will keep the
+ // downloaded data around so long as there are references to it, and delete
+ // it once there is none. We don't need to do that accounting.
+ data_manager_->DeleteRegistration(
+ registration_id,
+ base::BindOnce(&background_fetch::RecordRegistrationDeletedError));
}
void BackgroundFetchContext::DispatchClickEvent(const std::string& unique_id) {
@@ -555,14 +579,12 @@ void BackgroundFetchContext::DispatchClickEvent(const std::string& unique_id) {
return;
}
- // The fetch is active, or has been aborted/cancelled.
+ // The fetch is active.
auto controllers_iter = job_controllers_.find(unique_id);
if (controllers_iter == job_controllers_.end())
return;
- // TODO(crbug.com/873630): Implement a background fetch state manager to
- // keep track of states, and stop hard-coding it here.
auto registration = controllers_iter->second->NewRegistration(
- blink::mojom::BackgroundFetchState::PENDING);
+ blink::mojom::BackgroundFetchResult::UNSET);
event_dispatcher_.DispatchBackgroundFetchClickEvent(
controllers_iter->second->registration_id(), std::move(registration),
base::DoNothing());
@@ -583,7 +605,7 @@ void BackgroundFetchContext::MatchRequests(
void BackgroundFetchContext::DidGetMatchingRequests(
blink::mojom::BackgroundFetchService::MatchRequestsCallback callback,
blink::mojom::BackgroundFetchError error,
- bool background_fetch_succeeded,
+ FailureReason failure_reason,
std::vector<BackgroundFetchSettledFetch> settled_fetches,
std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -596,20 +618,11 @@ void BackgroundFetchContext::DidGetMatchingRequests(
std::move(callback).Run(std::move(settled_fetches));
}
-void BackgroundFetchContext::LastObserverGarbageCollected(
- const BackgroundFetchRegistrationId& registration_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- data_manager_->DeleteRegistration(
- registration_id,
- base::BindOnce(&background_fetch::RecordRegistrationDeletedError));
-}
-
void BackgroundFetchContext::Shutdown() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BackgroundFetchContext::ShutdownOnIO, this));
}
diff --git a/chromium/content/browser/background_fetch/background_fetch_context.h b/chromium/content/browser/background_fetch/background_fetch_context.h
index e25b9151c53..431e7ef081d 100644
--- a/chromium/content/browser/background_fetch/background_fetch_context.h
+++ b/chromium/content/browser/background_fetch/background_fetch_context.h
@@ -91,6 +91,7 @@ class CONTENT_EXPORT BackgroundFetchContext
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
+ blink::mojom::BackgroundFetchUkmDataPtr ukm_data,
RenderFrameHost* render_frame_host,
blink::mojom::BackgroundFetchService::FetchCallback callback);
@@ -135,7 +136,8 @@ class CONTENT_EXPORT BackgroundFetchContext
const BackgroundFetchRegistration& registration,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
- int num_requests) override;
+ int num_requests,
+ bool start_paused) override;
void OnUpdatedUI(const BackgroundFetchRegistrationId& registration_id,
const base::Optional<std::string>& title,
const base::Optional<SkBitmap>& icon) override;
@@ -143,6 +145,8 @@ class CONTENT_EXPORT BackgroundFetchContext
int64_t service_worker_registration_id) override;
void OnQuotaExceeded(
const BackgroundFetchRegistrationId& registration_id) override;
+ void OnFetchStorageError(
+ const BackgroundFetchRegistrationId& registration_id) override;
// ServiceWorkerContextCoreObserver implementation.
void OnRegistrationDeleted(int64_t registration_id,
@@ -150,7 +154,8 @@ class CONTENT_EXPORT BackgroundFetchContext
void OnStorageWiped() override;
private:
- using GetPermissionCallback = base::OnceCallback<void(bool)>;
+ using GetPermissionCallback =
+ base::OnceCallback<void(BackgroundFetchPermission)>;
FRIEND_TEST_ALL_PREFIXES(BackgroundFetchServiceTest,
JobsInitializedOnBrowserRestart);
@@ -175,7 +180,8 @@ class CONTENT_EXPORT BackgroundFetchContext
size_t num_completed_requests,
size_t num_requests,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
- active_fetch_requests);
+ active_fetch_requests,
+ bool start_paused);
// Called when an existing registration has been retrieved from the data
// manager. If the registration does not exist then |registration| is nullptr.
@@ -195,12 +201,12 @@ class CONTENT_EXPORT BackgroundFetchContext
void DidFinishJob(
base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback,
const BackgroundFetchRegistrationId& registration_id,
- BackgroundFetchReasonToAbort reason_to_abort);
+ blink::mojom::BackgroundFetchFailureReason failure_reason);
// Called when the data manager finishes marking a registration as deleted.
void DidMarkForDeletion(
const BackgroundFetchRegistrationId& registration_id,
- BackgroundFetchReasonToAbort reason_to_abort,
+ blink::mojom::BackgroundFetchFailureReason failure_reason,
base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback,
blink::mojom::BackgroundFetchError error);
@@ -208,9 +214,8 @@ class CONTENT_EXPORT BackgroundFetchContext
// retrieved from storage, and the Service Worker event can be invoked.
void DidGetSettledFetches(
const BackgroundFetchRegistrationId& registration_id,
- std::unique_ptr<BackgroundFetchRegistration> registration,
blink::mojom::BackgroundFetchError error,
- bool background_fetch_succeeded,
+ blink::mojom::BackgroundFetchFailureReason failure_reason,
std::vector<BackgroundFetchSettledFetch> settled_fetches,
std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles);
@@ -220,10 +225,15 @@ class CONTENT_EXPORT BackgroundFetchContext
void DidGetMatchingRequests(
blink::mojom::BackgroundFetchService::MatchRequestsCallback callback,
blink::mojom::BackgroundFetchError error,
- bool background_fetch_succeeded,
+ blink::mojom::BackgroundFetchFailureReason failure_reason,
std::vector<BackgroundFetchSettledFetch> settled_fetches,
std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles);
+ // Dispatches an appropriate event (success, fail, abort).
+ void DispatchCompletionEvent(
+ const BackgroundFetchRegistrationId& registration_id,
+ std::unique_ptr<BackgroundFetchRegistration> registration);
+
// Called when the notification UI for the background fetch job associated
// with |unique_id| is activated.
void DispatchClickEvent(const std::string& unique_id);
@@ -235,25 +245,17 @@ class CONTENT_EXPORT BackgroundFetchContext
initialization_data);
// Called when all processing for the |registration_id| has been finished and
- // the job is ready to be deleted. |blob_handles| are unused, but some callers
- // use it to keep blobs alive for the right duration.
- // |partial cleanup|, when set, preserves the registration ID, and the state
- // of Fetch when it completed, in |completed_fetches_|. This is not done when
- // fetch is aborted or cancelled. We use this information to propagate
- // BackgroundFetchClicked event to the developer, when the user taps the UI.
+ // the job is ready to be deleted.
+ // |preserve_info_to_dispatch_click_event|, when set, preserves the
+ // registration ID, and the result of the Fetch when it completed, in
+ // |completed_fetches_|. This is not done when fetch is aborted or cancelled.
+ // We use this information to propagate BackgroundFetchClicked event to the
+ // developer, when the user taps the UI.
void CleanupRegistration(
const BackgroundFetchRegistrationId& registration_id,
- const std::vector<std::unique_ptr<storage::BlobDataHandle>>&
- blob_data_handles,
- blink::mojom::BackgroundFetchState background_fetch_state,
+ blink::mojom::BackgroundFetchResult background_fetch_result,
bool preserve_info_to_dispatch_click_event = false);
- // Called when the last JavaScript BackgroundFetchRegistration object has been
- // garbage collected for a registration marked for deletion, and so it is now
- // safe to delete the underlying registration data.
- void LastObserverGarbageCollected(
- const BackgroundFetchRegistrationId& registration_id);
-
// Switches out |data_manager_| with a DataManager configured for testing
// environments. Must be called directly after the constructor.
void SetDataManagerForTesting(
@@ -271,9 +273,13 @@ class CONTENT_EXPORT BackgroundFetchContext
GetPermissionCallback callback);
// Callback for GetPermissionForOrigin.
- void DidGetPermission(base::OnceClosure permission_closure,
- const BackgroundFetchRegistrationId& registration_id,
- bool has_permission);
+ void DidGetPermission(const BackgroundFetchRegistrationId& registration_id,
+ const std::vector<ServiceWorkerFetchRequest>& requests,
+ const BackgroundFetchOptions& options,
+ const SkBitmap& icon,
+ blink::mojom::BackgroundFetchUkmDataPtr ukm_data,
+ int frame_tree_node_id,
+ BackgroundFetchPermission permission);
// |this| is owned, indirectly, by the BrowserContext.
BrowserContext* browser_context_;
diff --git a/chromium/content/browser/background_fetch/background_fetch_cross_origin_filter.cc b/chromium/content/browser/background_fetch/background_fetch_cross_origin_filter.cc
index 120b53c5723..50d79fe6281 100644
--- a/chromium/content/browser/background_fetch/background_fetch_cross_origin_filter.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_cross_origin_filter.cc
@@ -37,7 +37,7 @@ bool ParseOriginListHeader(const std::string& value,
for (const std::string& origin_string : origin_vector) {
url::Origin origin = url::Origin::Create(GURL(origin_string));
- if (origin.unique())
+ if (origin.opaque())
return false;
candidate_origins.insert(origin);
diff --git a/chromium/content/browser/background_fetch/background_fetch_data_manager.cc b/chromium/content/browser/background_fetch/background_fetch_data_manager.cc
index 1fac2a819f9..1007b8a027a 100644
--- a/chromium/content/browser/background_fetch/background_fetch_data_manager.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_data_manager.cc
@@ -98,11 +98,13 @@ void BackgroundFetchDataManager::CreateRegistration(
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
+ bool start_paused,
GetRegistrationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
AddDatabaseTask(std::make_unique<background_fetch::CreateMetadataTask>(
- this, registration_id, requests, options, icon, std::move(callback)));
+ this, registration_id, requests, options, icon, start_paused,
+ std::move(callback)));
}
void BackgroundFetchDataManager::GetRegistration(
@@ -133,41 +135,19 @@ void BackgroundFetchDataManager::PopNextRequest(
NextRequestCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- auto start_next_request = base::BindOnce(
- &BackgroundFetchDataManager::AddStartNextPendingRequestTask,
- weak_ptr_factory_.GetWeakPtr(), registration_id, std::move(callback));
-
- // Get the associated metadata, and add a StartNextPendingRequestTask.
- AddDatabaseTask(std::make_unique<background_fetch::GetRegistrationTask>(
- this, registration_id.service_worker_registration_id(),
- registration_id.origin(), registration_id.developer_id(),
- std::move(start_next_request)));
-}
-
-void BackgroundFetchDataManager::AddStartNextPendingRequestTask(
- const BackgroundFetchRegistrationId& registration_id,
- NextRequestCallback callback,
- blink::mojom::BackgroundFetchError error,
- const BackgroundFetchRegistration& registration) {
- if (error != blink::mojom::BackgroundFetchError::NONE) {
- // Stop giving out requests as registration aborted (or otherwise finished).
- std::move(callback).Run(nullptr /* request */);
- return;
- }
-
AddDatabaseTask(
std::make_unique<background_fetch::StartNextPendingRequestTask>(
- this, registration_id, registration, std::move(callback)));
+ this, registration_id, std::move(callback)));
}
void BackgroundFetchDataManager::MarkRequestAsComplete(
const BackgroundFetchRegistrationId& registration_id,
scoped_refptr<BackgroundFetchRequestInfo> request_info,
- base::OnceClosure closure) {
+ MarkRequestCompleteCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
AddDatabaseTask(std::make_unique<background_fetch::MarkRequestCompleteTask>(
- this, registration_id, std::move(request_info), std::move(closure)));
+ this, registration_id, std::move(request_info), std::move(callback)));
}
void BackgroundFetchDataManager::GetSettledFetchesForRegistration(
diff --git a/chromium/content/browser/background_fetch/background_fetch_data_manager.h b/chromium/content/browser/background_fetch/background_fetch_data_manager.h
index 253831a6deb..2c49a60d665 100644
--- a/chromium/content/browser/background_fetch/background_fetch_data_manager.h
+++ b/chromium/content/browser/background_fetch/background_fetch_data_manager.h
@@ -65,14 +65,17 @@ class CONTENT_EXPORT BackgroundFetchDataManager
std::vector<background_fetch::BackgroundFetchInitializationData>)>;
using SettledFetchesCallback = base::OnceCallback<void(
blink::mojom::BackgroundFetchError,
- bool /* background_fetch_succeeded */,
+ blink::mojom::BackgroundFetchFailureReason,
std::vector<BackgroundFetchSettledFetch>,
std::vector<std::unique_ptr<storage::BlobDataHandle>>)>;
using GetRegistrationCallback =
base::OnceCallback<void(blink::mojom::BackgroundFetchError,
const BackgroundFetchRegistration&)>;
+ using MarkRequestCompleteCallback =
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError)>;
using NextRequestCallback =
- base::OnceCallback<void(scoped_refptr<BackgroundFetchRequestInfo>)>;
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError,
+ scoped_refptr<BackgroundFetchRequestInfo>)>;
BackgroundFetchDataManager(
BrowserContext* browser_context,
@@ -102,6 +105,7 @@ class CONTENT_EXPORT BackgroundFetchDataManager
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
+ bool start_paused,
GetRegistrationCallback callback);
// Get the BackgroundFetchRegistration.
@@ -166,7 +170,7 @@ class CONTENT_EXPORT BackgroundFetchDataManager
void MarkRequestAsComplete(
const BackgroundFetchRegistrationId& registration_id,
scoped_refptr<BackgroundFetchRequestInfo> request_info,
- base::OnceClosure closure) override;
+ MarkRequestCompleteCallback callback) override;
void ShutdownOnIO();
@@ -193,12 +197,6 @@ class CONTENT_EXPORT BackgroundFetchDataManager
return quota_manager_proxy_.get();
}
- void AddStartNextPendingRequestTask(
- const BackgroundFetchRegistrationId& registration_id,
- NextRequestCallback callback,
- blink::mojom::BackgroundFetchError error,
- const BackgroundFetchRegistration& registration);
-
void AddDatabaseTask(std::unique_ptr<background_fetch::DatabaseTask> task);
// DatabaseTaskHost implementation.
diff --git a/chromium/content/browser/background_fetch/background_fetch_data_manager_observer.h b/chromium/content/browser/background_fetch/background_fetch_data_manager_observer.h
index ab1a9f2aca0..032cc1284ec 100644
--- a/chromium/content/browser/background_fetch/background_fetch_data_manager_observer.h
+++ b/chromium/content/browser/background_fetch/background_fetch_data_manager_observer.h
@@ -28,7 +28,8 @@ class BackgroundFetchDataManagerObserver {
const BackgroundFetchRegistration& registration,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
- int num_requests) = 0;
+ int num_requests,
+ bool start_paused) = 0;
// Called when the UI options for the Background Fetch |registration_id| have
// been updated in the data store.
@@ -44,6 +45,11 @@ class BackgroundFetchDataManagerObserver {
virtual void OnQuotaExceeded(
const BackgroundFetchRegistrationId& registration_id) = 0;
+ // Called if a database task encountered a storage error in the context of a
+ // fetch workflow, such as preparing a request or storing a response.
+ virtual void OnFetchStorageError(
+ const BackgroundFetchRegistrationId& registration_id) = 0;
+
virtual ~BackgroundFetchDataManagerObserver() {}
};
diff --git a/chromium/content/browser/background_fetch/background_fetch_data_manager_unittest.cc b/chromium/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
index 4b2a1074e78..3003797895a 100644
--- a/chromium/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
@@ -34,6 +34,7 @@
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -102,21 +103,23 @@ void AnnotateRequestInfoWithFakeDownloadManagerData(
std::string headers =
success ? "HTTP/1.1 200 OK\n" : "HTTP/1.1 404 Not found\n";
- request_info->PopulateWithResponse(std::make_unique<BackgroundFetchResponse>(
+ auto response = std::make_unique<BackgroundFetchResponse>(
std::vector<GURL>(1u, request_info->fetch_request().url),
- base::MakeRefCounted<net::HttpResponseHeaders>(headers)));
+ base::MakeRefCounted<net::HttpResponseHeaders>(headers));
if (!success) {
// Fill |request_info| with a failed result.
request_info->SetResult(std::make_unique<BackgroundFetchResult>(
- base::Time::Now(), BackgroundFetchResult::FailureReason::UNKNOWN));
+ std::move(response), base::Time::Now(),
+ BackgroundFetchResult::FailureReason::FETCH_ERROR));
return;
}
// This is treated as an empty response, but the size is set to
// |kResponseFileSize| for tests that use filesize.
request_info->SetResult(std::make_unique<BackgroundFetchResult>(
- base::Time::Now(), base::FilePath(), base::nullopt /* blob_handle */,
+ std::move(response), base::Time::Now(), base::FilePath(),
+ base::nullopt /* blob_handle */,
over_quota ? kBackgroundFetchMaxQuotaBytes + 1 : kResponseFileSize));
}
@@ -232,7 +235,7 @@ class BackgroundFetchDataManagerTest
base::RunLoop run_loop;
background_fetch_data_manager_->CreateRegistration(
- registration_id, requests, options, icon,
+ registration_id, requests, options, icon, /* start_paused = */ false,
base::BindOnce(&DidCreateRegistration, run_loop.QuitClosure(),
out_error));
run_loop.Run();
@@ -312,7 +315,9 @@ class BackgroundFetchDataManagerTest
// BackgroundFetchDataManager::PopNextRequest().
void PopNextRequest(
const BackgroundFetchRegistrationId& registration_id,
+ blink::mojom::BackgroundFetchError* out_error,
scoped_refptr<BackgroundFetchRequestInfo>* out_request_info) {
+ DCHECK(out_error);
DCHECK(out_request_info);
base::RunLoop run_loop;
@@ -320,7 +325,7 @@ class BackgroundFetchDataManagerTest
registration_id,
base::BindOnce(&BackgroundFetchDataManagerTest::DidPopNextRequest,
base::Unretained(this), run_loop.QuitClosure(),
- out_request_info));
+ out_error, out_request_info));
run_loop.Run();
}
@@ -353,13 +358,16 @@ class BackgroundFetchDataManagerTest
// Synchronous version of BackgroundFetchDataManager::MarkRequestAsComplete().
void MarkRequestAsComplete(
const BackgroundFetchRegistrationId& registration_id,
- BackgroundFetchRequestInfo* request_info) {
+ BackgroundFetchRequestInfo* request_info,
+ blink::mojom::BackgroundFetchError* out_error) {
+ DCHECK(out_error);
+
base::RunLoop run_loop;
background_fetch_data_manager_->MarkRequestAsComplete(
registration_id, request_info,
base::BindOnce(
&BackgroundFetchDataManagerTest::DidMarkRequestAsComplete,
- base::Unretained(this), run_loop.QuitClosure()));
+ base::Unretained(this), run_loop.QuitClosure(), out_error));
run_loop.Run();
}
@@ -371,10 +379,10 @@ class BackgroundFetchDataManagerTest
blink::mojom::QueryParamsPtr cache_query_params,
bool match_all,
blink::mojom::BackgroundFetchError* out_error,
- bool* out_succeeded,
+ blink::mojom::BackgroundFetchFailureReason* out_failure_reason,
std::vector<BackgroundFetchSettledFetch>* out_settled_fetches) {
DCHECK(out_error);
- DCHECK(out_succeeded);
+ DCHECK(out_failure_reason);
DCHECK(out_settled_fetches);
base::RunLoop run_loop;
@@ -385,7 +393,7 @@ class BackgroundFetchDataManagerTest
base::BindOnce(&BackgroundFetchDataManagerTest::
DidGetSettledFetchesForRegistration,
base::Unretained(this), run_loop.QuitClosure(),
- out_error, out_succeeded, out_settled_fetches));
+ out_error, out_failure_reason, out_settled_fetches));
run_loop.Run();
}
@@ -552,12 +560,13 @@ class BackgroundFetchDataManagerTest
}
// BackgroundFetchDataManagerObserver mocks:
- MOCK_METHOD5(OnRegistrationCreated,
+ MOCK_METHOD6(OnRegistrationCreated,
void(const BackgroundFetchRegistrationId& registration_id,
const BackgroundFetchRegistration& registration,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
- int num_requests));
+ int num_requests,
+ bool start_paused));
MOCK_METHOD3(OnUpdatedUI,
void(const BackgroundFetchRegistrationId& registration,
const base::Optional<std::string>& title,
@@ -566,6 +575,8 @@ class BackgroundFetchDataManagerTest
void(int64_t service_worker_registration_id));
MOCK_METHOD1(OnQuotaExceeded,
void(const BackgroundFetchRegistrationId& registration_id));
+ MOCK_METHOD1(OnFetchStorageError,
+ void(const BackgroundFetchRegistrationId& registration_id));
protected:
void DidGetRegistration(base::OnceClosure quit_closure,
@@ -615,27 +626,33 @@ class BackgroundFetchDataManagerTest
void DidPopNextRequest(
base::OnceClosure quit_closure,
+ blink::mojom::BackgroundFetchError* out_error,
scoped_refptr<BackgroundFetchRequestInfo>* out_request_info,
+ blink::mojom::BackgroundFetchError error,
scoped_refptr<BackgroundFetchRequestInfo> request_info) {
+ *out_error = error;
*out_request_info = request_info;
std::move(quit_closure).Run();
}
- void DidMarkRequestAsComplete(base::OnceClosure quit_closure) {
+ void DidMarkRequestAsComplete(base::OnceClosure quit_closure,
+ blink::mojom::BackgroundFetchError* out_error,
+ blink::mojom::BackgroundFetchError error) {
+ *out_error = error;
std::move(quit_closure).Run();
}
void DidGetSettledFetchesForRegistration(
base::OnceClosure quit_closure,
blink::mojom::BackgroundFetchError* out_error,
- bool* out_succeeded,
+ blink::mojom::BackgroundFetchFailureReason* out_failure_reason,
std::vector<BackgroundFetchSettledFetch>* out_settled_fetches,
blink::mojom::BackgroundFetchError error,
- bool succeeded,
+ blink::mojom::BackgroundFetchFailureReason failure_reason,
std::vector<BackgroundFetchSettledFetch> settled_fetches,
std::vector<std::unique_ptr<storage::BlobDataHandle>>) {
*out_error = error;
- *out_succeeded = succeeded;
+ *out_failure_reason = failure_reason;
*out_settled_fetches = std::move(settled_fetches);
std::move(quit_closure).Run();
@@ -707,7 +724,7 @@ TEST_F(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
// Creating the initial registration should succeed.
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id1, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id1, _, _, _, _, _));
CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -736,7 +753,7 @@ TEST_F(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
// is no longer an *active* registration with the same |developer_id|, even
// though the initial registration has not yet been deleted.
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _, _));
CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -764,6 +781,73 @@ TEST_F(BackgroundFetchDataManagerTest, ExceedingQuotaFailsCreation) {
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::QUOTA_EXCEEDED);
}
+TEST_F(BackgroundFetchDataManagerTest, RegistrationLimitIsEnforced) {
+ // Tests that the BackgroundFetchDataManager correctly rejects creating a
+ // registration when an origin exceeds the allowed number of registrations.
+ int64_t swid1 = RegisterServiceWorker();
+ ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, swid1);
+ int64_t swid2 = RegisterServiceWorker();
+ ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, swid2);
+
+ ASSERT_NE(swid1, swid2);
+
+ blink::mojom::BackgroundFetchError error;
+
+ // Create two registrations for every Service Worker.
+ for (int i = 0; i < 2; i++) {
+ // First Service Worker.
+ BackgroundFetchRegistrationId registration_id1(
+ swid1, origin(), kExampleDeveloperId + base::IntToString(i),
+ base::GenerateGUID());
+ CreateRegistration(registration_id1,
+ std::vector<ServiceWorkerFetchRequest>(),
+ BackgroundFetchOptions(), SkBitmap(), &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ // Second service Worker.
+ BackgroundFetchRegistrationId registration_id2(
+ swid2, origin(), kExampleDeveloperId + base::IntToString(i),
+ base::GenerateGUID());
+ CreateRegistration(registration_id2,
+ std::vector<ServiceWorkerFetchRequest>(),
+ BackgroundFetchOptions(), SkBitmap(), &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ }
+
+ // Create another registration in the first Service Worker,
+ // bringing us to the limit.
+ {
+ BackgroundFetchRegistrationId registration_id(
+ swid1, origin(), "developer_id1", base::GenerateGUID());
+ CreateRegistration(registration_id,
+ std::vector<ServiceWorkerFetchRequest>(),
+ BackgroundFetchOptions(), SkBitmap(), &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ }
+
+ // A registration this time should fail.
+ {
+ BackgroundFetchRegistrationId registration_id(
+ swid1, origin(), "developer_id2", base::GenerateGUID());
+ CreateRegistration(registration_id,
+ std::vector<ServiceWorkerFetchRequest>(),
+ BackgroundFetchOptions(), SkBitmap(), &error);
+ ASSERT_EQ(error,
+ blink::mojom::BackgroundFetchError::REGISTRATION_LIMIT_EXCEEDED);
+ }
+
+ // The registration should also fail for the other Service Worker.
+ {
+ BackgroundFetchRegistrationId registration_id(
+ swid2, origin(), "developer_id3", base::GenerateGUID());
+ CreateRegistration(registration_id,
+ std::vector<ServiceWorkerFetchRequest>(),
+ BackgroundFetchOptions(), SkBitmap(), &error);
+ ASSERT_EQ(error,
+ blink::mojom::BackgroundFetchError::REGISTRATION_LIMIT_EXCEEDED);
+ }
+}
+
TEST_F(BackgroundFetchDataManagerTest, GetDeveloperIds) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
@@ -781,7 +865,7 @@ TEST_F(BackgroundFetchDataManagerTest, GetDeveloperIds) {
BackgroundFetchRegistrationId registration_id1(
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id1, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id1, _, _, _, _, _));
CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -803,7 +887,7 @@ TEST_F(BackgroundFetchDataManagerTest, GetDeveloperIds) {
BackgroundFetchRegistrationId registration_id2(
sw_id, origin(), kAlternativeDeveloperId, kAlternativeUniqueId);
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _, _));
CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -835,7 +919,7 @@ TEST_F(BackgroundFetchDataManagerTest, GetRegistration) {
// Create a single registration.
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -877,7 +961,7 @@ TEST_F(BackgroundFetchDataManagerTest, GetMetadata) {
// Create a single registration.
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -915,7 +999,7 @@ TEST_F(BackgroundFetchDataManagerTest, LargeIconNotPersisted) {
// Create a single registration.
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, icon, &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -947,7 +1031,7 @@ TEST_F(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
// Create a single registration.
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, CreateTestIcon(),
&error);
@@ -1044,7 +1128,7 @@ TEST_F(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
blink::mojom::BackgroundFetchError error;
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id1, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id1, _, _, _, _, _));
CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -1091,7 +1175,7 @@ TEST_F(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
// |developer_id|, even though the initial registration has not yet been
// deleted.
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _, _));
CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -1104,10 +1188,53 @@ TEST_F(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
+TEST_F(BackgroundFetchDataManagerTest, MarkRegistrationForDeletion) {
+ int64_t sw_id = RegisterServiceWorker();
+ ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
+
+ BackgroundFetchRegistrationId registration_id1(
+ sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
+
+ std::vector<ServiceWorkerFetchRequest> requests(2u);
+ BackgroundFetchOptions options;
+ blink::mojom::BackgroundFetchError error;
+
+ CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ // Create a |developer_id| such that the other one is a substring.
+ std::string developer_id2 = std::string(kExampleDeveloperId) + "!";
+ BackgroundFetchRegistrationId registration_id2(sw_id, origin(), developer_id2,
+ kAlternativeUniqueId);
+
+ CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ // Get all active registration mappings.
+ {
+ auto registrations = GetRegistrationUserDataByKeyPrefix(
+ sw_id, background_fetch::ActiveRegistrationUniqueIdKey(""));
+ EXPECT_EQ(registrations.size(), 2u);
+ }
+
+ // Deactivate the first registration.
+ MarkRegistrationForDeletion(registration_id1, &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ // The second registration should still exist.
+ {
+ auto registrations = GetRegistrationUserDataByKeyPrefix(
+ sw_id, background_fetch::ActiveRegistrationUniqueIdKey(""));
+ ASSERT_EQ(registrations.size(), 1u);
+ EXPECT_EQ(registrations[0], kAlternativeUniqueId);
+ }
+}
+
TEST_F(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
+ blink::mojom::BackgroundFetchError error;
scoped_refptr<BackgroundFetchRequestInfo> request_info;
BackgroundFetchRegistrationId registration_id(
@@ -1115,7 +1242,8 @@ TEST_F(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
// There registration hasn't been created yet, so there are no pending
// requests.
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_FALSE(request_info);
EXPECT_EQ(
GetRequestStats(sw_id),
@@ -1124,10 +1252,9 @@ TEST_F(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
std::vector<ServiceWorkerFetchRequest> requests(2u);
BackgroundFetchOptions options;
- blink::mojom::BackgroundFetchError error;
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -1139,7 +1266,8 @@ TEST_F(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
0 /* completed_requests */}));
// Popping should work now.
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_TRUE(request_info);
EXPECT_EQ(request_info->request_index(), 0);
EXPECT_FALSE(request_info->download_guid().empty());
@@ -1150,7 +1278,8 @@ TEST_F(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
// Mark as complete.
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_EQ(
GetRequestStats(sw_id),
(ResponseStateStats{1 /* pending_requests */, 0 /* active_requests */,
@@ -1158,7 +1287,8 @@ TEST_F(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
RestartDataManagerFromPersistentStorage();
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_TRUE(request_info);
EXPECT_EQ(request_info->request_index(), 1);
EXPECT_FALSE(request_info->download_guid().empty());
@@ -1169,14 +1299,16 @@ TEST_F(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
// Mark as complete.
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_EQ(
GetRequestStats(sw_id),
(ResponseStateStats{0 /* pending_requests */, 0 /* active_requests */,
2 /* completed_requests */}));
// We are out of pending requests.
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_FALSE(request_info);
EXPECT_EQ(
GetRequestStats(sw_id),
@@ -1184,7 +1316,7 @@ TEST_F(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
2 /* completed_requests */}));
}
-TEST_F(BackgroundFetchDataManagerTest, DownloadTotalUpdated) {
+TEST_F(BackgroundFetchDataManagerTest, DownloadedUpdated) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
@@ -1195,7 +1327,7 @@ TEST_F(BackgroundFetchDataManagerTest, DownloadTotalUpdated) {
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -1204,36 +1336,42 @@ TEST_F(BackgroundFetchDataManagerTest, DownloadTotalUpdated) {
auto registration =
GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_EQ(registration.download_total, 0u);
+ EXPECT_EQ(registration.downloaded, 0u);
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
true /* succeeded */);
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_EQ(registration.download_total, kResponseFileSize);
+ EXPECT_EQ(registration.downloaded, kResponseFileSize);
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
true /* succeeded */);
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_EQ(registration.download_total, 2 * kResponseFileSize);
+ EXPECT_EQ(registration.downloaded, 2 * kResponseFileSize);
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
false /* succeeded */);
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- // |download_total| is unchanged.
- EXPECT_EQ(registration.download_total, 2 * kResponseFileSize);
+ // |registration.downloaded| is unchanged.
+ EXPECT_EQ(registration.downloaded, 2 * kResponseFileSize);
}
TEST_F(BackgroundFetchDataManagerTest, ExceedingQuotaAbandonsFetch) {
@@ -1247,19 +1385,21 @@ TEST_F(BackgroundFetchDataManagerTest, ExceedingQuotaAbandonsFetch) {
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
AnnotateRequestInfoWithFakeDownloadManagerData(
request_info.get(), true /* succeeded */, true /* over_quota */);
{
EXPECT_CALL(*this, OnQuotaExceeded(registration_id));
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::QUOTA_EXCEEDED);
}
}
@@ -1274,19 +1414,21 @@ TEST_F(BackgroundFetchDataManagerTest, WriteToCache) {
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
true /* success */);
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_TRUE(HasCache(kExampleUniqueId));
EXPECT_FALSE(HasCache("foo"));
@@ -1294,12 +1436,14 @@ TEST_F(BackgroundFetchDataManagerTest, WriteToCache) {
EXPECT_TRUE(MatchCache(requests[0]));
EXPECT_FALSE(MatchCache(requests[1]));
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
true /* success */);
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_TRUE(MatchCache(requests[0]));
EXPECT_TRUE(MatchCache(requests[1]));
@@ -1321,19 +1465,21 @@ TEST_F(BackgroundFetchDataManagerTest, CacheDeleted) {
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, {request}, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
true /* success */);
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_TRUE(HasCache(kExampleUniqueId));
EXPECT_TRUE(MatchCache(request));
@@ -1358,7 +1504,7 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -1370,22 +1516,24 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
0 /* completed_requests */}));
// Nothing is downloaded yet.
- bool succeeded = false;
+ blink::mojom::BackgroundFetchFailureReason failure_reason;
std::vector<BackgroundFetchSettledFetch> settled_fetches;
GetSettledFetchesForRegistration(
registration_id, base::nullopt /* request_to_match */,
nullptr /* cache_query_params */, false /* match_all */, &error,
- &succeeded, &settled_fetches);
+ &failure_reason, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_TRUE(succeeded);
+ EXPECT_EQ(failure_reason, blink::mojom::BackgroundFetchFailureReason::NONE);
EXPECT_EQ(settled_fetches.size(), 0u);
for (size_t i = 0; i < requests.size(); i++) {
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
RestartDataManagerFromPersistentStorage();
@@ -1398,11 +1546,12 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
GetSettledFetchesForRegistration(
registration_id, base::nullopt /* request_to_match */,
nullptr /* cache_query_params */, false /* match_all */, &error,
- &succeeded, &settled_fetches);
+ &failure_reason, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
// We are marking the responses as failed in Download Manager.
- EXPECT_FALSE(succeeded);
+ EXPECT_EQ(failure_reason,
+ blink::mojom::BackgroundFetchFailureReason::BAD_STATUS);
EXPECT_EQ(settled_fetches.size(), requests.size());
}
@@ -1417,50 +1566,54 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
- bool succeeded = false;
+ blink::mojom::BackgroundFetchFailureReason failure_reason;
std::vector<BackgroundFetchSettledFetch> settled_fetches;
// Nothing is downloaded yet.
GetSettledFetchesForRegistration(
registration_id, base::nullopt /* request_to_match */,
nullptr /* cache_query_params */, false /* match_all */, &error,
- &succeeded, &settled_fetches);
+ &failure_reason, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_TRUE(succeeded);
+ EXPECT_EQ(failure_reason, blink::mojom::BackgroundFetchFailureReason::NONE);
EXPECT_EQ(settled_fetches.size(), 0u);
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
true /* success */);
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
GetSettledFetchesForRegistration(
registration_id, base::nullopt /* request_to_match */,
nullptr /* cache_query_params */, false /* match_all */, &error,
- &succeeded, &settled_fetches);
+ &failure_reason, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_TRUE(succeeded);
+ EXPECT_EQ(failure_reason, blink::mojom::BackgroundFetchFailureReason::NONE);
EXPECT_EQ(settled_fetches.size(), 1u);
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
true /* success */);
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
GetSettledFetchesForRegistration(
registration_id, base::nullopt /* request_to_match */,
nullptr /* cache_query_params */, false /* match_all */, &error,
- &succeeded, &settled_fetches);
+ &failure_reason, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_TRUE(succeeded);
+ EXPECT_EQ(failure_reason, blink::mojom::BackgroundFetchFailureReason::NONE);
ASSERT_EQ(settled_fetches.size(), 2u);
// Sanity check that the responses are written to / read from the cache.
@@ -1476,9 +1629,9 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
GetSettledFetchesForRegistration(
registration_id, base::nullopt /* request_to_match */,
nullptr /* cache_query_params */, false /* match_all */, &error,
- &succeeded, &settled_fetches);
+ &failure_reason, &settled_fetches);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- EXPECT_TRUE(succeeded);
+ EXPECT_EQ(failure_reason, blink::mojom::BackgroundFetchFailureReason::NONE);
EXPECT_EQ(settled_fetches.size(), 2u);
}
@@ -1493,7 +1646,7 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForASpecificRequest) {
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -1502,10 +1655,12 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForASpecificRequest) {
for (size_t i = 0; i < requests.size(); i++) {
SCOPED_TRACE(i);
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
EXPECT_EQ(
@@ -1513,16 +1668,17 @@ TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForASpecificRequest) {
(ResponseStateStats{0 /* pending_requests */, 0 /* active_requests */,
requests.size() /* completed_requests */}));
- bool succeeded = false;
+ blink::mojom::BackgroundFetchFailureReason failure_reason;
std::vector<BackgroundFetchSettledFetch> settled_fetches;
GetSettledFetchesForRegistration(
registration_id, requests[0] /* request_to_match */,
nullptr /* cache_query_params */, false /* match_all */, &error,
- &succeeded, &settled_fetches);
+ &failure_reason, &settled_fetches);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
// We are marking the responses as failed in Download Manager.
- EXPECT_FALSE(succeeded);
+ EXPECT_EQ(failure_reason,
+ blink::mojom::BackgroundFetchFailureReason::BAD_STATUS);
EXPECT_EQ(settled_fetches.size(), 1u);
}
@@ -1538,7 +1694,7 @@ TEST_F(BackgroundFetchDataManagerTest,
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -1547,10 +1703,12 @@ TEST_F(BackgroundFetchDataManagerTest,
for (size_t i = 0; i < requests.size() - 1; i++) {
SCOPED_TRACE(i);
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
EXPECT_EQ(
@@ -1558,12 +1716,12 @@ TEST_F(BackgroundFetchDataManagerTest,
(ResponseStateStats{1 /* pending_requests */, 0 /* active_requests */,
requests.size() - 1 /* completed_requests */}));
- bool succeeded = false;
+ blink::mojom::BackgroundFetchFailureReason failure_reason;
std::vector<BackgroundFetchSettledFetch> settled_fetches;
GetSettledFetchesForRegistration(
registration_id, requests[2] /* request_to_match */,
nullptr /* cache_query_params */, false /* match_all */, &error,
- &succeeded, &settled_fetches);
+ &failure_reason, &settled_fetches);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_EQ(settled_fetches.size(), 1u);
EXPECT_EQ(settled_fetches[0].response->response_type,
@@ -1584,7 +1742,7 @@ TEST_F(BackgroundFetchDataManagerTest, IgnoreMethodAndMatchAll) {
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -1593,10 +1751,12 @@ TEST_F(BackgroundFetchDataManagerTest, IgnoreMethodAndMatchAll) {
for (size_t i = 0; i < requests.size(); i++) {
SCOPED_TRACE(i);
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
EXPECT_EQ(
@@ -1604,19 +1764,20 @@ TEST_F(BackgroundFetchDataManagerTest, IgnoreMethodAndMatchAll) {
(ResponseStateStats{0 /* pending_requests */, 0 /* active_requests */,
requests.size() /* completed_requests */}));
- bool succeeded = false;
+ blink::mojom::BackgroundFetchFailureReason failure_reason;
std::vector<BackgroundFetchSettledFetch> settled_fetches;
blink::mojom::QueryParamsPtr cache_query_params =
blink::mojom::QueryParams::New();
cache_query_params->ignore_method = true;
GetSettledFetchesForRegistration(
registration_id, requests[0] /* request_to_match */,
- std::move(cache_query_params), true /* match_all */, &error, &succeeded,
- &settled_fetches);
+ std::move(cache_query_params), true /* match_all */, &error,
+ &failure_reason, &settled_fetches);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
// We are marking the responses as failed in Download Manager.
- EXPECT_FALSE(succeeded);
+ EXPECT_EQ(failure_reason,
+ blink::mojom::BackgroundFetchFailureReason::BAD_STATUS);
// If the ASSERT below fails, the Cache Storage API implementation has likely
// changed to distinguish keys by request data other than just the URL.
// Thank you! Please can you update the 1u below to 2u, or file a bug against
@@ -1642,7 +1803,7 @@ TEST_F(BackgroundFetchDataManagerTest, Cleanup) {
GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
// Create a registration.
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -1660,12 +1821,7 @@ TEST_F(BackgroundFetchDataManagerTest, Cleanup) {
RestartDataManagerFromPersistentStorage();
- // Pending Requests should be deleted after marking a registration for
- // deletion.
- EXPECT_EQ(0u, GetRegistrationUserDataByKeyPrefix(
- sw_id, background_fetch::kPendingRequestKeyPrefix)
- .size());
- EXPECT_EQ(2u, // Metadata proto + title.
+ EXPECT_EQ(4u, // Metadata proto + UI options + remaining pending fetches.
GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
// Cleanup should delete the registration.
@@ -1708,7 +1864,7 @@ TEST_F(BackgroundFetchDataManagerTest, GetInitializationData) {
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id, _, _, _, _, _));
CreateRegistration(registration_id, requests, options, CreateTestIcon(),
&error);
@@ -1738,11 +1894,16 @@ TEST_F(BackgroundFetchDataManagerTest, GetInitializationData) {
// Mark one request as complete and start another.
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
+
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
- MarkRequestAsComplete(registration_id, request_info.get());
- PopNextRequest(registration_id, &request_info);
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
{
std::vector<BackgroundFetchInitializationData> data =
@@ -1767,7 +1928,7 @@ TEST_F(BackgroundFetchDataManagerTest, GetInitializationData) {
BackgroundFetchRegistrationId registration_id2(
sw_id, origin(), kAlternativeDeveloperId, kAlternativeUniqueId);
{
- EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(registration_id2, _, _, _, _, _));
CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
@@ -1794,7 +1955,7 @@ TEST_F(BackgroundFetchDataManagerTest, CreateInParallel) {
std::vector<blink::mojom::BackgroundFetchError> errors(5);
// We expect a single successful registration to be created.
- EXPECT_CALL(*this, OnRegistrationCreated(_, _, _, _, _));
+ EXPECT_CALL(*this, OnRegistrationCreated(_, _, _, _, _, _));
const int num_parallel_creates = 5;
@@ -1810,6 +1971,7 @@ TEST_F(BackgroundFetchDataManagerTest, CreateInParallel) {
background_fetch_data_manager_->CreateRegistration(
registration_id, requests, options, SkBitmap(),
+ /* start_paused = */ false,
base::BindOnce(&DidCreateRegistration, quit_once_all_finished_closure,
&errors[i]));
}
@@ -1868,20 +2030,22 @@ TEST_F(BackgroundFetchDataManagerTest, StorageErrorsReported) {
}
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- PopNextRequest(registration_id, &request_info);
+ PopNextRequest(registration_id, &error, &request_info);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
ASSERT_TRUE(request_info);
AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
true /* success */);
- MarkRequestAsComplete(registration_id, request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- bool succeeded = false;
+ blink::mojom::BackgroundFetchFailureReason failure_reason;
std::vector<BackgroundFetchSettledFetch> settled_fetches;
{
GetSettledFetchesForRegistration(
registration_id, base::nullopt /* request_to_match */,
nullptr /* cache_query_params */, false /* match_all */, &error,
- &succeeded, &settled_fetches);
+ &failure_reason, &settled_fetches);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
@@ -1896,7 +2060,7 @@ TEST_F(BackgroundFetchDataManagerTest, StorageErrorsReported) {
GetSettledFetchesForRegistration(
registration_id, base::nullopt /* request_to_match */,
nullptr /* cache_query_params */, false /* match_all */, &error,
- &succeeded, &settled_fetches);
+ &failure_reason, &settled_fetches);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::STORAGE_ERROR);
histogram_tester.ExpectBucketCount(
diff --git a/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.cc b/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.cc
index c8048feda17..79ca6513c22 100644
--- a/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.cc
@@ -6,11 +6,13 @@
#include <utility>
+#include "base/task/post_task.h"
#include "components/download/public/common/download_item.h"
#include "components/download/public/common/download_url_parameters.h"
#include "content/browser/background_fetch/background_fetch_job_controller.h"
#include "content/public/browser/background_fetch_description.h"
#include "content/public/browser/background_fetch_response.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/download_manager.h"
#include "ui/gfx/geometry/size.h"
@@ -43,11 +45,10 @@ class BackgroundFetchDelegateProxy::Core
void ForwardGetPermissionForOriginCallbackToIO(
BackgroundFetchDelegate::GetPermissionForOriginCallback callback,
- bool has_permission) {
+ BackgroundFetchPermission permission) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(std::move(callback), has_permission));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(std::move(callback), permission));
}
void GetPermissionForOrigin(
@@ -60,7 +61,7 @@ class BackgroundFetchDelegateProxy::Core
base::BindOnce(&Core::ForwardGetPermissionForOriginCallbackToIO,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
} else {
- std::move(callback).Run(false /* has_permission */);
+ std::move(callback).Run(BackgroundFetchPermission::BLOCKED);
}
}
@@ -68,8 +69,8 @@ class BackgroundFetchDelegateProxy::Core
BackgroundFetchDelegate::GetIconDisplaySizeCallback callback,
const gfx::Size& display_size) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(std::move(callback), display_size));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(std::move(callback), display_size));
}
void GetIconDisplaySize(
@@ -81,8 +82,8 @@ class BackgroundFetchDelegateProxy::Core
base::BindOnce(&Core::ForwardGetIconDisplaySizeCallbackToIO,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
} else {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), gfx::Size(0, 0)));
}
}
@@ -91,6 +92,13 @@ class BackgroundFetchDelegateProxy::Core
std::unique_ptr<BackgroundFetchDescription> fetch_description) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // If there are multiple clients created we might have registered the wrong
+ // one with the delegate by overwriting it. This check makes sure that we
+ // register the correct client until multiple clients are supported.
+ // TODO(crbug.com/907075): Support multiple clients.
+ if (delegate_ && delegate_->client().get() != this)
+ delegate_->SetDelegateClient(GetWeakPtrOnUI());
+
if (delegate_)
delegate_->CreateDownloadJob(std::move(fetch_description));
}
@@ -176,8 +184,9 @@ class BackgroundFetchDelegateProxy::Core
}
// BackgroundFetchDelegate::Client implementation:
- void OnJobCancelled(const std::string& job_unique_id,
- BackgroundFetchReasonToAbort reason_to_abort) override;
+ void OnJobCancelled(
+ const std::string& job_unique_id,
+ blink::mojom::BackgroundFetchFailureReason reason_to_abort) override;
void OnDownloadUpdated(const std::string& job_unique_id,
const std::string& guid,
uint64_t bytes_downloaded) override;
@@ -207,10 +216,10 @@ class BackgroundFetchDelegateProxy::Core
void BackgroundFetchDelegateProxy::Core::OnJobCancelled(
const std::string& job_unique_id,
- BackgroundFetchReasonToAbort reason_to_abort) {
+ blink::mojom::BackgroundFetchFailureReason reason_to_abort) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BackgroundFetchDelegateProxy::OnJobCancelled, io_parent_,
job_unique_id, reason_to_abort));
}
@@ -220,8 +229,8 @@ void BackgroundFetchDelegateProxy::Core::OnDownloadUpdated(
const std::string& guid,
uint64_t bytes_downloaded) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BackgroundFetchDelegateProxy::OnDownloadUpdated,
io_parent_, job_unique_id, guid, bytes_downloaded));
}
@@ -231,8 +240,8 @@ void BackgroundFetchDelegateProxy::Core::OnDownloadComplete(
const std::string& guid,
std::unique_ptr<BackgroundFetchResult> result) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BackgroundFetchDelegateProxy::OnDownloadComplete,
io_parent_, job_unique_id, guid, std::move(result)));
}
@@ -243,8 +252,8 @@ void BackgroundFetchDelegateProxy::Core::OnDownloadStarted(
std::unique_ptr<content::BackgroundFetchResponse> response) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BackgroundFetchDelegateProxy::DidStartRequest, io_parent_,
job_unique_id, guid, std::move(response)));
}
@@ -253,8 +262,8 @@ void BackgroundFetchDelegateProxy::Core::OnUIActivated(
const std::string& job_unique_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BackgroundFetchDelegateProxy::DidActivateUI, io_parent_,
job_unique_id));
}
@@ -307,9 +316,9 @@ void BackgroundFetchDelegateProxy::SetClickEventDispatcher(
void BackgroundFetchDelegateProxy::GetIconDisplaySize(
BackgroundFetchDelegate::GetIconDisplaySizeCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&Core::GetIconDisplaySize,
- ui_core_ptr_, std::move(callback)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&Core::GetIconDisplaySize,
+ ui_core_ptr_, std::move(callback)));
}
void BackgroundFetchDelegateProxy::GetPermissionForOrigin(
@@ -317,8 +326,8 @@ void BackgroundFetchDelegateProxy::GetPermissionForOrigin(
const ResourceRequestInfo::WebContentsGetter& wc_getter,
BackgroundFetchDelegate::GetPermissionForOriginCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Core::GetPermissionForOrigin, ui_core_ptr_, origin,
wc_getter, std::move(callback)));
}
@@ -335,9 +344,10 @@ void BackgroundFetchDelegateProxy::CreateDownloadJob(
fetch_description->job_unique_id,
JobDetails(controller, std::move(active_fetch_requests)));
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&Core::CreateDownloadJob, ui_core_ptr_,
- std::move(fetch_description)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&Core::CreateDownloadJob, ui_core_ptr_,
+ std::move(fetch_description)));
}
void BackgroundFetchDelegateProxy::StartRequest(
@@ -355,9 +365,9 @@ void BackgroundFetchDelegateProxy::StartRequest(
job_details.current_request_map[download_guid] = request;
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&Core::StartRequest, ui_core_ptr_,
- job_unique_id, origin, request));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&Core::StartRequest, ui_core_ptr_,
+ job_unique_id, origin, request));
}
void BackgroundFetchDelegateProxy::UpdateUI(
@@ -366,16 +376,16 @@ void BackgroundFetchDelegateProxy::UpdateUI(
const base::Optional<SkBitmap>& icon) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&Core::UpdateUI, ui_core_ptr_,
- job_unique_id, title, icon));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&Core::UpdateUI, ui_core_ptr_,
+ job_unique_id, title, icon));
}
void BackgroundFetchDelegateProxy::Abort(const std::string& job_unique_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Core::Abort, ui_core_ptr_, job_unique_id));
job_details_map_.erase(job_unique_id);
@@ -383,11 +393,12 @@ void BackgroundFetchDelegateProxy::Abort(const std::string& job_unique_id) {
void BackgroundFetchDelegateProxy::OnJobCancelled(
const std::string& job_unique_id,
- BackgroundFetchReasonToAbort reason_to_abort) {
+ blink::mojom::BackgroundFetchFailureReason reason_to_abort) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(reason_to_abort == BackgroundFetchReasonToAbort::CANCELLED_FROM_UI ||
- reason_to_abort ==
- BackgroundFetchReasonToAbort::TOTAL_DOWNLOAD_SIZE_EXCEEDED);
+ DCHECK(reason_to_abort ==
+ blink::mojom::BackgroundFetchFailureReason::CANCELLED_FROM_UI ||
+ reason_to_abort == blink::mojom::BackgroundFetchFailureReason::
+ TOTAL_DOWNLOAD_SIZE_EXCEEDED);
// TODO(delphick): The controller may not exist as persistence is not yet
// implemented.
@@ -419,8 +430,6 @@ void BackgroundFetchDelegateProxy::DidStartRequest(
DCHECK(request_info);
DCHECK_EQ(guid, request_info->download_guid());
- request_info->PopulateWithResponse(std::move(response));
-
if (job_details.controller)
job_details.controller->DidStartRequest(request_info);
}
diff --git a/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.h b/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.h
index d393db41cfc..e877ab60cfe 100644
--- a/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.h
+++ b/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.h
@@ -20,6 +20,7 @@
#include "content/public/browser/background_fetch_description.h"
#include "content/public/browser/background_fetch_response.h"
#include "content/public/browser/browser_thread.h"
+#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
namespace content {
@@ -48,7 +49,7 @@ class CONTENT_EXPORT BackgroundFetchDelegateProxy {
const scoped_refptr<BackgroundFetchRequestInfo>& request) = 0;
// Called when the delegate aborts a Background Fetch registration.
- virtual void Abort(BackgroundFetchReasonToAbort) = 0;
+ virtual void Abort(blink::mojom::BackgroundFetchFailureReason) = 0;
virtual ~Controller() {}
};
@@ -114,8 +115,9 @@ class CONTENT_EXPORT BackgroundFetchDelegateProxy {
// Called when the job identified by |job_unique|id| was cancelled by the
// delegate. Should only be called on the IO thread.
- void OnJobCancelled(const std::string& job_unique_id,
- BackgroundFetchReasonToAbort reason_to_abort);
+ void OnJobCancelled(
+ const std::string& job_unique_id,
+ blink::mojom::BackgroundFetchFailureReason reason_to_abort);
// Called when the download identified by |guid| has succeeded/failed/aborted.
// Should only be called on the IO thread.
diff --git a/chromium/content/browser/background_fetch/background_fetch_delegate_proxy_unittest.cc b/chromium/content/browser/background_fetch/background_fetch_delegate_proxy_unittest.cc
index 8d142789922..b5b5e2e94bf 100644
--- a/chromium/content/browser/background_fetch/background_fetch_delegate_proxy_unittest.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_delegate_proxy_unittest.cc
@@ -9,12 +9,15 @@
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "content/browser/background_fetch/background_fetch_test_base.h"
#include "content/public/browser/background_fetch_delegate.h"
#include "content/public/browser/background_fetch_description.h"
#include "content/public/browser/background_fetch_response.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
namespace content {
@@ -37,7 +40,7 @@ class FakeBackgroundFetchDelegate : public BackgroundFetchDelegate {
const url::Origin& origin,
const ResourceRequestInfo::WebContentsGetter& wc_getter,
GetPermissionForOriginCallback callback) override {
- std::move(callback).Run(true /* has_permission */);
+ std::move(callback).Run(BackgroundFetchPermission::ALLOWED);
}
void CreateDownloadJob(
std::unique_ptr<BackgroundFetchDescription> fetch_description) override {}
@@ -51,6 +54,7 @@ class FakeBackgroundFetchDelegate : public BackgroundFetchDelegate {
return;
download_guid_to_job_id_map_[guid] = job_unique_id;
+ download_guid_to_url_map_[guid] = url;
auto response = std::make_unique<BackgroundFetchResponse>(
std::vector<GURL>({url}),
@@ -58,8 +62,8 @@ class FakeBackgroundFetchDelegate : public BackgroundFetchDelegate {
client()->OnDownloadStarted(job_unique_id, guid, std::move(response));
if (complete_downloads_) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&FakeBackgroundFetchDelegate::CompleteDownload,
base::Unretained(this), job_unique_id, guid));
}
@@ -89,14 +93,21 @@ class FakeBackgroundFetchDelegate : public BackgroundFetchDelegate {
if (aborted_jobs_.count(download_guid_to_job_id_map_[guid]))
return;
- client()->OnDownloadComplete(job_unique_id, guid,
- std::make_unique<BackgroundFetchResult>(
- base::Time::Now(), base::FilePath(),
- base::nullopt /* blob_handle */, 10u));
+ auto response = std::make_unique<BackgroundFetchResponse>(
+ std::vector<GURL>({download_guid_to_url_map_[guid]}),
+ base::MakeRefCounted<net::HttpResponseHeaders>("200 OK"));
+
+ client()->OnDownloadComplete(
+ job_unique_id, guid,
+ std::make_unique<BackgroundFetchResult>(
+ std::move(response), base::Time::Now(), base::FilePath(),
+ base::nullopt /* blob_handle */, 10u));
+ download_guid_to_url_map_.erase(guid);
}
std::set<std::string> aborted_jobs_;
std::map<std::string, std::string> download_guid_to_job_id_map_;
+ std::map<std::string, GURL> download_guid_to_url_map_;
bool complete_downloads_ = true;
};
@@ -118,7 +129,8 @@ class FakeController : public BackgroundFetchDelegateProxy::Controller {
request_completed_ = true;
}
- void Abort(BackgroundFetchReasonToAbort reason_to_abort) override {}
+ void Abort(
+ blink::mojom::BackgroundFetchFailureReason reason_to_abort) override {}
bool request_started_ = false;
bool request_completed_ = false;
@@ -168,7 +180,7 @@ TEST_F(BackgroundFetchDelegateProxyTest, StartRequest) {
kExampleUniqueId, "Job 1", url::Origin(), SkBitmap(),
0 /* completed_parts */, 1 /* total_parts */,
0 /* completed_parts_size */, 0 /* total_parts_size */,
- std::vector<std::string>());
+ std::vector<std::string>(), /* start_paused = */ false);
delegate_proxy_.CreateDownloadJob(controller.weak_ptr_factory_.GetWeakPtr(),
std::move(fetch_description),
{} /* active_fetch_requests */);
@@ -193,7 +205,7 @@ TEST_F(BackgroundFetchDelegateProxyTest, StartRequest_NotCompleted) {
kExampleUniqueId, "Job 1", url::Origin(), SkBitmap(),
0 /* completed_parts */, 1 /* total_parts */,
0 /* completed_parts_size */, 0 /* total_parts_size */,
- std::vector<std::string>());
+ std::vector<std::string>(), /* start_paused = */ false);
delegate_proxy_.CreateDownloadJob(controller.weak_ptr_factory_.GetWeakPtr(),
std::move(fetch_description),
{} /* active_fetch_requests */);
@@ -222,7 +234,7 @@ TEST_F(BackgroundFetchDelegateProxyTest, Abort) {
kExampleUniqueId, "Job 1", url::Origin(), SkBitmap(),
0 /* completed_parts */, 1 /* total_parts */,
0 /* completed_parts_size */, 0 /* total_parts_size */,
- std::vector<std::string>());
+ std::vector<std::string>(), /* start_paused = */ false);
delegate_proxy_.CreateDownloadJob(controller.weak_ptr_factory_.GetWeakPtr(),
std::move(fetch_description1),
{} /* active_fetch_requests */);
@@ -231,7 +243,7 @@ TEST_F(BackgroundFetchDelegateProxyTest, Abort) {
kExampleUniqueId2, "Job 2", url::Origin(), SkBitmap(),
0 /* completed_parts */, 1 /* total_parts */,
0 /* completed_parts_size */, 0 /* total_parts_size */,
- std::vector<std::string>());
+ std::vector<std::string>(), /* start_paused = */ false);
delegate_proxy_.CreateDownloadJob(controller2.weak_ptr_factory_.GetWeakPtr(),
std::move(fetch_description2),
{} /* active_fetch_requests */);
@@ -267,7 +279,7 @@ TEST_F(BackgroundFetchDelegateProxyTest, UpdateUI) {
kExampleUniqueId, "Job 1 Started.", url::Origin(), SkBitmap(),
0 /* completed_parts */, 1 /* total_parts */,
0 /* completed_parts_size */, 0 /* total_parts_size */,
- std::vector<std::string>());
+ std::vector<std::string>(), /* start_paused = */ false);
delegate_proxy_.CreateDownloadJob(controller.weak_ptr_factory_.GetWeakPtr(),
std::move(fetch_description),
diff --git a/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc b/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc
index b1ba4db1748..48338d12f0b 100644
--- a/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc
@@ -25,10 +25,10 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent(
if (fail_abort_event_) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::REJECTED,
- base::Time::Now());
+ base::TimeTicks::Now());
} else {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
if (abort_event_closure_)
@@ -42,10 +42,10 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent(
if (fail_click_event_) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::REJECTED,
- base::Time::Now());
+ base::TimeTicks::Now());
} else {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
if (click_event_closure_)
@@ -59,10 +59,10 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent(
if (fail_fetch_fail_event_) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::REJECTED,
- base::Time::Now());
+ base::TimeTicks::Now());
} else {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
if (fetch_fail_event_closure_)
@@ -77,10 +77,10 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchSuccessEvent(
if (fail_fetched_event_) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::REJECTED,
- base::Time::Now());
+ base::TimeTicks::Now());
} else {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
if (fetched_event_closure_)
diff --git a/chromium/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc b/chromium/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
index 415e48ebf61..d897cb81851 100644
--- a/chromium/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
@@ -48,7 +48,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchInvalidRegistration) {
auto registration = CreateBackgroundFetchRegistration(
invalid_registration_id.developer_id(),
invalid_registration_id.unique_id(),
- blink::mojom::BackgroundFetchState::FAILURE,
+ blink::mojom::BackgroundFetchResult::FAILURE,
blink::mojom::BackgroundFetchFailureReason::QUOTA_EXCEEDED);
event_dispatcher_.DispatchBackgroundFetchAbortEvent(
invalid_registration_id, std::move(registration), run_loop.QuitClosure());
@@ -79,7 +79,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchAbortEvent) {
base::RunLoop run_loop;
auto registration = CreateBackgroundFetchRegistration(
kExampleDeveloperId, kExampleUniqueId,
- blink::mojom::BackgroundFetchState::FAILURE,
+ blink::mojom::BackgroundFetchResult::FAILURE,
blink::mojom::BackgroundFetchFailureReason::CANCELLED_FROM_UI);
event_dispatcher_.DispatchBackgroundFetchAbortEvent(
registration_id, std::move(registration), run_loop.QuitClosure());
@@ -109,7 +109,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchAbortEvent) {
base::RunLoop run_loop;
auto registration = CreateBackgroundFetchRegistration(
kExampleDeveloperId2, kExampleUniqueId2,
- blink::mojom::BackgroundFetchState::FAILURE,
+ blink::mojom::BackgroundFetchResult::FAILURE,
blink::mojom::BackgroundFetchFailureReason::QUOTA_EXCEEDED);
event_dispatcher_.DispatchBackgroundFetchAbortEvent(second_registration_id,
std::move(registration),
@@ -148,7 +148,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchClickEvent) {
base::RunLoop run_loop;
auto registration = CreateBackgroundFetchRegistration(
kExampleDeveloperId, kExampleUniqueId,
- blink::mojom::BackgroundFetchState::PENDING,
+ blink::mojom::BackgroundFetchResult::UNSET,
blink::mojom::BackgroundFetchFailureReason::NONE);
event_dispatcher_.DispatchBackgroundFetchClickEvent(
registration_id, std::move(registration), run_loop.QuitClosure());
@@ -159,8 +159,8 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchClickEvent) {
ASSERT_TRUE(embedded_worker_test_helper()->last_registration().has_value());
EXPECT_EQ(kExampleDeveloperId,
embedded_worker_test_helper()->last_registration()->developer_id);
- EXPECT_EQ(blink::mojom::BackgroundFetchState::PENDING,
- embedded_worker_test_helper()->last_registration()->state);
+ EXPECT_EQ(blink::mojom::BackgroundFetchResult::UNSET,
+ embedded_worker_test_helper()->last_registration()->result);
histogram_tester_.ExpectUniqueSample(
"BackgroundFetch.EventDispatchResult.ClickEvent",
@@ -176,7 +176,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchClickEvent) {
base::RunLoop run_loop;
auto registration = CreateBackgroundFetchRegistration(
kExampleDeveloperId2, kExampleUniqueId2,
- blink::mojom::BackgroundFetchState::FAILURE,
+ blink::mojom::BackgroundFetchResult::FAILURE,
blink::mojom::BackgroundFetchFailureReason::QUOTA_EXCEEDED);
event_dispatcher_.DispatchBackgroundFetchClickEvent(second_registration_id,
std::move(registration),
@@ -188,8 +188,8 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchClickEvent) {
ASSERT_TRUE(embedded_worker_test_helper()->last_registration().has_value());
EXPECT_EQ(kExampleDeveloperId2,
embedded_worker_test_helper()->last_registration()->developer_id);
- EXPECT_EQ(blink::mojom::BackgroundFetchState::FAILURE,
- embedded_worker_test_helper()->last_registration()->state);
+ EXPECT_EQ(blink::mojom::BackgroundFetchResult::FAILURE,
+ embedded_worker_test_helper()->last_registration()->result);
histogram_tester_.ExpectBucketCount(
"BackgroundFetch.EventDispatchResult.ClickEvent",
@@ -215,7 +215,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchFailEvent) {
base::RunLoop run_loop;
auto registration = CreateBackgroundFetchRegistration(
kExampleDeveloperId, kExampleUniqueId,
- blink::mojom::BackgroundFetchState::FAILURE,
+ blink::mojom::BackgroundFetchResult::FAILURE,
blink::mojom::BackgroundFetchFailureReason::QUOTA_EXCEEDED);
event_dispatcher_.DispatchBackgroundFetchFailEvent(
registration_id, std::move(registration), run_loop.QuitClosure());
@@ -241,7 +241,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchFailEvent) {
base::RunLoop run_loop;
auto registration = CreateBackgroundFetchRegistration(
kExampleDeveloperId2, kExampleUniqueId2,
- blink::mojom::BackgroundFetchState::FAILURE,
+ blink::mojom::BackgroundFetchResult::FAILURE,
blink::mojom::BackgroundFetchFailureReason::QUOTA_EXCEEDED);
event_dispatcher_.DispatchBackgroundFetchFailEvent(second_registration_id,
std::move(registration),
@@ -277,7 +277,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchFetchSuccessEvent) {
base::RunLoop run_loop;
auto registration = CreateBackgroundFetchRegistration(
kExampleDeveloperId, kExampleUniqueId,
- blink::mojom::BackgroundFetchState::SUCCESS,
+ blink::mojom::BackgroundFetchResult::SUCCESS,
blink::mojom::BackgroundFetchFailureReason::NONE);
event_dispatcher_.DispatchBackgroundFetchSuccessEvent(
registration_id, std::move(registration), run_loop.QuitClosure());
@@ -306,7 +306,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchFetchSuccessEvent) {
base::RunLoop run_loop;
auto registration = CreateBackgroundFetchRegistration(
kExampleDeveloperId2, kExampleUniqueId2,
- blink::mojom::BackgroundFetchState::SUCCESS,
+ blink::mojom::BackgroundFetchResult::SUCCESS,
blink::mojom::BackgroundFetchFailureReason::NONE);
event_dispatcher_.DispatchBackgroundFetchSuccessEvent(
second_registration_id, std::move(registration),
diff --git a/chromium/content/browser/background_fetch/background_fetch_job_controller.cc b/chromium/content/browser/background_fetch/background_fetch_job_controller.cc
index a2e82ba7bdd..a0e07e425fa 100644
--- a/chromium/content/browser/background_fetch/background_fetch_job_controller.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_job_controller.cc
@@ -3,6 +3,8 @@
// found in the LICENSE file.
#include "content/browser/background_fetch/background_fetch_job_controller.h"
+#include "content/public/common/origin_util.h"
+#include "services/network/public/cpp/cors/cors.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
#include <utility>
@@ -11,6 +13,8 @@
namespace content {
+using blink::mojom::BackgroundFetchFailureReason;
+
BackgroundFetchJobController::BackgroundFetchJobController(
BackgroundFetchDelegateProxy* delegate_proxy,
BackgroundFetchScheduler* scheduler,
@@ -37,13 +41,15 @@ void BackgroundFetchJobController::InitializeRequestStatus(
int total_downloads,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests,
- const std::string& ui_title) {
+ const std::string& ui_title,
+ bool start_paused) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Don't allow double initialization.
DCHECK_GT(total_downloads, 0);
DCHECK_EQ(total_downloads_, 0);
+ outstanding_requests_ = active_fetch_requests;
completed_downloads_ = completed_downloads;
total_downloads_ = total_downloads;
@@ -59,7 +65,7 @@ void BackgroundFetchJobController::InitializeRequestStatus(
registration_id().unique_id(), ui_title, registration_id().origin(),
icon_, completed_downloads, total_downloads,
complete_requests_downloaded_bytes_cache_, total_downloads_size_,
- std::move(active_guids));
+ std::move(active_guids), start_paused);
delegate_proxy_->CreateDownloadJob(GetWeakPtr(), std::move(fetch_description),
std::move(active_fetch_requests));
@@ -73,6 +79,41 @@ bool BackgroundFetchJobController::HasMoreRequests() {
return completed_downloads_ < total_downloads_;
}
+bool BackgroundFetchJobController::IsMixedContent(
+ const BackgroundFetchRequestInfo& request) {
+ // Empty request is valid, it shouldn't fail the mixed content check.
+ if (request.fetch_request().url.is_empty())
+ return false;
+
+ return !IsOriginSecure(request.fetch_request().url);
+}
+
+bool BackgroundFetchJobController::RequiresCORSPreflight(
+ const BackgroundFetchRequestInfo& request) {
+ auto fetch_request = request.fetch_request();
+
+ // Same origin requests don't require a CORS preflight.
+ // https://fetch.spec.whatwg.org/#main-fetch
+ // TODO(crbug.com/711354): Make sure that cross-origin redirects are disabled.
+ if (url::IsSameOriginWith(registration_id().origin().GetURL(),
+ fetch_request.url)) {
+ return false;
+ }
+
+ // Requests that are more involved than what is possible with HTML's form
+ // element require a CORS-preflight request.
+ // https://fetch.spec.whatwg.org/#main-fetch
+ if (!fetch_request.method.empty() &&
+ !network::cors::IsCORSSafelistedMethod(fetch_request.method)) {
+ return true;
+ }
+
+ net::HttpRequestHeaders::HeaderVector headers;
+ for (const auto& header : fetch_request.headers)
+ headers.emplace_back(header.first, header.second);
+ return !network::cors::CORSUnsafeRequestHeaderNames(headers).empty();
+}
+
void BackgroundFetchJobController::StartRequest(
scoped_refptr<BackgroundFetchRequestInfo> request,
RequestFinishedCallback request_finished_callback) {
@@ -84,15 +125,29 @@ void BackgroundFetchJobController::StartRequest(
active_request_downloaded_bytes_ = 0;
active_request_finished_callback_ = std::move(request_finished_callback);
+ if (IsMixedContent(*request.get()) || RequiresCORSPreflight(*request.get())) {
+ request->SetEmptyResultWithFailureReason(
+ BackgroundFetchResult::FailureReason::FETCH_ERROR);
+
+ ++completed_downloads_;
+ std::move(active_request_finished_callback_).Run(request);
+ return;
+ }
+
delegate_proxy_->StartRequest(registration_id().unique_id(),
registration_id().origin(), request);
}
+std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
+BackgroundFetchJobController::TakeOutstandingRequests() {
+ return std::move(outstanding_requests_);
+}
+
void BackgroundFetchJobController::DidStartRequest(
const scoped_refptr<BackgroundFetchRequestInfo>& request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // TODO(delphick): Either add CORS check here or remove this function and do
- // the CORS check in BackgroundFetchDelegateImpl (since
+ // TODO(crbug.com/884672): Either add CORS check here or remove this function
+ // and do the CORS check in BackgroundFetchDelegateImpl (since
// download::Client::OnDownloadStarted returns a value that can abort the
// download).
}
@@ -107,9 +162,10 @@ void BackgroundFetchJobController::DidUpdateRequest(
active_request_downloaded_bytes_ = bytes_downloaded;
- progress_callback_.Run(registration_id().unique_id(), options_.download_total,
- complete_requests_downloaded_bytes_cache_ +
- GetInProgressDownloadedBytes());
+ auto registration =
+ NewRegistration(blink::mojom::BackgroundFetchResult::UNSET);
+ registration->downloaded += GetInProgressDownloadedBytes();
+ progress_callback_.Run(*registration);
}
void BackgroundFetchJobController::DidCompleteRequest(
@@ -140,43 +196,20 @@ void BackgroundFetchJobController::UpdateUI(
std::unique_ptr<BackgroundFetchRegistration>
BackgroundFetchJobController::NewRegistration(
- blink::mojom::BackgroundFetchState state) const {
+ blink::mojom::BackgroundFetchResult result) const {
return std::make_unique<BackgroundFetchRegistration>(
registration_id().developer_id(), registration_id().unique_id(),
0 /* upload_total */, 0 /* uploaded */, total_downloads_size_,
- complete_requests_downloaded_bytes_cache_, state, MojoFailureReason());
+ complete_requests_downloaded_bytes_cache_, result, failure_reason_);
}
uint64_t BackgroundFetchJobController::GetInProgressDownloadedBytes() {
return active_request_downloaded_bytes_;
}
-// TODO(crbug.com/876691): Get rid of BackgroundFetchReasonToAbort and remove
-// this method.
-blink::mojom::BackgroundFetchFailureReason
-BackgroundFetchJobController::MojoFailureReason() const {
- switch (reason_to_abort_) {
- case BackgroundFetchReasonToAbort::NONE:
- return blink::mojom::BackgroundFetchFailureReason::NONE;
- case BackgroundFetchReasonToAbort::CANCELLED_FROM_UI:
- return blink::mojom::BackgroundFetchFailureReason::CANCELLED_FROM_UI;
- case BackgroundFetchReasonToAbort::ABORTED_BY_DEVELOPER:
- return blink::mojom::BackgroundFetchFailureReason::CANCELLED_BY_DEVELOPER;
- case BackgroundFetchReasonToAbort::TOTAL_DOWNLOAD_SIZE_EXCEEDED:
- return blink::mojom::BackgroundFetchFailureReason::
- TOTAL_DOWNLOAD_SIZE_EXCEEDED;
- case BackgroundFetchReasonToAbort::SERVICE_WORKER_UNAVAILABLE:
- return blink::mojom::BackgroundFetchFailureReason::
- SERVICE_WORKER_UNAVAILABLE;
- case BackgroundFetchReasonToAbort::QUOTA_EXCEEDED:
- return blink::mojom::BackgroundFetchFailureReason::QUOTA_EXCEEDED;
- }
- NOTREACHED();
-}
-
void BackgroundFetchJobController::Abort(
- BackgroundFetchReasonToAbort reason_to_abort) {
- reason_to_abort_ = reason_to_abort;
+ BackgroundFetchFailureReason failure_reason) {
+ failure_reason_ = failure_reason;
// Stop propagating any in-flight events to the scheduler.
active_request_finished_callback_.Reset();
@@ -184,7 +217,14 @@ void BackgroundFetchJobController::Abort(
// Cancel any in-flight downloads and UI through the BGFetchDelegate.
delegate_proxy_->Abort(registration_id().unique_id());
- Finish(reason_to_abort);
+ Finish(failure_reason_);
+}
+
+BackgroundFetchFailureReason BackgroundFetchJobController::MergeFailureReason(
+ BackgroundFetchFailureReason failure_reason) {
+ if (failure_reason_ == BackgroundFetchFailureReason::NONE)
+ failure_reason_ = failure_reason;
+ return failure_reason_;
}
} // namespace content
diff --git a/chromium/content/browser/background_fetch/background_fetch_job_controller.h b/chromium/content/browser/background_fetch/background_fetch_job_controller.h
index 7bc8b2fbf9e..ab829c87170 100644
--- a/chromium/content/browser/background_fetch/background_fetch_job_controller.h
+++ b/chromium/content/browser/background_fetch/background_fetch_job_controller.h
@@ -41,11 +41,9 @@ class CONTENT_EXPORT BackgroundFetchJobController final
public:
using FinishedCallback =
base::OnceCallback<void(const BackgroundFetchRegistrationId&,
- BackgroundFetchReasonToAbort)>;
+ blink::mojom::BackgroundFetchFailureReason)>;
using ProgressCallback =
- base::RepeatingCallback<void(const std::string& /* unique_id */,
- uint64_t /* download_total */,
- uint64_t /* downloaded */)>;
+ base::RepeatingCallback<void(const BackgroundFetchRegistration&)>;
BackgroundFetchJobController(
BackgroundFetchDelegateProxy* delegate_proxy,
@@ -66,7 +64,8 @@ class CONTENT_EXPORT BackgroundFetchJobController final
int total_downloads,
std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
active_fetch_requests,
- const std::string& ui_title);
+ const std::string& ui_title,
+ bool start_paused);
// Gets the number of bytes downloaded for jobs that are currently running.
uint64_t GetInProgressDownloadedBytes();
@@ -79,7 +78,7 @@ class CONTENT_EXPORT BackgroundFetchJobController final
// Returns a unique_ptr to a BackgroundFetchRegistration object
// created with member fields.
std::unique_ptr<BackgroundFetchRegistration> NewRegistration(
- blink::mojom::BackgroundFetchState state) const;
+ blink::mojom::BackgroundFetchResult result) const;
// Returns the options with which this job is fetching data.
const BackgroundFetchOptions& options() const { return options_; }
@@ -93,6 +92,11 @@ class CONTENT_EXPORT BackgroundFetchJobController final
// Returns the number of requests that comprise the whole job.
int total_downloads() const { return total_downloads_; }
+ // If |failure_reason_| is none, overwrites it with |failure_reason|, and
+ // returns the new value.
+ blink::mojom::BackgroundFetchFailureReason MergeFailureReason(
+ blink::mojom::BackgroundFetchFailureReason failure_reason);
+
base::WeakPtr<BackgroundFetchJobController> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
@@ -110,13 +114,24 @@ class CONTENT_EXPORT BackgroundFetchJobController final
bool HasMoreRequests() override;
void StartRequest(scoped_refptr<BackgroundFetchRequestInfo> request,
RequestFinishedCallback request_finished_callback) override;
- void Abort(BackgroundFetchReasonToAbort reason_to_abort) override;
+ std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
+ TakeOutstandingRequests() override;
+ void Abort(
+ blink::mojom::BackgroundFetchFailureReason failure_reason) override;
private:
- // Returns reason_to_abort_ as blink::mojom::BackgroundFetchFailureReason.
- // TODO(crbug.com/876691): Get rid of BackgroundFetchReasonToAbort and remove
- // this converter.
- blink::mojom::BackgroundFetchFailureReason MojoFailureReason() const;
+ // Performs mixed content checks on the |request| for Background Fetch.
+ // Background Fetch depends on Service Workers, which are restricted for use
+ // on secure origins. We can therefore assume that the registration's origin
+ // is secure. This test ensures that the origin for the url of every
+ // request is also secure.
+ bool IsMixedContent(const BackgroundFetchRequestInfo& request);
+
+ // Whether the |request| needs CORS preflight.
+ // Requests that require CORS preflights are temporarily blocked, because the
+ // browser side of Background Fetch doesn't yet support performing CORS
+ // checks. TODO(crbug.com/711354): Remove this temporary block.
+ bool RequiresCORSPreflight(const BackgroundFetchRequestInfo& request);
// Options for the represented background fetch registration.
BackgroundFetchOptions options_;
@@ -124,6 +139,10 @@ class CONTENT_EXPORT BackgroundFetchJobController final
// Icon for the represented background fetch registration.
SkBitmap icon_;
+ // The list of requests for this fetch that started in a previous session
+ // and did not finish.
+ std::vector<scoped_refptr<BackgroundFetchRequestInfo>> outstanding_requests_;
+
// Number of bytes downloaded for the active request.
uint64_t active_request_downloaded_bytes_ = 0;
@@ -151,8 +170,8 @@ class CONTENT_EXPORT BackgroundFetchJobController final
int completed_downloads_ = 0;
// The reason background fetch was aborted.
- BackgroundFetchReasonToAbort reason_to_abort_ =
- BackgroundFetchReasonToAbort::NONE;
+ blink::mojom::BackgroundFetchFailureReason failure_reason_ =
+ blink::mojom::BackgroundFetchFailureReason::NONE;
base::WeakPtrFactory<BackgroundFetchJobController> weak_ptr_factory_;
diff --git a/chromium/content/browser/background_fetch/background_fetch_job_controller_unittest.cc b/chromium/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
index b231b85f93f..259b466300b 100644
--- a/chromium/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
@@ -29,6 +29,7 @@
#include "content/public/test/fake_download_item.h"
#include "content/public/test/mock_download_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
using testing::_;
@@ -55,7 +56,7 @@ class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
const BackgroundFetchRegistrationId& registration_id) {
if (finished_requests_.count(registration_id)) {
DCHECK_NE(finished_requests_[registration_id],
- BackgroundFetchReasonToAbort::NONE);
+ blink::mojom::BackgroundFetchFailureReason::NONE);
return JobCompletionStatus::kAborted;
}
@@ -77,6 +78,20 @@ class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
pending_requests_counts_[registration_id]--;
}
+ // To be called when a request for |registration_id| has finished.
+ // Moves |request_info| to |out_request_info|.
+ void GetRequestInfoOnRequestFinished(
+ const BackgroundFetchRegistrationId& registration_id,
+ scoped_refptr<content::BackgroundFetchRequestInfo>* out_request_info,
+ scoped_refptr<content::BackgroundFetchRequestInfo> request_info) {
+ DCHECK(pending_requests_counts_.count(registration_id));
+ DCHECK(out_request_info);
+
+ EXPECT_GE(pending_requests_counts_[registration_id], 1);
+ pending_requests_counts_[registration_id]--;
+ *out_request_info = request_info;
+ }
+
// Creates a new Background Fetch registration, whose id will be stored in the
// |*registration_id|, and registers it with the DataManager for the included
// |request_data|. If |auto_complete_requests| is true, the request will
@@ -140,7 +155,8 @@ class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
base::Unretained(this)));
controller->InitializeRequestStatus(
- 0, total_downloads, {} /* outstanding_guids */, "" /* ui_title */);
+ 0, total_downloads, {} /* outstanding_guids */, "" /* ui_title */,
+ /* start_paused = */ false);
return controller;
}
@@ -179,7 +195,8 @@ class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
uint64_t last_downloaded_ = 0;
std::map<BackgroundFetchRegistrationId, int> pending_requests_counts_;
- std::map<BackgroundFetchRegistrationId, BackgroundFetchReasonToAbort>
+ std::map<BackgroundFetchRegistrationId,
+ blink::mojom::BackgroundFetchFailureReason>
finished_requests_;
// Closure that will be invoked every time the JobController receives a
@@ -190,17 +207,16 @@ class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
BackgroundFetchDelegate* delegate_;
private:
- void DidUpdateProgress(const std::string& unique_id,
- uint64_t download_total,
- uint64_t downloaded) {
- last_downloaded_ = downloaded;
+ void DidUpdateProgress(const BackgroundFetchRegistration& registration) {
+ last_downloaded_ = registration.downloaded;
if (job_progress_closure_)
job_progress_closure_.Run();
}
- void DidFinishJob(const BackgroundFetchRegistrationId& registration_id,
- BackgroundFetchReasonToAbort reason_to_abort) {
+ void DidFinishJob(
+ const BackgroundFetchRegistrationId& registration_id,
+ blink::mojom::BackgroundFetchFailureReason reason_to_abort) {
auto iter = pending_requests_counts_.find(registration_id);
DCHECK(iter != pending_requests_counts_.end());
@@ -235,6 +251,32 @@ TEST_F(BackgroundFetchJobControllerTest, SingleRequestJob) {
GetCompletionStatus(registration_id));
}
+TEST_F(BackgroundFetchJobControllerTest, SingleRequestJobWithInsecureOrigin) {
+ BackgroundFetchRegistrationId registration_id;
+
+ auto requests = CreateRegistrationForRequests(
+ &registration_id, {{GURL("http://example.com/funny_cat.png"), "GET"}},
+ true /* auto_complete_requests */);
+
+ EXPECT_EQ(JobCompletionStatus::kRunning,
+ GetCompletionStatus(registration_id));
+
+ std::unique_ptr<BackgroundFetchJobController> controller =
+ CreateJobController(registration_id, requests.size());
+
+ controller->StartRequest(
+ requests[0],
+ base::BindOnce(
+ &BackgroundFetchJobControllerTest::GetRequestInfoOnRequestFinished,
+ base::Unretained(this), registration_id, &requests[0]));
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(JobCompletionStatus::kCompleted,
+ GetCompletionStatus(registration_id));
+ EXPECT_FALSE(requests[0]->IsResultSuccess());
+}
+
TEST_F(BackgroundFetchJobControllerTest, MultipleRequestJob) {
BackgroundFetchRegistrationId registration_id;
@@ -282,6 +324,46 @@ TEST_F(BackgroundFetchJobControllerTest, MultipleRequestJob) {
GetCompletionStatus(registration_id));
}
+TEST_F(BackgroundFetchJobControllerTest, MultipleRequestsJobWithMixedContent) {
+ BackgroundFetchRegistrationId registration_id;
+
+ auto requests = CreateRegistrationForRequests(
+ &registration_id,
+ {{GURL("http://example.com/funny_cat.png"), "GET"},
+ {GURL("https://example.com/scary_cat.png"), "GET"}},
+ true /* auto_complete_requests */);
+
+ EXPECT_EQ(JobCompletionStatus::kRunning,
+ GetCompletionStatus(registration_id));
+
+ std::unique_ptr<BackgroundFetchJobController> controller =
+ CreateJobController(registration_id, requests.size());
+
+ controller->StartRequest(
+ requests[0],
+ base::BindOnce(
+ &BackgroundFetchJobControllerTest::GetRequestInfoOnRequestFinished,
+ base::Unretained(this), registration_id, &requests[0]));
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(JobCompletionStatus::kRunning,
+ GetCompletionStatus(registration_id));
+ EXPECT_FALSE(requests[0]->IsResultSuccess());
+
+ controller->StartRequest(
+ requests[1],
+ base::BindOnce(
+ &BackgroundFetchJobControllerTest::GetRequestInfoOnRequestFinished,
+ base::Unretained(this), registration_id, &requests[1]));
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(JobCompletionStatus::kCompleted,
+ GetCompletionStatus(registration_id));
+ EXPECT_TRUE(requests[1]->IsResultSuccess());
+}
+
TEST_F(BackgroundFetchJobControllerTest, Abort) {
BackgroundFetchRegistrationId registration_id;
@@ -300,7 +382,8 @@ TEST_F(BackgroundFetchJobControllerTest, Abort) {
base::BindOnce(&BackgroundFetchJobControllerTest::OnRequestFinished,
base::Unretained(this), registration_id));
- controller->Abort(BackgroundFetchReasonToAbort::CANCELLED_FROM_UI);
+ controller->Abort(
+ blink::mojom::BackgroundFetchFailureReason::CANCELLED_FROM_UI);
base::RunLoop().RunUntilIdle();
diff --git a/chromium/content/browser/background_fetch/background_fetch_metrics.cc b/chromium/content/browser/background_fetch/background_fetch_metrics.cc
index ec5979b21d1..430b46f0486 100644
--- a/chromium/content/browser/background_fetch/background_fetch_metrics.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_metrics.cc
@@ -5,11 +5,20 @@
#include "content/browser/background_fetch/background_fetch_metrics.h"
#include "base/metrics/histogram_macros.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
+#include "services/metrics/public/cpp/metrics_utils.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
namespace content {
namespace background_fetch {
+// Exponential bucket spacing for UKM event data.
+const double kUkmEventDataBucketSpacing = 2.0;
+
void RecordSchedulerFinishedError(blink::mojom::BackgroundFetchError error) {
UMA_HISTOGRAM_ENUMERATION("BackgroundFetch.SchedulerFinishedError", error);
}
@@ -22,6 +31,47 @@ void RecordRegistrationDeletedError(blink::mojom::BackgroundFetchError error) {
UMA_HISTOGRAM_ENUMERATION("BackgroundFetch.RegistrationDeletedError", error);
}
+void RecordRegistrationsOnStartup(int num_registrations) {
+ UMA_HISTOGRAM_COUNTS_100("BackgroundFetch.IncompleteFetchesOnStartup",
+ num_registrations);
+}
+
+void RecordBackgroundFetchUkmEvent(
+ const url::Origin& origin,
+ const std::vector<ServiceWorkerFetchRequest>& requests,
+ const BackgroundFetchOptions& options,
+ const SkBitmap& icon,
+ blink::mojom::BackgroundFetchUkmDataPtr ukm_data,
+ int frame_tree_node_id,
+ BackgroundFetchPermission permission) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // Only record UKM data if there's a frame associated.
+ auto* web_contents = WebContents::FromFrameTreeNodeId(frame_tree_node_id);
+ if (!web_contents)
+ return;
+
+ // Only record UKM data if the origin of the page currently being displayed
+ // is the same as the one the background fetch was started with.
+ auto displayed_origin = web_contents->GetLastCommittedURL().GetOrigin();
+ if (!origin.IsSameOriginWith(url::Origin::Create(displayed_origin)))
+ return;
+ ukm::SourceId source_id = static_cast<WebContentsImpl*>(web_contents)
+ ->GetUkmSourceIdForLastCommittedSource();
+
+ ukm::builders::BackgroundFetch(source_id)
+ .SetHasTitle(!options.title.empty())
+ .SetNumIcons(options.icons.size())
+ .SetRatioOfIdealToChosenIconSize(ukm_data->ideal_to_chosen_icon_size)
+ .SetDownloadTotal(ukm::GetExponentialBucketMin(
+ options.download_total, kUkmEventDataBucketSpacing))
+ .SetNumRequestsInFetch(ukm::GetExponentialBucketMin(
+ requests.size(), kUkmEventDataBucketSpacing))
+ .SetDeniedDueToPermissions(permission ==
+ BackgroundFetchPermission::BLOCKED)
+ .Record(ukm::UkmRecorder::Get());
+}
+
} // namespace background_fetch
} // namespace content
diff --git a/chromium/content/browser/background_fetch/background_fetch_metrics.h b/chromium/content/browser/background_fetch/background_fetch_metrics.h
index 977b33bc687..27f65916507 100644
--- a/chromium/content/browser/background_fetch/background_fetch_metrics.h
+++ b/chromium/content/browser/background_fetch/background_fetch_metrics.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_METRICS_H_
#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_METRICS_H_
+#include "content/public/browser/background_fetch_delegate.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
namespace content {
@@ -24,6 +25,22 @@ void RecordRegistrationCreatedError(blink::mojom::BackgroundFetchError error);
// associated with a registration has been completely deleted.
void RecordRegistrationDeletedError(blink::mojom::BackgroundFetchError error);
+// Records the number of registrations that have unfinished fetches found on
+// start-up.
+void RecordRegistrationsOnStartup(int num_registrations);
+
+// Records the BackgroundFetch UKM event. Must be called before a Background
+// Fetch registration has been created. Will be a no-op if |frame_tree_node_id|
+// does not identify a valid, live frame.
+void RecordBackgroundFetchUkmEvent(
+ const url::Origin& origin,
+ const std::vector<ServiceWorkerFetchRequest>& requests,
+ const BackgroundFetchOptions& options,
+ const SkBitmap& icon,
+ blink::mojom::BackgroundFetchUkmDataPtr ukm_data,
+ int frame_tree_node_id,
+ BackgroundFetchPermission permission);
+
} // namespace background_fetch
} // namespace content
diff --git a/chromium/content/browser/background_fetch/background_fetch_registration_notifier.cc b/chromium/content/browser/background_fetch/background_fetch_registration_notifier.cc
index 4590bb371e7..e5dfc98ca08 100644
--- a/chromium/content/browser/background_fetch/background_fetch_registration_notifier.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_registration_notifier.cc
@@ -5,7 +5,6 @@
#include "content/browser/background_fetch/background_fetch_registration_notifier.h"
#include "base/bind.h"
-#include "base/stl_util.h"
namespace content {
@@ -29,24 +28,30 @@ void BackgroundFetchRegistrationNotifier::AddObserver(
observers_.emplace(unique_id, std::move(observer));
}
-void BackgroundFetchRegistrationNotifier::Notify(const std::string& unique_id,
- uint64_t download_total,
- uint64_t downloaded) {
- auto range = observers_.equal_range(unique_id);
+void BackgroundFetchRegistrationNotifier::Notify(
+ const BackgroundFetchRegistration& registration) {
+ auto range = observers_.equal_range(registration.unique_id);
for (auto it = range.first; it != range.second; ++it) {
// TODO(crbug.com/774054): Uploads are not yet supported.
it->second->OnProgress(0 /* upload_total */, 0 /* uploaded */,
- download_total, downloaded);
+ registration.download_total, registration.downloaded,
+ registration.result, registration.failure_reason);
}
}
-void BackgroundFetchRegistrationNotifier::AddGarbageCollectionCallback(
- const std::string& unique_id,
- base::OnceClosure callback) {
- if (!observers_.count(unique_id))
- std::move(callback).Run();
- else
- garbage_collection_callbacks_.emplace(unique_id, std::move(callback));
+void BackgroundFetchRegistrationNotifier::NotifyRecordsUnavailable(
+ const std::string& unique_id) {
+ for (auto it = observers_.begin(); it != observers_.end();) {
+ if (it->first != unique_id) {
+ it++;
+ continue;
+ }
+
+ it->second->OnRecordsUnavailable();
+
+ // No more notifications will be sent to the observers from this point.
+ it = observers_.erase(it);
+ }
}
void BackgroundFetchRegistrationNotifier::OnConnectionError(
@@ -57,13 +62,6 @@ void BackgroundFetchRegistrationNotifier::OnConnectionError(
[observer](const auto& unique_id_observer_ptr_pair) {
return unique_id_observer_ptr_pair.second.get() == observer;
});
-
- auto callback_iter = garbage_collection_callbacks_.find(unique_id);
- if (callback_iter != garbage_collection_callbacks_.end() &&
- !observers_.count(unique_id)) {
- std::move(callback_iter->second).Run();
- garbage_collection_callbacks_.erase(callback_iter);
- }
}
} // namespace content
diff --git a/chromium/content/browser/background_fetch/background_fetch_registration_notifier.h b/chromium/content/browser/background_fetch/background_fetch_registration_notifier.h
index 80abea1ece9..0632473515f 100644
--- a/chromium/content/browser/background_fetch/background_fetch_registration_notifier.h
+++ b/chromium/content/browser/background_fetch/background_fetch_registration_notifier.h
@@ -30,18 +30,14 @@ class CONTENT_EXPORT BackgroundFetchRegistrationNotifier {
const std::string& unique_id,
blink::mojom::BackgroundFetchRegistrationObserverPtr observer);
- // Notifies any registered observers for the registration identified by the
- // |unique_id| of the progress. This will cause JavaScript events to fire.
- // Successful fetches must also call Notify with the final state.
- void Notify(const std::string& unique_id,
- uint64_t download_total,
- uint64_t downloaded);
+ // Notifies any registered observers for the |registration| of the progress.
+ // This will cause JavaScript events to fire.
+ // Completed fetches must also call Notify with the final state.
+ void Notify(const BackgroundFetchRegistration& registration);
- // Runs |callback| when the last observer for |unique_id| is removed, or
- // immediately if there are already no observers. Callback will never be run
- // if the browser is shutdown before the last observer is removed.
- void AddGarbageCollectionCallback(const std::string& unique_id,
- base::OnceClosure callback);
+ // Notifies any registered observers for the registration identifier by
+ // |unique_id| that the records for the fetch are no longer available.
+ void NotifyRecordsUnavailable(const std::string& unique_id);
base::WeakPtr<BackgroundFetchRegistrationNotifier> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
@@ -59,10 +55,6 @@ class CONTENT_EXPORT BackgroundFetchRegistrationNotifier {
blink::mojom::BackgroundFetchRegistrationObserverPtr>
observers_;
- // Map from registration |unique_id| to callback to run when last observer is
- // removed.
- std::map<std::string, base::OnceClosure> garbage_collection_callbacks_;
-
base::WeakPtrFactory<BackgroundFetchRegistrationNotifier> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchRegistrationNotifier);
diff --git a/chromium/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc b/chromium/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc
index 9be34593da1..cd9eee1f13c 100644
--- a/chromium/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_registration_notifier_unittest.cc
@@ -19,6 +19,7 @@
namespace content {
namespace {
+const char kDeveloperId[] = "my-fetch";
const char kPrimaryUniqueId[] = "7e57ab1e-c0de-a150-ca75-1e75f005ba11";
const char kSecondaryUniqueId[] = "bb48a9fb-c21f-4c2d-a9ae-58bd48a9fb53";
@@ -32,16 +33,24 @@ class TestRegistrationObserver
ProgressUpdate(uint64_t upload_total,
uint64_t uploaded,
uint64_t download_total,
- uint64_t downloaded)
+ uint64_t downloaded,
+ blink::mojom::BackgroundFetchResult result,
+ blink::mojom::BackgroundFetchFailureReason failure_reason)
: upload_total(upload_total),
uploaded(uploaded),
download_total(download_total),
- downloaded(downloaded) {}
+ downloaded(downloaded),
+ result(result),
+ failure_reason(failure_reason) {}
uint64_t upload_total = 0;
uint64_t uploaded = 0;
uint64_t download_total = 0;
uint64_t downloaded = 0;
+ blink::mojom::BackgroundFetchResult result =
+ blink::mojom::BackgroundFetchResult::UNSET;
+ blink::mojom::BackgroundFetchFailureReason failure_reason =
+ blink::mojom::BackgroundFetchFailureReason::NONE;
};
TestRegistrationObserver() : binding_(this) {}
@@ -62,18 +71,26 @@ class TestRegistrationObserver
return progress_updates_;
}
+ bool records_available() const { return records_available_; }
+
// blink::mojom::BackgroundFetchRegistrationObserver implementation.
- void OnProgress(uint64_t upload_total,
- uint64_t uploaded,
- uint64_t download_total,
- uint64_t downloaded) override {
+ void OnProgress(
+ uint64_t upload_total,
+ uint64_t uploaded,
+ uint64_t download_total,
+ uint64_t downloaded,
+ blink::mojom::BackgroundFetchResult result,
+ blink::mojom::BackgroundFetchFailureReason failure_reason) override {
progress_updates_.emplace_back(upload_total, uploaded, download_total,
- downloaded);
+ downloaded, result, failure_reason);
}
+ void OnRecordsUnavailable() override { records_available_ = false; }
+
private:
std::vector<ProgressUpdate> progress_updates_;
mojo::Binding<blink::mojom::BackgroundFetchRegistrationObserver> binding_;
+ bool records_available_ = true;
DISALLOW_COPY_AND_ASSIGN(TestRegistrationObserver);
};
@@ -89,14 +106,15 @@ class BackgroundFetchRegistrationNotifierTest : public ::testing::Test {
// Notifies all observers for the |unique_id| of the made progress, and waits
// until the task runner managing the Mojo connection has finished.
- void Notify(const std::string& unique_id,
- uint64_t download_total,
- uint64_t downloaded) {
- notifier_->Notify(unique_id, download_total, downloaded);
+ void Notify(const BackgroundFetchRegistration& registration) {
+ notifier_->Notify(registration);
task_runner_->RunUntilIdle();
}
- void CollectGarbage() { garbage_collected_ = true; }
+ void NotifyRecordsUnavailable(const std::string& unique_id) {
+ notifier_->NotifyRecordsUnavailable(unique_id);
+ task_runner_->RunUntilIdle();
+ }
protected:
scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
@@ -104,8 +122,6 @@ class BackgroundFetchRegistrationNotifierTest : public ::testing::Test {
std::unique_ptr<BackgroundFetchRegistrationNotifier> notifier_;
- bool garbage_collected_ = false;
-
private:
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchRegistrationNotifierTest);
};
@@ -116,7 +132,11 @@ TEST_F(BackgroundFetchRegistrationNotifierTest, NotifySingleObserver) {
notifier_->AddObserver(kPrimaryUniqueId, observer->GetPtr());
ASSERT_EQ(observer->progress_updates().size(), 0u);
- Notify(kPrimaryUniqueId, kDownloadTotal, kDownloaded);
+ Notify(BackgroundFetchRegistration(
+ kDeveloperId, kPrimaryUniqueId,
+ /* upload_total*/ 0, /* uploaded*/ 0, kDownloadTotal, kDownloaded,
+ blink::mojom::BackgroundFetchResult::UNSET,
+ blink::mojom::BackgroundFetchFailureReason::NONE));
ASSERT_EQ(observer->progress_updates().size(), 1u);
@@ -126,6 +146,9 @@ TEST_F(BackgroundFetchRegistrationNotifierTest, NotifySingleObserver) {
EXPECT_EQ(update.uploaded, 0u);
EXPECT_EQ(update.download_total, kDownloadTotal);
EXPECT_EQ(update.downloaded, kDownloaded);
+ EXPECT_EQ(update.result, blink::mojom::BackgroundFetchResult::UNSET);
+ EXPECT_EQ(update.failure_reason,
+ blink::mojom::BackgroundFetchFailureReason::NONE);
}
TEST_F(BackgroundFetchRegistrationNotifierTest, NotifyMultipleObservers) {
@@ -145,7 +168,11 @@ TEST_F(BackgroundFetchRegistrationNotifierTest, NotifyMultipleObservers) {
ASSERT_EQ(secondary_observer->progress_updates().size(), 0u);
// Notify the |kPrimaryUniqueId|.
- Notify(kPrimaryUniqueId, kDownloadTotal, kDownloaded);
+ Notify(BackgroundFetchRegistration(
+ kDeveloperId, kPrimaryUniqueId,
+ /* upload_total*/ 0, /* uploaded*/ 0, kDownloadTotal, kDownloaded,
+ blink::mojom::BackgroundFetchResult::UNSET,
+ blink::mojom::BackgroundFetchFailureReason::NONE));
for (auto& observer : primary_observers) {
ASSERT_EQ(observer->progress_updates().size(), 1u);
@@ -156,6 +183,9 @@ TEST_F(BackgroundFetchRegistrationNotifierTest, NotifyMultipleObservers) {
EXPECT_EQ(update.uploaded, 0u);
EXPECT_EQ(update.download_total, kDownloadTotal);
EXPECT_EQ(update.downloaded, kDownloaded);
+ EXPECT_EQ(update.result, blink::mojom::BackgroundFetchResult::UNSET);
+ EXPECT_EQ(update.failure_reason,
+ blink::mojom::BackgroundFetchFailureReason::NONE);
}
// The observer for |kSecondaryUniqueId| should not have been notified.
@@ -169,14 +199,22 @@ TEST_F(BackgroundFetchRegistrationNotifierTest,
notifier_->AddObserver(kPrimaryUniqueId, observer->GetPtr());
ASSERT_EQ(observer->progress_updates().size(), 0u);
- Notify(kPrimaryUniqueId, kDownloadTotal, kDownloaded);
+ Notify(BackgroundFetchRegistration(
+ kDeveloperId, kPrimaryUniqueId,
+ /* upload_total*/ 0, /* uploaded*/ 0, kDownloadTotal, kDownloaded,
+ blink::mojom::BackgroundFetchResult::UNSET,
+ blink::mojom::BackgroundFetchFailureReason::NONE));
ASSERT_EQ(observer->progress_updates().size(), 1u);
// Closes the binding as would be done from the renderer process.
observer->Close();
- Notify(kPrimaryUniqueId, kDownloadTotal, kDownloaded);
+ Notify(BackgroundFetchRegistration(
+ kDeveloperId, kPrimaryUniqueId,
+ /* upload_total*/ 0, /* uploaded*/ 0, kDownloadTotal, kDownloaded,
+ blink::mojom::BackgroundFetchResult::UNSET,
+ blink::mojom::BackgroundFetchFailureReason::NONE));
// The observers for |kPrimaryUniqueId| were removed, so no second update
// should have been received by the |observer|.
@@ -189,44 +227,25 @@ TEST_F(BackgroundFetchRegistrationNotifierTest, NotifyWithoutObservers) {
notifier_->AddObserver(kPrimaryUniqueId, observer->GetPtr());
ASSERT_EQ(observer->progress_updates().size(), 0u);
- Notify(kSecondaryUniqueId, kDownloadTotal, kDownloaded);
+ Notify(BackgroundFetchRegistration(
+ kDeveloperId, kSecondaryUniqueId,
+ /* upload_total*/ 0, /* uploaded*/ 0, kDownloadTotal, kDownloaded,
+ blink::mojom::BackgroundFetchResult::UNSET,
+ blink::mojom::BackgroundFetchFailureReason::NONE));
// Because the notification was for |kSecondaryUniqueId|, no progress updates
// should be received by the |observer|.
EXPECT_EQ(observer->progress_updates().size(), 0u);
}
-TEST_F(BackgroundFetchRegistrationNotifierTest,
- AddGarbageCollectionCallback_NoObservers) {
- notifier_->AddGarbageCollectionCallback(
- kPrimaryUniqueId,
- base::BindOnce(&BackgroundFetchRegistrationNotifierTest::CollectGarbage,
- base::Unretained(this)));
-
- ASSERT_TRUE(garbage_collected_)
- << "Garbage should be collected when there are no observers";
-}
-
-TEST_F(BackgroundFetchRegistrationNotifierTest,
- AddGarbageCollectionCallback_OneObserver) {
+TEST_F(BackgroundFetchRegistrationNotifierTest, NotifyRecordsUnavailable) {
auto observer = std::make_unique<TestRegistrationObserver>();
- auto foo = observer->GetPtr();
- notifier_->AddObserver(kPrimaryUniqueId, std::move(foo));
- notifier_->AddGarbageCollectionCallback(
- kPrimaryUniqueId,
- base::BindOnce(&BackgroundFetchRegistrationNotifierTest::CollectGarbage,
- base::Unretained(this)));
-
- ASSERT_FALSE(garbage_collected_)
- << "Garbage should not be collected when there is an observer";
-
- observer->Close();
+ notifier_->AddObserver(kPrimaryUniqueId, observer->GetPtr());
+ ASSERT_TRUE(observer->records_available());
- // TODO(crbug.com/777764): Add this back when non-exceptional binding closures
- // are detected properly.
- // ASSERT_TRUE(garbage_collected_) << "Garbage should be collected when the
- // "observer is closed.";
+ NotifyRecordsUnavailable(kPrimaryUniqueId);
+ ASSERT_FALSE(observer->records_available());
}
} // namespace
diff --git a/chromium/content/browser/background_fetch/background_fetch_request_info.cc b/chromium/content/browser/background_fetch/background_fetch_request_info.cc
index e13df709f2f..d2103e65700 100644
--- a/chromium/content/browser/background_fetch/background_fetch_request_info.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_request_info.cc
@@ -42,9 +42,27 @@ void BackgroundFetchRequestInfo::SetDownloadGuid(
download_guid_ = download_guid;
}
+void BackgroundFetchRequestInfo::SetResult(
+ std::unique_ptr<BackgroundFetchResult> result) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(result);
+
+ result_ = std::move(result);
+ PopulateWithResponse(std::move(result_->response));
+}
+
+void BackgroundFetchRequestInfo::SetEmptyResultWithFailureReason(
+ BackgroundFetchResult::FailureReason failure_reason) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ result_ = std::make_unique<BackgroundFetchResult>(
+ nullptr /* response */, base::Time::Now(), failure_reason);
+}
+
void BackgroundFetchRequestInfo::PopulateWithResponse(
std::unique_ptr<BackgroundFetchResponse> response) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(response);
url_chain_ = response->url_chain;
@@ -63,13 +81,6 @@ void BackgroundFetchRequestInfo::PopulateWithResponse(
response_headers_[base::ToLowerASCII(name)] = value;
}
-void BackgroundFetchRequestInfo::SetResult(
- std::unique_ptr<BackgroundFetchResult> result) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- result_ = std::move(result);
-}
-
int BackgroundFetchRequestInfo::GetResponseCode() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return response_code_;
diff --git a/chromium/content/browser/background_fetch/background_fetch_request_info.h b/chromium/content/browser/background_fetch/background_fetch_request_info.h
index 1a796748e4e..3b359aa5d7b 100644
--- a/chromium/content/browser/background_fetch/background_fetch_request_info.h
+++ b/chromium/content/browser/background_fetch/background_fetch_request_info.h
@@ -20,6 +20,7 @@
#include "content/browser/background_fetch/background_fetch_constants.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/browser/background_fetch_response.h"
#include "url/gurl.h"
namespace storage {
@@ -48,11 +49,13 @@ class CONTENT_EXPORT BackgroundFetchRequestInfo
// retrieved from storage). Can only be used if no GUID is already set.
void SetDownloadGuid(const std::string& download_guid);
- // Populates the cached state for the in-progress download.
- void PopulateWithResponse(std::unique_ptr<BackgroundFetchResponse> response);
-
void SetResult(std::unique_ptr<BackgroundFetchResult> result);
+ // Creates an empty result, with no response, and assigns |failure_reason|
+ // as its failure_reason.
+ void SetEmptyResultWithFailureReason(
+ BackgroundFetchResult::FailureReason failure_reason);
+
// Returns the index of this request within a Background Fetch registration.
int request_index() const { return request_index_; }
@@ -101,6 +104,9 @@ class CONTENT_EXPORT BackgroundFetchRequestInfo
friend class base::DeleteHelper<BackgroundFetchRequestInfo>;
friend class BackgroundFetchCrossOriginFilterTest;
+ // Extracts the headers and the status code.
+ void PopulateWithResponse(std::unique_ptr<BackgroundFetchResponse> response);
+
~BackgroundFetchRequestInfo();
// ---- Data associated with the request -------------------------------------
diff --git a/chromium/content/browser/background_fetch/background_fetch_scheduler.cc b/chromium/content/browser/background_fetch/background_fetch_scheduler.cc
index 4fe7cf3fbaf..6038067c002 100644
--- a/chromium/content/browser/background_fetch/background_fetch_scheduler.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_scheduler.cc
@@ -23,16 +23,18 @@ BackgroundFetchScheduler::Controller::Controller(
BackgroundFetchScheduler::Controller::~Controller() = default;
void BackgroundFetchScheduler::Controller::Finish(
- BackgroundFetchReasonToAbort reason_to_abort) {
- DCHECK(reason_to_abort != BackgroundFetchReasonToAbort::NONE ||
+ blink::mojom::BackgroundFetchFailureReason reason_to_abort) {
+ DCHECK(reason_to_abort != blink::mojom::BackgroundFetchFailureReason::NONE ||
!HasMoreRequests());
scheduler_->RemoveJobController(this);
// Developer-initiated abortions will have already marked the registration for
// deletion, so make sure that we don't execute the same code-path twice.
- if (reason_to_abort == BackgroundFetchReasonToAbort::ABORTED_BY_DEVELOPER)
+ if (reason_to_abort ==
+ blink::mojom::BackgroundFetchFailureReason::CANCELLED_BY_DEVELOPER) {
return;
+ }
// Race conditions make it possible for a controller to finish twice. This
// should be removed when the scheduler starts owning the controllers.
@@ -50,9 +52,26 @@ BackgroundFetchScheduler::~BackgroundFetchScheduler() = default;
void BackgroundFetchScheduler::AddJobController(Controller* controller) {
DCHECK(controller);
-
controller_queue_.push_back(controller);
+ std::vector<scoped_refptr<content::BackgroundFetchRequestInfo>>
+ outstanding_requests = controller->TakeOutstandingRequests();
+ // There are active downloads from the previous session.
+ if (!outstanding_requests.empty()) {
+ // The current assumption is that there can be at most one active fetch
+ // at any given time.
+ DCHECK(!active_controller_);
+ DCHECK_EQ(outstanding_requests.size(), 1u);
+
+ active_controller_ = controller;
+ for (auto& request_info : outstanding_requests) {
+ active_controller_->StartRequest(
+ std::move(request_info),
+ base::BindOnce(&BackgroundFetchScheduler::MarkRequestAsComplete,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+ }
+
if (!active_controller_)
ScheduleDownload();
}
@@ -88,6 +107,7 @@ void BackgroundFetchScheduler::ScheduleDownload() {
}
void BackgroundFetchScheduler::DidPopNextRequest(
+ blink::mojom::BackgroundFetchError error,
scoped_refptr<BackgroundFetchRequestInfo> request_info) {
// It's possible for the |active_controller_| to have been aborted while the
// next request was being retrieved. Bail out when that happens.
@@ -96,16 +116,13 @@ void BackgroundFetchScheduler::DidPopNextRequest(
return;
}
- // There might've been a storage error when |request_info| could not be loaded
- // from the database. Bail out in this case as well.
- if (!request_info) {
- // TODO(peter): Should we abort the |active_controller_| in this case?
- active_controller_ = nullptr;
-
- ScheduleDownload();
+ if (error != blink::mojom::BackgroundFetchError::NONE) {
+ // This fetch is being abandoned, after which something will be scheduled.
return;
}
+ DCHECK(request_info);
+
// Otherwise start the |request_info| through the live Job Controller.
active_controller_->StartRequest(
std::move(request_info),
@@ -126,12 +143,19 @@ void BackgroundFetchScheduler::MarkRequestAsComplete(
weak_ptr_factory_.GetWeakPtr()));
}
-void BackgroundFetchScheduler::DidMarkRequestAsComplete() {
+void BackgroundFetchScheduler::DidMarkRequestAsComplete(
+ blink::mojom::BackgroundFetchError error) {
// It's possible for the |active_controller_| to have been aborted while the
// request was being marked as completed. Bail out in that case.
if (!active_controller_)
return;
+ if (error != blink::mojom::BackgroundFetchError::NONE) {
+ // This fetch is being abandoned, after which something will be scheduled.
+ DCHECK_EQ(error, blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ }
+
// Continue with the |active_controller_| while there are files pending.
if (active_controller_->HasMoreRequests()) {
request_provider_->PopNextRequest(
@@ -141,7 +165,7 @@ void BackgroundFetchScheduler::DidMarkRequestAsComplete() {
return;
}
- active_controller_->Finish(BackgroundFetchReasonToAbort::NONE);
+ active_controller_->Finish(blink::mojom::BackgroundFetchFailureReason::NONE);
}
} // namespace content
diff --git a/chromium/content/browser/background_fetch/background_fetch_scheduler.h b/chromium/content/browser/background_fetch/background_fetch_scheduler.h
index 449ea6699f8..314f2184ec5 100644
--- a/chromium/content/browser/background_fetch/background_fetch_scheduler.h
+++ b/chromium/content/browser/background_fetch/background_fetch_scheduler.h
@@ -16,12 +16,12 @@
#include "base/memory/weak_ptr.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/common/content_export.h"
+#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
namespace content {
class BackgroundFetchRegistrationId;
class BackgroundFetchRequestInfo;
-enum class BackgroundFetchReasonToAbort;
// Maintains a list of Controllers and chooses which ones should launch new
// downloads.
@@ -29,7 +29,7 @@ class CONTENT_EXPORT BackgroundFetchScheduler {
public:
using FinishedCallback =
base::OnceCallback<void(const BackgroundFetchRegistrationId&,
- BackgroundFetchReasonToAbort)>;
+ blink::mojom::BackgroundFetchFailureReason)>;
// Interface for download job controllers.
class CONTENT_EXPORT Controller {
@@ -46,7 +46,12 @@ class CONTENT_EXPORT BackgroundFetchScheduler {
virtual void StartRequest(scoped_refptr<BackgroundFetchRequestInfo> request,
RequestFinishedCallback callback) = 0;
- void Finish(BackgroundFetchReasonToAbort reason_to_abort);
+ // Returns a list of requests that started in a previous session and did not
+ // complete. Clears the list of outstanding GUIDs in the controller.
+ virtual std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
+ TakeOutstandingRequests() = 0;
+
+ void Finish(blink::mojom::BackgroundFetchFailureReason reason_to_abort);
const BackgroundFetchRegistrationId& registration_id() const {
return registration_id_;
@@ -66,8 +71,11 @@ class CONTENT_EXPORT BackgroundFetchScheduler {
FinishedCallback finished_callback_;
};
+ using MarkRequestCompleteCallback =
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError)>;
using NextRequestCallback =
- base::OnceCallback<void(scoped_refptr<BackgroundFetchRequestInfo>)>;
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError,
+ scoped_refptr<BackgroundFetchRequestInfo>)>;
class CONTENT_EXPORT RequestProvider {
public:
@@ -83,7 +91,7 @@ class CONTENT_EXPORT BackgroundFetchScheduler {
virtual void MarkRequestAsComplete(
const BackgroundFetchRegistrationId& registration_id,
scoped_refptr<BackgroundFetchRequestInfo> request_info,
- base::OnceClosure closure) = 0;
+ MarkRequestCompleteCallback callback) = 0;
};
explicit BackgroundFetchScheduler(RequestProvider* request_provider);
@@ -101,11 +109,12 @@ class CONTENT_EXPORT BackgroundFetchScheduler {
void ScheduleDownload();
void DidPopNextRequest(
+ blink::mojom::BackgroundFetchError error,
scoped_refptr<BackgroundFetchRequestInfo> request_info);
void MarkRequestAsComplete(
scoped_refptr<BackgroundFetchRequestInfo> request_info);
- void DidMarkRequestAsComplete();
+ void DidMarkRequestAsComplete(blink::mojom::BackgroundFetchError error);
RequestProvider* request_provider_;
diff --git a/chromium/content/browser/background_fetch/background_fetch_scheduler_unittest.cc b/chromium/content/browser/background_fetch/background_fetch_scheduler_unittest.cc
index 156d262cdaf..ad18e4d5e4d 100644
--- a/chromium/content/browser/background_fetch/background_fetch_scheduler_unittest.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_scheduler_unittest.cc
@@ -8,8 +8,10 @@
#include "base/guid.h"
#include "base/strings/string_number_conversions.h"
+#include "base/task/post_task.h"
#include "content/browser/background_fetch/background_fetch_request_info.h"
#include "content/browser/background_fetch/background_fetch_test_base.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -49,11 +51,16 @@ class FakeController : public BackgroundFetchScheduler::Controller {
controller_sequence_list_->push_back(name_ +
base::IntToString(jobs_started_));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), std::move(request)));
}
+ std::vector<scoped_refptr<BackgroundFetchRequestInfo>>
+ TakeOutstandingRequests() override {
+ return {};
+ }
+
private:
int jobs_started_ = 0;
std::vector<std::string>* controller_sequence_list_;
@@ -76,8 +83,8 @@ class BackgroundFetchSchedulerTest
return;
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&BackgroundFetchSchedulerTest::PostQuitAfterRepeatingBarriers,
base::Unretained(this), std::move(quit_closure),
@@ -94,14 +101,15 @@ class BackgroundFetchSchedulerTest
0 /* request_count */, fetch_request);
request->InitializeDownloadGuid();
- std::move(callback).Run(std::move(request));
+ std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE,
+ std::move(request));
}
void MarkRequestAsComplete(
const BackgroundFetchRegistrationId& registration_id,
scoped_refptr<BackgroundFetchRequestInfo> request_info,
- base::OnceClosure closure) override {
- std::move(closure).Run();
+ BackgroundFetchScheduler::MarkRequestCompleteCallback closure) override {
+ std::move(closure).Run(blink::mojom::BackgroundFetchError::NONE);
}
protected:
diff --git a/chromium/content/browser/background_fetch/background_fetch_service_impl.cc b/chromium/content/browser/background_fetch/background_fetch_service_impl.cc
index f116ff5aad3..edfea31c08a 100644
--- a/chromium/content/browser/background_fetch/background_fetch_service_impl.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_service_impl.cc
@@ -8,6 +8,7 @@
#include "base/guid.h"
#include "base/optional.h"
+#include "base/task/post_task.h"
#include "content/browser/background_fetch/background_fetch_context.h"
#include "content/browser/background_fetch/background_fetch_metrics.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
@@ -15,6 +16,7 @@
#include "content/browser/bad_message.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
@@ -38,8 +40,8 @@ void BackgroundFetchServiceImpl::CreateForWorker(
const url::Origin& origin) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
BackgroundFetchServiceImpl::CreateOnIoThread,
WrapRefCounted(static_cast<StoragePartitionImpl*>(
@@ -60,8 +62,8 @@ void BackgroundFetchServiceImpl::CreateForFrame(
RenderFrameHost::FromID(render_process_host->GetID(), render_frame_id);
DCHECK(render_frame_host);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
BackgroundFetchServiceImpl::CreateOnIoThread,
WrapRefCounted(static_cast<StoragePartitionImpl*>(
@@ -105,6 +107,7 @@ void BackgroundFetchServiceImpl::Fetch(
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
+ blink::mojom::BackgroundFetchUkmDataPtr ukm_data,
FetchCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!ValidateDeveloperId(developer_id) || !ValidateRequests(requests)) {
@@ -122,9 +125,9 @@ void BackgroundFetchServiceImpl::Fetch(
origin_, developer_id,
base::GenerateGUID());
- background_fetch_context_->StartFetch(registration_id, requests, options,
- icon, render_frame_host_,
- std::move(callback));
+ background_fetch_context_->StartFetch(
+ registration_id, requests, options, icon, std::move(ukm_data),
+ render_frame_host_, std::move(callback));
}
void BackgroundFetchServiceImpl::GetIconDisplaySize(
diff --git a/chromium/content/browser/background_fetch/background_fetch_service_impl.h b/chromium/content/browser/background_fetch/background_fetch_service_impl.h
index 5abcc9b3b18..68f68503b06 100644
--- a/chromium/content/browser/background_fetch/background_fetch_service_impl.h
+++ b/chromium/content/browser/background_fetch/background_fetch_service_impl.h
@@ -50,6 +50,7 @@ class CONTENT_EXPORT BackgroundFetchServiceImpl
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
+ blink::mojom::BackgroundFetchUkmDataPtr ukm_data,
FetchCallback callback) override;
void GetIconDisplaySize(GetIconDisplaySizeCallback callback) override;
void MatchRequests(
diff --git a/chromium/content/browser/background_fetch/background_fetch_service_unittest.cc b/chromium/content/browser/background_fetch/background_fetch_service_unittest.cc
index 7ae027d417c..90dc6495006 100644
--- a/chromium/content/browser/background_fetch/background_fetch_service_unittest.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_service_unittest.cc
@@ -124,6 +124,7 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
base::RunLoop run_loop;
service_->Fetch(
service_worker_registration_id, developer_id, requests, options, icon,
+ blink::mojom::BackgroundFetchUkmData::New(),
base::BindOnce(&BackgroundFetchServiceTest::DidGetRegistration,
base::Unretained(this), run_loop.QuitClosure(),
out_error, out_registration));
@@ -154,7 +155,7 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
base::RunLoop run_loop;
context_->data_manager_->CreateRegistration(
- registration_id, requests, options, icon,
+ registration_id, requests, options, icon, /* start_paused = */ false,
base::BindOnce(&BackgroundFetchServiceTest::DidStartFetch,
base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run();
@@ -179,10 +180,11 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
base::RunLoop run_loop;
service_->Fetch(
service_worker_registration_id, developer_id, requests, options, icon,
+ blink::mojom::BackgroundFetchUkmData::New(),
base::BindOnce(&BackgroundFetchServiceTest::DidGetRegistration,
base::Unretained(this), run_loop.QuitClosure(),
out_error, out_registration));
- UnregisterServiceWorker();
+ UnregisterServiceWorker(service_worker_registration_id);
run_loop.Run();
}
@@ -213,7 +215,7 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
DCHECK(out_error);
base::RunLoop run_loop;
- service_->UpdateUI(service_worker_registration_id, unique_id, developer_id,
+ service_->UpdateUI(service_worker_registration_id, developer_id, unique_id,
title, SkBitmap(),
base::BindOnce(&BackgroundFetchServiceTest::DidGetError,
base::Unretained(this),
@@ -237,10 +239,11 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
run_loop.Run();
+ // Allow all the DatabaseTasks resulting from Abort to complete.
+ thread_bundle_.RunUntilIdle();
+
// We only delete the registration if we successfully abort.
if (*out_error == blink::mojom::BackgroundFetchError::NONE) {
- // TODO(crbug.com/850894): The Abort callback is being resolved early.
- base::RunLoop().RunUntilIdle();
// The error passed to the histogram counter is not related to this
// |*out_error|, but the result of
// BackgroundFetchDataManager::DeleteRegistration. For the purposes these
@@ -727,7 +730,7 @@ TEST_F(BackgroundFetchServiceTest, UpdateUI) {
// Immediately update the title. This should succeed.
UpdateUI(registration_id.service_worker_registration_id(),
- registration_id.unique_id(), registration_id.developer_id(),
+ registration_id.developer_id(), registration_id.unique_id(),
second_title, &error);
EXPECT_EQ(blink::mojom::BackgroundFetchError::NONE, error);
@@ -929,8 +932,8 @@ TEST_F(BackgroundFetchServiceTest, UniqueId) {
// title of the second registration only.
std::string updated_second_registration_title = "Foo";
UpdateUI(second_registration_id.service_worker_registration_id(),
- second_registration_id.unique_id(),
second_registration_id.developer_id(),
+ second_registration_id.unique_id(),
updated_second_registration_title, &error);
EXPECT_EQ(blink::mojom::BackgroundFetchError::NONE, error);
@@ -939,8 +942,8 @@ TEST_F(BackgroundFetchServiceTest, UniqueId) {
// backgroundfetchsuccess or backgroundfetchfail event, both of which should
// work even though that registration is no longer active).
UpdateUI(aborted_registration_id.service_worker_registration_id(),
- aborted_registration_id.unique_id(),
- aborted_registration_id.developer_id(), "Bar", &error);
+ aborted_registration_id.developer_id(),
+ aborted_registration_id.unique_id(), "Bar", &error);
EXPECT_EQ(blink::mojom::BackgroundFetchError::INVALID_ID, error);
// Verify that the second registration's title was indeed updated, and that it
diff --git a/chromium/content/browser/background_fetch/background_fetch_test_base.cc b/chromium/content/browser/background_fetch/background_fetch_test_base.cc
index ef6f354e99c..f09f7a36dda 100644
--- a/chromium/content/browser/background_fetch/background_fetch_test_base.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_test_base.cc
@@ -67,6 +67,10 @@ void DidUnregisterServiceWorker(base::Closure quit_closure,
std::move(quit_closure).Run();
}
+GURL GetPatternForId(int64_t id) {
+ return GURL(kTestOrigin + base::IntToString(id));
+}
+
} // namespace
BackgroundFetchTestBase::BackgroundFetchTestBase()
@@ -99,7 +103,7 @@ int64_t BackgroundFetchTestBase::RegisterServiceWorker() {
{
blink::mojom::ServiceWorkerRegistrationOptions options;
- options.scope = origin_.GetURL();
+ options.scope = GetPatternForId(next_pattern_id_++);
base::RunLoop run_loop;
embedded_worker_test_helper_.context()->RegisterServiceWorker(
script_url, options,
@@ -142,10 +146,11 @@ int64_t BackgroundFetchTestBase::RegisterServiceWorker() {
return service_worker_registration_id;
}
-void BackgroundFetchTestBase::UnregisterServiceWorker() {
+void BackgroundFetchTestBase::UnregisterServiceWorker(
+ int64_t service_worker_registration_id) {
base::RunLoop run_loop;
embedded_worker_test_helper_.context()->UnregisterServiceWorker(
- origin_.GetURL(),
+ GetPatternForId(service_worker_registration_id),
base::BindOnce(&DidUnregisterServiceWorker, run_loop.QuitClosure()));
run_loop.Run();
}
@@ -167,11 +172,11 @@ std::unique_ptr<BackgroundFetchRegistration>
BackgroundFetchTestBase::CreateBackgroundFetchRegistration(
const std::string& developer_id,
const std::string& unique_id,
- blink::mojom::BackgroundFetchState state,
+ blink::mojom::BackgroundFetchResult result,
blink::mojom::BackgroundFetchFailureReason failure_reason) {
auto registration = std::make_unique<BackgroundFetchRegistration>(
developer_id, unique_id, 0 /* upload_total */, 0 /* uploaded */,
- 0 /* download_total */, 0 /* downloaded */, state, failure_reason);
+ 0 /* download_total */, 0 /* downloaded */, result, failure_reason);
return registration;
}
diff --git a/chromium/content/browser/background_fetch/background_fetch_test_base.h b/chromium/content/browser/background_fetch/background_fetch_test_base.h
index 9bb6f0b09c9..4244b015be8 100644
--- a/chromium/content/browser/background_fetch/background_fetch_test_base.h
+++ b/chromium/content/browser/background_fetch/background_fetch_test_base.h
@@ -47,7 +47,7 @@ class BackgroundFetchTestBase : public ::testing::Test {
// Unregisters the test Service Worker and verifies that the unregistration
// succeeded.
- void UnregisterServiceWorker();
+ void UnregisterServiceWorker(int64_t service_worker_registration_id);
// Creates a ServiceWorkerFetchRequest instance for the given details and
// provides a faked |response|.
@@ -61,7 +61,7 @@ class BackgroundFetchTestBase : public ::testing::Test {
CreateBackgroundFetchRegistration(
const std::string& developer_id,
const std::string& unique_id,
- blink::mojom::BackgroundFetchState state,
+ blink::mojom::BackgroundFetchResult result,
blink::mojom::BackgroundFetchFailureReason failure_reason);
// Returns the embedded worker test helper instance, which can be used to
@@ -93,6 +93,8 @@ class BackgroundFetchTestBase : public ::testing::Test {
StoragePartition* storage_partition_;
+ int next_pattern_id_ = 0;
+
// Vector of ServiceWorkerRegistration instances that have to be kept alive
// for the lifetime of this test.
std::vector<scoped_refptr<ServiceWorkerRegistration>>
diff --git a/chromium/content/browser/background_fetch/mock_background_fetch_delegate.cc b/chromium/content/browser/background_fetch/mock_background_fetch_delegate.cc
index 3655aae7eb8..5a165cf5a9d 100644
--- a/chromium/content/browser/background_fetch/mock_background_fetch_delegate.cc
+++ b/chromium/content/browser/background_fetch/mock_background_fetch_delegate.cc
@@ -63,7 +63,7 @@ void MockBackgroundFetchDelegate::GetPermissionForOrigin(
GetPermissionForOriginCallback callback) {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(std::move(callback), true /* has_permission */));
+ base::BindOnce(std::move(callback), BackgroundFetchPermission::ALLOWED));
}
void MockBackgroundFetchDelegate::GetIconDisplaySize(
@@ -95,14 +95,12 @@ void MockBackgroundFetchDelegate::DownloadUrl(
std::unique_ptr<TestResponse> test_response = std::move(url_iter->second);
url_responses_.erase(url_iter);
- std::unique_ptr<BackgroundFetchResponse> response =
- std::make_unique<BackgroundFetchResponse>(std::vector<GURL>({url}),
- test_response->headers);
-
PostAbortCheckingTask(
job_unique_id,
base::BindOnce(&BackgroundFetchDelegate::Client::OnDownloadStarted,
- client(), job_unique_id, guid, std::move(response)));
+ client(), job_unique_id, guid,
+ std::make_unique<BackgroundFetchResponse>(
+ std::vector<GURL>({url}), test_response->headers)));
if (test_response->data.size()) {
// Report progress at 50% complete.
@@ -140,16 +138,20 @@ void MockBackgroundFetchDelegate::DownloadUrl(
&BackgroundFetchDelegate::Client::OnDownloadComplete, client(),
job_unique_id, guid,
std::make_unique<BackgroundFetchResult>(
+ std::make_unique<BackgroundFetchResponse>(
+ std::vector<GURL>({url}), test_response->headers),
base::Time::Now(), response_path,
base::nullopt /* blob_handle */, test_response->data.size())));
} else {
+ auto response = std::make_unique<BackgroundFetchResponse>(
+ std::vector<GURL>({url}), test_response->headers);
+ auto result = std::make_unique<BackgroundFetchResult>(
+ std::move(response), base::Time::Now(),
+ BackgroundFetchResult::FailureReason::FETCH_ERROR);
PostAbortCheckingTask(
job_unique_id,
base::BindOnce(&BackgroundFetchDelegate::Client::OnDownloadComplete,
- client(), job_unique_id, guid,
- std::make_unique<BackgroundFetchResult>(
- base::Time::Now(),
- BackgroundFetchResult::FailureReason::UNKNOWN)));
+ client(), job_unique_id, guid, std::move(result)));
}
seen_guids_.insert(guid);
diff --git a/chromium/content/browser/background_fetch/storage/create_metadata_task.cc b/chromium/content/browser/background_fetch/storage/create_metadata_task.cc
index 17665e2b145..93c37d4d2cd 100644
--- a/chromium/content/browser/background_fetch/storage/create_metadata_task.cc
+++ b/chromium/content/browser/background_fetch/storage/create_metadata_task.cc
@@ -4,8 +4,10 @@
#include "content/browser/background_fetch/storage/create_metadata_task.h"
+#include <set>
#include <utility>
+#include "base/barrier_closure.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/background_fetch/background_fetch_data_manager.h"
@@ -19,24 +21,148 @@ namespace content {
namespace background_fetch {
+namespace {
+
+// TODO(crbug.com/889401): Consider making this configurable by finch.
+constexpr size_t kRegistrationLimitPerOrigin = 5u;
+
+// Finds the number of active registrations associated with the provided origin,
+// and compares it with the limit to determine whether this registration can go
+// through.
+class CanCreateRegistrationTask : public DatabaseTask {
+ public:
+ using CanCreateRegistrationCallback =
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError, bool)>;
+
+ CanCreateRegistrationTask(DatabaseTaskHost* host,
+ const url::Origin& origin,
+ CanCreateRegistrationCallback callback)
+ : DatabaseTask(host),
+ origin_(origin),
+ callback_(std::move(callback)),
+ weak_factory_(this) {}
+
+ ~CanCreateRegistrationTask() override = default;
+
+ void Start() override {
+ service_worker_context()->GetRegistrationsForOrigin(
+ origin_,
+ base::BindOnce(&CanCreateRegistrationTask::DidGetRegistrationsForOrigin,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ private:
+ void DidGetRegistrationsForOrigin(
+ blink::ServiceWorkerStatusCode status,
+ const std::vector<scoped_refptr<ServiceWorkerRegistration>>&
+ registrations) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kOk:
+ break;
+ case DatabaseStatus::kNotFound:
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
+ return;
+ case DatabaseStatus::kFailed:
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ }
+
+ std::set<int64_t> registration_ids;
+ for (const auto& registration : registrations)
+ registration_ids.insert(registration->id());
+
+ base::RepeatingClosure barrier_closure = base::BarrierClosure(
+ registration_ids.size(),
+ base::BindOnce(&CanCreateRegistrationTask::FinishWithError,
+ weak_factory_.GetWeakPtr(),
+ blink::mojom::BackgroundFetchError::NONE));
+
+ for (int64_t registration_id : registration_ids) {
+ service_worker_context()->GetRegistrationUserDataByKeyPrefix(
+ registration_id, kActiveRegistrationUniqueIdKeyPrefix,
+ base::BindOnce(&CanCreateRegistrationTask::DidGetActiveRegistrations,
+ weak_factory_.GetWeakPtr(), barrier_closure));
+ }
+ }
+
+ void DidGetActiveRegistrations(base::OnceClosure done_closure,
+ const std::vector<std::string>& data,
+ blink::ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kNotFound:
+ std::move(done_closure).Run();
+ return;
+ case DatabaseStatus::kOk:
+ num_active_registrations_ += data.size();
+ std::move(done_closure).Run();
+ return;
+ case DatabaseStatus::kFailed:
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ }
+ }
+
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override {
+ std::move(callback_).Run(
+ error, num_active_registrations_ < kRegistrationLimitPerOrigin);
+ Finished(); // Destroys |this|.
+ }
+
+ url::Origin origin_;
+ CanCreateRegistrationCallback callback_;
+
+ // The number of existing registrations found for |origin_|.
+ size_t num_active_registrations_ = 0u;
+
+ base::WeakPtrFactory<CanCreateRegistrationTask>
+ weak_factory_; // Keep as last.
+};
+
+} // namespace
+
CreateMetadataTask::CreateMetadataTask(
DatabaseTaskHost* host,
const BackgroundFetchRegistrationId& registration_id,
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
+ bool start_paused,
CreateMetadataCallback callback)
: DatabaseTask(host),
registration_id_(registration_id),
requests_(requests),
options_(options),
icon_(icon),
+ start_paused_(start_paused),
callback_(std::move(callback)),
weak_factory_(this) {}
CreateMetadataTask::~CreateMetadataTask() = default;
void CreateMetadataTask::Start() {
+ // Check if the registration can be created.
+ AddSubTask(std::make_unique<CanCreateRegistrationTask>(
+ this, registration_id_.origin(),
+ base::BindOnce(&CreateMetadataTask::DidGetCanCreateRegistration,
+ weak_factory_.GetWeakPtr())));
+}
+
+void CreateMetadataTask::DidGetCanCreateRegistration(
+ blink::mojom::BackgroundFetchError error,
+ bool can_create) {
+ if (error == blink::mojom::BackgroundFetchError::STORAGE_ERROR) {
+ SetStorageErrorAndFinish(
+ BackgroundFetchStorageError::kServiceWorkerStorageError);
+ return;
+ }
+
+ DCHECK_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ if (!can_create) {
+ FinishWithError(
+ blink::mojom::BackgroundFetchError::REGISTRATION_LIMIT_EXCEEDED);
+ return;
+ }
+
// Check if there is enough quota to download the data first.
if (options_.download_total > 0) {
IsQuotaAvailable(registration_id_.origin(), options_.download_total,
@@ -101,8 +227,8 @@ void CreateMetadataTask::InitializeMetadataProto() {
registration_proto->set_unique_id(registration_id_.unique_id());
registration_proto->set_developer_id(registration_id_.developer_id());
registration_proto->set_download_total(options_.download_total);
- registration_proto->set_state(
- proto::BackgroundFetchRegistration_BackgroundFetchState_PENDING);
+ registration_proto->set_result(
+ proto::BackgroundFetchRegistration_BackgroundFetchResult_UNSET);
registration_proto->set_failure_reason(
proto::BackgroundFetchRegistration_BackgroundFetchFailureReason_NONE);
@@ -236,7 +362,7 @@ void CreateMetadataTask::FinishWithError(
for (auto& observer : data_manager()->observers()) {
observer.OnRegistrationCreated(registration_id_, registration, options_,
- icon_, requests_.size());
+ icon_, requests_.size(), start_paused_);
}
}
diff --git a/chromium/content/browser/background_fetch/storage/create_metadata_task.h b/chromium/content/browser/background_fetch/storage/create_metadata_task.h
index 33307624820..e7eedc65eb0 100644
--- a/chromium/content/browser/background_fetch/storage/create_metadata_task.h
+++ b/chromium/content/browser/background_fetch/storage/create_metadata_task.h
@@ -33,6 +33,7 @@ class CreateMetadataTask : public DatabaseTask {
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
+ bool start_paused,
CreateMetadataCallback callback);
~CreateMetadataTask() override;
@@ -40,6 +41,8 @@ class CreateMetadataTask : public DatabaseTask {
void Start() override;
private:
+ void DidGetCanCreateRegistration(blink::mojom::BackgroundFetchError error,
+ bool can_create);
void DidGetIsQuotaAvailable(bool is_available);
void GetRegistrationUniqueId();
@@ -64,6 +67,7 @@ class CreateMetadataTask : public DatabaseTask {
std::vector<ServiceWorkerFetchRequest> requests_;
BackgroundFetchOptions options_;
SkBitmap icon_;
+ bool start_paused_;
CreateMetadataCallback callback_;
std::unique_ptr<proto::BackgroundFetchMetadata> metadata_proto_;
diff --git a/chromium/content/browser/background_fetch/storage/database_helpers.cc b/chromium/content/browser/background_fetch/storage/database_helpers.cc
index 691e721e6ad..caac11bb7fc 100644
--- a/chromium/content/browser/background_fetch/storage/database_helpers.cc
+++ b/chromium/content/browser/background_fetch/storage/database_helpers.cc
@@ -101,15 +101,15 @@ bool ToBackgroundFetchRegistration(
registration->uploaded = registration_proto.uploaded();
registration->download_total = registration_proto.download_total();
registration->downloaded = registration_proto.downloaded();
- switch (registration_proto.state()) {
- case proto::BackgroundFetchRegistration_BackgroundFetchState_PENDING:
- registration->state = blink::mojom::BackgroundFetchState::PENDING;
+ switch (registration_proto.result()) {
+ case proto::BackgroundFetchRegistration_BackgroundFetchResult_UNSET:
+ registration->result = blink::mojom::BackgroundFetchResult::UNSET;
break;
- case proto::BackgroundFetchRegistration_BackgroundFetchState_FAILURE:
- registration->state = blink::mojom::BackgroundFetchState::FAILURE;
+ case proto::BackgroundFetchRegistration_BackgroundFetchResult_FAILURE:
+ registration->result = blink::mojom::BackgroundFetchResult::FAILURE;
break;
- case proto::BackgroundFetchRegistration_BackgroundFetchState_SUCCESS:
- registration->state = blink::mojom::BackgroundFetchState::SUCCESS;
+ case proto::BackgroundFetchRegistration_BackgroundFetchResult_SUCCESS:
+ registration->result = blink::mojom::BackgroundFetchResult::SUCCESS;
break;
default:
NOTREACHED();
diff --git a/chromium/content/browser/background_fetch/storage/database_helpers.h b/chromium/content/browser/background_fetch/storage/database_helpers.h
index bca77cdc83d..82ea96e1dab 100644
--- a/chromium/content/browser/background_fetch/storage/database_helpers.h
+++ b/chromium/content/browser/background_fetch/storage/database_helpers.h
@@ -34,7 +34,8 @@ const char kActiveRequestKeyPrefix[] = "bgfetch_active_request_";
const char kCompletedRequestKeyPrefix[] = "bgfetch_completed_request_";
// Database Keys.
-std::string ActiveRegistrationUniqueIdKey(const std::string& developer_id);
+CONTENT_EXPORT std::string ActiveRegistrationUniqueIdKey(
+ const std::string& developer_id);
CONTENT_EXPORT std::string RegistrationKey(const std::string& unique_id);
diff --git a/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.cc b/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.cc
index 1d9a170a594..ee60d40d93d 100644
--- a/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.cc
+++ b/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.cc
@@ -9,6 +9,7 @@
#include "content/browser/background_fetch/storage/database_helpers.h"
#include "content/browser/cache_storage/cache_storage_manager.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "services/network/public/cpp/cors/cors.h"
namespace content {
@@ -69,7 +70,7 @@ void GetSettledFetchesTask::DidGetCompletedRequests(
SetStorageError(BackgroundFetchStorageError::kServiceWorkerStorageError);
break;
case DatabaseStatus::kNotFound:
- background_fetch_succeeded_ = false;
+ failure_reason_ = blink::mojom::BackgroundFetchFailureReason::FETCH_ERROR;
error_ = blink::mojom::BackgroundFetchError::INVALID_ID;
break;
}
@@ -81,12 +82,11 @@ void GetSettledFetchesTask::DidGetCompletedRequests(
serialized_completed_request)) {
// Service worker database has been corrupted. Abandon fetches.
SetStorageError(BackgroundFetchStorageError::kServiceWorkerStorageError);
- background_fetch_succeeded_ = false;
+ failure_reason_ = blink::mojom::BackgroundFetchFailureReason::
+ SERVICE_WORKER_UNAVAILABLE;
AbandonFetches(registration_id_.service_worker_registration_id());
break;
}
- if (!completed_requests_.back().succeeded())
- background_fetch_succeeded_ = false;
}
std::move(done_closure).Run();
}
@@ -235,7 +235,7 @@ void GetSettledFetchesTask::DidMatchAllResponsesForRequest(
void GetSettledFetchesTask::FillUncachedResponse(
BackgroundFetchSettledFetch* settled_fetch,
base::OnceClosure callback) {
- background_fetch_succeeded_ = false;
+ failure_reason_ = blink::mojom::BackgroundFetchFailureReason::FETCH_ERROR;
// TODO(rayankans): Fill unmatched response with error reports.
DCHECK(!settled_fetch->response);
@@ -252,8 +252,24 @@ void GetSettledFetchesTask::FinishWithError(
if (HasStorageError())
error = blink::mojom::BackgroundFetchError::STORAGE_ERROR;
ReportStorageError();
+
+ if (error == blink::mojom::BackgroundFetchError::NONE) {
+ for (const auto& settled_fetch : settled_fetches_) {
+ if (!settled_fetch.response->status_code) {
+ // A status_code of 0 means no headers were returned.
+ failure_reason_ =
+ blink::mojom::BackgroundFetchFailureReason::FETCH_ERROR;
+ break;
+ }
+ if (!network::cors::IsOkStatus(settled_fetch.response->status_code)) {
+ failure_reason_ =
+ blink::mojom::BackgroundFetchFailureReason::BAD_STATUS;
+ break;
+ }
+ }
+ }
std::move(settled_fetches_callback_)
- .Run(error, background_fetch_succeeded_, std::move(settled_fetches_),
+ .Run(error, failure_reason_, std::move(settled_fetches_),
{} /* blob_data_handles */);
Finished(); // Destroys |this|.
}
diff --git a/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.h b/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.h
index 2b5183a09b5..15417204b74 100644
--- a/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.h
+++ b/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.h
@@ -25,7 +25,7 @@ class GetSettledFetchesTask : public DatabaseTask {
// TODO(nator): Remove BlobDataHandle since we're not using them.
using SettledFetchesCallback = base::OnceCallback<void(
blink::mojom::BackgroundFetchError,
- bool,
+ blink::mojom::BackgroundFetchFailureReason,
std::vector<BackgroundFetchSettledFetch>,
std::vector<std::unique_ptr<storage::BlobDataHandle>>)>;
@@ -81,7 +81,8 @@ class GetSettledFetchesTask : public DatabaseTask {
// SettledFetchesCallback params.
std::vector<BackgroundFetchSettledFetch> settled_fetches_;
- bool background_fetch_succeeded_ = true;
+ blink::mojom::BackgroundFetchFailureReason failure_reason_ =
+ blink::mojom::BackgroundFetchFailureReason::NONE;
// Storage params.
CacheStorageCacheHandle handle_;
diff --git a/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc b/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc
index 6007fb6b929..68c9de01889 100644
--- a/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc
+++ b/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc
@@ -63,14 +63,10 @@ void MarkRegistrationForDeletionTask::DidGetActiveUniqueId(
proto::BackgroundFetchMetadata metadata_proto;
if (metadata_proto.ParseFromString(data[1])) {
- // Mark registration as no longer active. Also deletes pending request
- // keys, since those are globally sorted and requests within deactivated
- // registrations are no longer eligible to be started. Pending request
- // keys are not required by GetRegistration.
- service_worker_context()->ClearRegistrationUserDataByKeyPrefixes(
+ // Mark registration as no longer active.
+ service_worker_context()->ClearRegistrationUserData(
registration_id_.service_worker_registration_id(),
- {ActiveRegistrationUniqueIdKey(registration_id_.developer_id()),
- PendingRequestKeyPrefix(registration_id_.unique_id())},
+ {ActiveRegistrationUniqueIdKey(registration_id_.developer_id())},
base::BindOnce(&MarkRegistrationForDeletionTask::DidDeactivate,
weak_factory_.GetWeakPtr()));
} else {
diff --git a/chromium/content/browser/background_fetch/storage/mark_request_complete_task.cc b/chromium/content/browser/background_fetch/storage/mark_request_complete_task.cc
index a6c9de6c61a..a941ac21a08 100644
--- a/chromium/content/browser/background_fetch/storage/mark_request_complete_task.cc
+++ b/chromium/content/browser/background_fetch/storage/mark_request_complete_task.cc
@@ -40,11 +40,11 @@ MarkRequestCompleteTask::MarkRequestCompleteTask(
DatabaseTaskHost* host,
BackgroundFetchRegistrationId registration_id,
scoped_refptr<BackgroundFetchRequestInfo> request_info,
- base::OnceClosure closure)
+ MarkRequestCompleteCallback callback)
: DatabaseTask(host),
registration_id_(registration_id),
request_info_(std::move(request_info)),
- closure_(std::move(closure)),
+ callback_(std::move(callback)),
weak_factory_(this) {}
MarkRequestCompleteTask::~MarkRequestCompleteTask() = default;
@@ -62,17 +62,23 @@ void MarkRequestCompleteTask::Start() {
void MarkRequestCompleteTask::StoreResponse(base::OnceClosure done_closure) {
auto response = blink::mojom::FetchAPIResponse::New();
response->url_list = request_info_->GetURLChain();
- // TODO(crbug.com/838837): fill error and cors_exposed_header_names in
- // response.
response->response_type = network::mojom::FetchResponseType::kDefault;
response->response_time = request_info_->GetResponseTime();
- BackgroundFetchCrossOriginFilter filter(registration_id_.origin(),
- *request_info_);
- if (filter.CanPopulateBody())
- PopulateResponseBody(response.get());
- else
+ if (request_info_->GetURLChain().empty()) {
+ // The URL chain was not provided, so this is a failed response.
+ DCHECK(!request_info_->IsResultSuccess());
is_response_successful_ = false;
+ } else {
+ // TODO(crbug.com/884672): Move cross origin checks to when the response
+ // headers are available.
+ BackgroundFetchCrossOriginFilter filter(registration_id_.origin(),
+ *request_info_);
+ if (filter.CanPopulateBody())
+ PopulateResponseBody(response.get());
+ else
+ is_response_successful_ = false;
+ }
if (!IsOK(*request_info_))
is_response_successful_ = false;
@@ -277,8 +283,8 @@ void MarkRequestCompleteTask::DidGetMetadata(
return;
}
- metadata->mutable_registration()->set_download_total(
- metadata->registration().download_total() + request_info_->GetFileSize());
+ metadata->mutable_registration()->set_downloaded(
+ metadata->registration().downloaded() + request_info_->GetFileSize());
service_worker_context()->StoreRegistrationUserData(
registration_id_.service_worker_registration_id(),
@@ -292,15 +298,21 @@ void MarkRequestCompleteTask::DidGetMetadata(
void MarkRequestCompleteTask::DidStoreMetadata(
base::OnceClosure done_closure,
blink::ServiceWorkerStatusCode status) {
- SetStorageError(BackgroundFetchStorageError::kServiceWorkerStorageError);
+ if (ToDatabaseStatus(status) != DatabaseStatus::kOk)
+ SetStorageError(BackgroundFetchStorageError::kServiceWorkerStorageError);
std::move(done_closure).Run();
}
void MarkRequestCompleteTask::FinishWithError(
blink::mojom::BackgroundFetchError error) {
+ if (HasStorageError()) {
+ error = blink::mojom::BackgroundFetchError::STORAGE_ERROR;
+ for (auto& observer : data_manager()->observers())
+ observer.OnFetchStorageError(registration_id_);
+ }
ReportStorageError();
- std::move(closure_).Run();
+ std::move(callback_).Run(error);
Finished();
}
diff --git a/chromium/content/browser/background_fetch/storage/mark_request_complete_task.h b/chromium/content/browser/background_fetch/storage/mark_request_complete_task.h
index 09e11561eb4..870f781255b 100644
--- a/chromium/content/browser/background_fetch/storage/mark_request_complete_task.h
+++ b/chromium/content/browser/background_fetch/storage/mark_request_complete_task.h
@@ -21,11 +21,14 @@ namespace background_fetch {
// download response in cache storage.
class MarkRequestCompleteTask : public DatabaseTask {
public:
+ using MarkRequestCompleteCallback =
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError)>;
+
MarkRequestCompleteTask(
DatabaseTaskHost* host,
BackgroundFetchRegistrationId registration_id,
scoped_refptr<BackgroundFetchRequestInfo> request_info,
- base::OnceClosure closure);
+ MarkRequestCompleteCallback callback);
~MarkRequestCompleteTask() override;
@@ -73,7 +76,7 @@ class MarkRequestCompleteTask : public DatabaseTask {
BackgroundFetchRegistrationId registration_id_;
scoped_refptr<BackgroundFetchRequestInfo> request_info_;
- base::OnceClosure closure_;
+ MarkRequestCompleteCallback callback_;
proto::BackgroundFetchCompletedRequest completed_request_;
bool is_response_successful_ = true;
diff --git a/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.cc b/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.cc
index acccbe39878..a28ed8a65e7 100644
--- a/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.cc
+++ b/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.cc
@@ -6,6 +6,7 @@
#include "base/guid.h"
#include "content/browser/background_fetch/background_fetch_data_manager.h"
+#include "content/browser/background_fetch/background_fetch_data_manager_observer.h"
#include "content/browser/background_fetch/storage/database_helpers.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
@@ -16,11 +17,9 @@ namespace background_fetch {
StartNextPendingRequestTask::StartNextPendingRequestTask(
DatabaseTaskHost* host,
const BackgroundFetchRegistrationId& registration_id,
- const BackgroundFetchRegistration& registration,
NextRequestCallback callback)
: DatabaseTask(host),
registration_id_(registration_id),
- registration_(registration),
callback_(std::move(callback)),
weak_factory_(this) {
DCHECK(!registration_id_.is_null());
@@ -35,7 +34,7 @@ void StartNextPendingRequestTask::Start() {
void StartNextPendingRequestTask::GetPendingRequests() {
service_worker_context()->GetRegistrationUserDataByKeyPrefix(
registration_id_.service_worker_registration_id(),
- PendingRequestKeyPrefix(registration_.unique_id),
+ PendingRequestKeyPrefix(registration_id_.unique_id()),
base::BindOnce(&StartNextPendingRequestTask::DidGetPendingRequests,
weak_factory_.GetWeakPtr()));
}
@@ -65,43 +64,7 @@ void StartNextPendingRequestTask::DidGetPendingRequests(
return;
}
- // Make sure there isn't already an Active Request.
- // This might happen if the browser is killed in-between writes.
- service_worker_context()->GetRegistrationUserData(
- registration_id_.service_worker_registration_id(),
- {ActiveRequestKey(pending_request_.unique_id(),
- pending_request_.request_index())},
- base::BindOnce(&StartNextPendingRequestTask::DidFindActiveRequest,
- weak_factory_.GetWeakPtr()));
-}
-
-void StartNextPendingRequestTask::DidFindActiveRequest(
- const std::vector<std::string>& data,
- blink::ServiceWorkerStatusCode status) {
- switch (ToDatabaseStatus(status)) {
- case DatabaseStatus::kFailed:
- SetStorageErrorAndFinish(
- BackgroundFetchStorageError::kServiceWorkerStorageError);
- return;
- case DatabaseStatus::kNotFound:
- CreateAndStoreActiveRequest();
- return;
- case DatabaseStatus::kOk:
- // We already stored the active request.
- if (!active_request_.ParseFromString(data.front())) {
- // Service worker database has been corrupted. Abandon fetches.
- AbandonFetches(registration_id_.service_worker_registration_id());
- SetStorageErrorAndFinish(
- BackgroundFetchStorageError::kServiceWorkerStorageError);
- return;
- }
- StartDownload();
- return;
- }
- NOTREACHED();
-}
-
-void StartNextPendingRequestTask::CreateAndStoreActiveRequest() {
+ // Create an active request.
proto::BackgroundFetchActiveRequest active_request;
active_request_.set_download_guid(base::GenerateGUID());
@@ -132,19 +95,12 @@ void StartNextPendingRequestTask::DidStoreActiveRequest(
BackgroundFetchStorageError::kServiceWorkerStorageError);
return;
}
- StartDownload();
-}
-void StartNextPendingRequestTask::StartDownload() {
- DCHECK(!active_request_.download_guid().empty());
-
- auto next_request = base::MakeRefCounted<BackgroundFetchRequestInfo>(
+ next_request_ = base::MakeRefCounted<BackgroundFetchRequestInfo>(
active_request_.request_index(),
ServiceWorkerFetchRequest::ParseFromString(
active_request_.serialized_request()));
- next_request->SetDownloadGuid(active_request_.download_guid());
-
- std::move(callback_).Run(next_request);
+ next_request_->SetDownloadGuid(active_request_.download_guid());
// Delete the pending request.
service_worker_context()->ClearRegistrationUserData(
@@ -167,10 +123,13 @@ void StartNextPendingRequestTask::DidDeletePendingRequest(
void StartNextPendingRequestTask::FinishWithError(
blink::mojom::BackgroundFetchError error) {
+ if (HasStorageError()) {
+ for (auto& observer : data_manager()->observers())
+ observer.OnFetchStorageError(registration_id_);
+ }
ReportStorageError();
- if (callback_)
- std::move(callback_).Run(nullptr /* request */);
+ std::move(callback_).Run(error, std::move(next_request_));
Finished(); // Destroys |this|.
}
diff --git a/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.h b/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.h
index 5faaeb00e5f..48be7080d15 100644
--- a/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.h
+++ b/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.h
@@ -21,12 +21,12 @@ namespace background_fetch {
class StartNextPendingRequestTask : public DatabaseTask {
public:
using NextRequestCallback =
- base::OnceCallback<void(scoped_refptr<BackgroundFetchRequestInfo>)>;
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError,
+ scoped_refptr<BackgroundFetchRequestInfo>)>;
StartNextPendingRequestTask(
DatabaseTaskHost* host,
const BackgroundFetchRegistrationId& registration_id,
- const BackgroundFetchRegistration& registration,
NextRequestCallback callback);
~StartNextPendingRequestTask() override;
@@ -43,12 +43,8 @@ class StartNextPendingRequestTask : public DatabaseTask {
void DidFindActiveRequest(const std::vector<std::string>& data,
blink::ServiceWorkerStatusCode status);
- void CreateAndStoreActiveRequest();
-
void DidStoreActiveRequest(blink::ServiceWorkerStatusCode status);
- void StartDownload();
-
void DidDeletePendingRequest(blink::ServiceWorkerStatusCode status);
void FinishWithError(blink::mojom::BackgroundFetchError error) override;
@@ -56,7 +52,6 @@ class StartNextPendingRequestTask : public DatabaseTask {
std::string HistogramName() const override;
BackgroundFetchRegistrationId registration_id_;
- BackgroundFetchRegistration registration_;
NextRequestCallback callback_;
// protos don't support move semantics, so these class members will be used
@@ -64,6 +59,8 @@ class StartNextPendingRequestTask : public DatabaseTask {
proto::BackgroundFetchPendingRequest pending_request_;
proto::BackgroundFetchActiveRequest active_request_;
+ scoped_refptr<BackgroundFetchRequestInfo> next_request_;
+
base::WeakPtrFactory<StartNextPendingRequestTask>
weak_factory_; // Keep as last.
diff --git a/chromium/content/browser/background_sync/background_sync_browsertest.cc b/chromium/content/browser/background_sync/background_sync_browsertest.cc
index 678766f9341..3c4f3d499b0 100644
--- a/chromium/content/browser/background_sync/background_sync_browsertest.cc
+++ b/chromium/content/browser/background_sync/background_sync_browsertest.cc
@@ -14,6 +14,7 @@
#include "base/run_loop.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/background_sync/background_sync_context.h"
@@ -24,6 +25,7 @@
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
@@ -131,13 +133,15 @@ class BackgroundSyncBrowserTest : public ContentBrowserTest {
~BackgroundSyncBrowserTest() override {}
void SetUp() override {
- background_sync_test_util::SetIgnoreNetworkChangeNotifier(true);
+ background_sync_test_util::SetIgnoreNetworkChanges(true);
ContentBrowserTest::SetUp();
}
void SetIncognitoMode(bool incognito) {
shell_ = incognito ? CreateOffTheRecordBrowser() : shell();
+ // Let any async shell creation logic finish.
+ base::RunLoop().RunUntilIdle();
}
StoragePartitionImpl* GetStorage() {
@@ -233,8 +237,8 @@ bool BackgroundSyncBrowserTest::RegistrationPending(const std::string& tag) {
base::BindOnce(&RegistrationPendingCallback, run_loop.QuitClosure(),
base::ThreadTaskRunnerHandle::Get(), &is_pending);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&RegistrationPendingOnIOThread, base::WrapRefCounted(sync_context),
base::WrapRefCounted(service_worker_context), tag,
@@ -251,8 +255,8 @@ void BackgroundSyncBrowserTest::SetMaxSyncAttempts(int max_sync_attempts) {
StoragePartitionImpl* storage = GetStorage();
BackgroundSyncContext* sync_context = storage->GetBackgroundSyncContext();
- BrowserThread::PostTaskAndReply(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SetMaxSyncAttemptsOnIOThread,
base::WrapRefCounted(sync_context), max_sync_attempts),
run_loop.QuitClosure());
diff --git a/chromium/content/browser/background_sync/background_sync_context.cc b/chromium/content/browser/background_sync/background_sync_context.cc
index d460b065966..82e1cac6f54 100644
--- a/chromium/content/browser/background_sync/background_sync_context.cc
+++ b/chromium/content/browser/background_sync/background_sync_context.cc
@@ -8,16 +8,18 @@
#include "base/bind.h"
#include "base/stl_util.h"
+#include "base/task/post_task.h"
#include "content/browser/background_sync/background_sync_manager.h"
#include "content/browser/background_sync/background_sync_service_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace content {
BackgroundSyncContext::BackgroundSyncContext()
: base::RefCountedDeleteOnSequence<BackgroundSyncContext>(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)) {}
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})) {}
BackgroundSyncContext::~BackgroundSyncContext() {
// The destructor must run on the IO thread because it implicitly accesses
@@ -32,24 +34,24 @@ void BackgroundSyncContext::Init(
const scoped_refptr<ServiceWorkerContextWrapper>& context) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BackgroundSyncContext::CreateBackgroundSyncManager, this,
context));
}
void BackgroundSyncContext::Shutdown() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BackgroundSyncContext::ShutdownOnIO, this));
}
void BackgroundSyncContext::CreateService(
blink::mojom::BackgroundSyncServiceRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BackgroundSyncContext::CreateServiceOnIOThread, this,
std::move(request)));
}
diff --git a/chromium/content/browser/background_sync/background_sync_manager.cc b/chromium/content/browser/background_sync/background_sync_manager.cc
index 0b5b90e9d39..73d01cfc92d 100644
--- a/chromium/content/browser/background_sync/background_sync_manager.cc
+++ b/chromium/content/browser/background_sync/background_sync_manager.cc
@@ -11,6 +11,7 @@
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/default_clock.h"
#include "base/time/time.h"
@@ -26,6 +27,7 @@
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/background_sync_controller.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/permission_controller.h"
#include "content/public/browser/permission_type.h"
@@ -149,7 +151,7 @@ void OnSyncEventFinished(scoped_refptr<ServiceWorkerVersion> active_version,
int request_id,
ServiceWorkerVersion::StatusCallback callback,
blink::mojom::ServiceWorkerEventStatus status,
- base::Time dispatch_event_time) {
+ base::TimeTicks dispatch_event_time) {
if (!active_version->FinishRequest(
request_id,
status == blink::mojom::ServiceWorkerEventStatus::COMPLETED,
@@ -344,8 +346,8 @@ void BackgroundSyncManager::InitImpl(base::OnceClosure callback) {
return;
}
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&GetControllerParameters, service_worker_context_,
std::make_unique<BackgroundSyncParameters>(*parameters_)),
base::BindOnce(&BackgroundSyncManager::InitDidGetControllerParameters,
@@ -494,8 +496,8 @@ void BackgroundSyncManager::RegisterImpl(
return;
}
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&GetBackgroundSyncPermissionOnUIThread,
service_worker_context_,
sw_registration->pattern().GetOrigin()),
@@ -527,8 +529,8 @@ void BackgroundSyncManager::RegisterDidAskForPermission(
return;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NotifyBackgroundSyncRegisteredOnUIThread,
service_worker_context_,
sw_registration->pattern().GetOrigin()));
@@ -638,8 +640,7 @@ BackgroundSyncRegistration* BackgroundSyncManager::LookupActiveRegistration(
const std::string& tag) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- SWIdToRegistrationsMap::iterator it =
- active_registrations_.find(sw_registration_id);
+ auto it = active_registrations_.find(sw_registration_id);
if (it == active_registrations_.end())
return nullptr;
@@ -836,8 +837,7 @@ void BackgroundSyncManager::GetRegistrationsImpl(
return;
}
- SWIdToRegistrationsMap::iterator it =
- active_registrations_.find(sw_registration_id);
+ auto it = active_registrations_.find(sw_registration_id);
if (it != active_registrations_.end()) {
const BackgroundSyncRegistrations& registrations = it->second;
@@ -917,8 +917,8 @@ void BackgroundSyncManager::RunInBackgroundIfNecessary() {
// In case the browser closes (or to prevent it from closing), call
// RunInBackground to either wake up the browser at the wakeup delta or to
// keep the browser running.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
RunInBackgroundOnUIThread, service_worker_context_,
!soonest_wakeup_delta.is_max() /* should run in background */,
diff --git a/chromium/content/browser/background_sync/background_sync_manager_unittest.cc b/chromium/content/browser/background_sync/background_sync_manager_unittest.cc
index 077a39c679d..f700acafc4e 100644
--- a/chromium/content/browser/background_sync/background_sync_manager_unittest.cc
+++ b/chromium/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -37,7 +37,7 @@
#include "content/public/test/test_utils.h"
#include "content/test/mock_background_sync_controller.h"
#include "content/test/test_background_sync_manager.h"
-#include "net/base/network_change_notifier.h"
+#include "services/network/test/test_network_connection_tracker.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
@@ -86,8 +86,7 @@ void UnregisterServiceWorkerCallback(bool* called,
class BackgroundSyncManagerTest : public testing::Test {
public:
BackgroundSyncManagerTest()
- : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
- network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {
+ : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {
sync_options_1_.tag = "foo";
sync_options_1_.network_state = NETWORK_STATE_ONLINE;
@@ -97,7 +96,7 @@ class BackgroundSyncManagerTest : public testing::Test {
void SetUp() override {
// Don't let the tests be confused by the real-world device connectivity
- background_sync_test_util::SetIgnoreNetworkChangeNotifier(true);
+ background_sync_test_util::SetIgnoreNetworkChanges(true);
// TODO(jkarlin): Create a new object with all of the necessary SW calls
// so that we can inject test versions instead of bringing up all of this
@@ -129,7 +128,7 @@ class BackgroundSyncManagerTest : public testing::Test {
void TearDown() override {
// Restore the network observer functionality for subsequent tests
- background_sync_test_util::SetIgnoreNetworkChangeNotifier(false);
+ background_sync_test_util::SetIgnoreNetworkChanges(false);
}
void RegisterServiceWorkers() {
@@ -168,13 +167,13 @@ class BackgroundSyncManagerTest : public testing::Test {
EXPECT_TRUE(sw_registration_2_);
}
- void SetNetwork(net::NetworkChangeNotifier::ConnectionType connection_type) {
- net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
+ void SetNetwork(network::mojom::ConnectionType connection_type) {
+ network::TestNetworkConnectionTracker::GetInstance()->SetConnectionType(
connection_type);
if (test_background_sync_manager_) {
BackgroundSyncNetworkObserver* network_observer =
test_background_sync_manager_->GetNetworkObserverForTesting();
- network_observer->NotifyManagerIfNetworkChangedForTesting(
+ network_observer->NotifyManagerIfConnectionChangedForTesting(
connection_type);
base::RunLoop().RunUntilIdle();
}
@@ -216,7 +215,7 @@ class BackgroundSyncManagerTest : public testing::Test {
// the sync event fires by manipulating the network state as needed.
// NOTE: The setup of the network connection must happen after the
// BackgroundSyncManager has been created.
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
}
void InitBackgroundSyncManager() {
@@ -346,7 +345,7 @@ class BackgroundSyncManagerTest : public testing::Test {
void SetupForSyncEvent(
const TestBackgroundSyncManager::DispatchSyncCallback& callback) {
test_background_sync_manager_->set_dispatch_sync_callback(callback);
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
}
void DispatchSyncStatusCallback(
@@ -411,7 +410,6 @@ class BackgroundSyncManagerTest : public testing::Test {
}
TestBrowserThreadBundle browser_thread_bundle_;
- std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
std::unique_ptr<BackgroundSyncManager> background_sync_manager_;
std::unique_ptr<StoragePartitionImpl> storage_partition_impl_;
@@ -853,7 +851,7 @@ TEST_F(BackgroundSyncManagerTest, OverwritePendingRegistration) {
InitFailedSyncEventTest();
// Prevent the first sync from running so that it stays in a pending state.
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
EXPECT_TRUE(Register(sync_options_1_));
EXPECT_TRUE(GetRegistration(sync_options_1_));
@@ -862,7 +860,7 @@ TEST_F(BackgroundSyncManagerTest, OverwritePendingRegistration) {
EXPECT_TRUE(GetRegistration(sync_options_1_));
// Verify that it only gets to run once.
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, sync_events_called_);
EXPECT_FALSE(GetRegistration(sync_options_1_));
@@ -870,7 +868,7 @@ TEST_F(BackgroundSyncManagerTest, OverwritePendingRegistration) {
TEST_F(BackgroundSyncManagerTest, DisableWhilePending) {
InitDelayedSyncEventTest();
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
EXPECT_TRUE(Register(sync_options_1_));
// Corrupting the backend should result in the manager disabling itself on the
@@ -879,7 +877,7 @@ TEST_F(BackgroundSyncManagerTest, DisableWhilePending) {
EXPECT_FALSE(Register(sync_options_2_));
test_background_sync_manager_->set_corrupt_backend(false);
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0, sync_events_called_);
}
@@ -906,12 +904,12 @@ TEST_F(BackgroundSyncManagerTest, DisableWhileFiring) {
TEST_F(BackgroundSyncManagerTest, FiresOnNetworkChange) {
InitSyncEventTest();
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
EXPECT_TRUE(Register(sync_options_1_));
EXPECT_EQ(0, sync_events_called_);
EXPECT_TRUE(GetRegistration(sync_options_1_));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, sync_events_called_);
EXPECT_FALSE(GetRegistration(sync_options_1_));
@@ -920,14 +918,14 @@ TEST_F(BackgroundSyncManagerTest, FiresOnNetworkChange) {
TEST_F(BackgroundSyncManagerTest, MultipleRegistrationsFireOnNetworkChange) {
InitSyncEventTest();
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
EXPECT_TRUE(Register(sync_options_1_));
EXPECT_TRUE(Register(sync_options_2_));
EXPECT_EQ(0, sync_events_called_);
EXPECT_TRUE(GetRegistration(sync_options_1_));
EXPECT_TRUE(GetRegistration(sync_options_2_));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
EXPECT_EQ(2, sync_events_called_);
EXPECT_FALSE(GetRegistration(sync_options_1_));
@@ -938,7 +936,7 @@ TEST_F(BackgroundSyncManagerTest, FiresOnManagerRestart) {
InitSyncEventTest();
// Initially the event won't run because there is no network.
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
EXPECT_TRUE(Register(sync_options_1_));
EXPECT_EQ(0, sync_events_called_);
EXPECT_TRUE(GetRegistration(sync_options_1_));
@@ -947,7 +945,7 @@ TEST_F(BackgroundSyncManagerTest, FiresOnManagerRestart) {
DeleteBackgroundSyncManager();
// The next time the manager is started, the network is good.
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
SetupBackgroundSyncManager();
InitSyncEventTest();
@@ -1138,7 +1136,7 @@ TEST_F(BackgroundSyncManagerTest, WakeBrowserCalled) {
EXPECT_LT(0, GetController()->run_in_background_count());
EXPECT_FALSE(GetController()->run_in_background_enabled());
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
EXPECT_FALSE(GetController()->run_in_background_enabled());
// Register a one-shot but it can't fire due to lack of network, wake up is
@@ -1148,7 +1146,7 @@ TEST_F(BackgroundSyncManagerTest, WakeBrowserCalled) {
// Start the event but it will pause mid-sync due to
// InitDelayedSyncEventTest() above.
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
EXPECT_TRUE(GetController()->run_in_background_enabled());
EXPECT_EQ(test_background_sync_manager_->background_sync_parameters()
->min_sync_recovery_time,
@@ -1435,7 +1433,7 @@ TEST_F(BackgroundSyncManagerTest, EmulateDispatchSyncEvent) {
background_sync_manager_->EmulateServiceWorkerOffline(sw_registration_id_1_,
false);
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
was_called = false;
code = blink::ServiceWorkerStatusCode::kOk;
background_sync_manager_->EmulateDispatchSyncEvent(
@@ -1445,7 +1443,7 @@ TEST_F(BackgroundSyncManagerTest, EmulateDispatchSyncEvent) {
EXPECT_TRUE(was_called);
EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNetwork, code);
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
was_called = false;
background_sync_manager_->EmulateDispatchSyncEvent(
"emulated_tag", sw_registration_1_->active_version(), false,
diff --git a/chromium/content/browser/background_sync/background_sync_network_observer.cc b/chromium/content/browser/background_sync/background_sync_network_observer.cc
index 0746401e1d9..496b401f206 100644
--- a/chromium/content/browser/background_sync/background_sync_network_observer.cc
+++ b/chromium/content/browser/background_sync/background_sync_network_observer.cc
@@ -6,33 +6,65 @@
#include "base/location.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/network_service_instance.h"
namespace content {
// static
-bool BackgroundSyncNetworkObserver::ignore_network_change_notifier_ = false;
+bool BackgroundSyncNetworkObserver::ignore_network_changes_ = false;
// static
-void BackgroundSyncNetworkObserver::SetIgnoreNetworkChangeNotifierForTests(
+void BackgroundSyncNetworkObserver::SetIgnoreNetworkChangesForTests(
bool ignore) {
- ignore_network_change_notifier_ = ignore;
+ ignore_network_changes_ = ignore;
}
BackgroundSyncNetworkObserver::BackgroundSyncNetworkObserver(
- const base::RepeatingClosure& network_changed_callback)
- : connection_type_(net::NetworkChangeNotifier::GetConnectionType()),
- network_changed_callback_(network_changed_callback) {
+ const base::RepeatingClosure& connection_changed_callback)
+ : network_connection_tracker_(nullptr),
+ connection_type_(network::mojom::ConnectionType::CONNECTION_UNKNOWN),
+ connection_changed_callback_(connection_changed_callback),
+ weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&GetNetworkConnectionTracker),
+ base::BindOnce(
+ &BackgroundSyncNetworkObserver::RegisterWithNetworkConnectionTracker,
+ weak_ptr_factory_.GetWeakPtr()));
}
BackgroundSyncNetworkObserver::~BackgroundSyncNetworkObserver() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
+ if (network_connection_tracker_)
+ network_connection_tracker_->RemoveNetworkConnectionObserver(this);
+}
+
+void BackgroundSyncNetworkObserver::RegisterWithNetworkConnectionTracker(
+ network::NetworkConnectionTracker* network_connection_tracker) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(network_connection_tracker);
+ network_connection_tracker_ = network_connection_tracker;
+ network_connection_tracker_->AddNetworkConnectionObserver(this);
+
+ UpdateConnectionType();
+}
+
+void BackgroundSyncNetworkObserver::UpdateConnectionType() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ network::mojom::ConnectionType connection_type;
+ bool synchronous_return = network_connection_tracker_->GetConnectionType(
+ &connection_type,
+ base::BindOnce(&BackgroundSyncNetworkObserver::OnConnectionChanged,
+ weak_ptr_factory_.GetWeakPtr()));
+ if (synchronous_return)
+ OnConnectionChanged(connection_type);
}
bool BackgroundSyncNetworkObserver::NetworkSufficient(
@@ -45,46 +77,47 @@ bool BackgroundSyncNetworkObserver::NetworkSufficient(
case NETWORK_STATE_AVOID_CELLULAR:
// Note that this returns true for CONNECTION_UNKNOWN to avoid never
// firing.
- return connection_type_ != net::NetworkChangeNotifier::CONNECTION_NONE &&
- !net::NetworkChangeNotifier::IsConnectionCellular(
+ return connection_type_ !=
+ network::mojom::ConnectionType::CONNECTION_NONE &&
+ !network::NetworkConnectionTracker::IsConnectionCellular(
connection_type_);
case NETWORK_STATE_ONLINE:
- return connection_type_ != net::NetworkChangeNotifier::CONNECTION_NONE;
+ return connection_type_ !=
+ network::mojom::ConnectionType::CONNECTION_NONE;
}
NOTREACHED();
return false;
}
-void BackgroundSyncNetworkObserver::OnNetworkChanged(
- net::NetworkChangeNotifier::ConnectionType connection_type) {
+void BackgroundSyncNetworkObserver::OnConnectionChanged(
+ network::mojom::ConnectionType connection_type) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (ignore_network_change_notifier_)
+ if (ignore_network_changes_)
return;
- NotifyManagerIfNetworkChanged(connection_type);
+ NotifyManagerIfConnectionChanged(connection_type);
}
-void BackgroundSyncNetworkObserver::NotifyManagerIfNetworkChangedForTesting(
- net::NetworkChangeNotifier::ConnectionType connection_type) {
- NotifyManagerIfNetworkChanged(connection_type);
+void BackgroundSyncNetworkObserver::NotifyManagerIfConnectionChangedForTesting(
+ network::mojom::ConnectionType connection_type) {
+ NotifyManagerIfConnectionChanged(connection_type);
}
-void BackgroundSyncNetworkObserver::NotifyManagerIfNetworkChanged(
- net::NetworkChangeNotifier::ConnectionType connection_type) {
+void BackgroundSyncNetworkObserver::NotifyManagerIfConnectionChanged(
+ network::mojom::ConnectionType connection_type) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (connection_type == connection_type_)
return;
connection_type_ = connection_type;
- NotifyNetworkChanged();
+ NotifyConnectionChanged();
}
-void BackgroundSyncNetworkObserver::NotifyNetworkChanged() {
+void BackgroundSyncNetworkObserver::NotifyConnectionChanged() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- network_changed_callback_);
+ connection_changed_callback_);
}
} // namespace content
diff --git a/chromium/content/browser/background_sync/background_sync_network_observer.h b/chromium/content/browser/background_sync/background_sync_network_observer.h
index c52dbe5c527..8e587d01d12 100644
--- a/chromium/content/browser/background_sync/background_sync_network_observer.h
+++ b/chromium/content/browser/background_sync/background_sync_network_observer.h
@@ -7,14 +7,15 @@
#include "base/bind.h"
#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "content/browser/background_sync/background_sync.pb.h"
#include "content/common/content_export.h"
-#include "net/base/network_change_notifier.h"
+#include "services/network/public/cpp/network_connection_tracker.h"
namespace content {
class CONTENT_EXPORT BackgroundSyncNetworkObserver
- : public net::NetworkChangeNotifier::NetworkChangeObserver {
+ : public network::NetworkConnectionTracker::NetworkConnectionObserver {
public:
// Creates a BackgroundSyncNetworkObserver. |network_changed_callback| is
// called when the network connection changes asynchronously via PostMessage.
@@ -23,37 +24,50 @@ class CONTENT_EXPORT BackgroundSyncNetworkObserver
~BackgroundSyncNetworkObserver() override;
- // Enable or disable notifications coming from the NetworkChangeNotifier. (For
- // preventing flakes in tests)
- static void SetIgnoreNetworkChangeNotifierForTests(bool ignore);
+ // Enable or disable notifications coming from the NetworkConnectionTracker.
+ // (For preventing flakes in tests)
+ static void SetIgnoreNetworkChangesForTests(bool ignore);
// Returns true if the state of the network meets the needs of
// |network_state|.
bool NetworkSufficient(SyncNetworkState network_state);
- // NetworkChangeObserver overrides
- void OnNetworkChanged(
- net::NetworkChangeNotifier::ConnectionType connection_type) override;
+ // NetworkConnectionObserver overrides
+ void OnConnectionChanged(
+ network::mojom::ConnectionType connection_type) override;
- // Allow tests to call NotifyManagerIfNetworkChanged.
- void NotifyManagerIfNetworkChangedForTesting(
- net::NetworkChangeNotifier::ConnectionType connection_type);
+ // Allow tests to call NotifyManagerIfConnectionChanged.
+ void NotifyManagerIfConnectionChangedForTesting(
+ network::mojom::ConnectionType connection_type);
private:
- // Calls NotifyNetworkChanged if the connection type has changed.
- void NotifyManagerIfNetworkChanged(
- net::NetworkChangeNotifier::ConnectionType connection_type);
+ // Finishes setup once we get the NetworkConnectionTracker from the UI thread.
+ virtual void RegisterWithNetworkConnectionTracker(
+ network::NetworkConnectionTracker* network_connection_tracker);
- void NotifyNetworkChanged();
+ // Update the current connection type from the NetworkConnectionTracker.
+ void UpdateConnectionType();
- net::NetworkChangeNotifier::ConnectionType connection_type_;
+ // Calls NotifyConnectionChanged if the connection type has changed.
+ void NotifyManagerIfConnectionChanged(
+ network::mojom::ConnectionType connection_type);
- // The callback to run when the network changes.
- base::RepeatingClosure network_changed_callback_;
+ void NotifyConnectionChanged();
- // Set true to ignore notifications coming from the NetworkChangeNotifier
+ // NetworkConnectionTracker is a global singleton which will outlive this
+ // object.
+ network::NetworkConnectionTracker* network_connection_tracker_;
+
+ network::mojom::ConnectionType connection_type_;
+
+ // The callback to run when the connection changes.
+ base::RepeatingClosure connection_changed_callback_;
+
+ // Set true to ignore notifications coming from the NetworkConnectionTracker
// (to prevent flakes in tests).
- static bool ignore_network_change_notifier_;
+ static bool ignore_network_changes_;
+
+ base::WeakPtrFactory<BackgroundSyncNetworkObserver> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BackgroundSyncNetworkObserver);
};
diff --git a/chromium/content/browser/background_sync/background_sync_network_observer_unittest.cc b/chromium/content/browser/background_sync/background_sync_network_observer_unittest.cc
index ed81a611987..9ab8e094051 100644
--- a/chromium/content/browser/background_sync/background_sync_network_observer_unittest.cc
+++ b/chromium/content/browser/background_sync/background_sync_network_observer_unittest.cc
@@ -6,103 +6,121 @@
#include "base/run_loop.h"
#include "content/public/test/test_browser_thread_bundle.h"
-#include "net/base/network_change_notifier.h"
+#include "services/network/test/test_network_connection_tracker.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
class BackgroundSyncNetworkObserverTest : public testing::Test {
- protected:
- BackgroundSyncNetworkObserverTest()
- : network_change_notifier(net::NetworkChangeNotifier::CreateMock()),
- network_observer_(new BackgroundSyncNetworkObserver(base::BindRepeating(
- &BackgroundSyncNetworkObserverTest::OnNetworkChanged,
- base::Unretained(this)))),
- network_changed_count_(0) {}
-
- void SetNetwork(net::NetworkChangeNotifier::ConnectionType connection_type) {
- net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
+ public:
+ BackgroundSyncNetworkObserverTest() : network_changed_count_(0) {
+ network_observer_ =
+ std::make_unique<BackgroundSyncNetworkObserver>(base::BindRepeating(
+ &BackgroundSyncNetworkObserverTest::OnConnectionChanged,
+ base::Unretained(this)));
+ }
+
+ void SetNetwork(network::mojom::ConnectionType connection_type) {
+ network::TestNetworkConnectionTracker::GetInstance()->SetConnectionType(
connection_type);
base::RunLoop().RunUntilIdle();
}
- void OnNetworkChanged() { network_changed_count_++; }
+ void OnConnectionChanged() { network_changed_count_++; }
+ protected:
TestBrowserThreadBundle browser_thread_bundle_;
- std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier;
std::unique_ptr<BackgroundSyncNetworkObserver> network_observer_;
int network_changed_count_;
};
TEST_F(BackgroundSyncNetworkObserverTest, NetworkChangeInvokesCallback) {
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
network_changed_count_ = 0;
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
EXPECT_EQ(1, network_changed_count_);
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_3G);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_3G);
EXPECT_EQ(2, network_changed_count_);
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_UNKNOWN);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_UNKNOWN);
EXPECT_EQ(3, network_changed_count_);
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
EXPECT_EQ(4, network_changed_count_);
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
EXPECT_EQ(4, network_changed_count_);
}
TEST_F(BackgroundSyncNetworkObserverTest, NetworkSufficientAnyNetwork) {
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
EXPECT_TRUE(network_observer_->NetworkSufficient(NETWORK_STATE_ANY));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_3G);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_3G);
EXPECT_TRUE(network_observer_->NetworkSufficient(NETWORK_STATE_ANY));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_UNKNOWN);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_UNKNOWN);
EXPECT_TRUE(network_observer_->NetworkSufficient(NETWORK_STATE_ANY));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
EXPECT_TRUE(network_observer_->NetworkSufficient(NETWORK_STATE_ANY));
}
TEST_F(BackgroundSyncNetworkObserverTest, NetworkSufficientAvoidCellular) {
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
EXPECT_TRUE(
network_observer_->NetworkSufficient(NETWORK_STATE_AVOID_CELLULAR));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_UNKNOWN);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_UNKNOWN);
EXPECT_TRUE(
network_observer_->NetworkSufficient(NETWORK_STATE_AVOID_CELLULAR));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_2G);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_2G);
EXPECT_FALSE(
network_observer_->NetworkSufficient(NETWORK_STATE_AVOID_CELLULAR));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_3G);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_3G);
EXPECT_FALSE(
network_observer_->NetworkSufficient(NETWORK_STATE_AVOID_CELLULAR));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_4G);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_4G);
EXPECT_FALSE(
network_observer_->NetworkSufficient(NETWORK_STATE_AVOID_CELLULAR));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
EXPECT_FALSE(
network_observer_->NetworkSufficient(NETWORK_STATE_AVOID_CELLULAR));
}
TEST_F(BackgroundSyncNetworkObserverTest, ConditionsMetOnline) {
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_WIFI);
EXPECT_TRUE(network_observer_->NetworkSufficient(NETWORK_STATE_ONLINE));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_3G);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_3G);
EXPECT_TRUE(network_observer_->NetworkSufficient(NETWORK_STATE_ONLINE));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_UNKNOWN);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_UNKNOWN);
EXPECT_TRUE(network_observer_->NetworkSufficient(NETWORK_STATE_ONLINE));
- SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
EXPECT_FALSE(network_observer_->NetworkSufficient(NETWORK_STATE_ONLINE));
}
+TEST_F(BackgroundSyncNetworkObserverTest, GetNetworkOnConstruction) {
+ // We need to emulate being disconnected before creating the network observer.
+ network_observer_.reset();
+ SetNetwork(network::mojom::ConnectionType::CONNECTION_NONE);
+
+ auto observer =
+ std::make_unique<BackgroundSyncNetworkObserver>(base::BindRepeating(
+ &BackgroundSyncNetworkObserverTest::OnConnectionChanged,
+ base::Unretained(this)));
+
+ base::RunLoop().RunUntilIdle();
+
+ // The network observer should have learned that the current network is not
+ // the default (UNKNOWN) but is in fact NONE.
+ EXPECT_EQ(1, network_changed_count_);
+ EXPECT_FALSE(observer->NetworkSufficient(NETWORK_STATE_ONLINE));
+}
+
} // namespace content
diff --git a/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc b/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc
index 4f6d1aa3caf..a1dd3ef2121 100644
--- a/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc
+++ b/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc
@@ -25,7 +25,6 @@
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/test_background_sync_context.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
-#include "net/base/network_change_notifier.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
@@ -90,14 +89,13 @@ class BackgroundSyncServiceImplTest : public testing::Test {
public:
BackgroundSyncServiceImplTest()
: thread_bundle_(
- new TestBrowserThreadBundle(TestBrowserThreadBundle::IO_MAINLOOP)),
- network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {
+ new TestBrowserThreadBundle(TestBrowserThreadBundle::IO_MAINLOOP)) {
default_sync_registration_ = blink::mojom::SyncRegistration::New();
}
void SetUp() override {
// Don't let the tests be confused by the real-world device connectivity
- background_sync_test_util::SetIgnoreNetworkChangeNotifier(true);
+ background_sync_test_util::SetIgnoreNetworkChanges(true);
CreateTestHelper();
CreateStoragePartition();
@@ -115,7 +113,7 @@ class BackgroundSyncServiceImplTest : public testing::Test {
background_sync_context_ = nullptr;
// Restore the network observer functionality for subsequent tests
- background_sync_test_util::SetIgnoreNetworkChangeNotifier(false);
+ background_sync_test_util::SetIgnoreNetworkChanges(false);
}
// SetUp helper methods
@@ -158,8 +156,8 @@ class BackgroundSyncServiceImplTest : public testing::Test {
BackgroundSyncNetworkObserver* network_observer =
background_sync_context_->background_sync_manager()
->GetNetworkObserverForTesting();
- network_observer->NotifyManagerIfNetworkChangedForTesting(
- net::NetworkChangeNotifier::CONNECTION_NONE);
+ network_observer->NotifyManagerIfConnectionChangedForTesting(
+ network::mojom::ConnectionType::CONNECTION_NONE);
base::RunLoop().RunUntilIdle();
}
@@ -211,7 +209,6 @@ class BackgroundSyncServiceImplTest : public testing::Test {
}
std::unique_ptr<TestBrowserThreadBundle> thread_bundle_;
- std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
std::unique_ptr<EmbeddedWorkerTestHelper> embedded_worker_helper_;
std::unique_ptr<StoragePartitionImpl> storage_partition_impl_;
scoped_refptr<BackgroundSyncContext> background_sync_context_;
diff --git a/chromium/content/browser/bad_message.cc b/chromium/content/browser/bad_message.cc
index ab82b3354a8..e0a02d18085 100644
--- a/chromium/content/browser/bad_message.cc
+++ b/chromium/content/browser/bad_message.cc
@@ -9,7 +9,9 @@
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/strings/string_number_conversions.h"
+#include "base/task/post_task.h"
#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
@@ -54,9 +56,9 @@ void ReceivedBadMessage(int render_process_id, BadMessageReason reason) {
base::debug::DumpWithoutCrashing();
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&ReceivedBadMessageOnUIThread,
- render_process_id, reason));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&ReceivedBadMessageOnUIThread,
+ render_process_id, reason));
return;
}
ReceivedBadMessageOnUIThread(render_process_id, reason);
diff --git a/chromium/content/browser/blob_storage/blob_registry_wrapper.cc b/chromium/content/browser/blob_storage/blob_registry_wrapper.cc
index 9188ea19669..de1add337d0 100644
--- a/chromium/content/browser/blob_storage/blob_registry_wrapper.cc
+++ b/chromium/content/browser/blob_storage/blob_registry_wrapper.cc
@@ -4,8 +4,10 @@
#include "content/browser/blob_storage/blob_registry_wrapper.h"
+#include "base/task/post_task.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/child_process_security_policy_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/common/content_features.h"
#include "storage/browser/blob/blob_registry_impl.h"
#include "storage/browser/blob/blob_storage_context.h"
@@ -47,8 +49,8 @@ scoped_refptr<BlobRegistryWrapper> BlobRegistryWrapper::Create(
scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
scoped_refptr<storage::FileSystemContext> file_system_context) {
scoped_refptr<BlobRegistryWrapper> result(new BlobRegistryWrapper());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BlobRegistryWrapper::InitializeOnIOThread, result,
std::move(blob_storage_context),
std::move(file_system_context)));
diff --git a/chromium/content/browser/blob_storage/blob_storage_browsertest.cc b/chromium/content/browser/blob_storage/blob_storage_browsertest.cc
index 6b248d9d661..9a5d9f99605 100644
--- a/chromium/content/browser/blob_storage/blob_storage_browsertest.cc
+++ b/chromium/content/browser/blob_storage/blob_storage_browsertest.cc
@@ -3,9 +3,11 @@
// found in the LICENSE file.
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "base/test/bind_test_util.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
@@ -57,9 +59,10 @@ class BlobStorageBrowserTest : public ContentBrowserTest {
}
void SetBlobLimits() {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&SetBlobLimitsOnIO, GetBlobContext(),
- base::ConstRef(limits_)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&SetBlobLimitsOnIO, GetBlobContext(),
+ base::ConstRef(limits_)));
}
void SimpleTest(const GURL& test_url, bool incognito = false) {
@@ -95,8 +98,8 @@ IN_PROC_BROWSER_TEST_F(BlobStorageBrowserTest, BlobCombinations) {
auto blob_context = GetBlobContext();
base::RunLoop loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE, base::BindLambdaForTesting([&]() {
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO}, base::BindLambdaForTesting([&]() {
const storage::BlobMemoryController& memory_controller =
blob_context->context()->memory_controller();
// Our exact usages depend on IPC message ordering & garbage collection.
diff --git a/chromium/content/browser/blob_storage/blob_url_browsertest.cc b/chromium/content/browser/blob_storage/blob_url_browsertest.cc
index dfb724f3c95..3932fcaa062 100644
--- a/chromium/content/browser/blob_storage/blob_url_browsertest.cc
+++ b/chromium/content/browser/blob_storage/blob_url_browsertest.cc
@@ -74,7 +74,7 @@ IN_PROC_BROWSER_TEST_P(BlobUrlBrowserTest, LinkToUniqueOriginBlob) {
EXPECT_TRUE(ExecuteScriptAndExtractString(
new_contents,
"domAutomationController.send("
- " document.origin + ' ' + document.body.innerText);",
+ " self.origin + ' ' + document.body.innerText);",
&page_content));
EXPECT_EQ("null potato", page_content);
}
@@ -105,7 +105,7 @@ IN_PROC_BROWSER_TEST_P(BlobUrlBrowserTest, LinkToSameOriginBlob) {
EXPECT_TRUE(ExecuteScriptAndExtractString(
new_contents,
"domAutomationController.send("
- " document.origin + ' ' + document.body.innerText);",
+ " self.origin + ' ' + document.body.innerText);",
&page_content));
EXPECT_EQ(origin.Serialize() + " potato", page_content);
}
@@ -143,7 +143,7 @@ IN_PROC_BROWSER_TEST_P(BlobUrlBrowserTest, LinkToSameOriginBlobWithAuthority) {
EXPECT_TRUE(ExecuteScriptAndExtractString(
new_contents,
"domAutomationController.send("
- " document.origin + ' ' + document.body.innerText);",
+ " self.origin + ' ' + document.body.innerText);",
&page_content));
EXPECT_EQ(origin.Serialize() + " ", page_content); // no potato
}
@@ -160,7 +160,7 @@ IN_PROC_BROWSER_TEST_P(BlobUrlBrowserTest, ReplaceStateToAddAuthorityToBlob) {
EXPECT_TRUE(ExecuteScript(
shell(),
"var spoof_fn = function () {\n"
- " host_port = document.origin.split('://')[1];\n"
+ " host_port = self.origin.split('://')[1];\n"
" spoof_url = 'blob:http://spoof.com@' + host_port + '/abcd';\n"
" window.history.replaceState({}, '', spoof_url);\n"
"};\n"
@@ -183,7 +183,7 @@ IN_PROC_BROWSER_TEST_P(BlobUrlBrowserTest, ReplaceStateToAddAuthorityToBlob) {
EXPECT_TRUE(ExecuteScriptAndExtractString(
new_contents,
"domAutomationController.send("
- " document.origin + ' ' + document.body.innerText);",
+ " self.origin + ' ' + document.body.innerText);",
&page_content));
EXPECT_EQ(origin.Serialize() + " potato", page_content);
diff --git a/chromium/content/browser/blob_storage/blob_url_unittest.cc b/chromium/content/browser/blob_storage/blob_url_unittest.cc
index 702da3728bd..283ded19bba 100644
--- a/chromium/content/browser/blob_storage/blob_url_unittest.cc
+++ b/chromium/content/browser/blob_storage/blob_url_unittest.cc
@@ -107,7 +107,8 @@ disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache,
return nullptr;
disk_cache::ScopedEntryPtr entry(temp_entry);
- scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data);
+ scoped_refptr<net::StringIOBuffer> iobuffer =
+ base::MakeRefCounted<net::StringIOBuffer>(data);
rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(),
iobuffer->size(), callback.callback(), false);
EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv));
@@ -121,7 +122,7 @@ disk_cache::ScopedEntryPtr CreateDiskCacheEntryWithSideData(
const std::string& side_data) {
disk_cache::ScopedEntryPtr entry = CreateDiskCacheEntry(cache, key, data);
scoped_refptr<net::StringIOBuffer> iobuffer =
- new net::StringIOBuffer(side_data);
+ base::MakeRefCounted<net::StringIOBuffer>(side_data);
net::TestCompletionCallback callback;
int rv = entry->WriteData(kTestDiskCacheSideStreamIndex, 0, iobuffer.get(),
iobuffer->size(), callback.callback(), false);
diff --git a/chromium/content/browser/blob_storage/chrome_blob_storage_context.cc b/chromium/content/browser/blob_storage/chrome_blob_storage_context.cc
index 203e9c7e94a..31bad2ca4cc 100644
--- a/chromium/content/browser/blob_storage/chrome_blob_storage_context.cc
+++ b/chromium/content/browser/blob_storage/chrome_blob_storage_context.cc
@@ -21,6 +21,7 @@
#include "content/browser/resource_context_impl.h"
#include "content/public/browser/blob_handle.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
#include "services/network/public/cpp/resource_request_body.h"
@@ -127,8 +128,8 @@ ChromeBlobStorageContext* ChromeBlobStorageContext::GetFor(
}
if (io_thread_valid) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ChromeBlobStorageContext::InitializeOnIOThread, blob,
std::move(blob_storage_dir),
std::move(file_task_runner)));
@@ -148,7 +149,8 @@ void ChromeBlobStorageContext::InitializeOnIOThread(
// Signal the BlobMemoryController when it's appropriate to calculate its
// storage limits.
BrowserThread::PostAfterStartupTask(
- FROM_HERE, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ FROM_HERE,
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
base::BindOnce(&storage::BlobMemoryController::CalculateBlobStorageLimits,
context_->mutable_memory_controller()->GetWeakPtr()));
}
@@ -181,8 +183,8 @@ ChromeBlobStorageContext::URLLoaderFactoryForToken(
blink::mojom::BlobURLTokenPtr token) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
network::mojom::URLLoaderFactoryPtr blob_url_loader_factory_ptr;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
[](scoped_refptr<ChromeBlobStorageContext> context,
network::mojom::URLLoaderFactoryRequest request,
@@ -204,8 +206,8 @@ ChromeBlobStorageContext::URLLoaderFactoryForUrl(
const GURL& url) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
network::mojom::URLLoaderFactoryPtr blob_url_loader_factory_ptr;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
[](scoped_refptr<ChromeBlobStorageContext> context,
network::mojom::URLLoaderFactoryRequest request, const GURL& url) {
@@ -226,8 +228,8 @@ blink::mojom::BlobPtr ChromeBlobStorageContext::GetBlobPtr(
const std::string& uuid) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
blink::mojom::BlobPtr blob_ptr;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
[](scoped_refptr<ChromeBlobStorageContext> context,
blink::mojom::BlobRequest request, const std::string& uuid) {
diff --git a/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.cc b/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.cc
index 4b4ce9a95a9..1c275f34260 100644
--- a/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.cc
+++ b/chromium/content/browser/bluetooth/bluetooth_allowed_devices_map.cc
@@ -19,7 +19,7 @@ BluetoothAllowedDevicesMap::GetOrCreateAllowedDevices(
const url::Origin& origin) {
// "Unique" Origins generate the same key in maps, therefore are not
// supported.
- CHECK(!origin.unique());
+ CHECK(!origin.opaque());
auto iter = origin_to_allowed_devices_map_.find(origin);
if (iter == origin_to_allowed_devices_map_.end()) {
iter = origin_to_allowed_devices_map_.insert(
diff --git a/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc b/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
index bea76778640..b561ce31363 100644
--- a/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
+++ b/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
@@ -344,9 +344,9 @@ void BluetoothDeviceChooserController::GetDevice(
REQUEST_DEVICE_FROM_CROSS_ORIGIN_IFRAME);
return;
}
- // The above also excludes unique origins, which are not even same-origin with
+ // The above also excludes opaque origins, which are not even same-origin with
// themselves.
- DCHECK(!requesting_origin.unique());
+ DCHECK(!requesting_origin.opaque());
if (!adapter_->IsPresent()) {
DVLOG(1) << "Bluetooth Adapter not present. Can't serve requestDevice.";
diff --git a/chromium/content/browser/browser_associated_interface_unittest.cc b/chromium/content/browser/browser_associated_interface_unittest.cc
index 8e3a8041c0c..2ddc8c2091b 100644
--- a/chromium/content/browser/browser_associated_interface_unittest.cc
+++ b/chromium/content/browser/browser_associated_interface_unittest.cc
@@ -12,9 +12,11 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/threading/thread.h"
#include "content/public/browser/browser_associated_interface.h"
#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/test_browser_associated_interfaces.mojom.h"
@@ -164,8 +166,9 @@ class TestClientRunner {
TEST_F(BrowserAssociatedInterfaceTest, Basic) {
TestBrowserThreadBundle browser_threads_;
mojo::MessagePipe pipe;
- ProxyRunner proxy(std::move(pipe.handle0), true,
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ ProxyRunner proxy(
+ std::move(pipe.handle0), true,
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
AddFilterToChannel(new TestDriverMessageFilter, proxy.channel());
TestClientRunner client(std::move(pipe.handle1));
diff --git a/chromium/content/browser/browser_child_process_host_impl.cc b/chromium/content/browser/browser_child_process_host_impl.cc
index 993ba401697..0d338c22edc 100644
--- a/chromium/content/browser/browser_child_process_host_impl.cc
+++ b/chromium/content/browser/browser_child_process_host_impl.cc
@@ -23,6 +23,7 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/tracing/common/trace_startup_config.h"
@@ -37,6 +38,7 @@
#include "content/common/service_manager/child_connection.h"
#include "content/public/browser/browser_child_process_host_delegate.h"
#include "content/public/browser/browser_child_process_observer.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/content_browser_client.h"
@@ -184,8 +186,8 @@ BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() {
g_child_process_list.Get().remove(this);
if (notify_child_disconnected_) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NotifyProcessHostDisconnected, data_.Duplicate()));
}
}
@@ -196,8 +198,7 @@ void BrowserChildProcessHostImpl::TerminateAll() {
// Make a copy since the BrowserChildProcessHost dtor mutates the original
// list.
BrowserChildProcessList copy = g_child_process_list.Get();
- for (BrowserChildProcessList::iterator it = copy.begin();
- it != copy.end(); ++it) {
+ for (auto it = copy.begin(); it != copy.end(); ++it) {
delete (*it)->delegate(); // ~*HostDelegate deletes *HostImpl.
}
}
@@ -383,15 +384,15 @@ void BrowserChildProcessHostImpl::OnChannelConnected(int32_t peer_pid) {
early_exit_watcher_.StopWatching();
#endif
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NotifyProcessHostConnected, data_.Duplicate()));
delegate_->OnChannelConnected(peer_pid);
if (IsProcessLaunched()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NotifyProcessLaunchedAndConnected, data_.Duplicate()));
}
}
@@ -442,16 +443,16 @@ void BrowserChildProcessHostImpl::OnChildDisconnected() {
GetTerminationInfo(true /* known_dead */);
#if defined(OS_ANDROID)
delegate_->OnProcessCrashed(info.exit_code);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NotifyProcessKilled, data_.Duplicate(), info));
#else // OS_ANDROID
switch (info.status) {
case base::TERMINATION_STATUS_PROCESS_CRASHED:
case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: {
delegate_->OnProcessCrashed(info.exit_code);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NotifyProcessCrashed, data_.Duplicate(), info));
UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed2",
static_cast<ProcessType>(data_.process_type),
@@ -463,8 +464,8 @@ void BrowserChildProcessHostImpl::OnChildDisconnected() {
#endif
case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: {
delegate_->OnProcessCrashed(info.exit_code);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NotifyProcessKilled, data_.Duplicate(), info));
// Report that this child process was killed.
UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed2",
@@ -608,8 +609,8 @@ void BrowserChildProcessHostImpl::OnProcessLaunched() {
delegate_->OnProcessLaunched();
if (is_channel_connected_) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NotifyProcessLaunchedAndConnected, data_.Duplicate()));
}
}
diff --git a/chromium/content/browser/browser_context.cc b/chromium/content/browser/browser_context.cc
index 840cafc185f..9797767f88e 100644
--- a/chromium/content/browser/browser_context.cc
+++ b/chromium/content/browser/browser_context.cc
@@ -14,7 +14,9 @@
#include <vector>
#include "base/base64.h"
+#include "base/bind.h"
#include "base/command_line.h"
+#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/guid.h"
#include "base/lazy_instance.h"
@@ -22,6 +24,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/rand_util.h"
+#include "base/supports_user_data.h"
#include "base/task/post_task.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -33,12 +36,14 @@
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/loader/shared_cors_origin_access_list_impl.h"
#include "content/browser/permissions/permission_controller_impl.h"
#include "content/browser/push_messaging/push_messaging_router.h"
#include "content/browser/service_manager/common_browser_interfaces.h"
#include "content/browser/storage_partition_impl_map.h"
#include "content/common/child_process_host_impl.h"
#include "content/public/browser/blob_handle.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_process_host.h"
@@ -58,13 +63,13 @@
#include "services/file/file_service.h"
#include "services/file/public/mojom/constants.mojom.h"
#include "services/file/user_id_map.h"
+#include "services/network/public/cpp/features.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/mojom/service.mojom.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/database/database_tracker.h"
#include "storage/browser/fileapi/external_mount_points.h"
-
using base::UserDataAdapter;
namespace content {
@@ -102,14 +107,61 @@ class ContentServiceDelegateHolder : public base::SupportsUserData::Data {
DISALLOW_COPY_AND_ASSIGN(ContentServiceDelegateHolder);
};
+// A class used to make an asynchronous Mojo call with cloned patterns for each
+// StoragePartition iteration. |this| instance will be destructed when all
+// existing asynchronous Mojo calls made in SetLists() are done, and |closure|
+// will be invoked on destructing |this|.
+class CorsOriginPatternSetter
+ : public base::RefCounted<CorsOriginPatternSetter> {
+ public:
+ CorsOriginPatternSetter(
+ const url::Origin& source_origin,
+ std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
+ std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
+ base::OnceClosure closure)
+ : source_origin_(source_origin),
+ allow_patterns_(std::move(allow_patterns)),
+ block_patterns_(std::move(block_patterns)),
+ closure_(std::move(closure)) {}
+
+ void SetLists(StoragePartition* partition) {
+ partition->GetNetworkContext()->SetCorsOriginAccessListsForOrigin(
+ source_origin_, ClonePatterns(allow_patterns_),
+ ClonePatterns(block_patterns_),
+ base::BindOnce([](scoped_refptr<CorsOriginPatternSetter> setter) {},
+ base::RetainedRef(this)));
+ }
+
+ private:
+ friend class base::RefCounted<CorsOriginPatternSetter>;
+
+ static std::vector<network::mojom::CorsOriginPatternPtr> ClonePatterns(
+ const std::vector<network::mojom::CorsOriginPatternPtr>& patterns) {
+ std::vector<network::mojom::CorsOriginPatternPtr> cloned_patterns;
+ cloned_patterns.reserve(patterns.size());
+ for (const auto& item : patterns)
+ cloned_patterns.push_back(item.Clone());
+ return cloned_patterns;
+ }
+
+ ~CorsOriginPatternSetter() { std::move(closure_).Run(); }
+
+ const url::Origin source_origin_;
+ const std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns_;
+ const std::vector<network::mojom::CorsOriginPatternPtr> block_patterns_;
+
+ base::OnceClosure closure_;
+};
+
// Key names on BrowserContext.
const char kBrowsingDataRemoverKey[] = "browsing-data-remover";
const char kContentServiceDelegateKey[] = "content-service-delegate";
-const char kPermissionControllerKey[] = "permission-controller";
const char kDownloadManagerKeyName[] = "download_manager";
const char kMojoWasInitialized[] = "mojo-was-initialized";
+const char kPermissionControllerKey[] = "permission-controller";
const char kServiceManagerConnection[] = "service-manager-connection";
const char kServiceUserId[] = "service-user-id";
+const char kSharedCorsOriginAccessListKey[] = "shared-cors-origin-access-list";
const char kStoragePartitionMapKeyName[] = "content_storage_partition_map";
const char kVideoDecodePerfHistoryId[] = "video-decode-perf-history";
@@ -195,7 +247,8 @@ class BrowserContextServiceManagerConnectionHolder
service_manager::mojom::ServiceRequest request)
: service_manager_connection_(ServiceManagerConnection::Create(
std::move(request),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))) {}
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {BrowserThread::IO}))) {}
~BrowserContextServiceManagerConnectionHolder() override {}
ServiceManagerConnection* service_manager_connection() {
@@ -364,8 +417,8 @@ void BrowserContext::CreateMemoryBackedBlob(BrowserContext* browser_context,
ChromeBlobStorageContext* blob_context =
ChromeBlobStorageContext::GetFor(browser_context);
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ChromeBlobStorageContext::CreateMemoryBackedBlob,
base::WrapRefCounted(blob_context), data, length,
content_type),
@@ -463,8 +516,8 @@ void BrowserContext::SaveSessionState(BrowserContext* browser_context) {
base::WrapRefCounted(database_tracker)));
if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&SaveSessionStateOnIOThread,
base::WrapRefCounted(storage_partition->GetURLRequestContext()),
@@ -626,8 +679,41 @@ ServiceManagerConnection* BrowserContext::GetServiceManagerConnectionFor(
: nullptr;
}
+// static
+const SharedCorsOriginAccessList* BrowserContext::GetSharedCorsOriginAccessList(
+ BrowserContext* browser_context) {
+ return UserDataAdapter<SharedCorsOriginAccessList>::Get(
+ browser_context, kSharedCorsOriginAccessListKey);
+}
+
+// static
+void BrowserContext::SetCorsOriginAccessListsForOrigin(
+ BrowserContext* browser_context,
+ const url::Origin& source_origin,
+ std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
+ std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
+ base::OnceClosure closure) {
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ UserDataAdapter<SharedCorsOriginAccessList>::Get(
+ browser_context, kSharedCorsOriginAccessListKey)
+ ->SetForOrigin(source_origin, std::move(allow_patterns),
+ std::move(block_patterns), std::move(closure));
+ } else {
+ auto setter = base::MakeRefCounted<CorsOriginPatternSetter>(
+ source_origin, std::move(allow_patterns), std::move(block_patterns),
+ std::move(closure));
+ ForEachStoragePartition(
+ browser_context, base::BindRepeating(&CorsOriginPatternSetter::SetLists,
+ base::RetainedRef(setter.get())));
+ }
+}
+
BrowserContext::BrowserContext()
- : unique_id_(base::UnguessableToken::Create().ToString()) {}
+ : unique_id_(base::UnguessableToken::Create().ToString()) {
+ SetUserData(kSharedCorsOriginAccessListKey,
+ std::make_unique<UserDataAdapter<SharedCorsOriginAccessList>>(
+ new SharedCorsOriginAccessListImpl()));
+}
BrowserContext::~BrowserContext() {
CHECK(GetUserData(kMojoWasInitialized))
@@ -672,10 +758,14 @@ media::VideoDecodePerfHistory* BrowserContext::GetVideoDecodePerfHistory() {
// occurs later upon first VideoDecodePerfHistory API request that requires DB
// access. DB operations will not block the UI thread.
if (!decode_history) {
- auto db_factory = std::make_unique<media::VideoDecodeStatsDBImplFactory>(
- GetPath().Append(FILE_PATH_LITERAL("VideoDecodeStats")));
- decode_history = new media::VideoDecodePerfHistory(std::move(db_factory));
- SetUserData(kVideoDecodePerfHistoryId, base::WrapUnique(decode_history));
+ std::unique_ptr<media::VideoDecodeStatsDBImpl> stats_db =
+ media::VideoDecodeStatsDBImpl::Create(
+ GetPath().Append(FILE_PATH_LITERAL("VideoDecodeStats")));
+ auto new_decode_history =
+ std::make_unique<media::VideoDecodePerfHistory>(std::move(stats_db));
+ decode_history = new_decode_history.get();
+
+ SetUserData(kVideoDecodePerfHistoryId, std::move(new_decode_history));
}
return decode_history;
diff --git a/chromium/content/browser/browser_ipc_logging.cc b/chromium/content/browser/browser_ipc_logging.cc
index ea431e0d338..07958a939f0 100644
--- a/chromium/content/browser/browser_ipc_logging.cc
+++ b/chromium/content/browser/browser_ipc_logging.cc
@@ -5,8 +5,10 @@
#include "content/public/browser/browser_ipc_logging.h"
#include "base/bind.h"
+#include "base/task/post_task.h"
#include "content/common/child_control.mojom.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/bind_interface_helpers.h"
@@ -38,9 +40,8 @@ void EnableIPCLogging(bool enable) {
// Now tell subprocesses. Messages to ChildProcess-derived
// processes must be done on the IO thread.
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::Bind(EnableIPCLoggingForChildProcesses, enable));
// Finally, tell the renderers which don't derive from ChildProcess.
diff --git a/chromium/content/browser/browser_main_loop.cc b/chromium/content/browser/browser_main_loop.cc
index 5cea69cfba0..20471ef5cca 100644
--- a/chromium/content/browser/browser_main_loop.cc
+++ b/chromium/content/browser/browser_main_loop.cc
@@ -37,7 +37,8 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/synchronization/waitable_event.h"
-#include "base/system_monitor/system_monitor.h"
+#include "base/system/system_monitor.h"
+#include "base/task/post_task.h"
#include "base/task/task_scheduler/initialization_util.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
@@ -85,6 +86,8 @@
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/scheduler/responsiveness/watcher.h"
+#include "content/browser/screenlock_monitor/screenlock_monitor.h"
+#include "content/browser/screenlock_monitor/screenlock_monitor_device_source.h"
#include "content/browser/service_manager/service_manager_context.h"
#include "content/browser/speech/speech_recognition_manager_impl.h"
#include "content/browser/startup_data_impl.h"
@@ -99,6 +102,7 @@
#include "content/common/service_manager/service_manager_connection_impl.h"
#include "content/common/task_scheduler.h"
#include "content/public/browser/browser_main_parts.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/gpu_data_manager_observer.h"
@@ -188,7 +192,6 @@
#include "base/memory/memory_pressure_monitor_win.h"
#include "net/base/winsock_init.h"
#include "services/service_manager/sandbox/win/sandbox_win.h"
-#include "ui/base/l10n/l10n_util_win.h"
#include "ui/display/win/screen_win.h"
#endif
@@ -343,46 +346,6 @@ enum WorkerPoolType : size_t {
WORKER_POOL_COUNT // Always last.
};
-std::unique_ptr<base::TaskScheduler::InitParams>
-GetDefaultTaskSchedulerInitParams() {
-#if defined(OS_ANDROID)
- // Mobile config, for iOS see ios/web/app/web_main_loop.cc.
- return std::make_unique<base::TaskScheduler::InitParams>(
- base::SchedulerWorkerPoolParams(
- base::RecommendedMaxNumberOfThreadsInPool(2, 8, 0.1, 0),
- base::TimeDelta::FromSeconds(30)),
- base::SchedulerWorkerPoolParams(
- base::RecommendedMaxNumberOfThreadsInPool(2, 8, 0.1, 0),
- base::TimeDelta::FromSeconds(30)),
- base::SchedulerWorkerPoolParams(
- base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.3, 0),
- base::TimeDelta::FromSeconds(30)),
- base::SchedulerWorkerPoolParams(
- base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.3, 0),
- base::TimeDelta::FromSeconds(60)));
-#else
- // Desktop config.
- return std::make_unique<base::TaskScheduler::InitParams>(
- base::SchedulerWorkerPoolParams(
- base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0),
- base::TimeDelta::FromSeconds(30)),
- base::SchedulerWorkerPoolParams(
- base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0),
- base::TimeDelta::FromSeconds(40)),
- base::SchedulerWorkerPoolParams(
- base::RecommendedMaxNumberOfThreadsInPool(8, 32, 0.3, 0),
- base::TimeDelta::FromSeconds(30)),
- base::SchedulerWorkerPoolParams(
- base::RecommendedMaxNumberOfThreadsInPool(8, 32, 0.3, 0),
- base::TimeDelta::FromSeconds(60))
-#if defined(OS_WIN)
- ,
- base::TaskScheduler::InitParams::SharedWorkerPoolEnvironment::COM_MTA
-#endif // defined(OS_WIN)
- );
-#endif
-}
-
#if !defined(OS_FUCHSIA)
// Time between updating and recording swap rates.
constexpr base::TimeDelta kSwapMetricsInterval =
@@ -437,6 +400,31 @@ void SetFileUrlPathAliasForIpcFuzzer() {
const base::Feature kBrowserResponsivenessCalculator{
"BrowserResponsivenessCalculator", base::FEATURE_DISABLED_BY_DEFAULT};
+std::unique_ptr<base::MemoryPressureMonitor> CreateMemoryPressureMonitor(
+ const base::CommandLine& command_line) {
+ // Behavior of browser tests should not depend on things outside of their
+ // control (like the amount of memory on the system running the tests).
+ if (command_line.HasSwitch(switches::kBrowserTest))
+ return nullptr;
+
+// TODO(chrisha): Simplify this code once MemoryPressureMonitor is made a
+// concrete class.
+#if defined(OS_CHROMEOS)
+ if (chromeos::switches::MemoryPressureHandlingEnabled()) {
+ return std::make_unique<base::chromeos::MemoryPressureMonitor>(
+ chromeos::switches::GetMemoryPressureThresholds());
+ }
+ return nullptr;
+#elif defined(OS_MACOSX)
+ return std::make_unique<base::mac::MemoryPressureMonitor>();
+#elif defined(OS_WIN)
+ return CreateWinMemoryPressureMonitor(command_line);
+#else
+ // No memory monitor on other platforms...
+ return nullptr;
+#endif
+}
+
} // namespace
#if defined(USE_X11)
@@ -493,8 +481,8 @@ class HDRProxy {
static void RequestHDRStatus() {
// The request must be sent to the GPU process from the IO thread.
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&HDRProxy::RequestOnIOThread));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&HDRProxy::RequestOnIOThread));
}
private:
@@ -511,8 +499,8 @@ class HDRProxy {
}
}
static void GotResultOnIOThread(bool hdr_enabled) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&HDRProxy::GotResult, hdr_enabled));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&HDRProxy::GotResult, hdr_enabled));
}
static void GotResult(bool hdr_enabled) {
display::win::ScreenWin::SetHDREnabled(hdr_enabled);
@@ -541,12 +529,18 @@ media::AudioManager* BrowserMainLoop::GetAudioManager() {
return g_current_browser_main_loop->audio_manager();
}
-BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters)
+BrowserMainLoop::BrowserMainLoop(
+ const MainFunctionParams& parameters,
+ std::unique_ptr<base::TaskScheduler::ScopedExecutionFence>
+ scoped_execution_fence)
: parameters_(parameters),
parsed_command_line_(parameters.command_line),
result_code_(service_manager::RESULT_CODE_NORMAL_EXIT),
- created_threads_(false) {
+ created_threads_(false),
+ scoped_execution_fence_(std::move(scoped_execution_fence)) {
DCHECK(!g_current_browser_main_loop);
+ DCHECK(scoped_execution_fence_)
+ << "TaskScheduler must be halted before kicking off content.";
g_current_browser_main_loop = this;
if (GetContentClient()->browser()->ShouldCreateTaskScheduler()) {
@@ -617,29 +611,11 @@ int BrowserMainLoop::EarlyInitialization() {
#endif // defined(USE_GLIB)
if (parts_) {
-#if defined(OS_WIN)
- // If we're running tests (ui_task is non-null), then the ResourceBundle
- // has already been initialized.
- if (!parameters_.ui_task) {
- // Override the configured locale with the user's preferred UI language.
- l10n_util::OverrideLocaleWithUILanguageList();
- }
-#endif
const int pre_early_init_error_code = parts_->PreEarlyInitialization();
if (pre_early_init_error_code != service_manager::RESULT_CODE_NORMAL_EXIT)
return pre_early_init_error_code;
}
- if (!parts_ || parts_->ShouldContentCreateFeatureList()) {
- // Note that we do not initialize a new FeatureList when calling this for
- // the second time.
- const base::CommandLine* command_line =
- base::CommandLine::ForCurrentProcess();
- base::FeatureList::InitializeInstance(
- command_line->GetSwitchValueASCII(switches::kEnableFeatures),
- command_line->GetSwitchValueASCII(switches::kDisableFeatures));
- }
-
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
// Up the priority of the UI thread unless it was already high (since recent
// versions of Android (O+) do this automatically).
@@ -732,6 +708,13 @@ void BrowserMainLoop::PostMainMessageLoopStart() {
network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
}
{
+ TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:ScreenlockMonitor");
+ std::unique_ptr<ScreenlockMonitorSource> screenlock_monitor_source =
+ std::make_unique<ScreenlockMonitorDeviceSource>();
+ screenlock_monitor_ = std::make_unique<ScreenlockMonitor>(
+ std::move(screenlock_monitor_source));
+ }
+ {
TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MediaFeatures");
media::InitializeMediaLibrary();
}
@@ -755,7 +738,7 @@ void BrowserMainLoop::PostMainMessageLoopStart() {
{
base::SetRecordActionTaskRunner(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}));
}
if (!features::IsMultiProcessMash()) {
@@ -960,31 +943,8 @@ void BrowserMainLoop::SynchronouslyFlushStartupTasks() {
int BrowserMainLoop::CreateThreads() {
TRACE_EVENT0("startup,rail", "BrowserMainLoop::CreateThreads");
- {
- auto task_scheduler_init_params =
- GetContentClient()->browser()->GetTaskSchedulerInitParams();
- if (!task_scheduler_init_params)
- task_scheduler_init_params = GetDefaultTaskSchedulerInitParams();
- DCHECK(task_scheduler_init_params);
-
- // If a renderer lives in the browser process, adjust the number of threads
- // in the foreground pool.
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kSingleProcess)) {
- const base::SchedulerWorkerPoolParams&
- current_foreground_worker_pool_params(
- task_scheduler_init_params->foreground_worker_pool_params);
- task_scheduler_init_params->foreground_worker_pool_params =
- base::SchedulerWorkerPoolParams(
- std::max(GetMinThreadsInRendererTaskSchedulerForegroundPool(),
- current_foreground_worker_pool_params.max_tasks()),
- current_foreground_worker_pool_params.suggested_reclaim_time(),
- current_foreground_worker_pool_params.backward_compatibility());
- }
-
- base::TaskScheduler::GetInstance()->Start(
- *task_scheduler_init_params.get());
- }
+ // Release the TaskScheduler's threads.
+ scoped_execution_fence_.reset();
// The |io_thread| can have optionally been injected into Init(), but if not,
// create it here. Thre thread is only tagged as BrowserThread::IO here in
@@ -1023,9 +983,8 @@ int BrowserMainLoop::PreMainMessageLoopRun() {
}
// If the UI thread blocks, the whole UI is unresponsive.
- // Do not allow disk IO from the UI thread.
- base::ThreadRestrictions::SetIOAllowed(false);
- base::ThreadRestrictions::DisallowWaiting();
+ // Do not allow unresponsive tasks from the UI thread.
+ base::DisallowUnresponsiveTasks();
return result_code_;
}
@@ -1054,8 +1013,8 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
// Teardown may start in PostMainMessageLoopRun, and during teardown we
// need to be able to perform IO.
base::ThreadRestrictions::SetIOAllowed(true);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), true));
@@ -1211,7 +1170,7 @@ void BrowserMainLoop::GetCompositingModeReporter(
// CompositingModeReporter.
return;
#else
- if (features::IsUsingWindowService()) {
+ if (features::IsMultiProcessMash()) {
// Mash == ChromeOS, which doesn't support software compositing, so no need
// to report compositing mode.
return;
@@ -1270,12 +1229,12 @@ int BrowserMainLoop::BrowserThreadsStarted() {
// BrowserGpuChannelHostFactory below, since that depends on an initialized
// ShaderCacheFactory.
InitShaderCacheFactorySingleton(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
// Initialize the FontRenderParams on IO thread. This needs to be initialized
// before gpu process initialization below.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&viz::GpuHostImpl::InitFontRenderParams,
gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr)));
@@ -1392,7 +1351,7 @@ int BrowserMainLoop::BrowserThreadsStarted() {
// network service.
resource_dispatcher_host_.reset(new ResourceDispatcherHostImpl(
base::Bind(&DownloadResourceHandler::Create),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
!parsed_command_line_.HasSwitch(switches::kDisableResourceScheduler)));
GetContentClient()->browser()->ResourceDispatcherHostCreated();
@@ -1458,8 +1417,8 @@ int BrowserMainLoop::BrowserThreadsStarted() {
!established_gpu_channel && always_uses_gpu && browser_is_viz_host) {
TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process",
TRACE_EVENT_SCOPE_THREAD);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(base::IgnoreResult(&GpuProcessHost::Get),
GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
true /* force_create */));
@@ -1498,21 +1457,7 @@ bool BrowserMainLoop::UsingInProcessGpu() const {
}
void BrowserMainLoop::InitializeMemoryManagementComponent() {
- // TODO(chrisha): Abstract away this construction mess to a helper function,
- // once MemoryPressureMonitor is made a concrete class.
-#if defined(OS_CHROMEOS)
- if (chromeos::switches::MemoryPressureHandlingEnabled()) {
- memory_pressure_monitor_ =
- std::make_unique<base::chromeos::MemoryPressureMonitor>(
- chromeos::switches::GetMemoryPressureThresholds());
- }
-#elif defined(OS_MACOSX)
- memory_pressure_monitor_ =
- std::make_unique<base::mac::MemoryPressureMonitor>();
-#elif defined(OS_WIN)
- memory_pressure_monitor_ =
- CreateWinMemoryPressureMonitor(parsed_command_line_);
-#endif
+ memory_pressure_monitor_ = CreateMemoryPressureMonitor(parsed_command_line_);
if (base::FeatureList::IsEnabled(features::kMemoryCoordinator))
MemoryCoordinatorImpl::GetInstance()->Start();
@@ -1575,7 +1520,7 @@ void BrowserMainLoop::MainMessageLoopRun() {
// Android's main message loop is the Java message loop.
NOTREACHED();
#else
- DCHECK(base::MessageLoopForUI::IsCurrent());
+ DCHECK(base::MessageLoopCurrentForUI::IsSet());
if (parameters_.ui_task) {
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
*parameters_.ui_task);
@@ -1596,7 +1541,7 @@ void BrowserMainLoop::InitializeMojo() {
}
mojo_ipc_support_.reset(new mojo::core::ScopedIPCSupport(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST));
service_manager_context_.reset(
@@ -1729,7 +1674,8 @@ void BrowserMainLoop::InitializeAudio() {
if (base::FeatureList::IsEnabled(features::kAudioServiceLaunchOnStartup)) {
// Schedule the audio service startup on the main thread.
BrowserThread::PostAfterStartupTask(
- FROM_HERE, BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
+ FROM_HERE,
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}),
base::BindOnce([]() {
TRACE_EVENT0("audio", "Starting audio service");
ServiceManagerConnection* connection =
diff --git a/chromium/content/browser/browser_main_loop.h b/chromium/content/browser/browser_main_loop.h
index feebf19dc5f..f9118502d31 100644
--- a/chromium/content/browser/browser_main_loop.h
+++ b/chromium/content/browser/browser_main_loop.h
@@ -11,6 +11,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/task/task_scheduler/task_scheduler.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "content/browser/browser_process_sub_thread.h"
@@ -95,6 +96,7 @@ class LoaderDelegateImpl;
class MediaStreamManager;
class ResourceDispatcherHostImpl;
class SaveFileManager;
+class ScreenlockMonitor;
class ServiceManagerContext;
class SpeechRecognitionManagerImpl;
class StartupTaskRunner;
@@ -128,7 +130,9 @@ class CONTENT_EXPORT BrowserMainLoop {
// The TaskScheduler instance must exist but not to be started when building
// BrowserMainLoop.
- explicit BrowserMainLoop(const MainFunctionParams& parameters);
+ explicit BrowserMainLoop(
+ const MainFunctionParams& parameters,
+ std::unique_ptr<base::TaskScheduler::ScopedExecutionFence> fence);
virtual ~BrowserMainLoop();
void Init();
@@ -284,6 +288,15 @@ class CONTENT_EXPORT BrowserMainLoop {
const base::CommandLine& parsed_command_line_;
int result_code_;
bool created_threads_; // True if the non-UI threads were created.
+ // //content must be initialized single-threaded until
+ // BrowserMainLoop::CreateThreads() as things initialized before it require an
+ // initialize-once happens-before relationship with all eventual content tasks
+ // running on other threads. This ScopedExecutionFence ensures that no tasks
+ // posted to TaskScheduler gets to run before CreateThreads(); satisfying this
+ // requirement even though the TaskScheduler is created and started before
+ // content is entered.
+ std::unique_ptr<base::TaskScheduler::ScopedExecutionFence>
+ scoped_execution_fence_;
// Members initialized in |MainMessageLoopStart()| ---------------------------
std::unique_ptr<base::MessageLoop> main_message_loop_;
@@ -294,6 +307,7 @@ class CONTENT_EXPORT BrowserMainLoop {
std::unique_ptr<base::PowerMonitor> power_monitor_;
std::unique_ptr<base::HighResolutionTimerManager> hi_res_timer_manager_;
std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
+ std::unique_ptr<ScreenlockMonitor> screenlock_monitor_;
// Per-process listener for online state changes.
std::unique_ptr<BrowserOnlineStateObserver> online_state_observer_;
diff --git a/chromium/content/browser/browser_main_loop_unittest.cc b/chromium/content/browser/browser_main_loop_unittest.cc
index a4bebc6547d..b5d345fc2d0 100644
--- a/chromium/content/browser/browser_main_loop_unittest.cc
+++ b/chromium/content/browser/browser_main_loop_unittest.cc
@@ -10,6 +10,8 @@
#include "base/task/task_scheduler/task_scheduler.h"
#include "base/test/scoped_command_line.h"
#include "content/browser/browser_thread_impl.h"
+#include "content/browser/scheduler/browser_task_executor.h"
+#include "content/browser/startup_helper.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
@@ -21,13 +23,17 @@ namespace content {
// the number of cores in its foreground pool.
TEST(BrowserMainLoopTest, CreateThreadsInSingleProcess) {
{
- base::TaskScheduler::Create("Browser");
base::test::ScopedCommandLine scoped_command_line;
scoped_command_line.GetProcessCommandLine()->AppendSwitch(
switches::kSingleProcess);
+ base::TaskScheduler::Create("Browser");
+ StartBrowserTaskScheduler();
+ BrowserTaskExecutor::Create();
MainFunctionParams main_function_params(
*scoped_command_line.GetProcessCommandLine());
- BrowserMainLoop browser_main_loop(main_function_params);
+ BrowserMainLoop browser_main_loop(
+ main_function_params,
+ std::make_unique<base::TaskScheduler::ScopedExecutionFence>());
browser_main_loop.MainMessageLoopStart();
browser_main_loop.Init();
browser_main_loop.CreateThreads();
@@ -37,6 +43,7 @@ TEST(BrowserMainLoopTest, CreateThreadsInSingleProcess) {
base::SysInfo::NumberOfProcessors() - 1);
browser_main_loop.ShutdownThreadsAndCleanUp();
}
+ BrowserTaskExecutor::ResetForTesting();
for (int id = BrowserThread::UI; id < BrowserThread::ID_COUNT; ++id) {
BrowserThreadImpl::ResetGlobalsForTesting(
static_cast<BrowserThread::ID>(id));
diff --git a/chromium/content/browser/browser_main_runner_impl.cc b/chromium/content/browser/browser_main_runner_impl.cc
index 94dc07ff40b..f779462715e 100644
--- a/chromium/content/browser/browser_main_runner_impl.cc
+++ b/chromium/content/browser/browser_main_runner_impl.cc
@@ -54,7 +54,10 @@ BrowserMainRunnerImpl* BrowserMainRunnerImpl::Create() {
}
BrowserMainRunnerImpl::BrowserMainRunnerImpl()
- : initialization_started_(false), is_shutdown_(false) {}
+ : initialization_started_(false),
+ is_shutdown_(false),
+ scoped_execution_fence_(
+ std::make_unique<base::TaskScheduler::ScopedExecutionFence>()) {}
BrowserMainRunnerImpl::~BrowserMainRunnerImpl() {
if (initialization_started_ && !is_shutdown_)
@@ -107,7 +110,8 @@ int BrowserMainRunnerImpl::Initialize(const MainFunctionParams& parameters) {
gfx::win::MaybeInitializeDirectWrite();
#endif // OS_WIN
- main_loop_.reset(new BrowserMainLoop(parameters));
+ main_loop_.reset(
+ new BrowserMainLoop(parameters, std::move(scoped_execution_fence_)));
main_loop_->Init();
diff --git a/chromium/content/browser/browser_main_runner_impl.h b/chromium/content/browser/browser_main_runner_impl.h
index 08e959ff7aa..7ab5d1c11e9 100644
--- a/chromium/content/browser/browser_main_runner_impl.h
+++ b/chromium/content/browser/browser_main_runner_impl.h
@@ -8,6 +8,7 @@
#include <memory>
#include "base/macros.h"
+#include "base/task/task_scheduler/task_scheduler.h"
#include "build/build_config.h"
#include "content/public/browser/browser_main_runner.h"
@@ -44,6 +45,12 @@ class BrowserMainRunnerImpl : public BrowserMainRunner {
// True if the runner has been shut down.
bool is_shutdown_;
+ // Prevents execution of TaskScheduler tasks from the moment content is
+ // entered. Handed off to |main_loop_| later so it can decide when to release
+ // worker threads again.
+ std::unique_ptr<base::TaskScheduler::ScopedExecutionFence>
+ scoped_execution_fence_;
+
std::unique_ptr<NotificationServiceImpl> notification_service_;
std::unique_ptr<BrowserMainLoop> main_loop_;
#if defined(OS_WIN)
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
index e5f885ab4bc..2c585e36dff 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -40,6 +40,7 @@
#include "content/common/input/ime_text_span_conversions.h"
#include "content/common/text_input_state.h"
#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
#include "content/public/browser/content_browser_client.h"
@@ -407,16 +408,6 @@ void BrowserPluginGuest::PointerLockPermissionResponse(bool allow) {
browser_plugin_instance_id(), allow));
}
-void BrowserPluginGuest::FirstSurfaceActivation(
- const viz::SurfaceInfo& surface_info) {
- if (!features::IsUsingWindowService() &&
- !features::IsSurfaceSynchronizationEnabled()) {
- SendMessageToEmbedder(
- std::make_unique<BrowserPluginMsg_FirstSurfaceActivation>(
- browser_plugin_instance_id(), surface_info));
- }
-}
-
void BrowserPluginGuest::ResendEventToEmbedder(
const blink::WebInputEvent& event) {
if (!attached() || !owner_web_contents_)
@@ -667,7 +658,7 @@ void BrowserPluginGuest::RenderViewReady() {
// In case we've created a new guest render process after a crash, let the
// associated BrowserPlugin know. We only need to send this if we're attached,
// as guest_crashed_ is cleared automatically on attach anyways.
- if (attached() && !features::IsUsingWindowService()) {
+ if (attached() && !features::IsMultiProcessMash()) {
RenderWidgetHostViewGuest* rwhv = static_cast<RenderWidgetHostViewGuest*>(
web_contents()->GetRenderWidgetHostView());
if (rwhv) {
@@ -726,12 +717,12 @@ bool BrowserPluginGuest::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message)
IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers,
OnHasTouchEventHandlers)
- IPC_MESSAGE_HANDLER(ViewHostMsg_LockMouse, OnLockMouse)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_LockMouse, OnLockMouse)
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus)
- IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_TextInputStateChanged,
OnTextInputStateChanged)
- IPC_MESSAGE_HANDLER(ViewHostMsg_UnlockMouse, OnUnlockMouse)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_UnlockMouse, OnUnlockMouse)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -955,7 +946,7 @@ void BrowserPluginGuest::OnLockMouse(bool user_gesture,
RenderWidgetHost* widget_host =
web_contents()->GetRenderViewHost()->GetWidget();
widget_host->Send(
- new ViewMsg_LockMouse_ACK(widget_host->GetRoutingID(), false));
+ new WidgetMsg_LockMouse_ACK(widget_host->GetRoutingID(), false));
return;
}
@@ -976,7 +967,7 @@ void BrowserPluginGuest::OnLockMouseAck(int browser_plugin_instance_id,
RenderWidgetHost* widget_host =
web_contents()->GetRenderViewHost()->GetWidget();
widget_host->Send(
- new ViewMsg_LockMouse_ACK(widget_host->GetRoutingID(), succeeded));
+ new WidgetMsg_LockMouse_ACK(widget_host->GetRoutingID(), succeeded));
pending_lock_request_ = false;
if (succeeded)
mouse_locked_ = true;
@@ -1030,7 +1021,7 @@ void BrowserPluginGuest::OnUnlockMouseAck(int browser_plugin_instance_id) {
if (mouse_locked_) {
RenderWidgetHost* widget_host =
web_contents()->GetRenderViewHost()->GetWidget();
- widget_host->Send(new ViewMsg_MouseLockLost(widget_host->GetRoutingID()));
+ widget_host->Send(new WidgetMsg_MouseLockLost(widget_host->GetRoutingID()));
}
mouse_locked_ = false;
}
@@ -1116,10 +1107,11 @@ void BrowserPluginGuest::OnShowPopup(
}
#endif
-void BrowserPluginGuest::OnShowWidget(int route_id,
+void BrowserPluginGuest::OnShowWidget(int widget_route_id,
const gfx::Rect& initial_rect) {
int process_id = GetWebContents()->GetMainFrame()->GetProcess()->GetID();
- GetWebContents()->ShowCreatedWidget(process_id, route_id, initial_rect);
+ GetWebContents()->ShowCreatedWidget(process_id, widget_route_id,
+ initial_rect);
}
void BrowserPluginGuest::OnTakeFocus(bool reverse) {
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.h b/chromium/content/browser/browser_plugin/browser_plugin_guest.h
index aab107192d0..c788a84e377 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.h
@@ -63,7 +63,6 @@ class RenderFrameMetadata;
namespace viz {
class LocalSurfaceId;
-class SurfaceInfo;
} // namespace viz
namespace content {
@@ -243,9 +242,6 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
void PointerLockPermissionResponse(bool allow);
- // The next function is virtual for test purposes.
- virtual void FirstSurfaceActivation(const viz::SurfaceInfo& surface_info);
-
void ResendEventToEmbedder(const blink::WebInputEvent& event);
// TODO(ekaramad): Remove this once https://crbug.com/642826 is resolved.
@@ -355,7 +351,7 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
void OnShowPopup(RenderFrameHost* render_frame_host,
const FrameHostMsg_ShowPopup_Params& params);
#endif
- void OnShowWidget(int route_id, const gfx::Rect& initial_rect);
+ void OnShowWidget(int widget_route_id, const gfx::Rect& initial_rect);
void OnTakeFocus(bool reverse);
void OnUpdateFrameName(int frame_id,
bool is_top_level,
diff --git a/chromium/content/browser/browser_process_sub_thread.cc b/chromium/content/browser/browser_process_sub_thread.cc
index 9172012c111..074fbfa8098 100644
--- a/chromium/content/browser/browser_process_sub_thread.cc
+++ b/chromium/content/browser/browser_process_sub_thread.cc
@@ -100,8 +100,7 @@ void BrowserProcessSubThread::Init() {
#endif
if (!is_blocking_allowed_for_testing_) {
- base::DisallowBlocking();
- base::DisallowBaseSyncPrimitives();
+ base::DisallowUnresponsiveTasks();
}
}
diff --git a/chromium/content/browser/browser_thread_impl.cc b/chromium/content/browser/browser_thread_impl.cc
index d90d84982a4..43c361db748 100644
--- a/chromium/content/browser/browser_thread_impl.cc
+++ b/chromium/content/browser/browser_thread_impl.cc
@@ -11,73 +11,20 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
-#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/no_destructor.h"
#include "base/sequence_checker.h"
#include "base/task/task_executor.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
-#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/content_browser_client.h"
namespace content {
namespace {
-// An implementation of SingleThreadTaskRunner to be used in conjunction
-// with BrowserThread.
-// TODO(gab): Consider replacing this with |g_globals->task_runners| -- only
-// works if none are requested before starting the threads.
-class BrowserThreadTaskRunner : public base::SingleThreadTaskRunner {
- public:
- explicit BrowserThreadTaskRunner(BrowserThread::ID identifier)
- : id_(identifier) {}
-
- // SingleThreadTaskRunner implementation.
- bool PostDelayedTask(const base::Location& from_here,
- base::OnceClosure task,
- base::TimeDelta delay) override {
- return BrowserThread::PostDelayedTask(id_, from_here, std::move(task),
- delay);
- }
-
- bool PostNonNestableDelayedTask(const base::Location& from_here,
- base::OnceClosure task,
- base::TimeDelta delay) override {
- return BrowserThread::PostNonNestableDelayedTask(id_, from_here,
- std::move(task), delay);
- }
-
- bool RunsTasksInCurrentSequence() const override {
- return BrowserThread::CurrentlyOn(id_);
- }
-
- protected:
- ~BrowserThreadTaskRunner() override {}
-
- private:
- BrowserThread::ID id_;
- DISALLOW_COPY_AND_ASSIGN(BrowserThreadTaskRunner);
-};
-
-// A separate helper is used just for the task runners, in order to avoid
-// needing to initialize the globals to create a task runner.
-struct BrowserThreadTaskRunners {
- BrowserThreadTaskRunners() {
- for (int i = 0; i < BrowserThread::ID_COUNT; ++i) {
- proxies[i] =
- new BrowserThreadTaskRunner(static_cast<BrowserThread::ID>(i));
- }
- }
-
- scoped_refptr<base::SingleThreadTaskRunner> proxies[BrowserThread::ID_COUNT];
-};
-
-base::LazyInstance<BrowserThreadTaskRunners>::Leaky g_task_runners =
- LAZY_INSTANCE_INITIALIZER;
-
// State of a given BrowserThread::ID in chronological order throughout the
// browser process' lifetime.
enum BrowserThreadState {
@@ -126,105 +73,11 @@ struct BrowserThreadGlobals {
base::subtle::Atomic32 states[BrowserThread::ID_COUNT] = {};
};
-base::LazyInstance<BrowserThreadGlobals>::Leaky
- g_globals = LAZY_INSTANCE_INITIALIZER;
-
-bool PostTaskHelper(BrowserThread::ID identifier,
- const base::Location& from_here,
- base::OnceClosure task,
- base::TimeDelta delay,
- bool nestable) {
- DCHECK_GE(identifier, 0);
- DCHECK_LT(identifier, BrowserThread::ID_COUNT);
-
- BrowserThreadGlobals& globals = g_globals.Get();
-
- // Tasks should always be posted while the BrowserThread is in a RUNNING or
- // SHUTDOWN state (will return false if SHUTDOWN).
- //
- // Posting tasks before BrowserThreads are initialized is incorrect as it
- // would silently no-op. If you need to support posting early, gate it on
- // BrowserThread::IsThreadInitialized(). If you hit this check in unittests,
- // you most likely posted a task outside the scope of a
- // TestBrowserThreadBundle (which also completely resets the state after
- // shutdown in ~TestBrowserThreadBundle(), ref. ResetGlobalsForTesting(),
- // making sure TestBrowserThreadBundle is the first member of your test
- // fixture and thus outlives everything is usually the right solution).
- DCHECK_GE(base::subtle::NoBarrier_Load(&globals.states[identifier]),
- BrowserThreadState::RUNNING);
- DCHECK(globals.task_runners[identifier]);
-
- if (nestable) {
- return globals.task_runners[identifier]->PostDelayedTask(
- from_here, std::move(task), delay);
- } else {
- return globals.task_runners[identifier]->PostNonNestableDelayedTask(
- from_here, std::move(task), delay);
- }
+BrowserThreadGlobals& GetBrowserThreadGlobals() {
+ static base::NoDestructor<BrowserThreadGlobals> globals;
+ return *globals;
}
-class BrowserThreadTaskExecutor : public base::TaskExecutor {
- public:
- BrowserThreadTaskExecutor() {}
- ~BrowserThreadTaskExecutor() override {}
-
- // base::TaskExecutor implementation.
- bool PostDelayedTaskWithTraits(const base::Location& from_here,
- const base::TaskTraits& traits,
- base::OnceClosure task,
- base::TimeDelta delay) override {
- return PostTaskHelper(
- GetBrowserThreadIdentifier(traits), from_here, std::move(task), delay,
- traits.GetExtension<BrowserTaskTraitsExtension>().nestable());
- }
-
- scoped_refptr<base::TaskRunner> CreateTaskRunnerWithTraits(
- const base::TaskTraits& traits) override {
- return GetTaskRunnerForThread(GetBrowserThreadIdentifier(traits));
- }
-
- scoped_refptr<base::SequencedTaskRunner> CreateSequencedTaskRunnerWithTraits(
- const base::TaskTraits& traits) override {
- return GetTaskRunnerForThread(GetBrowserThreadIdentifier(traits));
- }
-
- scoped_refptr<base::SingleThreadTaskRunner>
- CreateSingleThreadTaskRunnerWithTraits(
- const base::TaskTraits& traits,
- base::SingleThreadTaskRunnerThreadMode thread_mode) override {
- // It's not possible to request DEDICATED access to a BrowserThread.
- DCHECK_EQ(thread_mode, base::SingleThreadTaskRunnerThreadMode::SHARED);
- return GetTaskRunnerForThread(GetBrowserThreadIdentifier(traits));
- }
-
-#if defined(OS_WIN)
- scoped_refptr<base::SingleThreadTaskRunner> CreateCOMSTATaskRunnerWithTraits(
- const base::TaskTraits& traits,
- base::SingleThreadTaskRunnerThreadMode thread_mode) override {
- // Only the UI thread supports COM.
- DCHECK_EQ(GetBrowserThreadIdentifier(traits), BrowserThread::UI);
- return CreateSingleThreadTaskRunnerWithTraits(traits, thread_mode);
- }
-#endif // defined(OS_WIN)
-
- private:
- BrowserThread::ID GetBrowserThreadIdentifier(const base::TaskTraits& traits) {
- DCHECK_EQ(traits.extension_id(), BrowserTaskTraitsExtension::kExtensionId);
- BrowserThread::ID id =
- traits.GetExtension<BrowserTaskTraitsExtension>().browser_thread();
- DCHECK_LT(id, BrowserThread::ID_COUNT);
- return id;
- }
-
- scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunnerForThread(
- BrowserThread::ID identifier) {
- return g_task_runners.Get().proxies[identifier];
- }
-};
-
-// |g_browser_thread_task_executor| is intentionally leaked on shutdown.
-BrowserThreadTaskExecutor* g_browser_thread_task_executor = nullptr;
-
} // namespace
BrowserThreadImpl::BrowserThreadImpl(
@@ -235,7 +88,7 @@ BrowserThreadImpl::BrowserThreadImpl(
DCHECK_LT(identifier_, ID_COUNT);
DCHECK(task_runner);
- BrowserThreadGlobals& globals = g_globals.Get();
+ BrowserThreadGlobals& globals = GetBrowserThreadGlobals();
DCHECK_CALLED_ON_VALID_THREAD(globals.main_thread_checker_);
@@ -249,7 +102,7 @@ BrowserThreadImpl::BrowserThreadImpl(
}
BrowserThreadImpl::~BrowserThreadImpl() {
- BrowserThreadGlobals& globals = g_globals.Get();
+ BrowserThreadGlobals& globals = GetBrowserThreadGlobals();
DCHECK_CALLED_ON_VALID_THREAD(globals.main_thread_checker_);
DCHECK_EQ(base::subtle::NoBarrier_Load(&globals.states[identifier_]),
@@ -265,7 +118,7 @@ BrowserThreadImpl::~BrowserThreadImpl() {
// static
void BrowserThreadImpl::ResetGlobalsForTesting(BrowserThread::ID identifier) {
- BrowserThreadGlobals& globals = g_globals.Get();
+ BrowserThreadGlobals& globals = GetBrowserThreadGlobals();
DCHECK_CALLED_ON_VALID_THREAD(globals.main_thread_checker_);
DCHECK_EQ(base::subtle::NoBarrier_Load(&globals.states[identifier]),
@@ -304,7 +157,7 @@ bool BrowserThread::IsThreadInitialized(ID identifier) {
DCHECK_GE(identifier, 0);
DCHECK_LT(identifier, ID_COUNT);
- BrowserThreadGlobals& globals = g_globals.Get();
+ BrowserThreadGlobals& globals = GetBrowserThreadGlobals();
return base::subtle::NoBarrier_Load(&globals.states[identifier]) ==
BrowserThreadState::RUNNING;
}
@@ -314,7 +167,7 @@ bool BrowserThread::CurrentlyOn(ID identifier) {
DCHECK_GE(identifier, 0);
DCHECK_LT(identifier, ID_COUNT);
- BrowserThreadGlobals& globals = g_globals.Get();
+ BrowserThreadGlobals& globals = GetBrowserThreadGlobals();
// Thread-safe since |globals.task_runners| is read-only after being
// initialized from main thread (which happens before //content and embedders
@@ -338,49 +191,9 @@ std::string BrowserThread::GetDCheckCurrentlyOnErrorMessage(ID expected) {
return result;
}
-bool BrowserThread::PostTask(ID identifier,
- const base::Location& from_here,
- base::OnceClosure task) {
- return PostTaskHelper(identifier, from_here, std::move(task),
- base::TimeDelta(), true);
-}
-
-// static
-bool BrowserThread::PostDelayedTask(ID identifier,
- const base::Location& from_here,
- base::OnceClosure task,
- base::TimeDelta delay) {
- return PostTaskHelper(identifier, from_here, std::move(task), delay, true);
-}
-
-// static
-bool BrowserThread::PostNonNestableTask(ID identifier,
- const base::Location& from_here,
- base::OnceClosure task) {
- return PostTaskHelper(identifier, from_here, std::move(task),
- base::TimeDelta(), false);
-}
-
-// static
-bool BrowserThread::PostNonNestableDelayedTask(ID identifier,
- const base::Location& from_here,
- base::OnceClosure task,
- base::TimeDelta delay) {
- return PostTaskHelper(identifier, from_here, std::move(task), delay, false);
-}
-
-// static
-bool BrowserThread::PostTaskAndReply(ID identifier,
- const base::Location& from_here,
- base::OnceClosure task,
- base::OnceClosure reply) {
- return GetTaskRunnerForThread(identifier)
- ->PostTaskAndReply(from_here, std::move(task), std::move(reply));
-}
-
// static
bool BrowserThread::GetCurrentThreadIdentifier(ID* identifier) {
- BrowserThreadGlobals& globals = g_globals.Get();
+ BrowserThreadGlobals& globals = GetBrowserThreadGlobals();
// Thread-safe since |globals.task_runners| is read-only after being
// initialized from main thread (which happens before //content and embedders
@@ -400,24 +213,27 @@ bool BrowserThread::GetCurrentThreadIdentifier(ID* identifier) {
// static
scoped_refptr<base::SingleThreadTaskRunner>
BrowserThread::GetTaskRunnerForThread(ID identifier) {
- return g_task_runners.Get().proxies[identifier];
-}
+ DCHECK_GE(identifier, 0);
+ DCHECK_LT(identifier, ID_COUNT);
-// static
-void BrowserThreadImpl::CreateTaskExecutor() {
- DCHECK(!g_browser_thread_task_executor);
- g_browser_thread_task_executor = new BrowserThreadTaskExecutor();
- base::RegisterTaskExecutor(BrowserTaskTraitsExtension::kExtensionId,
- g_browser_thread_task_executor);
-}
+ BrowserThreadGlobals& globals = GetBrowserThreadGlobals();
-// static
-void BrowserThreadImpl::ResetTaskExecutorForTesting() {
- DCHECK(g_browser_thread_task_executor);
- base::UnregisterTaskExecutorForTesting(
- BrowserTaskTraitsExtension::kExtensionId);
- delete g_browser_thread_task_executor;
- g_browser_thread_task_executor = nullptr;
+ // Tasks should always be posted while the BrowserThread is in a RUNNING or
+ // SHUTDOWN state (will return false if SHUTDOWN).
+ //
+ // Posting tasks before BrowserThreads are initialized is incorrect as it
+ // would silently no-op. If you need to support posting early, gate it on
+ // BrowserThread::IsThreadInitialized(). If you hit this check in unittests,
+ // you most likely posted a task outside the scope of a
+ // TestBrowserThreadBundle (which also completely resets the state after
+ // shutdown in ~TestBrowserThreadBundle(), ref. ResetGlobalsForTesting(),
+ // making sure TestBrowserThreadBundle is the first member of your test
+ // fixture and thus outlives everything is usually the right solution).
+ DCHECK_GE(base::subtle::NoBarrier_Load(&globals.states[identifier]),
+ BrowserThreadState::RUNNING);
+ DCHECK(globals.task_runners[identifier]);
+
+ return globals.task_runners[identifier];
}
} // namespace content
diff --git a/chromium/content/browser/browser_thread_impl.h b/chromium/content/browser/browser_thread_impl.h
index 5789a29e1c5..a09d5832607 100644
--- a/chromium/content/browser/browser_thread_impl.h
+++ b/chromium/content/browser/browser_thread_impl.h
@@ -39,12 +39,9 @@ class CONTENT_EXPORT BrowserThreadImpl : public BrowserThread {
// |identifier|.
static void ResetGlobalsForTesting(BrowserThread::ID identifier);
- // Creates and registers a TaskExecutor that facilitates posting tasks to a
- // BrowserThread via //base/task/post_task.h.
- static void CreateTaskExecutor();
-
- // Unregister and delete the TaskExecutor after a test.
- static void ResetTaskExecutorForTesting();
+ // Exposed for BrowserTaskExecutor. Other code should use
+ // base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI/IO}).
+ using BrowserThread::GetTaskRunnerForThread;
private:
// Restrict instantiation to BrowserProcessSubThread as it performs important
diff --git a/chromium/content/browser/browser_thread_unittest.cc b/chromium/content/browser/browser_thread_unittest.cc
index f27b5b97f7f..377f0cbf866 100644
--- a/chromium/content/browser/browser_thread_unittest.cc
+++ b/chromium/content/browser/browser_thread_unittest.cc
@@ -18,6 +18,7 @@
#include "build/build_config.h"
#include "content/browser/browser_process_sub_thread.h"
#include "content/browser/browser_thread_impl.h"
+#include "content/browser/scheduler/browser_task_executor.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -37,7 +38,7 @@ class BrowserThreadTest : public testing::Test {
protected:
void SetUp() override {
- BrowserThreadImpl::CreateTaskExecutor();
+ BrowserTaskExecutor::Create();
ui_thread_ = std::make_unique<BrowserProcessSubThread>(BrowserThread::UI);
ui_thread_->Start();
@@ -57,7 +58,7 @@ class BrowserThreadTest : public testing::Test {
BrowserThreadImpl::ResetGlobalsForTesting(BrowserThread::UI);
BrowserThreadImpl::ResetGlobalsForTesting(BrowserThread::IO);
- BrowserThreadImpl::ResetTaskExecutorForTesting();
+ BrowserTaskExecutor::ResetForTesting();
}
// Prepares this BrowserThreadTest for Release() to be invoked. |on_release|
@@ -110,10 +111,9 @@ class UIThreadDestructionObserver
: callback_task_runner_(base::ThreadTaskRunnerHandle::Get()),
callback_(callback),
ui_task_runner_(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})),
did_shutdown_(did_shutdown) {
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)
- ->PostTask(FROM_HERE, base::BindOnce(&Watch, this));
+ ui_task_runner_->PostTask(FROM_HERE, base::BindOnce(&Watch, this));
}
private:
@@ -140,15 +140,6 @@ class UIThreadDestructionObserver
bool* did_shutdown_;
};
-TEST_F(BrowserThreadTest, PostTask) {
- base::RunLoop run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&BasicFunction, run_loop.QuitWhenIdleClosure(),
- BrowserThread::IO));
- run_loop.Run();
-}
-
TEST_F(BrowserThreadTest, PostTaskWithTraits) {
base::RunLoop run_loop;
EXPECT_TRUE(base::PostTaskWithTraits(
@@ -174,16 +165,6 @@ TEST_F(BrowserThreadTest, ReleasedOnCorrectThread) {
run_loop.Run();
}
-TEST_F(BrowserThreadTest, PostTaskViaTaskRunner) {
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
- base::RunLoop run_loop;
- task_runner->PostTask(
- FROM_HERE, base::BindOnce(&BasicFunction, run_loop.QuitWhenIdleClosure(),
- BrowserThread::IO));
- run_loop.Run();
-}
-
TEST_F(BrowserThreadTest, PostTaskViaTaskRunnerWithTraits) {
scoped_refptr<base::TaskRunner> task_runner =
base::CreateTaskRunnerWithTraits({BrowserThread::IO});
@@ -226,16 +207,6 @@ TEST_F(BrowserThreadTest, PostTaskViaCOMSTATaskRunnerWithTraits) {
}
#endif // defined(OS_WIN)
-TEST_F(BrowserThreadTest, ReleaseViaTaskRunner) {
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
-
- base::RunLoop run_loop;
- ExpectRelease(run_loop.QuitWhenIdleClosure());
- task_runner->ReleaseSoon(FROM_HERE, this);
- run_loop.Run();
-}
-
TEST_F(BrowserThreadTest, ReleaseViaTaskRunnerWithTraits) {
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
@@ -245,16 +216,6 @@ TEST_F(BrowserThreadTest, ReleaseViaTaskRunnerWithTraits) {
run_loop.Run();
}
-TEST_F(BrowserThreadTest, PostTaskAndReply) {
- // Most of the heavy testing for PostTaskAndReply() is done inside the
- // task runner test. This just makes sure we get piped through at all.
- base::RunLoop run_loop;
- ASSERT_TRUE(BrowserThread::PostTaskAndReply(BrowserThread::IO, FROM_HERE,
- base::DoNothing(),
- run_loop.QuitWhenIdleClosure()));
- run_loop.Run();
-}
-
TEST_F(BrowserThreadTest, PostTaskAndReplyWithTraits) {
// Most of the heavy testing for PostTaskAndReply() is done inside the
// task runner test. This just makes sure we get piped through at all.
diff --git a/chromium/content/browser/browsing_data/OWNERS b/chromium/content/browser/browsing_data/OWNERS
index 4b224ec6732..24085194c54 100644
--- a/chromium/content/browser/browsing_data/OWNERS
+++ b/chromium/content/browser/browsing_data/OWNERS
@@ -1,4 +1,3 @@
-bauerb@chromium.org
dullweber@chromium.org
markusheintz@chromium.org
jsbell@chromium.org
diff --git a/chromium/content/browser/browsing_data/browsing_data_filter_builder_impl.cc b/chromium/content/browser/browsing_data/browsing_data_filter_builder_impl.cc
index e569410d369..b06695ab36a 100644
--- a/chromium/content/browser/browsing_data/browsing_data_filter_builder_impl.cc
+++ b/chromium/content/browser/browsing_data/browsing_data_filter_builder_impl.cc
@@ -100,7 +100,7 @@ void BrowsingDataFilterBuilderImpl::AddOrigin(const url::Origin& origin) {
// This means that std::set::find() will use the same semantics for
// origin comparison as Origin::IsSameOriginWith(). Furthermore, this
// means that two filters are equal iff they are equal element-wise.
- DCHECK(!origin.unique()) << "Invalid origin passed into OriginFilter.";
+ DCHECK(!origin.opaque()) << "Invalid origin passed into OriginFilter.";
// TODO(msramek): All urls with file scheme currently map to the same
// origin. This is currently not a problem, but if it becomes one,
diff --git a/chromium/content/browser/browsing_data/browsing_data_remover_impl.cc b/chromium/content/browser/browsing_data/browsing_data_remover_impl.cc
index 5d0afd56593..cf3cedd6053 100644
--- a/chromium/content/browser/browsing_data/browsing_data_remover_impl.cc
+++ b/chromium/content/browser/browsing_data/browsing_data_remover_impl.cc
@@ -17,8 +17,10 @@
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/stl_util.h"
+#include "base/task/post_task.h"
#include "content/browser/browsing_data/storage_partition_http_cache_data_remover.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_filter_builder.h"
#include "content/public/browser/browsing_data_remover_delegate.h"
@@ -580,8 +582,8 @@ void BrowsingDataRemoverImpl::Notify() {
// Yield to the UI thread before executing the next removal task.
// TODO(msramek): Consider also adding a backoff if too many tasks
// are scheduled.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&BrowsingDataRemoverImpl::RunNextTask, GetWeakPtr()));
}
diff --git a/chromium/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc b/chromium/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
index a82100fd443..973d3d451b4 100644
--- a/chromium/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
+++ b/chromium/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
@@ -24,10 +24,12 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/cancelable_task_tracker.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "content/browser/browsing_data/browsing_data_remover_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browsing_data_filter_builder.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/cookie_store_factory.h"
@@ -174,8 +176,8 @@ class StoragePartitionRemovalTestStoragePartition
storage_partition_removal_data_.remove_end = end;
storage_partition_removal_data_.origin_matcher = origin_matcher;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&StoragePartitionRemovalTestStoragePartition::AsyncRunCallback,
base::Unretained(this), std::move(callback)));
@@ -198,8 +200,8 @@ class StoragePartitionRemovalTestStoragePartition
storage_partition_removal_data_.cookie_deletion_filter =
std::move(cookie_deletion_filter);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&StoragePartitionRemovalTestStoragePartition::AsyncRunCallback,
base::Unretained(this), std::move(callback)));
diff --git a/chromium/content/browser/browsing_data/clear_site_data_handler.cc b/chromium/content/browser/browsing_data/clear_site_data_handler.cc
index fc99ea9a22b..902c6b64ebc 100644
--- a/chromium/content/browser/browsing_data/clear_site_data_handler.cc
+++ b/chromium/content/browser/browsing_data/clear_site_data_handler.cc
@@ -290,7 +290,7 @@ bool ClearSiteDataHandler::Run() {
}
url::Origin origin = url::Origin::Create(url_);
- if (origin.unique()) {
+ if (origin.opaque()) {
delegate_->AddMessage(url_, "Not supported for unique origins.",
CONSOLE_MESSAGE_LEVEL_ERROR);
return false;
diff --git a/chromium/content/browser/browsing_data/clear_site_data_handler_browsertest.cc b/chromium/content/browser/browsing_data/clear_site_data_handler_browsertest.cc
index 0bf7f3c6adc..58b7e32758a 100644
--- a/chromium/content/browser/browsing_data/clear_site_data_handler_browsertest.cc
+++ b/chromium/content/browser/browsing_data/clear_site_data_handler_browsertest.cc
@@ -12,12 +12,14 @@
#include "base/scoped_observer.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/browser/browsing_data/browsing_data_filter_builder_impl.h"
#include "content/browser/service_worker/service_worker_context_core_observer.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/content_browser_client.h"
@@ -206,8 +208,8 @@ class ClearSiteDataHandlerBrowserTest : public ContentBrowserTest {
// Initialize the cookie store pointer on the IO thread.
base::RunLoop run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ClearSiteDataHandlerBrowserTest::InitializeCookieStore,
base::Unretained(this),
@@ -275,9 +277,10 @@ class ClearSiteDataHandlerBrowserTest : public ContentBrowserTest {
// Register the worker.
blink::mojom::ServiceWorkerRegistrationOptions options(
- scope_url, blink::mojom::ServiceWorkerUpdateViaCache::kImports);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ scope_url, blink::mojom::ScriptType::kClassic,
+ blink::mojom::ServiceWorkerUpdateViaCache::kImports);
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ServiceWorkerContextWrapper::RegisterServiceWorker,
base::Unretained(service_worker_context), js_url, options,
@@ -287,8 +290,8 @@ class ClearSiteDataHandlerBrowserTest : public ContentBrowserTest {
// Wait for its activation.
base::RunLoop run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerActivationObserver::SignalActivation,
base::Unretained(service_worker_context),
run_loop.QuitClosure()));
@@ -306,8 +309,8 @@ class ClearSiteDataHandlerBrowserTest : public ContentBrowserTest {
std::vector<ServiceWorkerUsageInfo> service_workers;
base::RunLoop run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ServiceWorkerContextWrapper::GetAllOriginsInfo,
base::Unretained(service_worker_context),
diff --git a/chromium/content/browser/browsing_data/clear_site_data_throttle.cc b/chromium/content/browser/browsing_data/clear_site_data_throttle.cc
index ba0a6e39c53..d1a6df336c5 100644
--- a/chromium/content/browser/browsing_data/clear_site_data_throttle.cc
+++ b/chromium/content/browser/browsing_data/clear_site_data_throttle.cc
@@ -11,9 +11,11 @@
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/values.h"
#include "content/browser/service_worker/service_worker_response_info.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_filter_builder.h"
#include "content/public/browser/browsing_data_remover.h"
@@ -72,7 +74,7 @@ int ParametersMask2(bool clear_cookies, bool clear_storage, bool clear_cache) {
// the UI thread.
void JumpFromUIToIOThread(base::OnceClosure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, std::move(callback));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO}, std::move(callback));
}
// Finds the BrowserContext associated with the request and requests
@@ -256,8 +258,8 @@ void ClearSiteDataThrottle::ConsoleMessagesDelegate::OutputMessages(
return;
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&OutputMessagesOnUIThread, web_contents_getter,
std::move(messages_), output_formatted_message_function_));
@@ -367,7 +369,7 @@ bool ClearSiteDataThrottle::HandleHeader() {
}
url::Origin origin = url::Origin::Create(GetCurrentURL());
- if (origin.unique()) {
+ if (origin.opaque()) {
delegate_->AddMessage(GetCurrentURL(), "Not supported for unique origins.",
CONSOLE_MESSAGE_LEVEL_ERROR);
return false;
@@ -523,8 +525,8 @@ void ClearSiteDataThrottle::ExecuteClearingTask(const url::Origin& origin,
bool clear_cache,
base::OnceClosure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&UIThreadSiteDataClearer::Run,
ResourceRequestInfo::ForRequest(request_)
->GetWebContentsGetterForRequest(),
diff --git a/chromium/content/browser/browsing_data/clear_site_data_throttle_unittest.cc b/chromium/content/browser/browsing_data/clear_site_data_throttle_unittest.cc
index 5af116cf2f6..4630b9cff5d 100644
--- a/chromium/content/browser/browsing_data/clear_site_data_throttle_unittest.cc
+++ b/chromium/content/browser/browsing_data/clear_site_data_throttle_unittest.cc
@@ -9,8 +9,10 @@
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_task_environment.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/test_browser_thread.h"
@@ -38,7 +40,8 @@ const char kClearCookiesHeader[] = "Clear-Site-Data: \"cookies\"";
void WaitForUIThread() {
base::RunLoop run_loop;
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, run_loop.QuitClosure());
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ run_loop.QuitClosure());
run_loop.Run();
}
diff --git a/chromium/content/browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc b/chromium/content/browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc
index 3d4ecc58671..9857560d855 100644
--- a/chromium/content/browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc
+++ b/chromium/content/browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc
@@ -10,10 +10,12 @@
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "content/browser/browsing_data/conditional_cache_deletion_helper.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
@@ -103,8 +105,8 @@ IN_PROC_BROWSER_TEST_F(ConditionalCacheDeletionHelperBrowserTest, Condition) {
GetCacheTestUtil()->CreateCacheEntries(keys);
// Delete the entries whose keys are even numbers.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ConditionalCacheDeletionHelperBrowserTest::DeleteEntries,
base::Unretained(this), base::Bind(&KeyIsEven)));
WaitForTasksOnIOThread();
@@ -163,8 +165,8 @@ IN_PROC_BROWSER_TEST_F(ConditionalCacheDeletionHelperBrowserTest,
base::Bind(&HasHttpsExampleOrigin), now, base::Time::Max());
// Delete the entries.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ConditionalCacheDeletionHelperBrowserTest::DeleteEntries,
base::Unretained(this), std::move(condition)));
WaitForTasksOnIOThread();
diff --git a/chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.cc b/chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.cc
index a6551a0c099..1f0e36632e8 100644
--- a/chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.cc
+++ b/chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.cc
@@ -7,10 +7,12 @@
#include "base/location.h"
#include "base/sequenced_task_runner_helpers.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/browsing_data/conditional_cache_deletion_helper.h"
#include "content/browser/code_cache/generated_code_cache.h"
#include "content/browser/code_cache/generated_code_cache_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_features.h"
@@ -73,8 +75,8 @@ void StoragePartitionHttpCacheDataRemover::Remove(
DCHECK(!done_callback.is_null());
done_callback_ = std::move(done_callback);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&StoragePartitionHttpCacheDataRemover::ClearHttpCacheOnIOThread,
base::Unretained(this)));
@@ -97,8 +99,8 @@ void StoragePartitionHttpCacheDataRemover::ClearedHttpCache() {
// The expected state sequence is CacheState::NONE --> CacheState::CREATE_MAIN
// --> CacheState::DELETE_MAIN --> CacheState::CREATE_MEDIA -->
-// CacheState::DELETE_MEDIA --> CacheState::DELETE_CODE --> CacheState::DONE,
-// and any errors are ignored.
+// CacheState::DELETE_MEDIA --> CacheState::DELETE_CODE_JS --> DELETE_CODE_WASM
+// -> CacheState::DONE, and any errors are ignored.
void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) {
DCHECK_NE(CacheState::NONE, next_cache_state_);
@@ -116,7 +118,7 @@ void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) {
if (!getter) {
next_cache_state_ = (next_cache_state_ == CacheState::CREATE_MAIN)
? CacheState::CREATE_MEDIA
- : CacheState::DELETE_CODE;
+ : CacheState::DELETE_CODE_JS;
break;
}
@@ -143,7 +145,7 @@ void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) {
case CacheState::DELETE_MEDIA: {
next_cache_state_ = (next_cache_state_ == CacheState::DELETE_MAIN)
? CacheState::CREATE_MEDIA
- : CacheState::DELETE_CODE;
+ : CacheState::DELETE_CODE_JS;
// |cache_| can be null if it cannot be initialized.
if (cache_) {
@@ -170,21 +172,28 @@ void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) {
}
break;
}
- case CacheState::DELETE_CODE: {
+ case CacheState::DELETE_CODE_JS: {
+ next_cache_state_ = CacheState::DELETE_CODE_WASM;
+ // TODO(crbug.com/866419): Currently we just clear entire caches.
+ // Change it to conditionally clear entries based on the filters.
+ // Likewise for DELETE_CODE_WASM.
+ if (generated_code_cache_context_ &&
+ generated_code_cache_context_->generated_js_code_cache()) {
+ rv = generated_code_cache_context_->generated_js_code_cache()
+ ->ClearCache(base::BindRepeating(
+ &StoragePartitionHttpCacheDataRemover::DoClearCache,
+ base::Unretained(this)));
+ }
+ break;
+ }
+ case CacheState::DELETE_CODE_WASM: {
next_cache_state_ = CacheState::DONE;
- if (base::FeatureList::IsEnabled(features::kIsolatedCodeCache)) {
- DCHECK(generated_code_cache_context_);
- GeneratedCodeCache* code_cache =
- generated_code_cache_context_->generated_code_cache();
- if (code_cache) {
- auto callback = base::BindRepeating(
- &StoragePartitionHttpCacheDataRemover::DoClearCache,
- base::Unretained(this));
- // TODO(crbug.com/866419): Currently we just clear the entire cache.
- // Change it to conditionally clear the entries based on the
- // filters.
- rv = code_cache->ClearCache(callback);
- }
+ if (generated_code_cache_context_ &&
+ generated_code_cache_context_->generated_wasm_code_cache()) {
+ rv = generated_code_cache_context_->generated_wasm_code_cache()
+ ->ClearCache(base::BindRepeating(
+ &StoragePartitionHttpCacheDataRemover::DoClearCache,
+ base::Unretained(this)));
}
break;
}
@@ -193,8 +202,8 @@ void StoragePartitionHttpCacheDataRemover::DoClearCache(int rv) {
next_cache_state_ = CacheState::NONE;
// Notify the UI thread that we are done.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&StoragePartitionHttpCacheDataRemover::ClearedHttpCache,
base::Unretained(this)));
diff --git a/chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.h b/chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.h
index 665a8f4e6b8..e9bf114541a 100644
--- a/chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.h
+++ b/chromium/content/browser/browsing_data/storage_partition_http_cache_data_remover.h
@@ -57,7 +57,8 @@ class StoragePartitionHttpCacheDataRemover {
CREATE_MEDIA,
DELETE_MAIN,
DELETE_MEDIA,
- DELETE_CODE,
+ DELETE_CODE_JS,
+ DELETE_CODE_WASM,
DONE
};
diff --git a/chromium/content/browser/browsing_instance.cc b/chromium/content/browser/browsing_instance.cc
index 9b24ae580a6..2b6c41a4b80 100644
--- a/chromium/content/browser/browsing_instance.cc
+++ b/chromium/content/browser/browsing_instance.cc
@@ -32,7 +32,7 @@ scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURL(
std::string site = SiteInstance::GetSiteForURL(browser_context_, url)
.possibly_invalid_spec();
- SiteInstanceMap::iterator i = site_instance_map_.find(site);
+ auto i = site_instance_map_.find(site);
if (i != site_instance_map_.end())
return i->second;
@@ -44,33 +44,10 @@ scoped_refptr<SiteInstanceImpl> BrowsingInstance::GetSiteInstanceForURL(
return instance;
}
-scoped_refptr<SiteInstanceImpl>
-BrowsingInstance::GetDefaultSubframeSiteInstance() {
- // This should only be used for --top-document-isolation mode.
- CHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled());
- if (!default_subframe_site_instance_) {
- SiteInstanceImpl* instance = new SiteInstanceImpl(this);
- instance->set_process_reuse_policy(
- SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS);
-
- // TODO(nick): This is a hack for now.
- instance->SetSite(GURL("http://web-subframes.invalid"));
-
- default_subframe_site_instance_ = instance;
- }
-
- return base::WrapRefCounted(default_subframe_site_instance_);
-}
-
void BrowsingInstance::RegisterSiteInstance(SiteInstanceImpl* site_instance) {
DCHECK(site_instance->browsing_instance_.get() == this);
DCHECK(site_instance->HasSite());
- // Don't register the default subframe SiteInstance, to prevent it from being
- // returned by GetSiteInstanceForURL.
- if (default_subframe_site_instance_ == site_instance)
- return;
-
std::string site = site_instance->GetSiteURL().possibly_invalid_spec();
// Only register if we don't have a SiteInstance for this site already.
@@ -78,7 +55,7 @@ void BrowsingInstance::RegisterSiteInstance(SiteInstanceImpl* site_instance) {
// tabs are navigated there at the same time. (We don't call SetSite or
// register them until DidNavigate.) If there is a previously existing
// SiteInstance for this site, we just won't register the new one.
- SiteInstanceMap::iterator i = site_instance_map_.find(site);
+ auto i = site_instance_map_.find(site);
if (i == site_instance_map_.end()) {
// Not previously registered, so register it.
site_instance_map_[site] = site_instance;
@@ -93,13 +70,11 @@ void BrowsingInstance::UnregisterSiteInstance(SiteInstanceImpl* site_instance) {
// Only unregister the SiteInstance if it is the same one that is registered
// for the site. (It might have been an unregistered SiteInstance. See the
// comments in RegisterSiteInstance.)
- SiteInstanceMap::iterator i = site_instance_map_.find(site);
+ auto i = site_instance_map_.find(site);
if (i != site_instance_map_.end() && i->second == site_instance) {
// Matches, so erase it.
site_instance_map_.erase(i);
}
- if (default_subframe_site_instance_ == site_instance)
- default_subframe_site_instance_ = nullptr;
}
BrowsingInstance::~BrowsingInstance() {
diff --git a/chromium/content/browser/browsing_instance.h b/chromium/content/browser/browsing_instance.h
index 2e17bf8d5c5..118f1781b30 100644
--- a/chromium/content/browser/browsing_instance.h
+++ b/chromium/content/browser/browsing_instance.h
@@ -87,12 +87,6 @@ class CONTENT_EXPORT BrowsingInstance final
// SiteInstance per site.
scoped_refptr<SiteInstanceImpl> GetSiteInstanceForURL(const GURL& url);
- // Returns a SiteInstance that should be used for subframes when an oopif is
- // required, but a dedicated process is not. This SiteInstance will be created
- // if it doesn't already exist. There is at most one of these per
- // BrowsingInstance.
- scoped_refptr<SiteInstanceImpl> GetDefaultSubframeSiteInstance();
-
// Adds the given SiteInstance to our map, to ensure that we do not create
// another SiteInstance for the same site.
void RegisterSiteInstance(SiteInstanceImpl* site_instance);
@@ -131,8 +125,6 @@ class CONTENT_EXPORT BrowsingInstance final
// Number of WebContentses currently using this BrowsingInstance.
size_t active_contents_count_;
- SiteInstanceImpl* default_subframe_site_instance_ = nullptr;
-
DISALLOW_COPY_AND_ASSIGN(BrowsingInstance);
};
diff --git a/chromium/content/browser/byte_stream.h b/chromium/content/browser/byte_stream.h
index 784bc67cc13..6e3719f0198 100644
--- a/chromium/content/browser/byte_stream.h
+++ b/chromium/content/browser/byte_stream.h
@@ -11,7 +11,9 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
+#include "base/task/post_task.h"
#include "content/common/content_export.h"
+#include "content/public/browser/browser_task_traits.h"
#include "net/base/io_buffer.h"
namespace base {
@@ -66,7 +68,7 @@ namespace content {
// std::unique_ptr<ByteStreamWriter> writer;
// std::unique_ptr<ByteStreamReader> reader;
// CreateByteStream(
-// BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+// base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
// base::CreateSequencedTaskRunnerWithTraits({base::MayBlock, ...}),
// kStreamBufferSize /* e.g. 10240. */,
// &writer,
diff --git a/chromium/content/browser/byte_stream_unittest.cc b/chromium/content/browser/byte_stream_unittest.cc
index 7335cf2f717..0d617d3b1fe 100644
--- a/chromium/content/browser/byte_stream_unittest.cc
+++ b/chromium/content/browser/byte_stream_unittest.cc
@@ -12,9 +12,10 @@
#include "base/callback.h"
#include "base/containers/circular_deque.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/test/test_simple_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "net/base/io_buffer.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -35,7 +36,8 @@ class ByteStreamTest : public testing::Test {
// contents of the created buffer will be kept, and can be validated
// by ValidateIOBuffer.
scoped_refptr<net::IOBuffer> NewIOBuffer(size_t buffer_size) {
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(buffer_size));
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(buffer_size);
char *bufferp = buffer->data();
for (size_t i = 0; i < buffer_size; i++)
bufferp[i] = (i + producing_seed_key_) % (1 << sizeof(char));
@@ -89,7 +91,7 @@ class ByteStreamTest : public testing::Test {
}
protected:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
private:
int producing_seed_key_;
@@ -107,8 +109,9 @@ ByteStreamTest::ByteStreamTest()
TEST_F(ByteStreamTest, ByteStream_PushBack) {
std::unique_ptr<ByteStreamWriter> byte_stream_input;
std::unique_ptr<ByteStreamReader> byte_stream_output;
- CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(),
- 3 * 1024, &byte_stream_input, &byte_stream_output);
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(), 3 * 1024,
+ &byte_stream_input, &byte_stream_output);
// Push a series of IO buffers on; test pushback happening and
// that it's advisory.
@@ -161,8 +164,9 @@ TEST_F(ByteStreamTest, ByteStream_PushBack) {
TEST_F(ByteStreamTest, ByteStream_Flush) {
std::unique_ptr<ByteStreamWriter> byte_stream_input;
std::unique_ptr<ByteStreamReader> byte_stream_output;
- CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(),
- 1024, &byte_stream_input, &byte_stream_output);
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(), 1024,
+ &byte_stream_input, &byte_stream_output);
EXPECT_TRUE(Write(byte_stream_input.get(), 1));
base::RunLoop().RunUntilIdle();
@@ -200,8 +204,9 @@ TEST_F(ByteStreamTest, ByteStream_Flush) {
TEST_F(ByteStreamTest, ByteStream_PushBackSplit) {
std::unique_ptr<ByteStreamWriter> byte_stream_input;
std::unique_ptr<ByteStreamReader> byte_stream_output;
- CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(),
- 9 * 1024, &byte_stream_input, &byte_stream_output);
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(), 9 * 1024,
+ &byte_stream_input, &byte_stream_output);
// Push a series of IO buffers on; test pushback happening and
// that it's advisory.
@@ -254,8 +259,9 @@ TEST_F(ByteStreamTest, ByteStream_CompleteTransmits) {
size_t output_length;
// Empty stream, non-error case.
- CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(),
- 3 * 1024, &byte_stream_input, &byte_stream_output);
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(), 3 * 1024,
+ &byte_stream_input, &byte_stream_output);
EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
byte_stream_output->Read(&output_io_buffer, &output_length));
byte_stream_input->Close(0);
@@ -265,8 +271,9 @@ TEST_F(ByteStreamTest, ByteStream_CompleteTransmits) {
EXPECT_EQ(0, byte_stream_output->GetStatus());
// Non-empty stream, non-error case.
- CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(),
- 3 * 1024, &byte_stream_input, &byte_stream_output);
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(), 3 * 1024,
+ &byte_stream_input, &byte_stream_output);
EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
byte_stream_output->Read(&output_io_buffer, &output_length));
EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
@@ -282,8 +289,9 @@ TEST_F(ByteStreamTest, ByteStream_CompleteTransmits) {
const int kFakeErrorCode = 22;
// Empty stream, error case.
- CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(),
- 3 * 1024, &byte_stream_input, &byte_stream_output);
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(), 3 * 1024,
+ &byte_stream_input, &byte_stream_output);
EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
byte_stream_output->Read(&output_io_buffer, &output_length));
byte_stream_input->Close(kFakeErrorCode);
@@ -293,8 +301,9 @@ TEST_F(ByteStreamTest, ByteStream_CompleteTransmits) {
EXPECT_EQ(kFakeErrorCode, byte_stream_output->GetStatus());
// Non-empty stream, error case.
- CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(),
- 3 * 1024, &byte_stream_input, &byte_stream_output);
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(), 3 * 1024,
+ &byte_stream_input, &byte_stream_output);
EXPECT_EQ(ByteStreamReader::STREAM_EMPTY,
byte_stream_output->Read(&output_io_buffer, &output_length));
EXPECT_TRUE(Write(byte_stream_input.get(), 1024));
@@ -315,7 +324,7 @@ TEST_F(ByteStreamTest, ByteStream_SinkCallback) {
std::unique_ptr<ByteStreamWriter> byte_stream_input;
std::unique_ptr<ByteStreamReader> byte_stream_output;
- CreateByteStream(message_loop_.task_runner(), task_runner, 10000,
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(), task_runner, 10000,
&byte_stream_input, &byte_stream_output);
scoped_refptr<net::IOBuffer> output_io_buffer;
@@ -366,7 +375,7 @@ TEST_F(ByteStreamTest, ByteStream_SourceCallback) {
std::unique_ptr<ByteStreamWriter> byte_stream_input;
std::unique_ptr<ByteStreamReader> byte_stream_output;
- CreateByteStream(task_runner, message_loop_.task_runner(), 10000,
+ CreateByteStream(task_runner, base::ThreadTaskRunnerHandle::Get(), 10000,
&byte_stream_input, &byte_stream_output);
scoped_refptr<net::IOBuffer> output_io_buffer;
@@ -427,7 +436,7 @@ TEST_F(ByteStreamTest, ByteStream_SinkInterrupt) {
std::unique_ptr<ByteStreamWriter> byte_stream_input;
std::unique_ptr<ByteStreamReader> byte_stream_output;
- CreateByteStream(message_loop_.task_runner(), task_runner, 10000,
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(), task_runner, 10000,
&byte_stream_input, &byte_stream_output);
scoped_refptr<net::IOBuffer> output_io_buffer;
@@ -473,7 +482,7 @@ TEST_F(ByteStreamTest, ByteStream_SourceInterrupt) {
std::unique_ptr<ByteStreamWriter> byte_stream_input;
std::unique_ptr<ByteStreamReader> byte_stream_output;
- CreateByteStream(task_runner, message_loop_.task_runner(), 10000,
+ CreateByteStream(task_runner, base::ThreadTaskRunnerHandle::Get(), 10000,
&byte_stream_input, &byte_stream_output);
scoped_refptr<net::IOBuffer> output_io_buffer;
@@ -524,7 +533,7 @@ TEST_F(ByteStreamTest, ByteStream_ZeroCallback) {
std::unique_ptr<ByteStreamWriter> byte_stream_input;
std::unique_ptr<ByteStreamReader> byte_stream_output;
- CreateByteStream(message_loop_.task_runner(), task_runner, 10000,
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(), task_runner, 10000,
&byte_stream_input, &byte_stream_output);
base::Closure intermediate_callback;
@@ -543,8 +552,9 @@ TEST_F(ByteStreamTest, ByteStream_ZeroCallback) {
TEST_F(ByteStreamTest, ByteStream_CloseWithoutAnyWrite) {
std::unique_ptr<ByteStreamWriter> byte_stream_input;
std::unique_ptr<ByteStreamReader> byte_stream_output;
- CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(),
- 3 * 1024, &byte_stream_input, &byte_stream_output);
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(), 3 * 1024,
+ &byte_stream_input, &byte_stream_output);
byte_stream_input->Close(0);
base::RunLoop().RunUntilIdle();
@@ -558,8 +568,9 @@ TEST_F(ByteStreamTest, ByteStream_CloseWithoutAnyWrite) {
TEST_F(ByteStreamTest, ByteStream_FlushWithoutAnyWrite) {
std::unique_ptr<ByteStreamWriter> byte_stream_input;
std::unique_ptr<ByteStreamReader> byte_stream_output;
- CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(),
- 3 * 1024, &byte_stream_input, &byte_stream_output);
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(), 3 * 1024,
+ &byte_stream_input, &byte_stream_output);
byte_stream_input->Flush();
base::RunLoop().RunUntilIdle();
@@ -579,7 +590,8 @@ TEST_F(ByteStreamTest, ByteStream_FlushWithoutAnyWrite) {
TEST_F(ByteStreamTest, ByteStream_WriteOverflow) {
std::unique_ptr<ByteStreamWriter> byte_stream_input;
std::unique_ptr<ByteStreamReader> byte_stream_output;
- CreateByteStream(message_loop_.task_runner(), message_loop_.task_runner(),
+ CreateByteStream(base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(),
std::numeric_limits<size_t>::max(), &byte_stream_input,
&byte_stream_output);
diff --git a/chromium/content/browser/cache_storage/cache_storage.cc b/chromium/content/browser/cache_storage/cache_storage.cc
index 78508c8b6f1..5371daf3c55 100644
--- a/chromium/content/browser/cache_storage/cache_storage.cc
+++ b/chromium/content/browser/cache_storage/cache_storage.cc
@@ -30,6 +30,7 @@
#include "content/browser/cache_storage/cache_storage.pb.h"
#include "content/browser/cache_storage/cache_storage_cache.h"
#include "content/browser/cache_storage/cache_storage_cache_handle.h"
+#include "content/browser/cache_storage/cache_storage_histogram_utils.h"
#include "content/browser/cache_storage/cache_storage_index.h"
#include "content/browser/cache_storage/cache_storage_manager.h"
#include "content/browser/cache_storage/cache_storage_quota_client.h"
@@ -132,7 +133,7 @@ class CacheStorage::CacheLoader {
cache_storage_(cache_storage),
origin_(origin),
owner_(owner) {
- DCHECK(!origin_.unique());
+ DCHECK(!origin_.opaque());
}
virtual ~CacheLoader() {}
@@ -895,8 +896,9 @@ void CacheStorage::CreateCacheDidCreateCache(
static_cast<bool>(cache));
if (!cache) {
- std::move(callback).Run(CacheStorageCacheHandle(),
- CacheStorageError::kErrorStorage);
+ std::move(callback).Run(
+ CacheStorageCacheHandle(),
+ MakeErrorStorage(ErrorStorageType::kDidCreateNullCache));
return;
}
@@ -966,14 +968,14 @@ void CacheStorage::DeleteCacheDidWriteIndex(
// Undo any changes if the index couldn't be written to disk.
cache_index_->RestoreDoomedCache();
cache_handle.value()->SetObserver(this);
- std::move(callback).Run(CacheStorageError::kErrorStorage);
+ std::move(callback).Run(
+ MakeErrorStorage(ErrorStorageType::kDeleteCacheFailed));
return;
}
cache_index_->FinalizeDoomedCache();
- CacheMap::iterator map_iter =
- cache_map_.find(cache_handle.value()->cache_name());
+ auto map_iter = cache_map_.find(cache_handle.value()->cache_name());
DCHECK(map_iter != cache_map_.end());
doomed_caches_.insert(
@@ -1159,7 +1161,7 @@ CacheStorageCacheHandle CacheStorage::GetLoadedCache(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(initialized_);
- CacheMap::iterator map_iter = cache_map_.find(cache_name);
+ auto map_iter = cache_map_.find(cache_name);
if (map_iter == cache_map_.end())
return CacheStorageCacheHandle();
diff --git a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc
index ad208e12186..dbfaccfc03e 100644
--- a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.cc
@@ -13,6 +13,7 @@
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_url_request_job_factory.h"
#include "storage/common/storage_histograms.h"
+#include "third_party/blink/public/common/blob/blob_utils.h"
namespace content {
@@ -31,6 +32,7 @@ void CacheStorageBlobToDiskCache::StreamBlobToCache(
disk_cache::ScopedEntryPtr entry,
int disk_cache_body_index,
blink::mojom::BlobPtr blob,
+ uint64_t blob_size,
EntryAndBoolCallback callback) {
DCHECK(entry);
DCHECK_LE(0, disk_cache_body_index);
@@ -38,10 +40,16 @@ void CacheStorageBlobToDiskCache::StreamBlobToCache(
DCHECK(!consumer_handle_.is_valid());
DCHECK(!pending_read_);
+ MojoCreateDataPipeOptions options;
+ options.struct_size = sizeof(MojoCreateDataPipeOptions);
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
+ options.element_num_bytes = 1;
+ options.capacity_num_bytes = blink::BlobUtils::GetDataPipeCapacity(blob_size);
+
mojo::ScopedDataPipeProducerHandle producer_handle;
- MojoResult result =
- CreateDataPipe(nullptr, &producer_handle, &consumer_handle_);
- if (result != MOJO_RESULT_OK) {
+ MojoResult rv =
+ mojo::CreateDataPipe(&options, &producer_handle, &consumer_handle_);
+ if (rv != MOJO_RESULT_OK) {
std::move(callback).Run(std::move(entry), false /* success */);
return;
}
diff --git a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h
index dbaf77d581a..efcfc5d5319 100644
--- a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h
+++ b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache.h
@@ -38,6 +38,7 @@ class CONTENT_EXPORT CacheStorageBlobToDiskCache
void StreamBlobToCache(disk_cache::ScopedEntryPtr entry,
int disk_cache_body_index,
blink::mojom::BlobPtr blob,
+ uint64_t blob_size,
EntryAndBoolCallback callback);
// BlobReaderClient:
diff --git a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc
index 103f821e3f8..c4f1c0216af 100644
--- a/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc
@@ -152,8 +152,8 @@ class CacheStorageBlobToDiskCacheTest : public testing::Test {
std::string ReadCacheContent() {
int bytes_to_read = disk_cache_entry_->GetDataSize(kCacheEntryIndex);
- scoped_refptr<net::IOBufferWithSize> buffer(
- new net::IOBufferWithSize(bytes_to_read));
+ scoped_refptr<net::IOBufferWithSize> buffer =
+ base::MakeRefCounted<net::IOBufferWithSize>(bytes_to_read);
int rv = disk_cache_entry_->ReadData(kCacheEntryIndex, 0 /* offset */,
buffer.get(), buffer->size(),
@@ -170,6 +170,7 @@ class CacheStorageBlobToDiskCacheTest : public testing::Test {
cache_storage_blob_to_disk_cache_->StreamBlobToCache(
std::move(disk_cache_entry_), kCacheEntryIndex, std::move(blob_ptr),
+ blob_handle_->size(),
base::BindOnce(&CacheStorageBlobToDiskCacheTest::StreamCallback,
base::Unretained(this)));
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache.cc b/chromium/content/browser/cache_storage/cache_storage_cache.cc
index a4e3aa14d58..72f27bb164f 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_cache.cc
@@ -29,6 +29,8 @@
#include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h"
#include "content/browser/cache_storage/cache_storage_cache_handle.h"
#include "content/browser/cache_storage/cache_storage_cache_observer.h"
+#include "content/browser/cache_storage/cache_storage_histogram_utils.h"
+#include "content/browser/cache_storage/cache_storage_manager.h"
#include "content/browser/cache_storage/cache_storage_quota_client.h"
#include "content/browser/cache_storage/cache_storage_scheduler.h"
#include "content/public/browser/browser_thread.h"
@@ -50,6 +52,7 @@
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/common/blob_storage/blob_handle.h"
#include "storage/common/storage_histograms.h"
+#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
#include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
@@ -83,10 +86,6 @@ const int32_t kCachePaddingAlgorithmVersion = 2;
using MetadataCallback =
base::OnceCallback<void(std::unique_ptr<proto::CacheMetadata>)>;
-// The maximum size of each cache. Ultimately, cache size
-// is controlled per-origin by the QuotaManager.
-const int kMaxCacheBytes = std::numeric_limits<int>::max();
-
network::mojom::FetchResponseType ProtoResponseTypeToFetchResponseType(
proto::CacheResponse::ResponseType response_type) {
switch (response_type) {
@@ -152,9 +151,8 @@ bool VaryMatches(const ServiceWorkerHeaderMap& request,
if (trimmed == "*")
return false;
- ServiceWorkerHeaderMap::const_iterator request_iter = request.find(trimmed);
- ServiceWorkerHeaderMap::const_iterator cached_request_iter =
- cached_request.find(trimmed);
+ auto request_iter = request.find(trimmed);
+ auto cached_request_iter = cached_request.find(trimmed);
// If the header exists in one but not the other, no match.
if ((request_iter == request.end()) !=
@@ -258,8 +256,9 @@ GURL RemoveQueryParam(const GURL& url) {
void ReadMetadata(disk_cache::Entry* entry, MetadataCallback callback) {
DCHECK(entry);
- scoped_refptr<net::IOBufferWithSize> buffer(new net::IOBufferWithSize(
- entry->GetDataSize(CacheStorageCache::INDEX_HEADERS)));
+ scoped_refptr<net::IOBufferWithSize> buffer =
+ base::MakeRefCounted<net::IOBufferWithSize>(
+ entry->GetDataSize(CacheStorageCache::INDEX_HEADERS));
net::CompletionCallback read_header_callback =
base::AdaptCallbackForRepeating(base::BindOnce(
@@ -446,19 +445,25 @@ struct CacheStorageCache::PutContext {
PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request,
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::BlobPtr blob,
+ uint64_t blob_size,
blink::mojom::BlobPtr side_data_blob,
+ uint64_t side_data_blob_size,
CacheStorageCache::ErrorCallback callback)
: request(std::move(request)),
response(std::move(response)),
blob(std::move(blob)),
+ blob_size(blob_size),
side_data_blob(std::move(side_data_blob)),
+ side_data_blob_size(side_data_blob_size),
callback(std::move(callback)) {}
// Input parameters to the Put function.
std::unique_ptr<ServiceWorkerFetchRequest> request;
blink::mojom::FetchAPIResponsePtr response;
blink::mojom::BlobPtr blob;
+ uint64_t blob_size;
blink::mojom::BlobPtr side_data_blob;
+ uint64_t side_data_blob_size;
CacheStorageCache::ErrorCallback callback;
disk_cache::ScopedEntryPtr cache_entry;
@@ -566,7 +571,8 @@ void CacheStorageCache::Match(
blink::mojom::QueryParamsPtr match_params,
ResponseCallback callback) {
if (backend_state_ == BACKEND_CLOSED) {
- std::move(callback).Run(CacheStorageError::kErrorStorage, nullptr);
+ std::move(callback).Run(
+ MakeErrorStorage(ErrorStorageType::kMatchBackendClosed), nullptr);
return;
}
@@ -581,8 +587,9 @@ void CacheStorageCache::MatchAll(
blink::mojom::QueryParamsPtr match_params,
ResponsesCallback callback) {
if (backend_state_ == BACKEND_CLOSED) {
- std::move(callback).Run(CacheStorageError::kErrorStorage,
- std::vector<blink::mojom::FetchAPIResponsePtr>());
+ std::move(callback).Run(
+ MakeErrorStorage(ErrorStorageType::kMatchAllBackendClosed),
+ std::vector<blink::mojom::FetchAPIResponsePtr>());
return;
}
@@ -600,7 +607,9 @@ void CacheStorageCache::WriteSideData(ErrorCallback callback,
if (backend_state_ == BACKEND_CLOSED) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(std::move(callback), CacheStorageError::kErrorStorage));
+ base::BindOnce(
+ std::move(callback),
+ MakeErrorStorage(ErrorStorageType::kWriteSideDataBackendClosed)));
return;
}
@@ -626,10 +635,12 @@ void CacheStorageCache::BatchOperation(
if (backend_state_ == BACKEND_CLOSED) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback),
- CacheStorageVerboseError::New(
- CacheStorageError::kErrorStorage,
- std::move(message))));
+ FROM_HERE,
+ base::BindOnce(
+ std::move(callback),
+ CacheStorageVerboseError::New(
+ MakeErrorStorage(ErrorStorageType::kBatchBackendClosed),
+ std::move(message))));
return;
}
@@ -689,10 +700,12 @@ void CacheStorageCache::BatchOperation(
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, std::move(bad_message_callback));
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback),
- CacheStorageVerboseError::New(
- CacheStorageError::kErrorStorage,
- std::move(message))));
+ FROM_HERE,
+ base::BindOnce(
+ std::move(callback),
+ CacheStorageVerboseError::New(
+ MakeErrorStorage(ErrorStorageType::kBatchInvalidSpace),
+ std::move(message))));
return;
}
uint64_t space_required = safe_space_required.ValueOrDie();
@@ -739,10 +752,13 @@ void CacheStorageCache::BatchDidGetUsageAndQuota(
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, std::move(bad_message_callback));
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback),
- CacheStorageVerboseError::New(
- CacheStorageError::kErrorStorage,
- std::move(message))));
+ FROM_HERE,
+ base::BindOnce(
+ std::move(callback),
+ CacheStorageVerboseError::New(
+ MakeErrorStorage(
+ ErrorStorageType::kBatchDidGetUsageAndQuotaInvalidSpace),
+ std::move(message))));
return;
}
if (status_code != blink::mojom::QuotaStatusCode::kOk ||
@@ -793,7 +809,8 @@ void CacheStorageCache::BatchDidGetUsageAndQuota(
NOTREACHED();
// TODO(nhiroki): This should return "TypeError".
// http://crbug.com/425505
- completion_callback.Run(CacheStorageError::kErrorStorage);
+ completion_callback.Run(MakeErrorStorage(
+ ErrorStorageType::kBatchDidGetUsageAndQuotaUndefinedOp));
break;
}
}
@@ -827,7 +844,8 @@ void CacheStorageCache::Keys(std::unique_ptr<ServiceWorkerFetchRequest> request,
blink::mojom::QueryParamsPtr options,
RequestsCallback callback) {
if (backend_state_ == BACKEND_CLOSED) {
- std::move(callback).Run(CacheStorageError::kErrorStorage, nullptr);
+ std::move(callback).Run(
+ MakeErrorStorage(ErrorStorageType::kKeysBackendClosed), nullptr);
return;
}
@@ -911,7 +929,7 @@ CacheStorageCache::CacheStorageCache(
cache_observer_(nullptr),
memory_only_(path.empty()),
weak_ptr_factory_(this) {
- DCHECK(!origin_.unique());
+ DCHECK(!origin_.opaque());
DCHECK(quota_manager_proxy_.get());
DCHECK(cache_padding_key_.get());
@@ -933,11 +951,13 @@ void CacheStorageCache::QueryCache(
QUERY_CACHE_ENTRIES | QUERY_CACHE_RESPONSES_WITH_BODIES,
query_types & (QUERY_CACHE_ENTRIES | QUERY_CACHE_RESPONSES_WITH_BODIES));
if (backend_state_ == BACKEND_CLOSED) {
- std::move(callback).Run(CacheStorageError::kErrorStorage, nullptr);
+ std::move(callback).Run(
+ MakeErrorStorage(ErrorStorageType::kQueryCacheBackendClosed), nullptr);
return;
}
- if ((!options || !options->ignore_method) && request &&
+ if (owner_ != CacheStorageOwner::kBackgroundFetch &&
+ (!options || !options->ignore_method) && request &&
!request->method.empty() && request->method != "GET") {
std::move(callback).Run(CacheStorageError::kSuccess,
std::make_unique<QueryCacheResults>());
@@ -1025,7 +1045,7 @@ void CacheStorageCache::QueryCacheFilterEntry(
if (rv < 0) {
std::move(query_cache_context->callback)
- .Run(CacheStorageError::kErrorStorage,
+ .Run(MakeErrorStorage(ErrorStorageType::kQueryCacheFilterEntryFailed),
std::move(query_cache_context->matches));
return;
}
@@ -1127,7 +1147,9 @@ void CacheStorageCache::QueryCacheDidReadMetadata(
if (!blob_storage_context_) {
std::move(query_cache_context->callback)
- .Run(CacheStorageError::kErrorStorage, nullptr);
+ .Run(MakeErrorStorage(
+ ErrorStorageType::kQueryCacheDidReadMetadataNullBlobContext),
+ nullptr);
return;
}
@@ -1214,8 +1236,9 @@ void CacheStorageCache::MatchAllImpl(
ResponsesCallback callback) {
DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
if (backend_state_ != BACKEND_OPEN) {
- std::move(callback).Run(CacheStorageError::kErrorStorage,
- std::vector<blink::mojom::FetchAPIResponsePtr>());
+ std::move(callback).Run(
+ MakeErrorStorage(ErrorStorageType::kStorageMatchAllBackendClosed),
+ std::vector<blink::mojom::FetchAPIResponsePtr>());
return;
}
@@ -1277,7 +1300,8 @@ void CacheStorageCache::WriteSideDataImpl(ErrorCallback callback,
int buf_len) {
DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
if (backend_state_ != BACKEND_OPEN) {
- std::move(callback).Run(CacheStorageError::kErrorStorage);
+ std::move(callback).Run(
+ MakeErrorStorage(ErrorStorageType::kWriteSideDataImplBackendClosed));
return;
}
@@ -1405,19 +1429,25 @@ void CacheStorageCache::Put(std::unique_ptr<ServiceWorkerFetchRequest> request,
DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
blink::mojom::BlobPtr blob;
+ uint64_t blob_size = blink::BlobUtils::kUnknownSize;
blink::mojom::BlobPtr side_data_blob;
+ uint64_t side_data_blob_size = blink::BlobUtils::kUnknownSize;
- if (response->blob)
+ if (response->blob) {
blob.Bind(std::move(response->blob->blob));
- if (response->side_data_blob)
+ blob_size = response->blob->size;
+ }
+ if (response->side_data_blob) {
side_data_blob.Bind(std::move(response->side_data_blob->blob));
+ side_data_blob_size = response->side_data_blob->size;
+ }
UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.Cache.AllWritesResponseType",
response->response_type);
auto put_context = std::make_unique<PutContext>(
- std::move(request), std::move(response), std::move(blob),
- std::move(side_data_blob),
+ std::move(request), std::move(response), std::move(blob), blob_size,
+ std::move(side_data_blob), side_data_blob_size,
scheduler_->WrapCallbackToRunNext(std::move(callback)));
scheduler_->ScheduleOperation(base::BindOnce(&CacheStorageCache::PutImpl,
@@ -1428,7 +1458,8 @@ void CacheStorageCache::Put(std::unique_ptr<ServiceWorkerFetchRequest> request,
void CacheStorageCache::PutImpl(std::unique_ptr<PutContext> put_context) {
DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
if (backend_state_ != BACKEND_OPEN) {
- std::move(put_context->callback).Run(CacheStorageError::kErrorStorage);
+ std::move(put_context->callback)
+ .Run(MakeErrorStorage(ErrorStorageType::kPutImplBackendClosed));
return;
}
@@ -1454,7 +1485,9 @@ void CacheStorageCache::PutDidDeleteEntry(
std::unique_ptr<PutContext> put_context,
CacheStorageError error) {
if (backend_state_ != BACKEND_OPEN) {
- std::move(put_context->callback).Run(CacheStorageError::kErrorStorage);
+ std::move(put_context->callback)
+ .Run(MakeErrorStorage(
+ ErrorStorageType::kPutDidDeleteEntryBackendClosed));
return;
}
@@ -1530,12 +1563,13 @@ void CacheStorageCache::PutDidCreateEntry(
std::unique_ptr<std::string> serialized(new std::string());
if (!metadata.SerializeToString(serialized.get())) {
- std::move(put_context->callback).Run(CacheStorageError::kErrorStorage);
+ std::move(put_context->callback)
+ .Run(MakeErrorStorage(ErrorStorageType::kMetadataSerializationFailed));
return;
}
- scoped_refptr<net::StringIOBuffer> buffer(
- new net::StringIOBuffer(std::move(serialized)));
+ scoped_refptr<net::StringIOBuffer> buffer =
+ base::MakeRefCounted<net::StringIOBuffer>(std::move(serialized));
// Get a temporary copy of the entry pointer before passing it in base::Bind.
disk_cache::Entry* temp_entry_ptr = put_context->cache_entry.get();
@@ -1560,7 +1594,8 @@ void CacheStorageCache::PutDidWriteHeaders(
int rv) {
if (rv != expected_bytes) {
put_context->cache_entry->Doom();
- std::move(put_context->callback).Run(CacheStorageError::kErrorStorage);
+ std::move(put_context->callback)
+ .Run(MakeErrorStorage(ErrorStorageType::kPutDidWriteHeadersWrongBytes));
return;
}
@@ -1594,6 +1629,10 @@ void CacheStorageCache::PutWriteBlobToCache(
: std::move(put_context->side_data_blob);
DCHECK(blob);
+ int64_t blob_size = disk_cache_body_index == INDEX_RESPONSE_BODY
+ ? put_context->blob_size
+ : put_context->side_data_blob_size;
+
disk_cache::ScopedEntryPtr entry(std::move(put_context->cache_entry));
put_context->cache_entry = nullptr;
@@ -1603,7 +1642,7 @@ void CacheStorageCache::PutWriteBlobToCache(
active_blob_to_disk_cache_writers_.Add(std::move(blob_to_cache));
blob_to_cache_raw->StreamBlobToCache(
- std::move(entry), disk_cache_body_index, std::move(blob),
+ std::move(entry), disk_cache_body_index, std::move(blob), blob_size,
base::BindOnce(&CacheStorageCache::PutDidWriteBlobToCache,
weak_ptr_factory_.GetWeakPtr(), std::move(put_context),
blob_to_cache_key));
@@ -1621,7 +1660,8 @@ void CacheStorageCache::PutDidWriteBlobToCache(
if (!success) {
put_context->cache_entry->Doom();
- std::move(put_context->callback).Run(CacheStorageError::kErrorStorage);
+ std::move(put_context->callback)
+ .Run(MakeErrorStorage(ErrorStorageType::kPutDidWriteBlobToCacheFailed));
return;
}
@@ -1636,19 +1676,19 @@ void CacheStorageCache::PutDidWriteBlobToCache(
void CacheStorageCache::CalculateCacheSizePadding(
SizePaddingCallback got_sizes_callback) {
- net::CompletionCallback got_size_callback =
+ net::Int64CompletionCallback got_size_callback =
base::AdaptCallbackForRepeating(base::BindOnce(
&CacheStorageCache::CalculateCacheSizePaddingGotSize,
weak_ptr_factory_.GetWeakPtr(), std::move(got_sizes_callback)));
- int rv = backend_->CalculateSizeOfAllEntries(got_size_callback);
+ int64_t rv = backend_->CalculateSizeOfAllEntries(got_size_callback);
if (rv != net::ERR_IO_PENDING)
std::move(got_size_callback).Run(rv);
}
void CacheStorageCache::CalculateCacheSizePaddingGotSize(
SizePaddingCallback callback,
- int cache_size) {
+ int64_t cache_size) {
// Enumerating entries is only done during cache initialization and only if
// necessary.
DCHECK_EQ(backend_state_, BACKEND_UNINITIALIZED);
@@ -1664,7 +1704,7 @@ void CacheStorageCache::CalculateCacheSizePaddingGotSize(
void CacheStorageCache::PaddingDidQueryCache(
SizePaddingCallback callback,
- int cache_size,
+ int64_t cache_size,
CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results) {
int64_t cache_padding = 0;
@@ -1683,8 +1723,8 @@ void CacheStorageCache::PaddingDidQueryCache(
}
void CacheStorageCache::CalculateCacheSize(
- const net::CompletionCallback& callback) {
- int rv = backend_->CalculateSizeOfAllEntries(callback);
+ const net::Int64CompletionCallback& callback) {
+ int64_t rv = backend_->CalculateSizeOfAllEntries(callback);
if (rv != net::ERR_IO_PENDING)
callback.Run(rv);
}
@@ -1705,7 +1745,7 @@ void CacheStorageCache::UpdateCacheSize(base::OnceClosure callback) {
void CacheStorageCache::UpdateCacheSizeGotSize(
CacheStorageCacheHandle cache_handle,
base::OnceClosure callback,
- int current_cache_size) {
+ int64_t current_cache_size) {
DCHECK_NE(current_cache_size, CacheStorage::kSizeUnknown);
cache_size_ = current_cache_size;
int64_t size_delta = PaddedCacheSize() - last_reported_size_;
@@ -1747,7 +1787,8 @@ void CacheStorageCache::DeleteImpl(
ErrorCallback callback) {
DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
if (backend_state_ != BACKEND_OPEN) {
- std::move(callback).Run(CacheStorageError::kErrorStorage);
+ std::move(callback).Run(
+ MakeErrorStorage(ErrorStorageType::kDeleteImplBackendClosed));
return;
}
@@ -1792,7 +1833,8 @@ void CacheStorageCache::KeysImpl(
RequestsCallback callback) {
DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
if (backend_state_ != BACKEND_OPEN) {
- std::move(callback).Run(CacheStorageError::kErrorStorage, nullptr);
+ std::move(callback).Run(
+ MakeErrorStorage(ErrorStorageType::kKeysImplBackendClosed), nullptr);
return;
}
@@ -1862,6 +1904,11 @@ void CacheStorageCache::CreateBackend(ErrorCallback callback) {
// Use APP_CACHE as opposed to DISK_CACHE to prevent cache eviction.
net::CacheType cache_type = memory_only_ ? net::MEMORY_CACHE : net::APP_CACHE;
+ // The maximum size of each cache. Ultimately, cache size
+ // is controlled per-origin by the QuotaManager.
+ uint64_t max_bytes = memory_only_ ? std::numeric_limits<int>::max()
+ : std::numeric_limits<int64_t>::max();
+
std::unique_ptr<ScopedBackendPtr> backend_ptr(new ScopedBackendPtr());
// Temporary pointer so that backend_ptr can be Pass()'d in Bind below.
@@ -1874,7 +1921,7 @@ void CacheStorageCache::CreateBackend(ErrorCallback callback) {
std::move(backend_ptr)));
int rv = disk_cache::CreateCacheBackend(
- cache_type, net::CACHE_BACKEND_SIMPLE, path_, kMaxCacheBytes,
+ cache_type, net::CACHE_BACKEND_SIMPLE, path_, max_bytes,
false, /* force */
nullptr, backend,
base::BindOnce(&CacheStorageCache::DeleteBackendCompletedIO,
@@ -1889,7 +1936,8 @@ void CacheStorageCache::CreateBackendDidCreate(
std::unique_ptr<ScopedBackendPtr> backend_ptr,
int rv) {
if (rv != net::OK) {
- std::move(callback).Run(CacheStorageError::kErrorStorage);
+ std::move(callback).Run(
+ MakeErrorStorage(ErrorStorageType::kCreateBackendDidCreateFailed));
return;
}
@@ -1921,7 +1969,7 @@ void CacheStorageCache::InitDidCreateBackend(
auto calculate_size_callback =
base::AdaptCallbackForRepeating(std::move(callback));
- int rv = backend_->CalculateSizeOfAllEntries(base::BindOnce(
+ int64_t rv = backend_->CalculateSizeOfAllEntries(base::BindOnce(
&CacheStorageCache::InitGotCacheSize, weak_ptr_factory_.GetWeakPtr(),
calculate_size_callback, cache_create_error));
@@ -1932,7 +1980,7 @@ void CacheStorageCache::InitDidCreateBackend(
void CacheStorageCache::InitGotCacheSize(base::OnceClosure callback,
CacheStorageError cache_create_error,
- int cache_size) {
+ int64_t cache_size) {
if (cache_create_error != CacheStorageError::kSuccess) {
InitGotCacheSizeAndPadding(std::move(callback), cache_create_error, 0, 0);
return;
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache.h b/chromium/content/browser/cache_storage/cache_storage_cache.h
index d0ab8ce63db..efcdca43ac1 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache.h
+++ b/chromium/content/browser/cache_storage/cache_storage_cache.h
@@ -391,7 +391,7 @@ class CONTENT_EXPORT CacheStorageCache {
void UpdateCacheSize(base::OnceClosure callback);
void UpdateCacheSizeGotSize(CacheStorageCacheHandle,
base::OnceClosure callback,
- int current_cache_size);
+ int64_t current_cache_size);
// Returns ERROR_NOT_FOUND if not found. Otherwise deletes and returns OK.
void Delete(blink::mojom::BatchOperationPtr operation,
@@ -429,22 +429,22 @@ class CONTENT_EXPORT CacheStorageCache {
// Calculate the size and padding of the cache.
void CalculateCacheSizePadding(SizePaddingCallback callback);
void CalculateCacheSizePaddingGotSize(SizePaddingCallback callback,
- int cache_size);
+ int64_t cache_size);
void PaddingDidQueryCache(
SizePaddingCallback callback,
- int cache_size,
+ int64_t cache_size,
blink::mojom::CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results);
// Calculate the size (but not padding) of the cache.
- void CalculateCacheSize(const net::CompletionCallback& callback);
+ void CalculateCacheSize(const net::Int64CompletionCallback& callback);
void InitBackend();
void InitDidCreateBackend(base::OnceClosure callback,
blink::mojom::CacheStorageError cache_create_error);
void InitGotCacheSize(base::OnceClosure callback,
blink::mojom::CacheStorageError cache_create_error,
- int cache_size);
+ int64_t cache_size);
void InitGotCacheSizeAndPadding(
base::OnceClosure callback,
blink::mojom::CacheStorageError cache_create_error,
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc b/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc
index 5578dd58900..55b20bc194e 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc
@@ -20,9 +20,11 @@
#include "base/run_loop.h"
#include "base/strings/string_split.h"
#include "base/test/bind_test_util.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/cache_storage/cache_storage_cache_handle.h"
+#include "content/browser/cache_storage/cache_storage_histogram_utils.h"
#include "content/browser/cache_storage/cache_storage_manager.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/browser/browser_thread.h"
@@ -60,7 +62,8 @@ namespace content {
namespace cache_storage_cache_unittest {
const char kTestData[] = "Hello World";
-const char kOrigin[] = "http://example.com";
+// TODO(crbug.com/889590): Use helper for url::Origin creation from string.
+const url::Origin kOrigin = url::Origin::Create(GURL("http://example.com"));
const char kCacheName[] = "test_cache";
const GURL kBodyUrl("http://example.com/body.html");
const GURL kBodyUrlWithQuery("http://example.com/body.html?query=test");
@@ -96,10 +99,10 @@ class DelayableBackend : public disk_cache::Backend {
return backend_->GetCacheType();
}
int32_t GetEntryCount() const override { return backend_->GetEntryCount(); }
- int OpenEntry(const std::string& key,
- net::RequestPriority request_priority,
- disk_cache::Entry** entry,
- CompletionOnceCallback callback) override {
+ net::Error OpenEntry(const std::string& key,
+ net::RequestPriority request_priority,
+ disk_cache::Entry** entry,
+ CompletionOnceCallback callback) override {
if (delay_open_entry_ && open_entry_callback_.is_null()) {
open_entry_callback_ = base::BindOnce(
&DelayableBackend::OpenEntryDelayedImpl, base::Unretained(this), key,
@@ -110,32 +113,33 @@ class DelayableBackend : public disk_cache::Backend {
std::move(callback));
}
- int CreateEntry(const std::string& key,
- net::RequestPriority request_priority,
- disk_cache::Entry** entry,
- CompletionOnceCallback callback) override {
+ net::Error CreateEntry(const std::string& key,
+ net::RequestPriority request_priority,
+ disk_cache::Entry** entry,
+ CompletionOnceCallback callback) override {
return backend_->CreateEntry(key, request_priority, entry,
std::move(callback));
}
- int DoomEntry(const std::string& key,
- net::RequestPriority request_priority,
- CompletionOnceCallback callback) override {
+ net::Error DoomEntry(const std::string& key,
+ net::RequestPriority request_priority,
+ CompletionOnceCallback callback) override {
return backend_->DoomEntry(key, request_priority, std::move(callback));
}
- int DoomAllEntries(CompletionOnceCallback callback) override {
+ net::Error DoomAllEntries(CompletionOnceCallback callback) override {
return backend_->DoomAllEntries(std::move(callback));
}
- int DoomEntriesBetween(base::Time initial_time,
- base::Time end_time,
- CompletionOnceCallback callback) override {
+ net::Error DoomEntriesBetween(base::Time initial_time,
+ base::Time end_time,
+ CompletionOnceCallback callback) override {
return backend_->DoomEntriesBetween(initial_time, end_time,
std::move(callback));
}
- int DoomEntriesSince(base::Time initial_time,
- CompletionOnceCallback callback) override {
+ net::Error DoomEntriesSince(base::Time initial_time,
+ CompletionOnceCallback callback) override {
return backend_->DoomEntriesSince(initial_time, std::move(callback));
}
- int CalculateSizeOfAllEntries(CompletionOnceCallback callback) override {
+ int64_t CalculateSizeOfAllEntries(
+ Int64CompletionOnceCallback callback) override {
return backend_->CalculateSizeOfAllEntries(std::move(callback));
}
std::unique_ptr<Iterator> CreateIterator() override {
@@ -384,9 +388,8 @@ class CacheStorageCacheTest : public testing::Test {
mock_quota_manager_ = new MockQuotaManager(
is_incognito, temp_dir_path, base::ThreadTaskRunnerHandle::Get().get(),
quota_policy_.get());
- mock_quota_manager_->SetQuota(GURL(kOrigin),
- blink::mojom::StorageType::kTemporary,
- 1024 * 1024 * 100);
+ mock_quota_manager_->SetQuota(
+ kOrigin, blink::mojom::StorageType::kTemporary, 1024 * 1024 * 100);
quota_manager_proxy_ = new MockQuotaManagerProxy(
mock_quota_manager_.get(), base::ThreadTaskRunnerHandle::Get().get());
@@ -412,8 +415,7 @@ class CacheStorageCacheTest : public testing::Test {
MakeRequest(&blob_ptr_));
cache_ = std::make_unique<TestCacheStorageCache>(
- url::Origin::Create(GURL(kOrigin)), kCacheName, temp_dir_path,
- nullptr /* CacheStorage */,
+ kOrigin, kCacheName, temp_dir_path, nullptr /* CacheStorage */,
BrowserContext::GetDefaultStoragePartition(&browser_context_)
->GetURLRequestContext(),
quota_manager_proxy_, blob_storage_context->context()->AsWeakPtr());
@@ -920,6 +922,8 @@ TEST_P(CacheStorageCacheTestP, PutBodyDropBlobRef) {
}
TEST_P(CacheStorageCacheTestP, PutBadMessage) {
+ base::HistogramTester histogram_tester;
+
// Two unique puts that will collectively overflow unit64_t size of the
// batch operation.
blink::mojom::BatchOperationPtr operation1 =
@@ -938,6 +942,8 @@ TEST_P(CacheStorageCacheTestP, PutBadMessage) {
operations.push_back(std::move(operation2));
EXPECT_EQ(CacheStorageError::kErrorStorage,
BatchOperation(std::move(operations)));
+ histogram_tester.ExpectBucketCount("ServiceWorkerCache.ErrorStorageType",
+ ErrorStorageType::kBatchInvalidSpace, 1);
EXPECT_EQ("CSDH_UNEXPECTED_OPERATION", bad_message_reason_);
EXPECT_FALSE(Match(body_request_));
@@ -1532,8 +1538,7 @@ TEST_P(CacheStorageCacheTestP, PutWithSideData) {
}
TEST_P(CacheStorageCacheTestP, PutWithSideData_QuotaExceeded) {
- mock_quota_manager_->SetQuota(GURL(kOrigin),
- blink::mojom::StorageType::kTemporary,
+ mock_quota_manager_->SetQuota(kOrigin, blink::mojom::StorageType::kTemporary,
expected_blob_data_.size() - 1);
blink::mojom::FetchAPIResponsePtr response = CreateBlobBodyResponse();
const std::string expected_side_data = "SideData";
@@ -1548,8 +1553,7 @@ TEST_P(CacheStorageCacheTestP, PutWithSideData_QuotaExceeded) {
}
TEST_P(CacheStorageCacheTestP, PutWithSideData_QuotaExceededSkipSideData) {
- mock_quota_manager_->SetQuota(GURL(kOrigin),
- blink::mojom::StorageType::kTemporary,
+ mock_quota_manager_->SetQuota(kOrigin, blink::mojom::StorageType::kTemporary,
expected_blob_data_.size());
blink::mojom::FetchAPIResponsePtr response = CreateBlobBodyResponse();
const std::string expected_side_data = "SideData";
@@ -1570,6 +1574,7 @@ TEST_P(CacheStorageCacheTestP, PutWithSideData_QuotaExceededSkipSideData) {
}
TEST_P(CacheStorageCacheTestP, PutWithSideData_BadMessage) {
+ base::HistogramTester histogram_tester;
blink::mojom::FetchAPIResponsePtr response = CreateBlobBodyResponse();
const std::string expected_side_data = "SideData";
@@ -1589,6 +1594,9 @@ TEST_P(CacheStorageCacheTestP, PutWithSideData_BadMessage) {
operations.emplace_back(std::move(operation));
EXPECT_EQ(CacheStorageError::kErrorStorage,
BatchOperation(std::move(operations)));
+ histogram_tester.ExpectBucketCount(
+ "ServiceWorkerCache.ErrorStorageType",
+ ErrorStorageType::kBatchDidGetUsageAndQuotaInvalidSpace, 1);
EXPECT_EQ("CSDH_UNEXPECTED_OPERATION", bad_message_reason_);
EXPECT_FALSE(Match(body_request_));
@@ -1601,8 +1609,8 @@ TEST_P(CacheStorageCacheTestP, WriteSideData) {
EXPECT_TRUE(Put(body_request_, std::move(response)));
const std::string expected_side_data1 = "SideDataSample";
- scoped_refptr<net::IOBuffer> buffer1(
- new net::StringIOBuffer(expected_side_data1));
+ scoped_refptr<net::IOBuffer> buffer1 =
+ base::MakeRefCounted<net::StringIOBuffer>(expected_side_data1);
EXPECT_TRUE(WriteSideData(body_request_.url, response_time, buffer1,
expected_side_data1.length()));
@@ -1613,8 +1621,8 @@ TEST_P(CacheStorageCacheTestP, WriteSideData) {
EXPECT_TRUE(ResponseSideDataEqual(expected_side_data1, blob1.get()));
const std::string expected_side_data2 = "New data";
- scoped_refptr<net::IOBuffer> buffer2(
- new net::StringIOBuffer(expected_side_data2));
+ scoped_refptr<net::IOBuffer> buffer2 =
+ base::MakeRefCounted<net::StringIOBuffer>(expected_side_data2);
EXPECT_TRUE(WriteSideData(body_request_.url, response_time, buffer2,
expected_side_data2.length()));
EXPECT_TRUE(Match(body_request_));
@@ -1627,15 +1635,16 @@ TEST_P(CacheStorageCacheTestP, WriteSideData) {
}
TEST_P(CacheStorageCacheTestP, WriteSideData_QuotaExceeded) {
- mock_quota_manager_->SetQuota(
- GURL(kOrigin), blink::mojom::StorageType::kTemporary, 1024 * 1023);
+ mock_quota_manager_->SetQuota(kOrigin, blink::mojom::StorageType::kTemporary,
+ 1024 * 1023);
base::Time response_time(base::Time::Now());
blink::mojom::FetchAPIResponsePtr response(CreateNoBodyResponse());
response->response_time = response_time;
EXPECT_TRUE(Put(no_body_request_, std::move(response)));
const size_t kSize = 1024 * 1024;
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(kSize);
memset(buffer->data(), 0, kSize);
EXPECT_FALSE(
WriteSideData(no_body_request_.url, response_time, buffer, kSize));
@@ -1655,7 +1664,8 @@ TEST_P(CacheStorageCacheTestP, WriteSideData_QuotaManagerModified) {
EXPECT_EQ(1, quota_manager_proxy_->notify_storage_modified_count());
const size_t kSize = 10;
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(kSize);
memset(buffer->data(), 0, kSize);
EXPECT_TRUE(
WriteSideData(no_body_request_.url, response_time, buffer, kSize));
@@ -1671,7 +1681,8 @@ TEST_P(CacheStorageCacheTestP, WriteSideData_DifferentTimeStamp) {
EXPECT_TRUE(Put(no_body_request_, std::move(response)));
const size_t kSize = 10;
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(kSize);
memset(buffer->data(), 0, kSize);
EXPECT_FALSE(WriteSideData(no_body_request_.url,
response_time + base::TimeDelta::FromSeconds(1),
@@ -1682,7 +1693,8 @@ TEST_P(CacheStorageCacheTestP, WriteSideData_DifferentTimeStamp) {
TEST_P(CacheStorageCacheTestP, WriteSideData_NotFound) {
const size_t kSize = 10;
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize));
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(kSize);
memset(buffer->data(), 0, kSize);
EXPECT_FALSE(WriteSideData(GURL("http://www.example.com/not_exist"),
base::Time::Now(), buffer, kSize));
@@ -1731,8 +1743,8 @@ TEST_P(CacheStorageCacheTestP, QuotaManagerModified) {
}
TEST_P(CacheStorageCacheTestP, PutObeysQuotaLimits) {
- mock_quota_manager_->SetQuota(GURL(kOrigin),
- blink::mojom::StorageType::kTemporary, 0);
+ mock_quota_manager_->SetQuota(kOrigin, blink::mojom::StorageType::kTemporary,
+ 0);
EXPECT_FALSE(Put(body_request_, CreateBlobBodyResponse()));
EXPECT_EQ(CacheStorageError::kErrorQuotaExceeded, callback_error_);
}
@@ -1769,8 +1781,8 @@ TEST_F(CacheStorageCacheTest, VerifyOpaqueSizePadding) {
// Now write some side data to that cache.
const std::string expected_side_data(2048, 'X');
- scoped_refptr<net::IOBuffer> side_data_buffer(
- new net::StringIOBuffer(expected_side_data));
+ scoped_refptr<net::IOBuffer> side_data_buffer =
+ base::MakeRefCounted<net::StringIOBuffer>(expected_side_data);
EXPECT_TRUE(WriteSideData(non_opaque_request.url, response_time,
side_data_buffer, expected_side_data.length()));
int64_t unpadded_total_resource_size = Size();
@@ -1813,8 +1825,8 @@ TEST_F(CacheStorageCacheTest, VerifyOpaqueSizePadding) {
// Now reset opaque side data back to zero.
const std::string expected_side_data2 = "";
- scoped_refptr<net::IOBuffer> buffer2(
- new net::StringIOBuffer(expected_side_data2));
+ scoped_refptr<net::IOBuffer> buffer2 =
+ base::MakeRefCounted<net::StringIOBuffer>(expected_side_data2);
EXPECT_TRUE(WriteSideData(opaque_request.url, response_time, buffer2,
expected_side_data2.length()));
EXPECT_EQ(size_after_opaque_put, Size());
@@ -1835,8 +1847,8 @@ TEST_F(CacheStorageCacheTest, TestDifferentOpaqueSideDataSizes) {
int64_t opaque_cache_size_no_side_data = Size();
const std::string small_side_data(1024, 'X');
- scoped_refptr<net::IOBuffer> buffer1(
- new net::StringIOBuffer(small_side_data));
+ scoped_refptr<net::IOBuffer> buffer1 =
+ base::MakeRefCounted<net::StringIOBuffer>(small_side_data);
EXPECT_TRUE(WriteSideData(request.url, response_time, buffer1,
small_side_data.length()));
int64_t opaque_cache_size_with_side_data = Size();
@@ -1846,8 +1858,8 @@ TEST_F(CacheStorageCacheTest, TestDifferentOpaqueSideDataSizes) {
// at all.
const std::string large_side_data(2048, 'X');
EXPECT_NE(large_side_data.length(), small_side_data.length());
- scoped_refptr<net::IOBuffer> buffer2(
- new net::StringIOBuffer(large_side_data));
+ scoped_refptr<net::IOBuffer> buffer2 =
+ base::MakeRefCounted<net::StringIOBuffer>(large_side_data);
EXPECT_TRUE(WriteSideData(request.url, response_time, buffer2,
large_side_data.length()));
int side_data_delta = large_side_data.length() - small_side_data.length();
diff --git a/chromium/content/browser/cache_storage/cache_storage_context_impl.cc b/chromium/content/browser/cache_storage/cache_storage_context_impl.cc
index c61cf8c1d81..ffc6bc04f4b 100644
--- a/chromium/content/browser/cache_storage/cache_storage_context_impl.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_context_impl.cc
@@ -11,6 +11,7 @@
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/cache_storage/cache_storage_manager.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/url_request/url_request_context_getter.h"
#include "storage/browser/blob/blob_storage_context.h"
@@ -49,8 +50,8 @@ void CacheStorageContextImpl::Init(
return;
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CacheStorageContextImpl::CreateCacheStorageManager, this,
user_data_directory, cache_task_runner,
std::move(quota_manager_proxy)));
@@ -59,8 +60,8 @@ void CacheStorageContextImpl::Init(
void CacheStorageContextImpl::Shutdown() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CacheStorageContextImpl::ShutdownOnIO, this));
}
@@ -85,8 +86,8 @@ void CacheStorageContextImpl::GetAllOriginsInfo(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!cache_manager_) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(callback, std::vector<CacheStorageUsageInfo>()));
return;
}
diff --git a/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc b/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc
index 5f50ea600d4..9394792d4bb 100644
--- a/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_dispatcher_host.cc
@@ -13,6 +13,7 @@
#include "base/optional.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
@@ -20,6 +21,7 @@
#include "content/browser/cache_storage/cache_storage_cache_handle.h"
#include "content/browser/cache_storage/cache_storage_context_impl.h"
#include "content/browser/cache_storage/cache_storage_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/origin_util.h"
@@ -28,7 +30,6 @@
#include "url/gurl.h"
#include "url/origin.h"
-
namespace content {
namespace {
@@ -40,7 +41,7 @@ const int32_t kCachePreservationSeconds = 5;
// TODO(lucmult): Check this before binding.
bool OriginCanAccessCacheStorage(const url::Origin& origin) {
- return !origin.unique() && IsOriginSecure(origin.GetURL());
+ return !origin.opaque() && IsOriginSecure(origin.GetURL());
}
void StopPreservingCache(CacheStorageCacheHandle cache_handle) {}
@@ -211,8 +212,8 @@ CacheStorageDispatcherHost::~CacheStorageDispatcherHost() = default;
void CacheStorageDispatcherHost::Init(CacheStorageContextImpl* context) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CacheStorageDispatcherHost::CreateCacheListener,
base::RetainedRef(this), base::RetainedRef(context)));
}
diff --git a/chromium/content/browser/cache_storage/cache_storage_histogram_utils.cc b/chromium/content/browser/cache_storage/cache_storage_histogram_utils.cc
new file mode 100644
index 00000000000..89d8aae6792
--- /dev/null
+++ b/chromium/content/browser/cache_storage/cache_storage_histogram_utils.cc
@@ -0,0 +1,14 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/cache_storage/cache_storage_histogram_utils.h"
+
+namespace content {
+
+blink::mojom::CacheStorageError MakeErrorStorage(ErrorStorageType type) {
+ UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.ErrorStorageType", type);
+ return blink::mojom::CacheStorageError::kErrorStorage;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/cache_storage/cache_storage_histogram_macros.h b/chromium/content/browser/cache_storage/cache_storage_histogram_utils.h
index 92b0d87e03b..3743d0d3e35 100644
--- a/chromium/content/browser/cache_storage/cache_storage_histogram_macros.h
+++ b/chromium/content/browser/cache_storage/cache_storage_histogram_utils.h
@@ -2,14 +2,45 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_HISTOGRAM_MACROS_H_
-#define CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_HISTOGRAM_MACROS_H_
+#ifndef CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_HISTOGRAM_UTILS_H_
+#define CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_HISTOGRAM_UTILS_H_
#include "base/metrics/histogram_macros.h"
#include "content/browser/cache_storage/cache_storage_scheduler_client.h"
+#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h"
namespace content {
+// This enum gets recorded as a histogram. Do not renumber the values.
+enum class ErrorStorageType {
+ kDidCreateNullCache = 0,
+ kDeleteCacheFailed = 1,
+ kMatchBackendClosed = 2,
+ kMatchAllBackendClosed = 3,
+ kWriteSideDataBackendClosed = 4,
+ kBatchBackendClosed = 5,
+ kBatchInvalidSpace = 6,
+ kBatchDidGetUsageAndQuotaInvalidSpace = 7,
+ kBatchDidGetUsageAndQuotaUndefinedOp = 8,
+ kKeysBackendClosed = 9,
+ kQueryCacheBackendClosed = 10,
+ kQueryCacheFilterEntryFailed = 11,
+ kQueryCacheDidReadMetadataNullBlobContext = 12,
+ kStorageMatchAllBackendClosed = 13,
+ kWriteSideDataImplBackendClosed = 14,
+ kPutImplBackendClosed = 15,
+ kPutDidDeleteEntryBackendClosed = 16,
+ kMetadataSerializationFailed = 17,
+ kPutDidWriteHeadersWrongBytes = 18,
+ kPutDidWriteBlobToCacheFailed = 19,
+ kDeleteImplBackendClosed = 20,
+ kKeysImplBackendClosed = 21,
+ kCreateBackendDidCreateFailed = 22,
+ kMaxValue = kCreateBackendDidCreateFailed,
+};
+
+blink::mojom::CacheStorageError MakeErrorStorage(ErrorStorageType type);
+
// Metrics to make it easier to write histograms for several clients.
#define CACHE_STORAGE_SCHEDULER_UMA_THUNK(uma_type, args) \
UMA_HISTOGRAM_##uma_type args
@@ -40,4 +71,4 @@ namespace content {
} // namespace content
-#endif // CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_HISTOGRAM_MACROS_H_
+#endif // CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_HISTOGRAM_UTILS_H_
diff --git a/chromium/content/browser/cache_storage/cache_storage_manager.cc b/chromium/content/browser/cache_storage/cache_storage_manager.cc
index 6eab90f4d1e..2b5c01e2362 100644
--- a/chromium/content/browser/cache_storage/cache_storage_manager.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_manager.cc
@@ -431,7 +431,7 @@ void CacheStorageManager::DeleteOriginData(
// Create the CacheStorage for the origin if it hasn't been loaded yet.
FindOrCreateCacheStorage(origin, owner);
- CacheStorageMap::iterator it = cache_storage_map_.find({origin, owner});
+ auto it = cache_storage_map_.find({origin, owner});
DCHECK(it != cache_storage_map_.end());
CacheStorage* cache_storage = it->second.release();
diff --git a/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc b/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc
index c9aa9486f41..9c9f451e123 100644
--- a/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -259,9 +259,9 @@ class CacheStorageManagerTest : public testing::Test {
mock_quota_manager_ = new MockQuotaManager(
MemoryOnly(), temp_dir_path, base::ThreadTaskRunnerHandle::Get().get(),
quota_policy_.get());
- mock_quota_manager_->SetQuota(origin1_.GetURL(), StorageType::kTemporary,
+ mock_quota_manager_->SetQuota(origin1_, StorageType::kTemporary,
1024 * 1024 * 100);
- mock_quota_manager_->SetQuota(origin2_.GetURL(), StorageType::kTemporary,
+ mock_quota_manager_->SetQuota(origin2_, StorageType::kTemporary,
1024 * 1024 * 100);
quota_manager_proxy_ = new MockCacheStorageQuotaManagerProxy(
diff --git a/chromium/content/browser/cache_storage/cache_storage_operation.cc b/chromium/content/browser/cache_storage/cache_storage_operation.cc
index 89502144f0b..38ea200db9e 100644
--- a/chromium/content/browser/cache_storage/cache_storage_operation.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_operation.cc
@@ -4,7 +4,7 @@
#include "content/browser/cache_storage/cache_storage_operation.h"
-#include "content/browser/cache_storage/cache_storage_histogram_macros.h"
+#include "content/browser/cache_storage/cache_storage_histogram_utils.h"
namespace content {
diff --git a/chromium/content/browser/cache_storage/cache_storage_scheduler.cc b/chromium/content/browser/cache_storage/cache_storage_scheduler.cc
index d28492ff53d..28215800d27 100644
--- a/chromium/content/browser/cache_storage/cache_storage_scheduler.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_scheduler.cc
@@ -12,7 +12,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/browser/cache_storage/cache_storage_histogram_macros.h"
+#include "content/browser/cache_storage/cache_storage_histogram_utils.h"
#include "content/browser/cache_storage/cache_storage_operation.h"
namespace content {
diff --git a/chromium/content/browser/child_process_launcher_helper.cc b/chromium/content/browser/child_process_launcher_helper.cc
index 6e0eebe2361..2f75fff5eed 100644
--- a/chromium/content/browser/child_process_launcher_helper.cc
+++ b/chromium/content/browser/child_process_launcher_helper.cc
@@ -13,6 +13,7 @@
#include "base/task/single_thread_task_runner_thread_mode.h"
#include "base/task/task_traits.h"
#include "content/browser/child_process_launcher.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/child_process_launcher_utils.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
@@ -151,8 +152,8 @@ void ChildProcessLauncherHelper::PostLaunchOnLauncherThread(
}
}
- BrowserThread::PostTask(
- client_thread_id_, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {client_thread_id_},
base::BindOnce(&ChildProcessLauncherHelper::PostLaunchOnClientThread,
this, std::move(process), launch_result));
}
diff --git a/chromium/content/browser/child_process_launcher_helper_android.cc b/chromium/content/browser/child_process_launcher_helper_android.cc
index 83be7e6bbb4..5118e3622aa 100644
--- a/chromium/content/browser/child_process_launcher_helper_android.cc
+++ b/chromium/content/browser/child_process_launcher_helper_android.cc
@@ -10,11 +10,13 @@
#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
+#include "base/task/post_task.h"
#include "content/browser/child_process_launcher.h"
#include "content/browser/child_process_launcher_helper.h"
#include "content/browser/child_process_launcher_helper_posix.h"
#include "content/browser/posix_file_descriptor_info_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_launcher_utils.h"
#include "content/public/browser/render_process_host.h"
@@ -134,8 +136,8 @@ ChildProcessLauncherHelper::LaunchProcessOnLauncherThread(
java_peer_.Reset(Java_ChildProcessLauncherHelperImpl_createAndStart(
env, reinterpret_cast<intptr_t>(this), j_argv, j_file_infos));
AddRef(); // Balanced by OnChildProcessStarted.
- BrowserThread::PostTask(
- client_thread_id_, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {client_thread_id_},
base::Bind(
&ChildProcessLauncherHelper::set_java_peer_available_on_client_thread,
this));
diff --git a/chromium/content/browser/child_process_launcher_helper_mac.cc b/chromium/content/browser/child_process_launcher_helper_mac.cc
index c1b02ef4855..60a5a647015 100644
--- a/chromium/content/browser/child_process_launcher_helper_mac.cc
+++ b/chromium/content/browser/child_process_launcher_helper_mac.cc
@@ -73,34 +73,8 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
command_line_->HasSwitch(service_manager::switches::kNoSandbox) ||
service_manager::IsUnsandboxedSandboxType(sandbox_type);
- // TODO(kerrnel): Delete this switch once the V2 sandbox is always enabled.
- bool use_v2 = base::FeatureList::IsEnabled(features::kMacV2Sandbox);
-
- switch (sandbox_type) {
- case service_manager::SANDBOX_TYPE_NO_SANDBOX:
- break;
- case service_manager::SANDBOX_TYPE_CDM:
- case service_manager::SANDBOX_TYPE_PPAPI:
- case service_manager::SANDBOX_TYPE_RENDERER:
- case service_manager::SANDBOX_TYPE_UTILITY:
- case service_manager::SANDBOX_TYPE_NACL_LOADER:
- case service_manager::SANDBOX_TYPE_PDF_COMPOSITOR:
- case service_manager::SANDBOX_TYPE_PROFILING:
- // If the feature experiment is enabled and this process type supports
- // the v2 sandbox, use it.
- use_v2 &= true;
- break;
- case service_manager::SANDBOX_TYPE_AUDIO:
- // The audio service only exists with the v2 sandbox.
- use_v2 |= true;
- break;
- default:
- // This is a 'break' because the V2 sandbox is not enabled for all
- // processes yet, and so there are sandbox types like NETWORK that
- // should not be run under the V2 sandbox.
- use_v2 = false;
- break;
- }
+ bool use_v2 =
+ !no_sandbox && (sandbox_type != service_manager::SANDBOX_TYPE_GPU);
if (use_v2 && !no_sandbox) {
// Generate the profile string.
@@ -133,8 +107,16 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
case service_manager::SANDBOX_TYPE_PROFILING:
profile += service_manager::kSeatbeltPolicyString_utility;
break;
- default:
+ case service_manager::SANDBOX_TYPE_NETWORK:
+ // Put a separate CHECK() for the network sandbox so that crash reports
+ // will show which invalid case was hit.
CHECK(false);
+ break;
+ case service_manager::SANDBOX_TYPE_INVALID:
+ case service_manager::SANDBOX_TYPE_FIRST_TYPE:
+ case service_manager::SANDBOX_TYPE_AFTER_LAST_TYPE:
+ CHECK(false);
+ break;
}
// Disable os logging to com.apple.diagnosticd which is a performance
diff --git a/chromium/content/browser/child_process_security_policy_browsertest.cc b/chromium/content/browser/child_process_security_policy_browsertest.cc
index a308f42cdee..810e975b253 100644
--- a/chromium/content/browser/child_process_security_policy_browsertest.cc
+++ b/chromium/content/browser/child_process_security_policy_browsertest.cc
@@ -24,16 +24,20 @@ class ChildProcessSecurityPolicyInProcessBrowserTest
: public ContentBrowserTest {
public:
void SetUp() override {
- EXPECT_EQ(
- ChildProcessSecurityPolicyImpl::GetInstance()->security_state_.size(),
- 0U);
+ auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
+ {
+ base::AutoLock lock(policy->lock_);
+ EXPECT_EQ(0u, policy->security_state_.size());
+ }
ContentBrowserTest::SetUp();
}
void TearDown() override {
- EXPECT_EQ(
- ChildProcessSecurityPolicyImpl::GetInstance()->security_state_.size(),
- 0U);
+ auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
+ {
+ base::AutoLock lock(policy->lock_);
+ EXPECT_EQ(0u, policy->security_state_.size());
+ }
ContentBrowserTest::TearDown();
}
};
@@ -44,11 +48,14 @@ IN_PROC_BROWSER_TEST_F(ChildProcessSecurityPolicyInProcessBrowserTest, DISABLED_
IN_PROC_BROWSER_TEST_F(ChildProcessSecurityPolicyInProcessBrowserTest, NoLeak) {
#endif
GURL url = GetTestUrl("", "simple_page.html");
+ auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
NavigateToURL(shell(), url);
- EXPECT_EQ(
- RenderProcessHostImpl::IsSpareProcessKeptAtAllTimes() ? 2u : 1u,
- ChildProcessSecurityPolicyImpl::GetInstance()->security_state_.size());
+ {
+ base::AutoLock lock(policy->lock_);
+ EXPECT_EQ(RenderProcessHostImpl::IsSpareProcessKeptAtAllTimes() ? 2u : 1u,
+ policy->security_state_.size());
+ }
WebContents* web_contents = shell()->web_contents();
content::RenderProcessHostWatcher exit_observer(
@@ -58,9 +65,11 @@ IN_PROC_BROWSER_TEST_F(ChildProcessSecurityPolicyInProcessBrowserTest, NoLeak) {
exit_observer.Wait();
web_contents->GetController().Reload(ReloadType::NORMAL, true);
- EXPECT_EQ(
- RenderProcessHostImpl::IsSpareProcessKeptAtAllTimes() ? 2u : 1u,
- ChildProcessSecurityPolicyImpl::GetInstance()->security_state_.size());
+ {
+ base::AutoLock lock(policy->lock_);
+ EXPECT_EQ(RenderProcessHostImpl::IsSpareProcessKeptAtAllTimes() ? 2u : 1u,
+ policy->security_state_.size());
+ }
}
} // namespace content
diff --git a/chromium/content/browser/child_process_security_policy_impl.cc b/chromium/content/browser/child_process_security_policy_impl.cc
index bd757e4fdef..323f85836c3 100644
--- a/chromium/content/browser/child_process_security_policy_impl.cc
+++ b/chromium/content/browser/child_process_security_policy_impl.cc
@@ -108,24 +108,24 @@ class ChildProcessSecurityPolicyImpl::SecurityState {
~SecurityState() {
storage::IsolatedContext* isolated_context =
storage::IsolatedContext::GetInstance();
- for (FileSystemMap::iterator iter = filesystem_permissions_.begin();
- iter != filesystem_permissions_.end();
- ++iter) {
+ for (auto iter = filesystem_permissions_.begin();
+ iter != filesystem_permissions_.end(); ++iter) {
isolated_context->RemoveReference(iter->first);
}
- UMA_HISTOGRAM_COUNTS("ChildProcessSecurityPolicy.PerChildFilePermissions",
- file_permissions_.size());
+ UMA_HISTOGRAM_COUNTS_1M(
+ "ChildProcessSecurityPolicy.PerChildFilePermissions",
+ file_permissions_.size());
}
// Grant permission to request and commit URLs with the specified origin.
void GrantCommitOrigin(const url::Origin& origin) {
- if (origin.unique())
+ if (origin.opaque())
return;
origin_map_[origin] = CommitRequestPolicy::kCommitAndRequest;
}
void GrantRequestOrigin(const url::Origin& origin) {
- if (origin.unique())
+ if (origin.opaque())
return;
// Anything already in |origin_map_| must have at least request permission
// already. In that case, the emplace() below will be a no-op.
@@ -146,8 +146,9 @@ class ChildProcessSecurityPolicyImpl::SecurityState {
void GrantPermissionsForFile(const base::FilePath& file, int permissions) {
base::FilePath stripped = file.StripTrailingSeparators();
file_permissions_[stripped] |= permissions;
- UMA_HISTOGRAM_COUNTS("ChildProcessSecurityPolicy.FilePermissionPathLength",
- stripped.value().size());
+ UMA_HISTOGRAM_COUNTS_1M(
+ "ChildProcessSecurityPolicy.FilePermissionPathLength",
+ stripped.value().size());
}
// Grant navigation to a file but not the file:// scheme in general.
@@ -508,7 +509,7 @@ void ChildProcessSecurityPolicyImpl::GrantCommitURL(int child_id,
// TODO(dcheng): In the future, URLs with opaque origins would ideally carry
// around an origin with them, so we wouldn't need to grant commit access to
// the entire scheme.
- if (!origin.unique())
+ if (!origin.opaque())
GrantCommitOrigin(child_id, origin);
// The scheme has already been whitelisted for every child process, so no need
@@ -522,7 +523,7 @@ void ChildProcessSecurityPolicyImpl::GrantCommitURL(int child_id,
if (state == security_state_.end())
return;
- if (origin.unique()) {
+ if (origin.opaque()) {
// If it's impossible to grant commit rights to just the origin (among other
// things, URLs with non-standard schemes will be treated as opaque
// origins), then grant access to commit all URLs of that scheme.
@@ -542,7 +543,7 @@ void ChildProcessSecurityPolicyImpl::GrantRequestSpecificFileURL(
{
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return;
@@ -578,7 +579,7 @@ void ChildProcessSecurityPolicyImpl::GrantPermissionsForFile(
int child_id, const base::FilePath& file, int permissions) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return;
@@ -589,7 +590,7 @@ void ChildProcessSecurityPolicyImpl::RevokeAllPermissionsForFile(
int child_id, const base::FilePath& file) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return;
@@ -630,7 +631,7 @@ void ChildProcessSecurityPolicyImpl::GrantDeleteFromFileSystem(
void ChildProcessSecurityPolicyImpl::GrantSendMidiSysExMessage(int child_id) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return;
@@ -642,7 +643,7 @@ void ChildProcessSecurityPolicyImpl::GrantCommitOrigin(
const url::Origin& origin) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return;
@@ -654,7 +655,7 @@ void ChildProcessSecurityPolicyImpl::GrantRequestOrigin(
const url::Origin& origin) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return;
@@ -681,7 +682,7 @@ void ChildProcessSecurityPolicyImpl::GrantWebUIBindings(int child_id,
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return;
@@ -697,7 +698,7 @@ void ChildProcessSecurityPolicyImpl::GrantWebUIBindings(int child_id,
void ChildProcessSecurityPolicyImpl::GrantReadRawCookies(int child_id) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return;
@@ -707,7 +708,7 @@ void ChildProcessSecurityPolicyImpl::GrantReadRawCookies(int child_id) {
void ChildProcessSecurityPolicyImpl::RevokeReadRawCookies(int child_id) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return;
@@ -740,7 +741,7 @@ bool ChildProcessSecurityPolicyImpl::CanRequestURL(
return false;
url::Origin origin = url::Origin::Create(url);
- return origin.unique() || CanRequestURL(child_id, GURL(origin.Serialize()));
+ return origin.opaque() || CanRequestURL(child_id, GURL(origin.Serialize()));
}
if (IsWebSafeScheme(scheme))
@@ -749,7 +750,7 @@ bool ChildProcessSecurityPolicyImpl::CanRequestURL(
{
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return false;
@@ -793,7 +794,8 @@ bool ChildProcessSecurityPolicyImpl::CanRedirectToURL(const GURL& url) {
}
bool ChildProcessSecurityPolicyImpl::CanCommitURL(int child_id,
- const GURL& url) {
+ const GURL& url,
+ bool check_origin_locks) {
if (!url.is_valid())
return false; // Can't commit invalid URLs.
@@ -811,9 +813,19 @@ bool ChildProcessSecurityPolicyImpl::CanCommitURL(int child_id,
return false;
url::Origin origin = url::Origin::Create(url);
- return origin.unique() || CanCommitURL(child_id, GURL(origin.Serialize()));
+ return origin.opaque() ||
+ CanCommitURL(child_id, GURL(origin.Serialize()), check_origin_locks);
}
+ // With site isolation, a URL from a site may only be committed in a process
+ // dedicated to that site. This check will ensure that |url| can't commit if
+ // the process is locked to a different site. Note that this check is only
+ // effective for processes that are locked to a site, but even with strict
+ // site isolation, currently not all processes are locked (e.g., extensions
+ // or <webview> tags - see ShouldLockToOrigin()).
+ if (check_origin_locks && !CanAccessDataForOrigin(child_id, url))
+ return false;
+
{
base::AutoLock lock(lock_);
@@ -821,17 +833,12 @@ bool ChildProcessSecurityPolicyImpl::CanCommitURL(int child_id,
// schemes_okay_to_commit_in_any_process_ here, which is stricter than
// IsWebSafeScheme().
//
- // TODO(creis, nick): https://crbug.com/515309: in generalized Site
- // Isolation and/or --site-per-process, there will be no such thing as a
- // scheme that is okay to commit in any process. Instead, an URL from a site
- // that is isolated may only be committed in a process dedicated to that
- // site, so CanCommitURL will need to rely on explicit, per-process grants.
- // Note how today, even with extension isolation, the line below does not
+ // TODO(creis, nick): https://crbug.com/515309: The line below does not
// enforce that http pages cannot commit in an extension process.
if (base::ContainsKey(schemes_okay_to_commit_in_any_process_, scheme))
return true;
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return false;
@@ -841,6 +848,11 @@ bool ChildProcessSecurityPolicyImpl::CanCommitURL(int child_id,
}
}
+bool ChildProcessSecurityPolicyImpl::CanCommitURL(int child_id,
+ const GURL& url) {
+ return CanCommitURL(child_id, url, true /* check_origin_lock */);
+}
+
bool ChildProcessSecurityPolicyImpl::CanSetAsOriginHeader(int child_id,
const GURL& url) {
if (!url.is_valid())
@@ -852,7 +864,12 @@ bool ChildProcessSecurityPolicyImpl::CanSetAsOriginHeader(int child_id,
// If this process can commit |url|, it can use |url| as an origin for
// outbound requests.
- if (CanCommitURL(child_id, url))
+ //
+ // TODO(alexmos): This should eventually also check the origin lock, but
+ // currently this is not done due to certain corner cases involving HTML
+ // imports and layout tests that simulate requests from isolated worlds. See
+ // https://crbug.com/515309.
+ if (CanCommitURL(child_id, url, false /* check_origin_lock */))
return true;
// Allow schemes which may come from scripts executing in isolated worlds;
@@ -971,7 +988,7 @@ bool ChildProcessSecurityPolicyImpl::HasPermissionsForFile(
if (!result) {
// If this is a worker thread that has no access to a given file,
// let's check that its renderer process has access to that file instead.
- WorkerToMainProcessMap::iterator iter = worker_map_.find(child_id);
+ auto iter = worker_map_.find(child_id);
if (iter != worker_map_.end() && iter->second != 0) {
result = ChildProcessHasPermissionsForFile(iter->second,
file,
@@ -1013,20 +1030,27 @@ bool ChildProcessSecurityPolicyImpl::HasPermissionsForFileSystemFile(
return false;
}
- FileSystemPermissionPolicyMap::iterator found =
- file_system_policy_map_.find(filesystem_url.type());
- if (found == file_system_policy_map_.end())
- return false;
+ int found_permissions = 0;
+ {
+ base::AutoLock lock(lock_);
+ auto found = file_system_policy_map_.find(filesystem_url.type());
+ if (found == file_system_policy_map_.end())
+ return false;
+ found_permissions = found->second;
+ }
- if ((found->second & storage::FILE_PERMISSION_READ_ONLY) &&
+ if ((found_permissions & storage::FILE_PERMISSION_READ_ONLY) &&
permissions & ~READ_FILE_GRANT) {
return false;
}
- if (found->second & storage::FILE_PERMISSION_USE_FILE_PERMISSION)
+ // Note that HasPermissionsForFile (called below) will internally acquire the
+ // |lock_|, therefore the |lock_| has to be released before the call (since
+ // base::Lock is not reentrant).
+ if (found_permissions & storage::FILE_PERMISSION_USE_FILE_PERMISSION)
return HasPermissionsForFile(child_id, filesystem_url.path(), permissions);
- if (found->second & storage::FILE_PERMISSION_SANDBOX)
+ if (found_permissions & storage::FILE_PERMISSION_SANDBOX)
return true;
return false;
@@ -1077,7 +1101,7 @@ bool ChildProcessSecurityPolicyImpl::CanDeleteFileSystemFile(
bool ChildProcessSecurityPolicyImpl::HasWebUIBindings(int child_id) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return false;
@@ -1087,7 +1111,7 @@ bool ChildProcessSecurityPolicyImpl::HasWebUIBindings(int child_id) {
bool ChildProcessSecurityPolicyImpl::CanReadRawCookies(int child_id) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return false;
@@ -1105,7 +1129,7 @@ void ChildProcessSecurityPolicyImpl::AddChild(int child_id) {
bool ChildProcessSecurityPolicyImpl::ChildProcessHasPermissionsForFile(
int child_id, const base::FilePath& file, int permissions) {
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return false;
return state->second->HasPermissionsForFile(file, permissions);
@@ -1113,28 +1137,26 @@ bool ChildProcessSecurityPolicyImpl::ChildProcessHasPermissionsForFile(
bool ChildProcessSecurityPolicyImpl::CanAccessDataForOrigin(int child_id,
const GURL& url) {
- // It's important to call GetSiteForURL before acquiring |lock_|, since
- // GetSiteForURL consults IsIsolatedOrigin, which needs to grab the same
- // lock.
- //
- // TODO(creis): We must pass the valid browser_context to convert hosted apps
- // URLs. Currently, hosted apps cannot set cookies in this mode. See
- // http://crbug.com/160576.
- GURL site_url = SiteInstance::GetSiteForURL(nullptr, url);
+ // It's important to call DetermineProcessLockURL before
+ // acquiring |lock_|, since DetermineProcessLockURL consults
+ // IsIsolatedOrigin, which needs to grab the same lock.
+ GURL expected_process_lock =
+ SiteInstanceImpl::DetermineProcessLockURL(nullptr, url);
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end()) {
// TODO(nick): Returning true instead of false here is a temporary
// workaround for https://crbug.com/600441
return true;
}
- bool can_access = state->second->CanAccessDataForOrigin(site_url);
+ bool can_access =
+ state->second->CanAccessDataForOrigin(expected_process_lock);
if (!can_access) {
// Returning false here will result in a renderer kill. Set some crash
// keys that will help understand the circumstances of that kill.
base::debug::SetCrashKeyString(bad_message::GetRequestedSiteURLKey(),
- site_url.spec());
+ expected_process_lock.spec());
base::debug::SetCrashKeyString(bad_message::GetKilledProcessOriginLockKey(),
state->second->origin_lock().spec());
@@ -1155,7 +1177,7 @@ void ChildProcessSecurityPolicyImpl::LockToOrigin(int child_id,
// "gurl" can be currently empty in some cases, such as file://blah.
DCHECK_EQ(SiteInstanceImpl::DetermineProcessLockURL(nullptr, gurl), gurl);
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
DCHECK(state != security_state_.end());
state->second->LockToOrigin(gurl);
}
@@ -1164,7 +1186,7 @@ ChildProcessSecurityPolicyImpl::CheckOriginLockResult
ChildProcessSecurityPolicyImpl::CheckOriginLock(int child_id,
const GURL& site_url) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return ChildProcessSecurityPolicyImpl::CheckOriginLockResult::NO_LOCK;
return state->second->CheckOriginLock(site_url);
@@ -1172,7 +1194,7 @@ ChildProcessSecurityPolicyImpl::CheckOriginLock(int child_id,
GURL ChildProcessSecurityPolicyImpl::GetOriginLock(int child_id) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return GURL();
return state->second->origin_lock();
@@ -1184,7 +1206,7 @@ void ChildProcessSecurityPolicyImpl::GrantPermissionsForFileSystem(
int permission) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return;
state->second->GrantPermissionsForFileSystem(filesystem_id, permission);
@@ -1196,7 +1218,7 @@ bool ChildProcessSecurityPolicyImpl::HasPermissionsForFileSystem(
int permission) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return false;
return state->second->HasPermissionsForFileSystem(filesystem_id, permission);
@@ -1212,7 +1234,7 @@ void ChildProcessSecurityPolicyImpl::RegisterFileSystemPermissionPolicy(
bool ChildProcessSecurityPolicyImpl::CanSendMidiSysExMessage(int child_id) {
base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
+ auto state = security_state_.find(child_id);
if (state == security_state_.end())
return false;
@@ -1230,10 +1252,18 @@ void ChildProcessSecurityPolicyImpl::AddIsolatedOrigins(
return true; // Remove.
});
- // Taking the lock once and doing a batch insertion via base::flat_set::insert
- // is important because of performance characteristics of base::flat_set.
base::AutoLock lock(lock_);
- isolated_origins_.insert(origins_to_add.begin(), origins_to_add.end());
+ for (const url::Origin& origin : origins_to_add) {
+ // GetSiteForOrigin() is used to look up the site URL of |origin| to speed
+ // up the isolated origin lookup. This only performs a straightforward
+ // translation of an origin to eTLD+1; it does *not* take into account
+ // effective URLs, isolated origins, and other logic that's not needed
+ // here, but *is* typically needed for making process model decisions. Be
+ // very careful about using GetSiteForOrigin() elsewhere, and consider
+ // whether you should be using GetSiteForURL() instead.
+ GURL key(SiteInstanceImpl::GetSiteForOrigin(origin));
+ isolated_origins_[key].insert(origin);
+ }
}
bool ChildProcessSecurityPolicyImpl::IsIsolatedOrigin(
@@ -1245,20 +1275,54 @@ bool ChildProcessSecurityPolicyImpl::IsIsolatedOrigin(
bool ChildProcessSecurityPolicyImpl::GetMatchingIsolatedOrigin(
const url::Origin& origin,
url::Origin* result) {
+ // GetSiteForOrigin() is used to look up the site URL of |origin| to speed
+ // up the isolated origin lookup. This only performs a straightforward
+ // translation of an origin to eTLD+1; it does *not* take into account
+ // effective URLs, isolated origins, and other logic that's not needed
+ // here, but *is* typically needed for making process model decisions. Be
+ // very careful about using GetSiteForOrigin() elsewhere, and consider
+ // whether you should be using GetSiteForURL() instead.
+ return GetMatchingIsolatedOrigin(
+ origin, SiteInstanceImpl::GetSiteForOrigin(origin), result);
+}
+
+bool ChildProcessSecurityPolicyImpl::GetMatchingIsolatedOrigin(
+ const url::Origin& origin,
+ const GURL& site_url,
+ url::Origin* result) {
*result = url::Origin();
base::AutoLock lock(lock_);
+ // Look up the list of origins corresponding to |origin|'s site.
+ auto it = isolated_origins_.find(site_url);
+
+ // Subtle corner case: if the site's host ends with a dot, do the lookup
+ // without it. A trailing dot shouldn't be able to bypass isolated origins:
+ // if "https://foo.com" is an isolated origin, "https://foo.com." should
+ // match it.
+ if (it == isolated_origins_.end() && site_url.has_host() &&
+ site_url.host_piece().back() == '.') {
+ GURL::Replacements replacements;
+ base::StringPiece host(site_url.host_piece());
+ host.remove_suffix(1);
+ replacements.SetHostStr(host);
+ it = isolated_origins_.find(site_url.ReplaceComponents(replacements));
+ }
+
// If multiple isolated origins are registered with a common domain suffix,
// return the most specific one. For example, if foo.isolated.com and
- // isolated.com are both isolated origins, bar.foo.isolated.com should return
- // foo.isolated.com.
+ // isolated.com are both isolated origins, bar.foo.isolated.com should
+ // return foo.isolated.com.
bool found = false;
- for (auto isolated_origin : isolated_origins_) {
- if (IsolatedOriginUtil::DoesOriginMatchIsolatedOrigin(origin,
- isolated_origin)) {
- if (!found || result->host().length() < isolated_origin.host().length()) {
- *result = isolated_origin;
- found = true;
+ if (it != isolated_origins_.end()) {
+ for (const url::Origin& isolated_origin : it->second) {
+ if (IsolatedOriginUtil::DoesOriginMatchIsolatedOrigin(origin,
+ isolated_origin)) {
+ if (!found ||
+ result->host().length() < isolated_origin.host().length()) {
+ *result = isolated_origin;
+ found = true;
+ }
}
}
}
@@ -1268,8 +1332,11 @@ bool ChildProcessSecurityPolicyImpl::GetMatchingIsolatedOrigin(
void ChildProcessSecurityPolicyImpl::RemoveIsolatedOriginForTesting(
const url::Origin& origin) {
+ GURL key(SiteInstanceImpl::GetSiteForOrigin(origin));
base::AutoLock lock(lock_);
- isolated_origins_.erase(origin);
+ isolated_origins_[key].erase(origin);
+ if (isolated_origins_[key].empty())
+ isolated_origins_.erase(key);
}
} // namespace content
diff --git a/chromium/content/browser/child_process_security_policy_impl.h b/chromium/content/browser/child_process_security_policy_impl.h
index a82411ecdce..9dbc29b83e7 100644
--- a/chromium/content/browser/child_process_security_policy_impl.h
+++ b/chromium/content/browser/child_process_security_policy_impl.h
@@ -12,12 +12,14 @@
#include <vector>
#include "base/compiler_specific.h"
+#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/common/resource_type.h"
#include "storage/common/fileapi/file_system_types.h"
@@ -97,6 +99,15 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
bool GetMatchingIsolatedOrigin(const url::Origin& origin,
url::Origin* result) override;
+ // A version of GetMatchingIsolatedOrigin that takes in both the |origin| and
+ // the |site_url| that |origin| corresponds to. |site_url| is the key by
+ // which |origin| will be looked up in |isolated_origins_|; this function
+ // allows it to be passed in when it is already known to avoid recomputing it
+ // internally.
+ bool GetMatchingIsolatedOrigin(const url::Origin& origin,
+ const GURL& site_url,
+ url::Origin* result);
+
// Returns if |child_id| can read all of the |files|.
bool CanReadAllFiles(int child_id, const std::vector<base::FilePath>& files);
@@ -160,6 +171,20 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
// Revoke read raw cookies permission.
void RevokeReadRawCookies(int child_id);
+ // A version of the public ChildProcessSecurityPolicy::CanCommitURL() which
+ // takes an additional bool |check_origin_lock|, specifying whether to
+ // reject |url| if it does not match the origin lock on process |child_id|.
+ // Passing true for |check_origin_lock| provides stronger enforcement with
+ // strict site isolation; it is only set to false by features (e.g., Origin
+ // header validation) that aren't yet ready for this enforcement. This
+ // function should *not* be used by new features; use the public
+ // ChildProcessSecurityPolicy::CanCommitURL() instead, which internally calls
+ // this with |check_origin_lock| being true.
+ //
+ // TODO(alexmos): Remove |check_origin_lock| and check origin locks
+ // unconditionally once https://crbug.com/515309 is fixed.
+ bool CanCommitURL(int child_id, const GURL& url, bool check_origin_lock);
+
// Whether the given origin is valid for an origin header. Valid origin
// headers are commitable URLs.
bool CanSetAsOriginHeader(int child_id, const GURL& url);
@@ -286,13 +311,14 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
friend struct base::DefaultSingletonTraits<ChildProcessSecurityPolicyImpl>;
// Adds child process during registration.
- void AddChild(int child_id);
+ void AddChild(int child_id) EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Determines if certain permissions were granted for a file to given child
// process. |permissions| is an internally defined bit-set.
bool ChildProcessHasPermissionsForFile(int child_id,
const base::FilePath& file,
- int permissions);
+ int permissions)
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Grant a particular permission set for a file. |permissions| is an
// internally defined bit-set.
@@ -336,32 +362,43 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
// These schemes are white-listed for all child processes in various contexts.
// These sets are protected by |lock_|.
- SchemeSet schemes_okay_to_commit_in_any_process_;
- SchemeSet schemes_okay_to_request_in_any_process_;
- SchemeSet schemes_okay_to_appear_as_origin_headers_;
+ SchemeSet schemes_okay_to_commit_in_any_process_ GUARDED_BY(lock_);
+ SchemeSet schemes_okay_to_request_in_any_process_ GUARDED_BY(lock_);
+ SchemeSet schemes_okay_to_appear_as_origin_headers_ GUARDED_BY(lock_);
// These schemes do not actually represent retrievable URLs. For example,
// the the URLs in the "about" scheme are aliases to other URLs. This set is
// protected by |lock_|.
- SchemeSet pseudo_schemes_;
+ SchemeSet pseudo_schemes_ GUARDED_BY(lock_);
// This map holds a SecurityState for each child process. The key for the
// map is the ID of the ChildProcessHost. The SecurityState objects are
// owned by this object and are protected by |lock_|. References to them must
// not escape this class.
- SecurityStateMap security_state_;
+ SecurityStateMap security_state_ GUARDED_BY(lock_);
// This maps keeps the record of which js worker thread child process
// corresponds to which main js thread child process.
- WorkerToMainProcessMap worker_map_;
+ WorkerToMainProcessMap worker_map_ GUARDED_BY(lock_);
- FileSystemPermissionPolicyMap file_system_policy_map_;
+ FileSystemPermissionPolicyMap file_system_policy_map_ GUARDED_BY(lock_);
// Tracks origins for which the entire origin should be treated as a site
// when making process model decisions, rather than the origin's scheme and
// eTLD+1. Each of these origins requires a dedicated process. This set is
// protected by |lock_|.
- base::flat_set<url::Origin> isolated_origins_;
+ //
+ // The origins are stored in a map indexed by a site URL computed for each
+ // origin. For example, adding https://foo.com, https://bar.foo.com, and
+ // https://www.bar.com would result in the following structure:
+ // https://foo.com -> { https://foo.com, https://bar.foo.com }
+ // https://bar.com -> { https://www.bar.com }
+ // This organization speeds up lookups of isolated origins. The site can be
+ // found in O(log n) time, and the corresponding list of origins to search
+ // using the expensive DoesOriginMatchIsolatedOrigin() comparison is
+ // typically small.
+ base::flat_map<GURL, base::flat_set<url::Origin>> isolated_origins_
+ GUARDED_BY(lock_);
DISALLOW_COPY_AND_ASSIGN(ChildProcessSecurityPolicyImpl);
};
diff --git a/chromium/content/browser/child_process_security_policy_unittest.cc b/chromium/content/browser/child_process_security_policy_unittest.cc
index 57bc04c9d8c..d571d8e9883 100644
--- a/chromium/content/browser/child_process_security_policy_unittest.cc
+++ b/chromium/content/browser/child_process_security_policy_unittest.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/test/mock_log.h"
#include "content/browser/child_process_security_policy_impl.h"
+#include "content/browser/site_instance_impl.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/url_constants.h"
#include "content/test/test_content_browser_client.h"
@@ -497,8 +498,8 @@ TEST_F(ChildProcessSecurityPolicyTest, GrantCommitURLToNonStandardScheme) {
const GURL url("httpxml://awesome");
const GURL url2("httpxml://also-awesome");
- ASSERT_TRUE(url::Origin::Create(url).unique());
- ASSERT_TRUE(url::Origin::Create(url2).unique());
+ ASSERT_TRUE(url::Origin::Create(url).opaque());
+ ASSERT_TRUE(url::Origin::Create(url2).opaque());
RegisterTestScheme("httpxml");
p->Add(kRendererID);
@@ -1086,12 +1087,38 @@ TEST_F(ChildProcessSecurityPolicyTest, OriginGranting) {
p->Remove(kRendererID);
}
+
+namespace {
+
+// Helpers to construct (key, value) entries used to validate the
+// isolated_origins_ map.
+auto IsolatedOriginEntry(const url::Origin& origin) {
+ return std::pair<GURL, base::flat_set<url::Origin>>(
+ SiteInstanceImpl::GetSiteForOrigin(origin), {origin});
+}
+
+auto IsolatedOriginEntry(const url::Origin& origin1,
+ const url::Origin& origin2) {
+ EXPECT_EQ(SiteInstanceImpl::GetSiteForOrigin(origin1),
+ SiteInstanceImpl::GetSiteForOrigin(origin2));
+ return std::pair<GURL, base::flat_set<url::Origin>>(
+ SiteInstanceImpl::GetSiteForOrigin(origin1), {origin1, origin2});
+}
+
+} // namespace
+
+#define LOCKED_EXPECT_THAT(lock, value, matcher) \
+ do { \
+ base::AutoLock auto_lock(lock); \
+ EXPECT_THAT(value, matcher); \
+ } while (0);
+
// Verifies ChildProcessSecurityPolicyImpl::AddIsolatedOrigins method.
TEST_F(ChildProcessSecurityPolicyTest, AddIsolatedOrigins) {
url::Origin foo = url::Origin::Create(GURL("https://foo.com/"));
url::Origin bar = url::Origin::Create(GURL("https://bar.com/"));
url::Origin baz = url::Origin::Create(GURL("https://baz.com/"));
- url::Origin foobar = url::Origin::Create(GURL("https://foobar.com/"));
+ url::Origin quxfoo = url::Origin::Create(GURL("https://qux.foo.com/"));
url::Origin baz_http_8000 = url::Origin::Create(GURL("http://baz.com:8000/"));
url::Origin baz_https_8000 =
url::Origin::Create(GURL("https://baz.com:8000/"));
@@ -1100,32 +1127,43 @@ TEST_F(ChildProcessSecurityPolicyTest, AddIsolatedOrigins) {
ChildProcessSecurityPolicyImpl::GetInstance();
// Initially there should be no isolated origins.
- EXPECT_THAT(p->isolated_origins_, testing::IsEmpty());
+ LOCKED_EXPECT_THAT(p->lock_, p->isolated_origins_, testing::IsEmpty());
// Verify deduplication of the argument.
p->AddIsolatedOrigins({foo, bar, bar});
- EXPECT_THAT(p->isolated_origins_, testing::UnorderedElementsAre(foo, bar));
+ LOCKED_EXPECT_THAT(p->lock_, p->isolated_origins_,
+ testing::UnorderedElementsAre(IsolatedOriginEntry(foo),
+ IsolatedOriginEntry(bar)));
// Verify that the old set is extended (not replaced).
p->AddIsolatedOrigins({baz});
- EXPECT_THAT(p->isolated_origins_,
- testing::UnorderedElementsAre(foo, bar, baz));
+ LOCKED_EXPECT_THAT(p->lock_, p->isolated_origins_,
+ testing::UnorderedElementsAre(IsolatedOriginEntry(foo),
+ IsolatedOriginEntry(bar),
+ IsolatedOriginEntry(baz)));
// Verify deduplication against the old set.
p->AddIsolatedOrigins({foo});
- EXPECT_THAT(p->isolated_origins_,
- testing::UnorderedElementsAre(foo, bar, baz));
+ LOCKED_EXPECT_THAT(p->lock_, p->isolated_origins_,
+ testing::UnorderedElementsAre(IsolatedOriginEntry(foo),
+ IsolatedOriginEntry(bar),
+ IsolatedOriginEntry(baz)));
- // Verify deduplication considers scheme and port differences.
+ // Verify deduplication considers scheme and port differences. Note that
+ // origins that differ only in ports map to the same key.
p->AddIsolatedOrigins({baz, baz_http_8000, baz_https_8000});
- EXPECT_THAT(p->isolated_origins_,
- testing::UnorderedElementsAre(foo, bar, baz, baz_http_8000,
- baz_https_8000));
+ LOCKED_EXPECT_THAT(p->lock_, p->isolated_origins_,
+ testing::UnorderedElementsAre(
+ IsolatedOriginEntry(foo), IsolatedOriginEntry(bar),
+ IsolatedOriginEntry(baz, baz_https_8000),
+ IsolatedOriginEntry(baz_http_8000)));
// Verify that adding an origin that is invalid for isolation will 1) log a
// warning and 2) won't CHECK or crash the browser process, 3) will not add
// the invalid origin, but will add the remaining origins passed to
- // AddIsolatedOrigins.
+ // AddIsolatedOrigins. Note that the new |quxfoo| origin should map to the
+ // same key (i.e., the https://foo.com/ site URL) as the existing |foo|
+ // origin.
{
base::test::MockLog mock_log;
EXPECT_CALL(mock_log,
@@ -1134,11 +1172,23 @@ TEST_F(ChildProcessSecurityPolicyTest, AddIsolatedOrigins) {
.Times(1);
mock_log.StartCapturingLogs();
- p->AddIsolatedOrigins({foobar, invalid_etld});
- EXPECT_THAT(p->isolated_origins_,
- testing::UnorderedElementsAre(foo, bar, baz, baz_http_8000,
- baz_https_8000, foobar));
+ p->AddIsolatedOrigins({quxfoo, invalid_etld});
+ LOCKED_EXPECT_THAT(
+ p->lock_, p->isolated_origins_,
+ testing::UnorderedElementsAre(IsolatedOriginEntry(foo, quxfoo),
+ IsolatedOriginEntry(bar),
+ IsolatedOriginEntry(baz, baz_https_8000),
+ IsolatedOriginEntry(baz_http_8000)));
}
}
+// Check that an unsuccessful isolated origin lookup for a URL with an empty
+// host doesn't crash. See https://crbug.com/882686.
+TEST_F(ChildProcessSecurityPolicyTest, IsIsolatedOriginWithEmptyHost) {
+ ChildProcessSecurityPolicyImpl* p =
+ ChildProcessSecurityPolicyImpl::GetInstance();
+ EXPECT_FALSE(p->IsIsolatedOrigin(url::Origin::Create(GURL())));
+ EXPECT_FALSE(p->IsIsolatedOrigin(url::Origin::Create(GURL("file:///foo"))));
+}
+
} // namespace content
diff --git a/chromium/content/browser/cocoa/system_hotkey_helper_mac.mm b/chromium/content/browser/cocoa/system_hotkey_helper_mac.mm
index 0a26a48fd62..27b8fae73bc 100644
--- a/chromium/content/browser/cocoa/system_hotkey_helper_mac.mm
+++ b/chromium/content/browser/cocoa/system_hotkey_helper_mac.mm
@@ -12,6 +12,7 @@
#include "base/task/task_traits.h"
#include "base/threading/scoped_blocking_call.h"
#include "content/browser/cocoa/system_hotkey_map.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace {
@@ -62,11 +63,9 @@ void SystemHotkeyHelperMac::LoadSystemHotkeys() {
// will destroy the object.
NSDictionary* dictionary = [SystemHotkeyMap::DictionaryFromData(data) retain];
- BrowserThread::PostTask(BrowserThread::UI,
- FROM_HERE,
- base::Bind(&SystemHotkeyHelperMac::FileDidLoad,
- base::Unretained(this),
- dictionary));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::Bind(&SystemHotkeyHelperMac::FileDidLoad,
+ base::Unretained(this), dictionary));
}
void SystemHotkeyHelperMac::FileDidLoad(NSDictionary* dictionary) {
diff --git a/chromium/content/browser/code_cache/generated_code_cache.cc b/chromium/content/browser/code_cache/generated_code_cache.cc
index f1f3ec32393..90028a32b48 100644
--- a/chromium/content/browser/code_cache/generated_code_cache.cc
+++ b/chromium/content/browser/code_cache/generated_code_cache.cc
@@ -4,6 +4,7 @@
#include "content/browser/code_cache/generated_code_cache.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
#include "net/base/completion_callback.h"
#include "net/base/completion_once_callback.h"
#include "net/http/http_util.h"
@@ -24,7 +25,7 @@ bool IsAllowedToCache(const GURL& resource_url,
// Don't cache the code corresponding to unique origins. The same-origin
// checks should always fail for unique origins but the serialized value of
// unique origins does not ensure this.
- if (requesting_origin.unique())
+ if (requesting_origin.opaque())
return false;
// If the resource url or requesting url is invalid don't cache the code.
@@ -39,7 +40,7 @@ bool IsAllowedToCache(const GURL& resource_url,
// serialized url and origin with a separator in between.
std::string GetCacheKey(const GURL& resource_url,
const url::Origin& requesting_origin) {
- DCHECK(!requesting_origin.unique());
+ DCHECK(!requesting_origin.opaque());
DCHECK(resource_url.is_valid());
// Add a prefix _ so it can't be parsed as a valid URL.
std::string key = "_key";
@@ -54,6 +55,18 @@ std::string GetCacheKey(const GURL& resource_url,
}
} // namespace
+void GeneratedCodeCache::CollectStatistics(
+ GeneratedCodeCache::CacheEntryStatus status) {
+ switch (cache_type_) {
+ case GeneratedCodeCache::CodeCacheType::kJavaScript:
+ UMA_HISTOGRAM_ENUMERATION("SiteIsolatedCodeCache.JS.Behaviour", status);
+ break;
+ case GeneratedCodeCache::CodeCacheType::kWebAssembly:
+ UMA_HISTOGRAM_ENUMERATION("SiteIsolatedCodeCache.WASM.Behaviour", status);
+ break;
+ }
+}
+
// Stores the information about a pending request while disk backend is
// being initialized.
class GeneratedCodeCache::PendingOperation {
@@ -141,10 +154,12 @@ GeneratedCodeCache::PendingOperation::PendingOperation(
GeneratedCodeCache::PendingOperation::~PendingOperation() = default;
GeneratedCodeCache::GeneratedCodeCache(const base::FilePath& path,
- int max_size_bytes)
+ int max_size_bytes,
+ CodeCacheType cache_type)
: backend_state_(kUnInitialized),
path_(path),
max_size_bytes_(max_size_bytes),
+ cache_type_(cache_type),
weak_ptr_factory_(this) {
CreateBackend();
}
@@ -156,18 +171,23 @@ void GeneratedCodeCache::WriteData(const GURL& url,
const base::Time& response_time,
const std::vector<uint8_t>& data) {
// Silently ignore the requests.
- if (backend_state_ == kFailed)
+ if (backend_state_ == kFailed) {
+ CollectStatistics(CacheEntryStatus::kError);
return;
+ }
// If the url is invalid or if it is from a unique origin, we should not
// cache the code.
- if (!IsAllowedToCache(url, origin))
+ if (!IsAllowedToCache(url, origin)) {
+ CollectStatistics(CacheEntryStatus::kError);
return;
+ }
// Append the response time to the metadata. Code caches store
// response_time + generated code as a single entry.
- scoped_refptr<net::IOBufferWithSize> buffer(
- new net::IOBufferWithSize(data.size() + kResponseTimeSizeInBytes));
+ scoped_refptr<net::IOBufferWithSize> buffer =
+ base::MakeRefCounted<net::IOBufferWithSize>(data.size() +
+ kResponseTimeSizeInBytes);
int64_t serialized_time =
response_time.ToDeltaSinceWindowsEpoch().InMicroseconds();
memcpy(buffer->data(), &serialized_time, kResponseTimeSizeInBytes);
@@ -192,6 +212,7 @@ void GeneratedCodeCache::FetchEntry(const GURL& url,
const url::Origin& origin,
ReadDataCallback read_data_callback) {
if (backend_state_ == kFailed) {
+ CollectStatistics(CacheEntryStatus::kError);
// Silently ignore the requests.
std::move(read_data_callback).Run(base::Time(), std::vector<uint8_t>());
return;
@@ -200,6 +221,7 @@ void GeneratedCodeCache::FetchEntry(const GURL& url,
// If the url is invalid or if it is from a unique origin, we should not
// cache the code.
if (!IsAllowedToCache(url, origin)) {
+ CollectStatistics(CacheEntryStatus::kError);
std::move(read_data_callback).Run(base::Time(), std::vector<uint8_t>());
return;
}
@@ -220,13 +242,17 @@ void GeneratedCodeCache::FetchEntry(const GURL& url,
void GeneratedCodeCache::DeleteEntry(const GURL& url,
const url::Origin& origin) {
// Silently ignore the requests.
- if (backend_state_ == kFailed)
+ if (backend_state_ == kFailed) {
+ CollectStatistics(CacheEntryStatus::kError);
return;
+ }
// If the url is invalid or if it is from a unique origin, we should not
// cache the code.
- if (!IsAllowedToCache(url, origin))
+ if (!IsAllowedToCache(url, origin)) {
+ CollectStatistics(CacheEntryStatus::kError);
return;
+ }
std::string key = GetCacheKey(url, origin);
if (backend_state_ != kInitialized) {
@@ -355,6 +381,7 @@ void GeneratedCodeCache::OpenCompleteForWriteData(
DCHECK(entry->data);
disk_cache::ScopedEntryPtr disk_entry(entry->data);
+ CollectStatistics(CacheEntryStatus::kUpdate);
// This call will truncate the data. This is safe to do since we read the
// entire data at the same time currently. If we want to read in parts we have
// to doom the entry first.
@@ -366,11 +393,14 @@ void GeneratedCodeCache::CreateCompleteForWriteData(
scoped_refptr<net::IOBufferWithSize> buffer,
scoped_refptr<base::RefCountedData<disk_cache::Entry*>> entry,
int rv) {
- if (rv != net::OK)
+ if (rv != net::OK) {
+ CollectStatistics(CacheEntryStatus::kError);
return;
+ }
DCHECK(entry->data);
disk_cache::ScopedEntryPtr disk_entry(entry->data);
+ CollectStatistics(CacheEntryStatus::kCreate);
disk_entry->WriteData(kDataIndex, 0, buffer.get(), buffer->size(),
net::CompletionOnceCallback(), true);
}
@@ -402,6 +432,7 @@ void GeneratedCodeCache::OpenCompleteForReadData(
scoped_refptr<base::RefCountedData<disk_cache::Entry*>> entry,
int rv) {
if (rv != net::OK) {
+ CollectStatistics(CacheEntryStatus::kMiss);
std::move(read_data_callback).Run(base::Time(), std::vector<uint8_t>());
return;
}
@@ -411,7 +442,8 @@ void GeneratedCodeCache::OpenCompleteForReadData(
disk_cache::ScopedEntryPtr disk_entry(entry->data);
int size = disk_entry->GetDataSize(kDataIndex);
- scoped_refptr<net::IOBufferWithSize> buffer(new net::IOBufferWithSize(size));
+ scoped_refptr<net::IOBufferWithSize> buffer =
+ base::MakeRefCounted<net::IOBufferWithSize>(size);
net::CompletionOnceCallback callback = base::BindOnce(
&GeneratedCodeCache::ReadDataComplete, weak_ptr_factory_.GetWeakPtr(),
read_data_callback, buffer);
@@ -427,13 +459,30 @@ void GeneratedCodeCache::ReadDataComplete(
scoped_refptr<net::IOBufferWithSize> buffer,
int rv) {
if (rv != buffer->size()) {
+ CollectStatistics(CacheEntryStatus::kMiss);
+ std::move(callback).Run(base::Time(), std::vector<uint8_t>());
+ } else if (buffer->size() < kResponseTimeSizeInBytes) {
+ // TODO(crbug.com/886892): Change the implementation, so serialize requests
+ // for the same key here. When we do that, this case should not arise.
+ // We might be reading an entry before the write was completed. This can
+ // happen if we have a write and read operation for the same key almost at
+ // the same time and they interleave as:
+ // W(Create) -> R(Open) -> R(Read) -> W(Write).
+ CollectStatistics(CacheEntryStatus::kIncompleteEntry);
std::move(callback).Run(base::Time(), std::vector<uint8_t>());
} else {
+ // DiskCache ensures that the operations that are queued for an entry
+ // go in order. Hence, we would either read an empty data or read the full
+ // data. Please look at comment in else to see why we read empty data.
+ CollectStatistics(CacheEntryStatus::kHit);
int64_t raw_response_time = *(reinterpret_cast<int64_t*>(buffer->data()));
base::Time response_time = base::Time::FromDeltaSinceWindowsEpoch(
base::TimeDelta::FromMicroseconds(raw_response_time));
- std::vector<uint8_t> data(buffer->data() + kResponseTimeSizeInBytes,
- buffer->data() + buffer->size());
+ std::vector<uint8_t> data;
+ if (buffer->size() > kResponseTimeSizeInBytes) {
+ data = std::vector<uint8_t>(buffer->data() + kResponseTimeSizeInBytes,
+ buffer->data() + buffer->size());
+ }
std::move(callback).Run(response_time, data);
}
}
@@ -442,6 +491,7 @@ void GeneratedCodeCache::DeleteEntryImpl(const std::string& key) {
if (backend_state_ != kInitialized)
return;
+ CollectStatistics(CacheEntryStatus::kClear);
backend_->DoomEntry(key, net::LOWEST, net::CompletionOnceCallback());
}
diff --git a/chromium/content/browser/code_cache/generated_code_cache.h b/chromium/content/browser/code_cache/generated_code_cache.h
index 58e735b447d..2ad53ff0329 100644
--- a/chromium/content/browser/code_cache/generated_code_cache.h
+++ b/chromium/content/browser/code_cache/generated_code_cache.h
@@ -36,10 +36,28 @@ class CONTENT_EXPORT GeneratedCodeCache {
const std::vector<uint8_t>&)>;
static const int kResponseTimeSizeInBytes = sizeof(int64_t);
+ // Cache type. Used for collecting statistics for JS and Wasm in separate
+ // buckets.
+ enum CodeCacheType { kJavaScript, kWebAssembly };
+
+ // Used for collecting statistics about cache behaviour.
+ enum CacheEntryStatus {
+ kHit,
+ kMiss,
+ kClear,
+ kUpdate,
+ kCreate,
+ kError,
+ kIncompleteEntry,
+ kMaxValue = kIncompleteEntry
+ };
+
// Creates a GeneratedCodeCache with the specified path and the maximum size.
// If |max_size_bytes| is 0, then disk_cache picks a default size based on
// some heuristics.
- GeneratedCodeCache(const base::FilePath& path, int max_size_bytes);
+ GeneratedCodeCache(const base::FilePath& path,
+ int max_size_bytes,
+ CodeCacheType cache_type);
~GeneratedCodeCache();
@@ -120,6 +138,8 @@ class CONTENT_EXPORT GeneratedCodeCache {
void DoPendingClearCache(net::CompletionCallback callback);
void PendingClearComplete(net::CompletionCallback callback, int rv);
+ void CollectStatistics(GeneratedCodeCache::CacheEntryStatus status);
+
std::unique_ptr<disk_cache::Backend> backend_;
BackendState backend_state_;
@@ -127,6 +147,7 @@ class CONTENT_EXPORT GeneratedCodeCache {
base::FilePath path_;
int max_size_bytes_;
+ CodeCacheType cache_type_;
base::WeakPtrFactory<GeneratedCodeCache> weak_ptr_factory_;
diff --git a/chromium/content/browser/code_cache/generated_code_cache_context.cc b/chromium/content/browser/code_cache/generated_code_cache_context.cc
index 9aa1621fce3..b119832b8d4 100644
--- a/chromium/content/browser/code_cache/generated_code_cache_context.cc
+++ b/chromium/content/browser/code_cache/generated_code_cache_context.cc
@@ -3,7 +3,9 @@
// found in the LICENSE file.
#include "content/browser/code_cache/generated_code_cache_context.h"
#include "base/files/file_path.h"
+#include "base/task/post_task.h"
#include "content/browser/code_cache/generated_code_cache.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@@ -16,20 +18,31 @@ void GeneratedCodeCacheContext::Initialize(const base::FilePath& path,
int max_bytes) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&GeneratedCodeCacheContext::InitializeOnIO, this, path,
max_bytes));
}
void GeneratedCodeCacheContext::InitializeOnIO(const base::FilePath& path,
int max_bytes) {
- generated_code_cache_.reset(new GeneratedCodeCache(path, max_bytes));
+ generated_js_code_cache_.reset(
+ new GeneratedCodeCache(path.AppendASCII("js"), max_bytes,
+ GeneratedCodeCache::CodeCacheType::kJavaScript));
+ generated_wasm_code_cache_.reset(
+ new GeneratedCodeCache(path.AppendASCII("wasm"), max_bytes,
+ GeneratedCodeCache::CodeCacheType::kWebAssembly));
}
-GeneratedCodeCache* GeneratedCodeCacheContext::generated_code_cache() const {
+GeneratedCodeCache* GeneratedCodeCacheContext::generated_js_code_cache() const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return generated_code_cache_.get();
+ return generated_js_code_cache_.get();
+}
+
+GeneratedCodeCache* GeneratedCodeCacheContext::generated_wasm_code_cache()
+ const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ return generated_wasm_code_cache_.get();
}
GeneratedCodeCacheContext::~GeneratedCodeCacheContext() = default;
diff --git a/chromium/content/browser/code_cache/generated_code_cache_context.h b/chromium/content/browser/code_cache/generated_code_cache_context.h
index 4a42bebef7b..7e26e3269ee 100644
--- a/chromium/content/browser/code_cache/generated_code_cache_context.h
+++ b/chromium/content/browser/code_cache/generated_code_cache_context.h
@@ -30,8 +30,9 @@ class CONTENT_EXPORT GeneratedCodeCacheContext
// being setup.
void Initialize(const base::FilePath& path, int max_bytes);
- // Call on the IO thread to get the code cache instance.
- GeneratedCodeCache* generated_code_cache() const;
+ // Call on the IO thread to get the code cache instances.
+ GeneratedCodeCache* generated_js_code_cache() const;
+ GeneratedCodeCache* generated_wasm_code_cache() const;
private:
friend class base::RefCountedThreadSafe<GeneratedCodeCacheContext>;
@@ -41,7 +42,9 @@ class CONTENT_EXPORT GeneratedCodeCacheContext
// Created, used and deleted on the IO thread.
std::unique_ptr<GeneratedCodeCache, BrowserThread::DeleteOnIOThread>
- generated_code_cache_;
+ generated_js_code_cache_;
+ std::unique_ptr<GeneratedCodeCache, BrowserThread::DeleteOnIOThread>
+ generated_wasm_code_cache_;
DISALLOW_COPY_AND_ASSIGN(GeneratedCodeCacheContext);
};
diff --git a/chromium/content/browser/code_cache/generated_code_cache_unittest.cc b/chromium/content/browser/code_cache/generated_code_cache_unittest.cc
index 4f005c89c9a..3a2e4ca7fc5 100644
--- a/chromium/content/browser/code_cache/generated_code_cache_unittest.cc
+++ b/chromium/content/browser/code_cache/generated_code_cache_unittest.cc
@@ -25,8 +25,6 @@ class GeneratedCodeCacheTest : public testing::Test {
void SetUp() override {
ASSERT_TRUE(cache_dir_.CreateUniqueTempDir());
cache_path_ = cache_dir_.GetPath();
- generated_code_cache_ =
- std::make_unique<GeneratedCodeCache>(cache_path_, kMaxSizeInBytes);
}
void TearDown() override {
@@ -36,7 +34,11 @@ class GeneratedCodeCacheTest : public testing::Test {
// This function initializes the cache and waits till the transaction is
// finished. When this function returns, the backend is already initialized.
- void InitializeCache() {
+ void InitializeCache(GeneratedCodeCache::CodeCacheType cache_type) {
+ // Create code cache
+ generated_code_cache_ = std::make_unique<GeneratedCodeCache>(
+ cache_path_, kMaxSizeInBytes, cache_type);
+
GURL url(kInitialUrl);
url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
WriteToCache(url, origin, kInitialData, base::Time::Now());
@@ -46,10 +48,10 @@ class GeneratedCodeCacheTest : public testing::Test {
// This function initializes the cache and reopens it. When this function
// returns, the backend initialization is not complete yet. This is used
// to test the pending operaions path.
- void InitializeCacheAndReOpen() {
- InitializeCache();
+ void InitializeCacheAndReOpen(GeneratedCodeCache::CodeCacheType cache_type) {
+ InitializeCache(cache_type);
generated_code_cache_.reset(
- new GeneratedCodeCache(cache_path_, kMaxSizeInBytes));
+ new GeneratedCodeCache(cache_path_, kMaxSizeInBytes, cache_type));
}
void WriteToCache(const GURL& url,
@@ -113,6 +115,7 @@ TEST_F(GeneratedCodeCacheTest, CheckResponseTime) {
GURL url(kInitialUrl);
url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
std::string data = "SerializedCodeForScript";
base::Time response_time = base::Time::Now();
WriteToCache(url, origin, data, response_time);
@@ -129,7 +132,7 @@ TEST_F(GeneratedCodeCacheTest, FetchEntry) {
GURL url(kInitialUrl);
url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
- InitializeCache();
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
FetchFromCache(url, origin);
scoped_task_environment_.RunUntilIdle();
@@ -141,7 +144,7 @@ TEST_F(GeneratedCodeCacheTest, WriteEntry) {
GURL new_url("http://example1.com/script.js");
url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
- InitializeCache();
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
std::string data = "SerializedCodeForScript";
base::Time response_time = base::Time::Now();
WriteToCache(new_url, origin, data, response_time);
@@ -158,7 +161,7 @@ TEST_F(GeneratedCodeCacheTest, DeleteEntry) {
GURL url(kInitialUrl);
url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
- InitializeCache();
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
DeleteFromCache(url, origin);
FetchFromCache(url, origin);
scoped_task_environment_.RunUntilIdle();
@@ -167,11 +170,27 @@ TEST_F(GeneratedCodeCacheTest, DeleteEntry) {
ASSERT_TRUE(received_null_);
}
+TEST_F(GeneratedCodeCacheTest, WriteEntryWithEmptyData) {
+ GURL url(kInitialUrl);
+ url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
+ base::Time response_time = base::Time::Now();
+ WriteToCache(url, origin, std::string(), response_time);
+ scoped_task_environment_.RunUntilIdle();
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+
+ ASSERT_TRUE(received_);
+ ASSERT_TRUE(received_null_);
+ EXPECT_EQ(response_time, received_response_time_);
+}
+
TEST_F(GeneratedCodeCacheTest, FetchEntryPendingOp) {
GURL url(kInitialUrl);
url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
- InitializeCacheAndReOpen();
+ InitializeCacheAndReOpen(GeneratedCodeCache::CodeCacheType::kJavaScript);
FetchFromCache(url, origin);
scoped_task_environment_.RunUntilIdle();
@@ -183,7 +202,7 @@ TEST_F(GeneratedCodeCacheTest, WriteEntryPendingOp) {
GURL new_url("http://example1.com/script1.js");
url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
- InitializeCache();
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
std::string data = "SerializedCodeForScript";
base::Time response_time = base::Time::Now();
WriteToCache(new_url, origin, data, response_time);
@@ -200,7 +219,7 @@ TEST_F(GeneratedCodeCacheTest, DeleteEntryPendingOp) {
GURL url(kInitialUrl);
url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
- InitializeCacheAndReOpen();
+ InitializeCacheAndReOpen(GeneratedCodeCache::CodeCacheType::kJavaScript);
DeleteFromCache(url, origin);
FetchFromCache(url, origin);
scoped_task_environment_.RunUntilIdle();
@@ -213,7 +232,7 @@ TEST_F(GeneratedCodeCacheTest, UpdateDataOfExistingEntry) {
GURL url(kInitialUrl);
url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
- InitializeCache();
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
std::string new_data = "SerializedCodeForScriptOverwrite";
base::Time response_time = base::Time::Now();
WriteToCache(url, origin, new_data, response_time);
@@ -227,7 +246,7 @@ TEST_F(GeneratedCodeCacheTest, UpdateDataOfExistingEntry) {
}
TEST_F(GeneratedCodeCacheTest, FetchFailsForNonexistingOrigin) {
- InitializeCache();
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
url::Origin new_origin = url::Origin::Create(GURL("http://not-example.com"));
FetchFromCache(GURL(kInitialUrl), new_origin);
scoped_task_environment_.RunUntilIdle();
@@ -241,6 +260,7 @@ TEST_F(GeneratedCodeCacheTest, FetchEntriesFromSameOrigin) {
GURL second_url("http://script.com/one.js");
url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
std::string data_first_resource = "SerializedCodeForFirstResource";
WriteToCache(url, origin, data_first_resource, base::Time());
@@ -264,6 +284,7 @@ TEST_F(GeneratedCodeCacheTest, FetchSucceedsFromDifferentOrigins) {
url::Origin origin = url::Origin::Create(GURL("http://example.com"));
url::Origin origin1 = url::Origin::Create(GURL("http://example1.com"));
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
std::string data_origin = "SerializedCodeForFirstOrigin";
WriteToCache(url, origin, data_origin, base::Time());
@@ -287,6 +308,7 @@ TEST_F(GeneratedCodeCacheTest, FetchFailsForUniqueOrigin) {
url::Origin origin =
url::Origin::Create(GURL("data:text/html,<script></script>"));
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
std::string data = "SerializedCodeForUniqueOrigin";
WriteToCache(url, origin, data, base::Time());
scoped_task_environment_.RunUntilIdle();
@@ -301,6 +323,7 @@ TEST_F(GeneratedCodeCacheTest, FetchFailsForInvalidOrigin) {
GURL url("http://example.com/script.js");
url::Origin origin = url::Origin::Create(GURL("invalidURL"));
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
std::string data = "SerializedCodeForInvalidOrigin";
WriteToCache(url, origin, data, base::Time());
scoped_task_environment_.RunUntilIdle();
@@ -316,6 +339,7 @@ TEST_F(GeneratedCodeCacheTest, FetchFailsForInvalidURL) {
GURL url("InvalidURL");
url::Origin origin = url::Origin::Create(GURL("http://example.com"));
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
std::string data = "SerializedCodeForInvalidURL";
WriteToCache(url, origin, data, base::Time());
scoped_task_environment_.RunUntilIdle();
@@ -330,7 +354,7 @@ TEST_F(GeneratedCodeCacheTest, ClearCache) {
GURL url("http://example.com/script.js");
url::Origin origin = url::Origin::Create(GURL("http://example.com"));
- InitializeCache();
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
ClearCache();
scoped_task_environment_.RunUntilIdle();
FetchFromCache(url, origin);
@@ -339,4 +363,16 @@ TEST_F(GeneratedCodeCacheTest, ClearCache) {
ASSERT_TRUE(received_);
ASSERT_TRUE(received_null_);
}
+
+TEST_F(GeneratedCodeCacheTest, WasmCache) {
+ GURL url(kInitialUrl);
+ url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+
+ InitializeCache(GeneratedCodeCache::CodeCacheType::kWebAssembly);
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+
+ ASSERT_TRUE(received_);
+ EXPECT_EQ(kInitialData, received_data_);
+}
} // namespace content
diff --git a/chromium/content/browser/compositor/gpu_process_transport_factory.cc b/chromium/content/browser/compositor/gpu_process_transport_factory.cc
index 642fff3b436..e8741caf69a 100644
--- a/chromium/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/chromium/content/browser/compositor/gpu_process_transport_factory.cc
@@ -48,9 +48,9 @@
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/common/gpu_stream_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_stream_constants.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/raster_interface.h"
@@ -217,7 +217,7 @@ GpuProcessTransportFactory::CreateSoftwareOutputDevice(
return base::WrapUnique(new viz::SoftwareOutputDevice);
#if defined(USE_AURA)
- if (features::IsUsingWindowService()) {
+ if (features::IsMultiProcessMash()) {
NOTREACHED();
return nullptr;
}
@@ -344,8 +344,7 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
use_gpu_compositing = false;
// The widget might have been released in the meantime.
- PerCompositorDataMap::iterator it =
- per_compositor_data_.find(compositor.get());
+ auto it = per_compositor_data_.find(compositor.get());
if (it == per_compositor_data_.end())
return;
@@ -404,7 +403,7 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
auto result = shared_worker_context_provider_->BindToCurrentThread();
if (result != gpu::ContextResult::kSuccess) {
shared_worker_context_provider_ = nullptr;
- if (result == gpu::ContextResult::kFatalFailure)
+ if (gpu::IsFatalOrSurfaceFailure(result))
use_gpu_compositing = false;
}
}
@@ -434,7 +433,7 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
auto result = context_provider->BindToCurrentThread();
if (result != gpu::ContextResult::kSuccess) {
context_provider = nullptr;
- if (result == gpu::ContextResult::kFatalFailure)
+ if (gpu::IsFatalOrSurfaceFailure(result))
use_gpu_compositing = false;
}
}
@@ -708,7 +707,7 @@ void GpuProcessTransportFactory::RemoveReflector(ui::Reflector* reflector) {
}
void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
- PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ auto it = per_compositor_data_.find(compositor);
if (it == per_compositor_data_.end())
return;
PerCompositorData* data = it->second.get();
@@ -780,7 +779,7 @@ GpuProcessTransportFactory::GetHostFrameSinkManager() {
void GpuProcessTransportFactory::SetDisplayVisible(ui::Compositor* compositor,
bool visible) {
- PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ auto it = per_compositor_data_.find(compositor);
if (it == per_compositor_data_.end())
return;
PerCompositorData* data = it->second.get();
@@ -793,7 +792,7 @@ void GpuProcessTransportFactory::SetDisplayVisible(ui::Compositor* compositor,
void GpuProcessTransportFactory::ResizeDisplay(ui::Compositor* compositor,
const gfx::Size& size) {
- PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ auto it = per_compositor_data_.find(compositor);
if (it == per_compositor_data_.end())
return;
PerCompositorData* data = it->second.get();
@@ -804,7 +803,7 @@ void GpuProcessTransportFactory::ResizeDisplay(ui::Compositor* compositor,
void GpuProcessTransportFactory::DisableSwapUntilResize(
ui::Compositor* compositor) {
- PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ auto it = per_compositor_data_.find(compositor);
if (it == per_compositor_data_.end())
return;
PerCompositorData* data = it->second.get();
@@ -816,7 +815,7 @@ void GpuProcessTransportFactory::DisableSwapUntilResize(
void GpuProcessTransportFactory::SetDisplayColorMatrix(
ui::Compositor* compositor,
const SkMatrix44& matrix) {
- PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ auto it = per_compositor_data_.find(compositor);
if (it == per_compositor_data_.end())
return;
PerCompositorData* data = it->second.get();
@@ -830,7 +829,7 @@ void GpuProcessTransportFactory::SetDisplayColorSpace(
ui::Compositor* compositor,
const gfx::ColorSpace& blending_color_space,
const gfx::ColorSpace& output_color_space) {
- PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ auto it = per_compositor_data_.find(compositor);
if (it == per_compositor_data_.end())
return;
PerCompositorData* data = it->second.get();
@@ -841,23 +840,11 @@ void GpuProcessTransportFactory::SetDisplayColorSpace(
data->display->SetColorSpace(blending_color_space, output_color_space);
}
-void GpuProcessTransportFactory::SetAuthoritativeVSyncInterval(
- ui::Compositor* compositor,
- base::TimeDelta interval) {
- PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
- if (it == per_compositor_data_.end())
- return;
- PerCompositorData* data = it->second.get();
- DCHECK(data);
- if (data->synthetic_begin_frame_source)
- data->synthetic_begin_frame_source->SetAuthoritativeVSyncInterval(interval);
-}
-
void GpuProcessTransportFactory::SetDisplayVSyncParameters(
ui::Compositor* compositor,
base::TimeTicks timebase,
base::TimeDelta interval) {
- PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ auto it = per_compositor_data_.find(compositor);
if (it == per_compositor_data_.end())
return;
PerCompositorData* data = it->second.get();
@@ -871,7 +858,7 @@ void GpuProcessTransportFactory::SetDisplayVSyncParameters(
void GpuProcessTransportFactory::IssueExternalBeginFrame(
ui::Compositor* compositor,
const viz::BeginFrameArgs& args) {
- PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ auto it = per_compositor_data_.find(compositor);
if (it == per_compositor_data_.end())
return;
PerCompositorData* data = it->second.get();
@@ -882,7 +869,7 @@ void GpuProcessTransportFactory::IssueExternalBeginFrame(
void GpuProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor,
bool secure) {
- PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ auto it = per_compositor_data_.find(compositor);
if (it == per_compositor_data_.end())
return;
PerCompositorData* data = it->second.get();
@@ -1071,13 +1058,16 @@ GpuProcessTransportFactory::CreateContextCommon(
attributes.enable_gles2_interface = support_gles2_interface;
attributes.enable_raster_interface = support_raster_interface;
+ gpu::SharedMemoryLimits memory_limits =
+ gpu::SharedMemoryLimits::ForDisplayCompositor();
+
constexpr bool automatic_flushes = false;
GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
return base::MakeRefCounted<ws::ContextProviderCommandBuffer>(
std::move(gpu_channel_host), GetGpuMemoryBufferManager(), stream_id,
stream_priority, surface_handle, url, automatic_flushes, support_locking,
- support_grcontext, gpu::SharedMemoryLimits(), attributes, type);
+ support_grcontext, memory_limits, attributes, type);
}
} // namespace content
diff --git a/chromium/content/browser/compositor/gpu_process_transport_factory.h b/chromium/content/browser/compositor/gpu_process_transport_factory.h
index 08384de8696..b9f2cf332cd 100644
--- a/chromium/content/browser/compositor/gpu_process_transport_factory.h
+++ b/chromium/content/browser/compositor/gpu_process_transport_factory.h
@@ -96,8 +96,6 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
void SetDisplayColorSpace(ui::Compositor* compositor,
const gfx::ColorSpace& blending_color_space,
const gfx::ColorSpace& output_color_space) override;
- void SetAuthoritativeVSyncInterval(ui::Compositor* compositor,
- base::TimeDelta interval) override;
void SetDisplayVSyncParameters(ui::Compositor* compositor,
base::TimeTicks timebase,
base::TimeDelta interval) override;
diff --git a/chromium/content/browser/compositor/reflector_impl_unittest.cc b/chromium/content/browser/compositor/reflector_impl_unittest.cc
index 40a83a865a1..21319bfc09d 100644
--- a/chromium/content/browser/compositor/reflector_impl_unittest.cc
+++ b/chromium/content/browser/compositor/reflector_impl_unittest.cc
@@ -6,9 +6,9 @@
#include "base/callback.h"
#include "base/feature_list.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
@@ -134,12 +134,11 @@ class ReflectorImplTest : public testing::Test {
ui::ContextFactory* context_factory = nullptr;
ui::ContextFactoryPrivate* context_factory_private = nullptr;
- message_loop_ = std::make_unique<base::MessageLoop>();
ui::InitializeContextFactoryForTests(enable_pixel_output, &context_factory,
&context_factory_private);
ImageTransportFactory::SetFactory(
std::make_unique<TestImageTransportFactory>());
- task_runner_ = message_loop_->task_runner();
+ task_runner_ = base::ThreadTaskRunnerHandle::Get();
compositor_task_runner_ = new FakeTaskRunner();
begin_frame_source_ = std::make_unique<viz::DelayBasedBeginFrameSource>(
std::make_unique<viz::DelayBasedTimeSource>(
@@ -193,7 +192,7 @@ class ReflectorImplTest : public testing::Test {
protected:
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
std::unique_ptr<viz::SyntheticBeginFrameSource> begin_frame_source_;
- std::unique_ptr<base::MessageLoop> message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
std::unique_ptr<ui::Compositor> compositor_;
std::unique_ptr<ui::Layer> root_layer_;
diff --git a/chromium/content/browser/compositor/viz_process_transport_factory.cc b/chromium/content/browser/compositor/viz_process_transport_factory.cc
index 07fe6eeaf90..8ae1f00fdbc 100644
--- a/chromium/content/browser/compositor/viz_process_transport_factory.cc
+++ b/chromium/content/browser/compositor/viz_process_transport_factory.cc
@@ -10,6 +10,7 @@
#include "base/command_line.h"
#include "base/debug/dump_without_crashing.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
#include "cc/raster/single_thread_task_graph_runner.h"
#include "components/viz/client/hit_test_data_provider_draw_quad.h"
@@ -25,10 +26,11 @@
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
-#include "content/common/gpu_stream_constants.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_stream_constants.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "gpu/ipc/client/gpu_channel_host.h"
@@ -69,12 +71,15 @@ scoped_refptr<ws::ContextProviderCommandBuffer> CreateContextProviderImpl(
attributes.enable_gles2_interface = support_gles2_interface;
attributes.enable_raster_interface = support_raster_interface;
+ gpu::SharedMemoryLimits memory_limits =
+ gpu::SharedMemoryLimits::ForDisplayCompositor();
+
GURL url("chrome://gpu/VizProcessTransportFactory::CreateContextProvider");
return base::MakeRefCounted<ws::ContextProviderCommandBuffer>(
std::move(gpu_channel_host), gpu_memory_buffer_manager,
kGpuStreamIdDefault, kGpuStreamPriorityUI, gpu::kNullSurfaceHandle,
std::move(url), kAutomaticFlushes, support_locking, support_grcontext,
- gpu::SharedMemoryLimits(), attributes, type);
+ memory_limits, attributes, type);
}
bool IsContextLost(viz::ContextProvider* context_provider) {
@@ -170,8 +175,8 @@ void VizProcessTransportFactory::ConnectHostFrameSinkManager() {
std::move(request), std::move(client));
}
};
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(connect_on_io_thread,
std::move(frame_sink_manager_request),
frame_sink_manager_client.PassInterface()));
@@ -204,6 +209,10 @@ void VizProcessTransportFactory::CreateLayerTreeFrameSink(
compositor->widget());
#endif
+ // Create the data map entry so that we can set properties like output secure
+ // while we are waiting for the GpuChannel to be established.
+ AddCompositor(compositor.get());
+
if (is_gpu_compositing_disabled() ||
compositor->force_software_compositor()) {
OnEstablishedGpuChannel(compositor, nullptr);
@@ -225,10 +234,11 @@ VizProcessTransportFactory::SharedMainThreadContextProvider() {
context_result = TryCreateContextsForGpuCompositing(
gpu_channel_establish_factory_->EstablishGpuChannelSync());
- if (context_result == gpu::ContextResult::kFatalFailure)
+ if (gpu::IsFatalOrSurfaceFailure(context_result))
DisableGpuCompositing(nullptr);
}
- // On kFatalFailure |main_context_provider_| will be null.
+ // On kFatalFailure or kSurfaceFailure, |main_context_provider_| will be
+ // null.
}
return main_context_provider_;
@@ -367,7 +377,7 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel(
base::BindOnce(&VizProcessTransportFactory::OnEstablishedGpuChannel,
weak_ptr_factory_.GetWeakPtr(), compositor_weak_ptr));
return;
- } else if (context_result == gpu::ContextResult::kFatalFailure) {
+ } else if (gpu::IsFatalOrSurfaceFailure(context_result)) {
DisableGpuCompositing(compositor);
gpu_compositing = false;
}
@@ -380,7 +390,7 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel(
compositor_context = main_context_provider_;
worker_context = worker_context_provider_;
}
- ConfigureCompositor(compositor_weak_ptr, std::move(compositor_context),
+ ConfigureCompositor(compositor, std::move(compositor_context),
std::move(worker_context));
}
diff --git a/chromium/content/browser/compositor/viz_process_transport_factory.h b/chromium/content/browser/compositor/viz_process_transport_factory.h
index 41619afe58d..5823501edca 100644
--- a/chromium/content/browser/compositor/viz_process_transport_factory.h
+++ b/chromium/content/browser/compositor/viz_process_transport_factory.h
@@ -104,8 +104,8 @@ class VizProcessTransportFactory : public ui::ContextFactory,
// blacklisted.
//
// Returns kSuccess if caller can use GPU compositing, kTransientFailure if
- // caller should try again or kFatalFailure if caller should fallback to
- // software compositing.
+ // caller should try again or kFatalFailure/kSurfaceFailure if caller should
+ // fallback to software compositing.
gpu::ContextResult TryCreateContextsForGpuCompositing(
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host);
diff --git a/chromium/content/browser/content_service_browsertest.cc b/chromium/content/browser/content_service_browsertest.cc
index 633ff83f863..8c45554d59a 100644
--- a/chromium/content/browser/content_service_browsertest.cc
+++ b/chromium/content/browser/content_service_browsertest.cc
@@ -34,25 +34,107 @@ class ContentServiceBrowserTest : public ContentBrowserTest {
CHECK(embedded_test_server()->Start());
}
+ protected:
+ content::mojom::NavigableContentsFactory* GetFactory() {
+ if (!factory_) {
+ auto* connector = BrowserContext::GetConnectorFor(
+ shell()->web_contents()->GetBrowserContext());
+ connector->BindInterface(content::mojom::kServiceName, &factory_);
+ }
+ return factory_.get();
+ }
+
private:
+ content::mojom::NavigableContentsFactoryPtr factory_;
+
DISALLOW_COPY_AND_ASSIGN(ContentServiceBrowserTest);
};
+class StopLoadingObserver : public content::NavigableContentsObserver {
+ public:
+ StopLoadingObserver() {}
+ ~StopLoadingObserver() override {}
+
+ void CallOnNextStopLoading(base::OnceClosure callback) {
+ callback_ = std::move(callback);
+ }
+
+ private:
+ // content::NavigableContentsObserver:
+ void DidStopLoading() override {
+ if (callback_)
+ std::move(callback_).Run();
+ }
+
+ base::OnceClosure callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(StopLoadingObserver);
+};
+
+class NavigationObserver : public content::NavigableContentsObserver {
+ public:
+ NavigationObserver() {}
+ ~NavigationObserver() override {}
+
+ void CallOnNextNavigation(base::OnceClosure callback) {
+ callback_ = std::move(callback);
+ }
+
+ size_t navigations_finished() const { return navigations_finished_; }
+ const GURL& last_url() const { return last_url_; }
+
+ private:
+ void DidFinishNavigation(
+ const GURL& url,
+ bool is_main_frame,
+ bool is_error_page,
+ const net::HttpResponseHeaders* response_headers) override {
+ ++navigations_finished_;
+ last_url_ = url;
+ if (callback_)
+ std::move(callback_).Run();
+ }
+
+ base::OnceClosure callback_;
+ size_t navigations_finished_ = 0;
+ GURL last_url_;
+
+ DISALLOW_COPY_AND_ASSIGN(NavigationObserver);
+};
+
// Verifies that the embedded Content Service is reachable. Does a basic
// end-to-end sanity check to also verify that a NavigableContents is backed by
// a WebContents instance in the browser.
IN_PROC_BROWSER_TEST_F(ContentServiceBrowserTest, EmbeddedContentService) {
- auto* browser_context = shell()->web_contents()->GetBrowserContext();
- auto* connector = BrowserContext::GetConnectorFor(browser_context);
+ auto contents = std::make_unique<NavigableContents>(GetFactory());
- content::mojom::NavigableContentsFactoryPtr factory;
- connector->BindInterface(content::mojom::kServiceName, &factory);
- auto contents = std::make_unique<content::NavigableContents>(factory.get());
+ const GURL kTestUrl = embedded_test_server()->GetURL("/hello.html");
+ StopLoadingObserver observer;
+ base::RunLoop loop;
+ observer.CallOnNextStopLoading(loop.QuitClosure());
+ contents->AddObserver(&observer);
+ contents->Navigate(kTestUrl);
+ loop.Run();
+ contents->RemoveObserver(&observer);
+}
+
+IN_PROC_BROWSER_TEST_F(ContentServiceBrowserTest, DidFinishNavigation) {
+ auto contents = std::make_unique<NavigableContents>(GetFactory());
+ const GURL kTestUrl = embedded_test_server()->GetURL("/hello.html");
+ NavigationObserver observer;
base::RunLoop loop;
- contents->set_did_stop_loading_callback_for_testing(loop.QuitClosure());
- contents->Navigate(embedded_test_server()->GetURL("/hello.html"));
+ observer.CallOnNextNavigation(loop.QuitClosure());
+ contents->AddObserver(&observer);
+ contents->Navigate(kTestUrl);
+
+ EXPECT_EQ(0u, observer.navigations_finished());
+
loop.Run();
+ contents->RemoveObserver(&observer);
+
+ EXPECT_EQ(1u, observer.navigations_finished());
+ EXPECT_EQ(kTestUrl, observer.last_url());
}
} // namespace
diff --git a/chromium/content/browser/content_service_delegate_impl.cc b/chromium/content/browser/content_service_delegate_impl.cc
index 40eb806f117..7c7f3f38d33 100644
--- a/chromium/content/browser/content_service_delegate_impl.cc
+++ b/chromium/content/browser/content_service_delegate_impl.cc
@@ -5,7 +5,10 @@
#include "content/browser/content_service_delegate_impl.h"
#include "base/macros.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "services/content/navigable_contents_delegate.h"
#include "services/content/service.h"
@@ -17,14 +20,19 @@ namespace {
// Bridge between Content Service navigable contents delegation API and a
// WebContentsImpl.
class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
+ public WebContentsDelegate,
public WebContentsObserver {
public:
- explicit NavigableContentsDelegateImpl(BrowserContext* browser_context,
- mojom::NavigableContentsClient* client)
- : client_(client) {
- WebContents::CreateParams params(browser_context);
- web_contents_ = WebContents::Create(params);
+ explicit NavigableContentsDelegateImpl(
+ BrowserContext* browser_context,
+ const mojom::NavigableContentsParams& params,
+ mojom::NavigableContentsClient* client)
+ : client_(client),
+ enable_view_auto_resize_(params.enable_view_auto_resize) {
+ WebContents::CreateParams create_params(browser_context);
+ web_contents_ = WebContents::Create(create_params);
WebContentsObserver::Observe(web_contents_.get());
+ web_contents_->SetDelegate(this);
}
~NavigableContentsDelegateImpl() override {
@@ -37,18 +45,48 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
return web_contents_->GetNativeView();
}
- void Navigate(const GURL& url) override {
- NavigationController::LoadURLParams params(url);
- params.transition_type = ui::PAGE_TRANSITION_AUTO_TOPLEVEL;
- web_contents_->GetController().LoadURLWithParams(params);
+ void Navigate(const GURL& url,
+ content::mojom::NavigateParamsPtr params) override {
+ NavigationController::LoadURLParams load_url_params(url);
+ load_url_params.transition_type = ui::PAGE_TRANSITION_AUTO_TOPLEVEL;
+ load_url_params.should_clear_history_list =
+ params->should_clear_session_history;
+ web_contents_->GetController().LoadURLWithParams(load_url_params);
+ }
+
+ // WebContentsDelegate:
+ void ResizeDueToAutoResize(WebContents* web_contents,
+ const gfx::Size& new_size) override {
+ DCHECK_EQ(web_contents, web_contents_.get());
+ client_->DidAutoResizeView(new_size);
}
// WebContentsObserver:
+ void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) override {
+ if (enable_view_auto_resize_ && web_contents_->GetRenderWidgetHostView()) {
+ web_contents_->GetRenderWidgetHostView()->EnableAutoResize(
+ gfx::Size(1, 1), gfx::Size(INT_MAX, INT_MAX));
+ }
+ }
+
+ void DidFinishNavigation(NavigationHandle* navigation_handle) override {
+ client_->DidFinishNavigation(
+ navigation_handle->GetURL(), navigation_handle->IsInMainFrame(),
+ navigation_handle->IsErrorPage(),
+ navigation_handle->GetResponseHeaders()
+ ? base::MakeRefCounted<net::HttpResponseHeaders>(
+ navigation_handle->GetResponseHeaders()->raw_headers())
+ : nullptr);
+ }
+
void DidStopLoading() override { client_->DidStopLoading(); }
std::unique_ptr<WebContents> web_contents_;
mojom::NavigableContentsClient* const client_;
+ const bool enable_view_auto_resize_;
+
DISALLOW_COPY_AND_ASSIGN(NavigableContentsDelegateImpl);
};
@@ -82,9 +120,10 @@ void ContentServiceDelegateImpl::WillDestroyServiceInstance(
std::unique_ptr<content::NavigableContentsDelegate>
ContentServiceDelegateImpl::CreateNavigableContentsDelegate(
+ const mojom::NavigableContentsParams& params,
mojom::NavigableContentsClient* client) {
return std::make_unique<NavigableContentsDelegateImpl>(browser_context_,
- client);
+ params, client);
}
} // namespace content
diff --git a/chromium/content/browser/content_service_delegate_impl.h b/chromium/content/browser/content_service_delegate_impl.h
index 70b2295f950..4515c7f44aa 100644
--- a/chromium/content/browser/content_service_delegate_impl.h
+++ b/chromium/content/browser/content_service_delegate_impl.h
@@ -37,6 +37,7 @@ class ContentServiceDelegateImpl : public content::ServiceDelegate {
// content::ContentServiceDelegate:
void WillDestroyServiceInstance(content::Service* service) override;
std::unique_ptr<NavigableContentsDelegate> CreateNavigableContentsDelegate(
+ const mojom::NavigableContentsParams& params,
mojom::NavigableContentsClient* client) override;
BrowserContext* const browser_context_;
diff --git a/chromium/content/browser/cookie_store/cookie_store_context.cc b/chromium/content/browser/cookie_store/cookie_store_context.cc
index eeea0d01a97..84be95782e2 100644
--- a/chromium/content/browser/cookie_store/cookie_store_context.cc
+++ b/chromium/content/browser/cookie_store/cookie_store_context.cc
@@ -4,7 +4,9 @@
#include "content/browser/cookie_store/cookie_store_context.h"
+#include "base/task/post_task.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
@@ -12,7 +14,7 @@ namespace content {
CookieStoreContext::CookieStoreContext()
: base::RefCountedDeleteOnSequence<CookieStoreContext>(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)) {}
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})) {}
CookieStoreContext::~CookieStoreContext() {
// The destructor must be called on the IO thread, because it runs
@@ -30,8 +32,8 @@ void CookieStoreContext::Initialize(
initialize_called_ = true;
#endif // DCHECK_IS_ON()
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&CookieStoreContext::InitializeOnIOThread, this,
std::move(service_worker_context),
@@ -56,8 +58,8 @@ void CookieStoreContext::ListenToCookieChanges(
network_context->GetCookieManager(
mojo::MakeRequest(&cookie_manager_ptr_info));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&CookieStoreContext::ListenToCookieChangesOnIOThread, this,
std::move(cookie_manager_ptr_info),
@@ -77,8 +79,8 @@ void CookieStoreContext::CreateService(blink::mojom::CookieStoreRequest request,
DCHECK(initialize_called_) << __func__ << " called before Initialize()";
#endif // DCHECK_IS_ON()
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CookieStoreContext::CreateServiceOnIOThread, this,
std::move(request), origin));
}
diff --git a/chromium/content/browser/cookie_store/cookie_store_manager_unittest.cc b/chromium/content/browser/cookie_store/cookie_store_manager_unittest.cc
index b74748e9a2a..0cd0a1336a7 100644
--- a/chromium/content/browser/cookie_store/cookie_store_manager_unittest.cc
+++ b/chromium/content/browser/cookie_store/cookie_store_manager_unittest.cc
@@ -167,7 +167,7 @@ class CookieStoreWorkerTestHelper : public EmbeddedWorkerTestHelper {
override {
changes_.emplace_back(cookie, cause);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
private:
diff --git a/chromium/content/browser/devtools/browser_devtools_agent_host.cc b/chromium/content/browser/devtools/browser_devtools_agent_host.cc
index a83315a158b..bf38edb2d2c 100644
--- a/chromium/content/browser/devtools/browser_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/browser_devtools_agent_host.cc
@@ -52,7 +52,7 @@ BrowserDevToolsAgentHost::~BrowserDevToolsAgentHost() {
bool BrowserDevToolsAgentHost::AttachSession(DevToolsSession* session,
TargetRegistry* parent_registry) {
- if (session->restricted())
+ if (!session->client()->MayAttachToBrowser())
return false;
TargetRegistry* registry = parent_registry;
@@ -63,7 +63,7 @@ bool BrowserDevToolsAgentHost::AttachSession(DevToolsSession* session,
}
session->SetBrowserOnly(true);
session->AddHandler(std::make_unique<protocol::TargetHandler>(
- true /* browser_only */, GetId(), registry));
+ protocol::TargetHandler::AccessMode::kBrowser, GetId(), registry));
if (only_discovery_)
return true;
diff --git a/chromium/content/browser/devtools/devtools_agent_host_impl.cc b/chromium/content/browser/devtools/devtools_agent_host_impl.cc
index d32bd45d916..32d7899b635 100644
--- a/chromium/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/chromium/content/browser/devtools/devtools_agent_host_impl.cc
@@ -13,7 +13,6 @@
#include "base/lazy_instance.h"
#include "base/observer_list.h"
#include "content/browser/devtools/devtools_manager.h"
-#include "content/browser/devtools/devtools_session.h"
#include "content/browser/devtools/forwarding_agent_host.h"
#include "content/browser/devtools/protocol/page.h"
#include "content/browser/devtools/protocol/security_handler.h"
@@ -115,7 +114,8 @@ DevToolsAgentHost::List DevToolsAgentHost::GetOrCreateAll() {
return result;
}
-DevToolsAgentHostImpl::DevToolsAgentHostImpl(const std::string& id) : id_(id) {
+DevToolsAgentHostImpl::DevToolsAgentHostImpl(const std::string& id)
+ : id_(id), renderer_channel_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
@@ -129,7 +129,7 @@ scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForId(
const std::string& id) {
if (!g_devtools_instances.IsCreated())
return nullptr;
- DevToolsMap::iterator it = g_devtools_instances.Get().find(id);
+ auto it = g_devtools_instances.Get().find(id);
if (it == g_devtools_instances.Get().end())
return nullptr;
return it->second;
@@ -177,18 +177,14 @@ DevToolsSession* DevToolsAgentHostImpl::SessionByClient(
}
bool DevToolsAgentHostImpl::InnerAttachClient(DevToolsAgentHostClient* client,
- TargetRegistry* registry,
- bool restricted) {
+ TargetRegistry* registry) {
scoped_refptr<DevToolsAgentHostImpl> protect(this);
- DevToolsSession* session = new DevToolsSession(this, client, restricted);
- sessions_.insert(session);
- session_by_client_[client].reset(session);
- if (!AttachSession(session, registry)) {
- sessions_.erase(session);
- session_by_client_.erase(client);
+ auto session = std::make_unique<DevToolsSession>(this, client);
+ if (!AttachSession(session.get(), registry))
return false;
- }
-
+ renderer_channel_.AttachSession(session.get());
+ sessions_.insert(session.get());
+ session_by_client_[client] = std::move(session);
if (sessions_.size() == 1)
NotifyAttached();
DevToolsManager* manager = DevToolsManager::GetInstance();
@@ -197,10 +193,10 @@ bool DevToolsAgentHostImpl::InnerAttachClient(DevToolsAgentHostClient* client,
return true;
}
-void DevToolsAgentHostImpl::AttachClient(DevToolsAgentHostClient* client) {
+bool DevToolsAgentHostImpl::AttachClient(DevToolsAgentHostClient* client) {
if (SessionByClient(client))
- return;
- InnerAttachClient(client, nullptr, false /* restricted */);
+ return false;
+ return InnerAttachClient(client, nullptr);
}
void DevToolsAgentHostImpl::AttachSubtargetClient(
@@ -208,14 +204,7 @@ void DevToolsAgentHostImpl::AttachSubtargetClient(
TargetRegistry* registry) {
if (SessionByClient(client))
return;
- InnerAttachClient(client, registry, false /* restricted */);
-}
-
-bool DevToolsAgentHostImpl::AttachRestrictedClient(
- DevToolsAgentHostClient* client) {
- if (SessionByClient(client))
- return false;
- return InnerAttachClient(client, nullptr, true /* restricted */);
+ InnerAttachClient(client, registry);
}
bool DevToolsAgentHostImpl::DetachClient(DevToolsAgentHostClient* client) {
@@ -349,6 +338,8 @@ bool DevToolsAgentHostImpl::AttachSession(DevToolsSession* session,
void DevToolsAgentHostImpl::DetachSession(DevToolsSession* session) {}
+void DevToolsAgentHostImpl::UpdateRendererChannel(bool force) {}
+
// static
void DevToolsAgentHost::DetachAllClients() {
if (!g_devtools_instances.IsCreated())
@@ -357,12 +348,10 @@ void DevToolsAgentHost::DetachAllClients() {
// Make a copy, since detaching may lead to agent destruction, which
// removes it from the instances.
std::vector<scoped_refptr<DevToolsAgentHostImpl>> copy;
- for (DevToolsMap::iterator it(g_devtools_instances.Get().begin());
+ for (auto it(g_devtools_instances.Get().begin());
it != g_devtools_instances.Get().end(); ++it)
copy.push_back(it->second);
- for (std::vector<scoped_refptr<DevToolsAgentHostImpl>>::iterator it(
- copy.begin());
- it != copy.end(); ++it)
+ for (auto it(copy.begin()); it != copy.end(); ++it)
it->get()->ForceDetachAllSessions();
}
diff --git a/chromium/content/browser/devtools/devtools_agent_host_impl.h b/chromium/content/browser/devtools/devtools_agent_host_impl.h
index 0910548167e..1db750429e3 100644
--- a/chromium/content/browser/devtools/devtools_agent_host_impl.h
+++ b/chromium/content/browser/devtools/devtools_agent_host_impl.h
@@ -14,6 +14,8 @@
#include "base/containers/flat_set.h"
#include "base/process/kill.h"
#include "content/browser/devtools/devtools_io_context.h"
+#include "content/browser/devtools/devtools_renderer_channel.h"
+#include "content/browser/devtools/devtools_session.h"
#include "content/common/content_export.h"
#include "content/public/browser/certificate_request_result_type.h"
#include "content/public/browser/devtools_agent_host.h"
@@ -22,7 +24,6 @@
namespace content {
class BrowserContext;
-class DevToolsSession;
class TargetRegistry;
// Describes interface for managing devtools agents from the browser process.
@@ -38,8 +39,7 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
CertErrorCallback callback);
// DevToolsAgentHost implementation.
- void AttachClient(DevToolsAgentHostClient* client) override;
- bool AttachRestrictedClient(DevToolsAgentHostClient* client) override;
+ bool AttachClient(DevToolsAgentHostClient* client) override;
bool DetachClient(DevToolsAgentHostClient* client) override;
bool DispatchProtocolMessage(DevToolsAgentHostClient* client,
const std::string& message) override;
@@ -59,6 +59,19 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
bool Inspect();
+ template <typename Handler>
+ std::vector<Handler*> HandlersByName(const std::string& name) {
+ std::vector<Handler*> result;
+ if (sessions_.empty())
+ return result;
+ for (DevToolsSession* session : sessions_) {
+ auto it = session->handlers().find(name);
+ if (it != session->handlers().end())
+ result.push_back(static_cast<Handler*>(it->second.get()));
+ }
+ return result;
+ }
+
protected:
DevToolsAgentHostImpl(const std::string& id);
~DevToolsAgentHostImpl() override;
@@ -69,11 +82,11 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
virtual bool AttachSession(DevToolsSession* session,
TargetRegistry* registry);
virtual void DetachSession(DevToolsSession* session);
-
virtual bool DispatchProtocolMessage(
DevToolsAgentHostClient* client,
const std::string& message,
std::unique_ptr<base::DictionaryValue> parsed_message);
+ virtual void UpdateRendererChannel(bool force);
void NotifyCreated();
void NotifyNavigated();
@@ -82,17 +95,17 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
void ForceDetachRestrictedSessions(
const std::vector<DevToolsSession*>& restricted_sessions);
DevToolsIOContext* GetIOContext() { return &io_context_; }
+ DevToolsRendererChannel* GetRendererChannel() { return &renderer_channel_; }
base::flat_set<DevToolsSession*>& sessions() { return sessions_; }
private:
friend class DevToolsAgentHost; // for static methods
- friend class DevToolsSession;
friend class TargetRegistry; // for subtarget management
+ friend class DevToolsRendererChannel;
bool InnerAttachClient(DevToolsAgentHostClient* client,
- TargetRegistry* registry,
- bool restricted);
+ TargetRegistry* registry);
void InnerDetachClient(DevToolsAgentHostClient* client);
void NotifyAttached();
void NotifyDetached();
@@ -108,6 +121,7 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
base::flat_map<DevToolsAgentHostClient*, std::unique_ptr<DevToolsSession>>
session_by_client_;
DevToolsIOContext io_context_;
+ DevToolsRendererChannel renderer_channel_;
static int s_force_creation_count_;
};
diff --git a/chromium/content/browser/devtools/devtools_http_handler.cc b/chromium/content/browser/devtools/devtools_http_handler.cc
index a0ce6d621d8..baa7d79aec2 100644
--- a/chromium/content/browser/devtools/devtools_http_handler.cc
+++ b/chromium/content/browser/devtools/devtools_http_handler.cc
@@ -29,6 +29,7 @@
#include "content/browser/devtools/devtools_http_handler.h"
#include "content/browser/devtools/devtools_manager.h"
#include "content/browser/devtools/grit/devtools_resources.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_external_agent_proxy_delegate.h"
#include "content/public/browser/devtools_frontend_host.h"
@@ -295,8 +296,8 @@ void StartServerOnHandlerThread(
#endif
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ServerStartedOnUI, std::move(handler), thread.release(),
server_wrapper.release(), socket_factory.release(),
std::move(ip_address)));
@@ -316,6 +317,7 @@ class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient {
connection_id_(connection_id),
agent_host_(agent_host) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // TODO(dgozman): handle return value of AttachClient.
agent_host_->AttachClient(this);
}
@@ -426,16 +428,16 @@ void ServerWrapper::OnHttpRequest(int connection_id,
server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools);
if (base::StartsWith(info.path, "/json", base::CompareCase::SENSITIVE)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&DevToolsHttpHandler::OnJsonRequest,
- handler_, connection_id, info));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&DevToolsHttpHandler::OnJsonRequest,
+ handler_, connection_id, info));
return;
}
if (info.path.empty() || info.path == "/") {
// Discovery page request.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DevToolsHttpHandler::OnDiscoveryPageRequest, handler_,
connection_id));
return;
@@ -460,8 +462,8 @@ void ServerWrapper::OnHttpRequest(int connection_id,
}
if (bundles_resources_) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DevToolsHttpHandler::OnFrontendResourceRequest,
handler_, connection_id, filename));
return;
@@ -472,23 +474,23 @@ void ServerWrapper::OnHttpRequest(int connection_id,
void ServerWrapper::OnWebSocketRequest(
int connection_id,
const net::HttpServerRequestInfo& request) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DevToolsHttpHandler::OnWebSocketRequest, handler_,
connection_id, request));
}
void ServerWrapper::OnWebSocketMessage(int connection_id,
const std::string& data) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DevToolsHttpHandler::OnWebSocketMessage, handler_,
connection_id, data));
}
void ServerWrapper::OnClose(int connection_id) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DevToolsHttpHandler::OnClose, handler_, connection_id));
}
@@ -763,8 +765,7 @@ void DevToolsHttpHandler::OnWebSocketRequest(
void DevToolsHttpHandler::OnWebSocketMessage(
int connection_id,
const std::string& data) {
- ConnectionToClientMap::iterator it =
- connection_to_client_.find(connection_id);
+ auto it = connection_to_client_.find(connection_id);
if (it != connection_to_client_.end())
it->second->OnMessage(data);
}
diff --git a/chromium/content/browser/devtools/devtools_http_handler_unittest.cc b/chromium/content/browser/devtools/devtools_http_handler_unittest.cc
index 97ac6d57e1d..3e47c6c4b6b 100644
--- a/chromium/content/browser/devtools/devtools_http_handler_unittest.cc
+++ b/chromium/content/browser/devtools/devtools_http_handler_unittest.cc
@@ -17,8 +17,10 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_manager_delegate.h"
#include "content/public/browser/devtools_socket_factory.h"
@@ -59,7 +61,7 @@ class DummyServerSocket : public net::ServerSocket {
};
void QuitFromHandlerThread(const base::Closure& quit_closure) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_closure);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, quit_closure);
}
class DummyServerSocketFactory : public DevToolsSocketFactory {
@@ -70,8 +72,7 @@ class DummyServerSocketFactory : public DevToolsSocketFactory {
quit_closure_2_(quit_closure_2) {}
~DummyServerSocketFactory() override {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, quit_closure_2_);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, quit_closure_2_);
}
protected:
diff --git a/chromium/content/browser/devtools/devtools_interceptor_controller.cc b/chromium/content/browser/devtools/devtools_interceptor_controller.cc
index a2c27cba5df..4ba252da7a4 100644
--- a/chromium/content/browser/devtools/devtools_interceptor_controller.cc
+++ b/chromium/content/browser/devtools/devtools_interceptor_controller.cc
@@ -5,9 +5,11 @@
#include "content/browser/devtools/devtools_interceptor_controller.h"
#include "base/supports_user_data.h"
+#include "base/task/post_task.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@@ -34,8 +36,8 @@ DevToolsInterceptorController::StartInterceptingRequests(
std::unique_ptr<InterceptionHandle> handle(new InterceptionHandle(
std::move(registration_handle), interceptor_, filter_entry.get()));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsNetworkInterceptor::AddFilterEntry, interceptor_,
std::move(filter_entry)));
return handle;
@@ -47,8 +49,8 @@ void DevToolsInterceptorController::ContinueInterceptedRequest(
std::unique_ptr<ContinueInterceptedRequestCallback> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsNetworkInterceptor::ContinueInterceptedRequest,
interceptor_, interception_id, std::move(modifications),
std::move(callback)));
@@ -68,8 +70,8 @@ void DevToolsInterceptorController::GetResponseBody(
std::string interception_id,
std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsNetworkInterceptor::GetResponseBody, interceptor_,
std::move(interception_id), std::move(callback)));
}
@@ -116,16 +118,16 @@ InterceptionHandle::InterceptionHandle(
entry_(entry) {}
InterceptionHandle::~InterceptionHandle() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsNetworkInterceptor::RemoveFilterEntry,
interceptor_, entry_));
}
void InterceptionHandle::UpdatePatterns(
std::vector<DevToolsNetworkInterceptor::Pattern> patterns) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsNetworkInterceptor::UpdatePatterns, interceptor_,
base::Unretained(entry_), std::move(patterns)));
}
diff --git a/chromium/content/browser/devtools/devtools_network_interceptor.cc b/chromium/content/browser/devtools/devtools_network_interceptor.cc
index e4206b1f0bd..7554d6ff982 100644
--- a/chromium/content/browser/devtools/devtools_network_interceptor.cc
+++ b/chromium/content/browser/devtools/devtools_network_interceptor.cc
@@ -25,8 +25,7 @@ DevToolsNetworkInterceptor::FilterEntry::FilterEntry(
DevToolsNetworkInterceptor::FilterEntry::FilterEntry(FilterEntry&&) {}
DevToolsNetworkInterceptor::FilterEntry::~FilterEntry() {}
-DevToolsNetworkInterceptor::Modifications::Modifications()
- : mark_as_canceled(false) {}
+DevToolsNetworkInterceptor::Modifications::Modifications() = default;
DevToolsNetworkInterceptor::Modifications::Modifications(
base::Optional<net::Error> error_reason,
@@ -36,16 +35,14 @@ DevToolsNetworkInterceptor::Modifications::Modifications(
protocol::Maybe<std::string> modified_post_data,
protocol::Maybe<protocol::Network::Headers> modified_headers,
protocol::Maybe<protocol::Network::AuthChallengeResponse>
- auth_challenge_response,
- bool mark_as_canceled)
+ auth_challenge_response)
: error_reason(std::move(error_reason)),
raw_response(std::move(raw_response)),
modified_url(std::move(modified_url)),
modified_method(std::move(modified_method)),
modified_post_data(std::move(modified_post_data)),
modified_headers(std::move(modified_headers)),
- auth_challenge_response(std::move(auth_challenge_response)),
- mark_as_canceled(mark_as_canceled) {}
+ auth_challenge_response(std::move(auth_challenge_response)) {}
DevToolsNetworkInterceptor::Modifications::~Modifications() {}
diff --git a/chromium/content/browser/devtools/devtools_network_interceptor.h b/chromium/content/browser/devtools/devtools_network_interceptor.h
index 43dbf902448..9d89ad6d55f 100644
--- a/chromium/content/browser/devtools/devtools_network_interceptor.h
+++ b/chromium/content/browser/devtools/devtools_network_interceptor.h
@@ -59,8 +59,7 @@ class DevToolsNetworkInterceptor {
protocol::Maybe<std::string> modified_post_data,
protocol::Maybe<protocol::Network::Headers> modified_headers,
protocol::Maybe<protocol::Network::AuthChallengeResponse>
- auth_challenge_response,
- bool mark_as_canceled);
+ auth_challenge_response);
~Modifications();
// If none of the following are set then the request will be allowed to
@@ -77,8 +76,6 @@ class DevToolsNetworkInterceptor {
// AuthChallengeResponse is mutually exclusive with the above.
protocol::Maybe<protocol::Network::AuthChallengeResponse>
auth_challenge_response;
-
- bool mark_as_canceled;
};
enum InterceptionStage {
diff --git a/chromium/content/browser/devtools/devtools_pipe_handler.cc b/chromium/content/browser/devtools/devtools_pipe_handler.cc
index 8552cf21711..ea1c61db746 100644
--- a/chromium/content/browser/devtools/devtools_pipe_handler.cc
+++ b/chromium/content/browser/devtools/devtools_pipe_handler.cc
@@ -23,6 +23,7 @@
#include "base/task/post_task.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_agent_host.h"
#include "net/server/http_connection.h"
@@ -152,8 +153,8 @@ bool PipeReader::HandleReadResult(int result) {
if (read_buffer_->StartOfBuffer()[i] == '\0') {
std::string str(read_buffer_->StartOfBuffer() + offset, i - offset);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DevToolsPipeHandler::HandleMessage, devtools_handler_,
std::move(str)));
offset = i + 1;
@@ -165,8 +166,8 @@ bool PipeReader::HandleReadResult(int result) {
}
void PipeReader::ConnectionClosed() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DevToolsPipeHandler::Shutdown, devtools_handler_));
}
diff --git a/chromium/content/browser/devtools/devtools_renderer_channel.cc b/chromium/content/browser/devtools/devtools_renderer_channel.cc
new file mode 100644
index 00000000000..bd09fc1e7bb
--- /dev/null
+++ b/chromium/content/browser/devtools/devtools_renderer_channel.cc
@@ -0,0 +1,57 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/devtools/devtools_renderer_channel.h"
+
+#include "content/browser/devtools/devtools_agent_host_impl.h"
+#include "content/browser/devtools/devtools_session.h"
+#include "content/browser/devtools/protocol/devtools_domain_handler.h"
+#include "content/public/common/child_process_host.h"
+#include "ui/gfx/geometry/point.h"
+
+namespace content {
+
+DevToolsRendererChannel::DevToolsRendererChannel(DevToolsAgentHostImpl* owner)
+ : owner_(owner),
+ binding_(this),
+ process_id_(ChildProcessHost::kInvalidUniqueID) {}
+
+DevToolsRendererChannel::~DevToolsRendererChannel() = default;
+
+void DevToolsRendererChannel::SetRenderer(
+ blink::mojom::DevToolsAgentAssociatedPtr agent_ptr,
+ blink::mojom::DevToolsAgentHostAssociatedRequest host_request,
+ int process_id,
+ RenderFrameHostImpl* frame_host) {
+ binding_.Close();
+ if (host_request)
+ binding_.Bind(std::move(host_request));
+ agent_ptr_ = std::move(agent_ptr);
+ process_id_ = process_id;
+ frame_host_ = frame_host;
+ for (DevToolsSession* session : owner_->sessions()) {
+ for (auto& pair : session->handlers())
+ pair.second->SetRenderer(process_id_, frame_host_);
+ session->AttachToAgent(agent_ptr_.get());
+ }
+}
+
+void DevToolsRendererChannel::AttachSession(DevToolsSession* session) {
+ if (!agent_ptr_)
+ owner_->UpdateRendererChannel(true /* force */);
+ for (auto& pair : session->handlers())
+ pair.second->SetRenderer(process_id_, frame_host_);
+ session->AttachToAgent(agent_ptr_.get());
+}
+
+void DevToolsRendererChannel::InspectElement(const gfx::Point& point) {
+ if (!agent_ptr_)
+ owner_->UpdateRendererChannel(true /* force */);
+ // Previous call might update |agent_ptr_|
+ // via SetRenderer(), so we should check it again.
+ if (agent_ptr_)
+ agent_ptr_->InspectElement(point);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_renderer_channel.h b/chromium/content/browser/devtools/devtools_renderer_channel.h
new file mode 100644
index 00000000000..1e390457bac
--- /dev/null
+++ b/chromium/content/browser/devtools/devtools_renderer_channel.h
@@ -0,0 +1,55 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_RENDERER_CHANNEL_H_
+#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_RENDERER_CHANNEL_H_
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "third_party/blink/public/web/devtools_agent.mojom.h"
+
+namespace gfx {
+class Point;
+}
+
+namespace content {
+
+class DevToolsAgentHostImpl;
+class DevToolsSession;
+class RenderFrameHostImpl;
+
+// This class encapsulates a connection to blink::mojom::DevToolsAgent
+// in the renderer.
+// When the renderer changes, different DevToolsAgentHostImpl subclasses
+// retrieve a new blink::mojom::DevToolsAgent pointer, and this channel
+// starts using it for all existing and future sessions.
+class CONTENT_EXPORT DevToolsRendererChannel
+ : public blink::mojom::DevToolsAgentHost {
+ public:
+ explicit DevToolsRendererChannel(DevToolsAgentHostImpl* owner);
+ ~DevToolsRendererChannel() override;
+
+ void SetRenderer(
+ blink::mojom::DevToolsAgentAssociatedPtr agent_ptr,
+ blink::mojom::DevToolsAgentHostAssociatedRequest host_request,
+ int process_id,
+ RenderFrameHostImpl* frame_host);
+ void AttachSession(DevToolsSession* session);
+ void InspectElement(const gfx::Point& point);
+
+ private:
+ DevToolsAgentHostImpl* owner_;
+ mojo::AssociatedBinding<blink::mojom::DevToolsAgentHost> binding_;
+ blink::mojom::DevToolsAgentAssociatedPtr agent_ptr_;
+ int process_id_;
+ RenderFrameHostImpl* frame_host_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(DevToolsRendererChannel);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_RENDERER_CHANNEL_H_
diff --git a/chromium/content/browser/devtools/devtools_session.cc b/chromium/content/browser/devtools/devtools_session.cc
index 0d91850d5e7..fa29cf6a41f 100644
--- a/chromium/content/browser/devtools/devtools_session.cc
+++ b/chromium/content/browser/devtools/devtools_session.cc
@@ -7,11 +7,11 @@
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "content/browser/devtools/devtools_manager.h"
+#include "content/browser/devtools/protocol/devtools_domain_handler.h"
#include "content/browser/devtools/protocol/protocol.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/public/browser/devtools_manager_delegate.h"
-#include "content/public/common/child_process_host.h"
namespace content {
@@ -32,17 +32,12 @@ bool ShouldSendOnIO(const std::string& method) {
} // namespace
DevToolsSession::DevToolsSession(DevToolsAgentHostImpl* agent_host,
- DevToolsAgentHostClient* client,
- bool restricted)
+ DevToolsAgentHostClient* client)
: binding_(this),
agent_host_(agent_host),
client_(client),
- restricted_(restricted),
- process_host_id_(ChildProcessHost::kInvalidUniqueID),
- host_(nullptr),
dispatcher_(new protocol::UberDispatcher(this)),
- weak_factory_(this) {
-}
+ weak_factory_(this) {}
DevToolsSession::~DevToolsSession() {
// It is Ok for session to be deleted without the dispose -
@@ -61,24 +56,21 @@ void DevToolsSession::Dispose() {
void DevToolsSession::AddHandler(
std::unique_ptr<protocol::DevToolsDomainHandler> handler) {
handler->Wire(dispatcher_.get());
- handler->SetRenderer(process_host_id_, host_);
handlers_[handler->name()] = std::move(handler);
}
-void DevToolsSession::SetRenderer(int process_host_id,
- RenderFrameHostImpl* frame_host) {
- process_host_id_ = process_host_id;
- host_ = frame_host;
- for (auto& pair : handlers_)
- pair.second->SetRenderer(process_host_id_, host_);
-}
-
void DevToolsSession::SetBrowserOnly(bool browser_only) {
browser_only_ = browser_only;
}
-void DevToolsSession::AttachToAgent(
- const blink::mojom::DevToolsAgentAssociatedPtr& agent) {
+void DevToolsSession::AttachToAgent(blink::mojom::DevToolsAgent* agent) {
+ if (!agent) {
+ binding_.Close();
+ session_ptr_.reset();
+ io_session_ptr_.reset();
+ return;
+ }
+
blink::mojom::DevToolsSessionHostAssociatedPtrInfo host_ptr_info;
binding_.Bind(mojo::MakeRequest(&host_ptr_info));
agent->AttachDevToolsSession(
diff --git a/chromium/content/browser/devtools/devtools_session.h b/chromium/content/browser/devtools/devtools_session.h
index 467edb43869..b845a54446a 100644
--- a/chromium/content/browser/devtools/devtools_session.h
+++ b/chromium/content/browser/devtools/devtools_session.h
@@ -11,58 +11,46 @@
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/values.h"
-#include "content/browser/devtools/devtools_agent_host_impl.h"
-#include "content/browser/devtools/protocol/devtools_domain_handler.h"
+#include "content/browser/devtools/protocol/forward.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "third_party/blink/public/web/devtools_agent.mojom.h"
namespace content {
class DevToolsAgentHostClient;
-class RenderFrameHostImpl;
+class DevToolsAgentHostImpl;
+
+namespace protocol {
+class DevToolsDomainHandler;
+}
class DevToolsSession : public protocol::FrontendChannel,
public blink::mojom::DevToolsSessionHost {
public:
DevToolsSession(DevToolsAgentHostImpl* agent_host,
- DevToolsAgentHostClient* client,
- bool restricted);
+ DevToolsAgentHostClient* client);
~DevToolsSession() override;
void Dispose();
- bool restricted() { return restricted_; }
- DevToolsAgentHost* agent_host() { return agent_host_; };
+ DevToolsAgentHostImpl* agent_host() { return agent_host_; };
DevToolsAgentHostClient* client() { return client_; };
// Browser-only sessions do not talk to mojom::DevToolsAgent, but instead
// handle all protocol messages locally in the browser process.
void SetBrowserOnly(bool browser_only);
-
void AddHandler(std::unique_ptr<protocol::DevToolsDomainHandler> handler);
- // TODO(dgozman): maybe combine this with AttachToAgent?
- void SetRenderer(int process_host_id, RenderFrameHostImpl* frame_host);
- void AttachToAgent(const blink::mojom::DevToolsAgentAssociatedPtr& agent);
+ void AttachToAgent(blink::mojom::DevToolsAgent* agent);
void DispatchProtocolMessage(
const std::string& message,
std::unique_ptr<base::DictionaryValue> parsed_message);
void SuspendSendingMessagesToAgent();
void ResumeSendingMessagesToAgent();
- template <typename Handler>
- static std::vector<Handler*> HandlersForAgentHost(
- DevToolsAgentHostImpl* agent_host,
- const std::string& name) {
- std::vector<Handler*> result;
- if (agent_host->sessions().empty())
- return result;
- for (DevToolsSession* session : agent_host->sessions()) {
- auto it = session->handlers_.find(name);
- if (it != session->handlers_.end())
- result.push_back(static_cast<Handler*>(it->second.get()));
- }
- return result;
- }
+ using HandlersMap =
+ base::flat_map<std::string,
+ std::unique_ptr<protocol::DevToolsDomainHandler>>;
+ HandlersMap& handlers() { return handlers_; }
private:
void SendResponse(std::unique_ptr<base::DictionaryValue> response);
@@ -101,12 +89,8 @@ class DevToolsSession : public protocol::FrontendChannel,
blink::mojom::DevToolsSessionPtr io_session_ptr_;
DevToolsAgentHostImpl* agent_host_;
DevToolsAgentHostClient* client_;
- bool restricted_;
bool browser_only_ = false;
- base::flat_map<std::string, std::unique_ptr<protocol::DevToolsDomainHandler>>
- handlers_;
- int process_host_id_;
- RenderFrameHostImpl* host_;
+ HandlersMap handlers_;
std::unique_ptr<protocol::UberDispatcher> dispatcher_;
// These messages were queued after suspending, not sent to the agent,
diff --git a/chromium/content/browser/devtools/devtools_stream_blob.cc b/chromium/content/browser/devtools/devtools_stream_blob.cc
index 2dca3fb2bfb..27135840da1 100644
--- a/chromium/content/browser/devtools/devtools_stream_blob.cc
+++ b/chromium/content/browser/devtools/devtools_stream_blob.cc
@@ -7,7 +7,9 @@
#include "base/base64.h"
#include "base/bind.h"
#include "base/strings/string_piece.h"
+#include "base/task/post_task.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "net/base/io_buffer.h"
@@ -29,7 +31,7 @@ DevToolsStreamBlob::ReadRequest::~ReadRequest() = default;
DevToolsStreamBlob::DevToolsStreamBlob()
: DevToolsIOContext::Stream(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})),
last_read_pos_(0),
failed_(false),
is_binary_(false) {}
@@ -64,18 +66,19 @@ scoped_refptr<DevToolsIOContext::Stream> DevToolsStreamBlob::Create(
}
void DevToolsStreamBlob::ReadRequest::Fail() {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), nullptr, false,
- Stream::StatusFailure));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), nullptr, false,
+ Stream::StatusFailure));
}
void DevToolsStreamBlob::Open(scoped_refptr<ChromeBlobStorageContext> context,
StoragePartition* partition,
const std::string& handle,
OpenCallback callback) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&DevToolsStreamBlob::OpenOnIO, this,
- context, handle, std::move(callback)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&DevToolsStreamBlob::OpenOnIO, this, context, handle,
+ std::move(callback)));
}
void DevToolsStreamBlob::Read(off_t position,
@@ -83,8 +86,8 @@ void DevToolsStreamBlob::Read(off_t position,
ReadCallback callback) {
std::unique_ptr<ReadRequest> request(
new ReadRequest(position, max_size, std::move(callback)));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsStreamBlob::ReadOnIO, this, std::move(request)));
}
@@ -115,8 +118,8 @@ void DevToolsStreamBlob::OnBlobConstructionComplete(
FailOnIO(std::move(open_callback_));
return;
}
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(open_callback_), true));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(open_callback_), true));
if (!pending_reads_.empty())
StartReadRequest();
}
@@ -141,8 +144,8 @@ void DevToolsStreamBlob::FailOnIO() {
}
void DevToolsStreamBlob::FailOnIO(OpenCallback callback) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), false));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), false));
FailOnIO();
}
@@ -166,7 +169,7 @@ void DevToolsStreamBlob::BeginRead() {
DCHECK_GE(pending_reads_.size(), 1UL);
ReadRequest& request = *pending_reads_.front();
if (!io_buf_ || static_cast<size_t>(io_buf_->size()) < request.max_size)
- io_buf_ = new net::IOBufferWithSize(request.max_size);
+ io_buf_ = base::MakeRefCounted<net::IOBufferWithSize>(request.max_size);
int bytes_read;
BlobReader::Status status = blob_reader_->Read(
io_buf_.get(), request.max_size, &bytes_read,
@@ -178,8 +181,8 @@ void DevToolsStreamBlob::BeginRead() {
bytes_read = blob_reader_->net_error();
DCHECK_LT(0, bytes_read);
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsStreamBlob::OnReadComplete, this, bytes_read));
}
@@ -207,8 +210,8 @@ void DevToolsStreamBlob::OnReadComplete(int bytes_read) {
*data = std::string(io_buf_->data(), bytes_read);
}
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(request->callback), std::move(data),
base64_encoded, status));
if (!pending_reads_.empty())
diff --git a/chromium/content/browser/devtools/devtools_stream_file.cc b/chromium/content/browser/devtools/devtools_stream_file.cc
index 1e0aa6b6bd3..a258da32b6e 100644
--- a/chromium/content/browser/devtools/devtools_stream_file.cc
+++ b/chromium/content/browser/devtools/devtools_stream_file.cc
@@ -12,7 +12,7 @@
#include "base/task/lazy_task_runner.h"
#include "base/task/post_task.h"
#include "base/third_party/icu/icu_utf.h"
-#include "base/threading/thread_restrictions.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "storage/browser/fileapi/file_system_context.h"
@@ -46,7 +46,6 @@ DevToolsStreamFile::~DevToolsStreamFile() {
bool DevToolsStreamFile::InitOnFileSequenceIfNeeded() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- base::AssertBlockingAllowed();
if (had_errors_)
return false;
if (file_.IsValid())
@@ -122,9 +121,9 @@ void DevToolsStreamFile::ReadOnFileSequence(off_t position,
base::Base64Encode(raw_data, data.get());
base64_encoded = true;
}
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), std::move(data),
- base64_encoded, status));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), std::move(data),
+ base64_encoded, status));
}
void DevToolsStreamFile::AppendOnFileSequence(
diff --git a/chromium/content/browser/devtools/devtools_url_interceptor_request_job.cc b/chromium/content/browser/devtools/devtools_url_interceptor_request_job.cc
index d07eca5061f..4e6a637f824 100644
--- a/chromium/content/browser/devtools/devtools_url_interceptor_request_job.cc
+++ b/chromium/content/browser/devtools/devtools_url_interceptor_request_job.cc
@@ -7,10 +7,12 @@
#include "base/base64.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "content/browser/devtools/protocol/network_handler.h"
#include "content/browser/devtools/protocol/page.h"
#include "content/browser/loader/download_utils_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "ipc/ipc_channel.h"
#include "net/base/completion_once_callback.h"
#include "net/base/elements_upload_data_stream.h"
@@ -142,6 +144,7 @@ DevToolsURLInterceptorRequestJob::SubRequest::SubRequest(
resource_request_info->GetRequestID(),
resource_request_info->GetRenderFrameID(),
resource_request_info->IsMainFrame(),
+ resource_request_info->fetch_window_id(),
resource_request_info->GetResourceType(),
resource_request_info->GetPageTransition(),
resource_request_info->IsDownload(), resource_request_info->is_stream(),
@@ -273,7 +276,7 @@ DevToolsURLInterceptorRequestJob::InterceptedRequest::InterceptedRequest(
: SubRequest(request_details,
devtools_interceptor_request_job,
interceptor),
- response_buffer_(new net::GrowableIOBuffer()),
+ response_buffer_(base::MakeRefCounted<net::GrowableIOBuffer>()),
read_response_result_(0),
read_started_(false) {}
@@ -456,8 +459,6 @@ int DevToolsURLInterceptorRequestJob::MockResponseDetails::ReadRawData(
namespace {
-using DevToolsStatus = ResourceRequestInfoImpl::DevToolsStatus;
-
void SendPendingBodyRequestsOnUiThread(
std::vector<std::unique_ptr<
protocol::Network::Backend::GetResponseBodyForInterceptionCallback>>
@@ -532,14 +533,6 @@ std::unique_ptr<net::UploadDataStream> GetUploadData(net::URLRequest* request) {
std::move(proxy_readers), 0);
}
-void SetDevToolsStatus(net::URLRequest* request,
- DevToolsStatus devtools_status) {
- ResourceRequestInfoImpl* resource_request_info =
- ResourceRequestInfoImpl::ForRequest(request);
- DCHECK(resource_request_info);
- resource_request_info->set_devtools_status(devtools_status);
-}
-
bool IsDownload(net::URLRequest* orig_request, net::URLRequest* subrequest) {
auto* req_info = ResourceRequestInfoImpl::ForRequest(orig_request);
// Only happens to downloads that are initiated by the download manager.
@@ -644,8 +637,8 @@ void DevToolsURLInterceptorRequestJob::StartWithCookies(
DCHECK(stage_to_intercept_ == InterceptionStage::REQUEST ||
stage_to_intercept_ == InterceptionStage::BOTH);
waiting_for_user_response_ = WaitingForUserResponse::WAITING_FOR_REQUEST_ACK;
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(callback_, BuildRequestInfo()));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(callback_, BuildRequestInfo()));
}
void DevToolsURLInterceptorRequestJob::Kill() {
@@ -771,8 +764,8 @@ void DevToolsURLInterceptorRequestJob::OnSubRequestAuthRequired(
.SetScheme(auth_info->scheme)
.SetRealm(auth_info->realm)
.Build();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(callback_, std::move(request_info)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(callback_, std::move(request_info)));
}
void DevToolsURLInterceptorRequestJob::OnSubRequestResponseStarted(
@@ -794,8 +787,6 @@ void DevToolsURLInterceptorRequestJob::OnSubRequestRedirectReceived(
bool* defer_redirect) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(sub_request_);
- SetDevToolsStatus(sub_request_->request(),
- DevToolsStatus::kCanceledAsRedirect);
// If we're not intercepting results or are a response then cancel this
// redirect and tell the parent request it was redirected through |redirect_|.
@@ -829,8 +820,8 @@ void DevToolsURLInterceptorRequestJob::OnSubRequestRedirectReceived(
protocol::Object::fromValue(headers_dict.get(), nullptr);
request_info->http_response_status_code = redirectinfo.status_code;
request_info->redirect_url = redirectinfo.new_url.spec();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(callback_, std::move(request_info)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(callback_, std::move(request_info)));
sub_request_.reset();
}
@@ -865,8 +856,8 @@ void DevToolsURLInterceptorRequestJob::OnInterceptedRequestResponseStarted(
protocol::Object::fromValue(headers_dict.get(), nullptr);
request_info->is_download = IsDownload(request(), sub_request_->request());
}
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(callback_, std::move(request_info)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(callback_, std::move(request_info)));
}
// If result is < 0 it means error.
@@ -876,8 +867,8 @@ void DevToolsURLInterceptorRequestJob::OnInterceptedRequestResponseReady(
DCHECK(sub_request_);
if (result < 0) {
sub_request_->Cancel();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&SendPendingBodyRequestsWithErrorOnUiThread,
std::move(pending_body_requests_),
@@ -885,10 +876,10 @@ void DevToolsURLInterceptorRequestJob::OnInterceptedRequestResponseReady(
"Could not get response body because of error code: %d",
result))));
} else {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&SendPendingBodyRequestsOnUiThread,
- std::move(pending_body_requests_),
- std::string(buf.data(), result)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&SendPendingBodyRequestsOnUiThread,
+ std::move(pending_body_requests_),
+ std::string(buf.data(), result)));
}
if (request_->status().status() == net::URLRequestStatus::CANCELED ||
waiting_for_user_response_ != WaitingForUserResponse::NOT_WAITING) {
@@ -920,8 +911,7 @@ void DevToolsURLInterceptorRequestJob::StopIntercepting() {
base::nullopt, base::nullopt, protocol::Maybe<std::string>(),
protocol::Maybe<std::string>(), protocol::Maybe<std::string>(),
protocol::Maybe<protocol::Network::Headers>(),
- protocol::Maybe<protocol::Network::AuthChallengeResponse>(),
- false));
+ protocol::Maybe<protocol::Network::AuthChallengeResponse>()));
return;
case WaitingForUserResponse::WAITING_FOR_AUTH_ACK: {
std::unique_ptr<protocol::Network::AuthChallengeResponse> auth_response =
@@ -934,7 +924,7 @@ void DevToolsURLInterceptorRequestJob::StopIntercepting() {
base::nullopt, base::nullopt, protocol::Maybe<std::string>(),
protocol::Maybe<std::string>(), protocol::Maybe<std::string>(),
protocol::Maybe<protocol::Network::Headers>(),
- std::move(auth_response), false));
+ std::move(auth_response)));
return;
}
@@ -950,8 +940,8 @@ void DevToolsURLInterceptorRequestJob::ContinueInterceptedRequest(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
switch (waiting_for_user_response_) {
case WaitingForUserResponse::NOT_WAITING:
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ContinueInterceptedRequestCallback::sendFailure,
std::move(callback),
protocol::Response::InvalidParams(
@@ -962,8 +952,8 @@ void DevToolsURLInterceptorRequestJob::ContinueInterceptedRequest(
// Fallthough.
case WaitingForUserResponse::WAITING_FOR_REQUEST_ACK:
if (modifications->auth_challenge_response.isJust()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ContinueInterceptedRequestCallback::sendFailure,
std::move(callback),
protocol::Response::InvalidParams(
@@ -971,16 +961,16 @@ void DevToolsURLInterceptorRequestJob::ContinueInterceptedRequest(
break;
}
ProcessInterceptionResponse(std::move(modifications));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ContinueInterceptedRequestCallback::sendSuccess,
std::move(callback)));
break;
case WaitingForUserResponse::WAITING_FOR_AUTH_ACK:
if (!modifications->auth_challenge_response.isJust()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ContinueInterceptedRequestCallback::sendFailure,
std::move(callback),
protocol::Response::InvalidParams(
@@ -988,13 +978,13 @@ void DevToolsURLInterceptorRequestJob::ContinueInterceptedRequest(
break;
}
if (ProcessAuthResponse(std::move(modifications))) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ContinueInterceptedRequestCallback::sendSuccess,
std::move(callback)));
} else {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ContinueInterceptedRequestCallback::sendFailure,
std::move(callback),
protocol::Response::InvalidParams(
@@ -1040,8 +1030,8 @@ void DevToolsURLInterceptorRequestJob::GetResponseBody(
"received.";
}
if (error_reason.size()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&GetResponseBodyForInterceptionCallback::sendFailure,
std::move(callback),
@@ -1073,9 +1063,6 @@ void DevToolsURLInterceptorRequestJob::ProcessInterceptionResponse(
WaitingForUserResponse::WAITING_FOR_RESPONSE_ACK;
waiting_for_user_response_ = WaitingForUserResponse::NOT_WAITING;
- if (modifications->mark_as_canceled)
- SetDevToolsStatus(request(), DevToolsStatus::kCanceled);
-
if (modifications->error_reason) {
if (sub_request_) {
sub_request_->Cancel();
@@ -1248,6 +1235,11 @@ void DevToolsURLInterceptorRequestJob::SetResponseHeadersCallback(
response_headers_callback_ = std::move(callback);
}
+void DevToolsURLInterceptorRequestJob::ContinueDespiteLastError() {
+ if (sub_request_)
+ sub_request_->request()->ContinueDespiteLastError();
+}
+
DevToolsURLInterceptorRequestJob::RequestDetails::RequestDetails(
const GURL& url,
const std::string& method,
diff --git a/chromium/content/browser/devtools/devtools_url_interceptor_request_job.h b/chromium/content/browser/devtools/devtools_url_interceptor_request_job.h
index ac37f7204ff..0dc53c267fd 100644
--- a/chromium/content/browser/devtools/devtools_url_interceptor_request_job.h
+++ b/chromium/content/browser/devtools/devtools_url_interceptor_request_job.h
@@ -61,6 +61,7 @@ class DevToolsURLInterceptorRequestJob : public net::URLRequestJob {
void SetRequestHeadersCallback(net::RequestHeadersCallback callback) override;
void SetResponseHeadersCallback(
net::ResponseHeadersCallback callback) override;
+ void ContinueDespiteLastError() override;
// Must be called on IO thread.
void StopIntercepting();
diff --git a/chromium/content/browser/devtools/devtools_url_loader_interceptor.cc b/chromium/content/browser/devtools/devtools_url_loader_interceptor.cc
index 99e8fd164e5..af405769294 100644
--- a/chromium/content/browser/devtools/devtools_url_loader_interceptor.cc
+++ b/chromium/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -6,11 +6,13 @@
#include "base/base64.h"
#include "base/no_destructor.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "content/browser/devtools/protocol/network_handler.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/loader/download_utils_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/system/data_pipe_drainer.h"
@@ -70,8 +72,8 @@ class BodyReader : public mojo::DataPipeDrainer::Client {
callbacks_.push_back(std::move(callback));
if (data_complete_) {
DCHECK_EQ(1UL, callbacks_.size());
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&BodyReader::DispatchBodyOnUI, std::move(callbacks_),
encoded_body_));
}
@@ -81,8 +83,8 @@ class BodyReader : public mojo::DataPipeDrainer::Client {
const std::string& body() const { return body_; }
void CancelWithError(std::string error) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&BodyReader::DispatchErrorOnUI, std::move(callbacks_),
std::move(error)));
}
@@ -124,9 +126,10 @@ void BodyReader::OnDataComplete() {
body_pipe_drainer_.reset();
// TODO(caseq): only encode if necessary.
base::Base64Encode(body_, &encoded_body_);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&BodyReader::DispatchBodyOnUI,
- std::move(callbacks_), encoded_body_));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&BodyReader::DispatchBodyOnUI, std::move(callbacks_),
+ encoded_body_));
std::move(download_complete_callback_).Run();
}
@@ -204,7 +207,7 @@ class InterceptionJob : public network::mojom::URLLoaderClient,
Response InnerContinueRequest(std::unique_ptr<Modifications> modifications);
Response ProcessAuthResponse(AuthChallengeResponse* auth_challenge_response);
Response ProcessResponseOverride(const std::string& response);
- Response ProcessRedirectByClient(const std::string& location);
+ Response ProcessRedirectByClient(const GURL& redirect_url);
void SendResponse(const base::StringPiece& body);
void ApplyModificationsToRequest(
std::unique_ptr<Modifications> modifications);
@@ -387,8 +390,8 @@ class DevToolsURLLoaderInterceptor::Impl
auto it = jobs_.find(id);
if (it != jobs_.end())
return it->second;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&Callback::sendFailure, std::move(*callback),
protocol::Response::InvalidParams("Invalid InterceptionId.")));
@@ -458,8 +461,8 @@ DevToolsURLLoaderFactoryProxy::DevToolsURLLoaderFactoryProxy(
is_download_(is_download),
interceptor_(std::move(interceptor)) {
DETACH_FROM_SEQUENCE(sequence_checker_);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DevToolsURLLoaderFactoryProxy::StartOnIO,
base::Unretained(this), std::move(loader_request),
std::move(target_factory_info)));
@@ -543,7 +546,8 @@ DevToolsURLLoaderInterceptor::DevToolsURLLoaderInterceptor(
enabled_(false),
impl_(new DevToolsURLLoaderInterceptor::Impl(std::move(callback)),
base::OnTaskRunnerDeleter(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))),
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {BrowserThread::IO}))),
weak_impl_(impl_->AsWeakPtr()) {}
DevToolsURLLoaderInterceptor::~DevToolsURLLoaderInterceptor() {
@@ -571,8 +575,8 @@ void DevToolsURLLoaderInterceptor::SetPatterns(
enabled_ = !!patterns.size();
UpdateSubresourceLoaderFactories();
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&Impl::SetPatterns, base::Unretained(impl_.get()),
std::move(patterns)));
}
@@ -580,8 +584,8 @@ void DevToolsURLLoaderInterceptor::SetPatterns(
void DevToolsURLLoaderInterceptor::GetResponseBody(
const std::string& interception_id,
std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&Impl::GetResponseBody, base::Unretained(impl_.get()),
interception_id, std::move(callback)));
}
@@ -589,8 +593,8 @@ void DevToolsURLLoaderInterceptor::GetResponseBody(
void DevToolsURLLoaderInterceptor::TakeResponseBodyPipe(
const std::string& interception_id,
DevToolsNetworkInterceptor::TakeResponseBodyPipeCallback callback) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&Impl::TakeResponseBodyPipe, base::Unretained(impl_.get()),
interception_id, std::move(callback)));
}
@@ -599,8 +603,8 @@ void DevToolsURLLoaderInterceptor::ContinueInterceptedRequest(
const std::string& interception_id,
std::unique_ptr<Modifications> modifications,
std::unique_ptr<ContinueInterceptedRequestCallback> callback) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&Impl::ContinueInterceptedRequest,
base::Unretained(impl_.get()), interception_id,
std::move(modifications), std::move(callback)));
@@ -699,8 +703,8 @@ void InterceptionJob::GetResponseBody(
std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) {
std::string error_reason;
if (!CanGetResponseBody(&error_reason)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&GetResponseBodyForInterceptionCallback::sendFailure,
std::move(callback),
Response::Error(std::move(error_reason))));
@@ -719,8 +723,8 @@ void InterceptionJob::TakeResponseBodyPipe(
TakeResponseBodyPipeCallback callback) {
std::string error_reason;
if (!CanGetResponseBody(&error_reason)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback),
Response::Error(std::move(error_reason)),
mojo::ScopedDataPipeConsumerHandle(), std::string()));
@@ -745,7 +749,7 @@ void InterceptionJob::ContinueInterceptedRequest(
std::move(callback))
: base::BindOnce(&ContinueInterceptedRequestCallback::sendFailure,
std::move(callback), std::move(response));
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(task));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(task));
}
void InterceptionJob::Detach() {
@@ -777,12 +781,9 @@ Response InterceptionJob::InnerContinueRequest(
if (modifications->auth_challenge_response.isJust())
return Response::InvalidParams("authChallengeResponse not expected.");
- if (modifications->mark_as_canceled || modifications->error_reason) {
- int error = modifications->error_reason
- ? *modifications->error_reason
- : (modifications->mark_as_canceled ? net::ERR_ABORTED
- : net::ERR_FAILED);
- network::URLLoaderCompletionStatus status(error);
+ if (modifications->error_reason) {
+ network::URLLoaderCompletionStatus status(
+ modifications->error_reason.value());
status.completion_time = base::TimeTicks::Now();
if (modifications->error_reason == net::ERR_BLOCKED_BY_CLIENT) {
// So we know that these modifications originated from devtools
@@ -820,7 +821,8 @@ Response InterceptionJob::InnerContinueRequest(
auto* headers = response_metadata_->head.headers.get();
headers->RemoveHeader("location");
headers->AddHeader("location: " + location);
- return ProcessRedirectByClient(location);
+ return ProcessRedirectByClient(
+ create_loader_params_->request.url.Resolve(location));
}
client_->OnReceiveRedirect(*response_metadata_->redirect_info,
response_metadata_->head);
@@ -940,7 +942,9 @@ Response InterceptionJob::ProcessResponseOverride(const std::string& response) {
head->headers = new net::HttpResponseHeaders(std::move(raw_headers));
head->headers->GetMimeTypeAndCharset(&head->mime_type, &head->charset);
if (head->mime_type.empty()) {
- net::SniffMimeType(response.data() + header_size, body_size,
+ size_t bytes_to_sniff =
+ std::min(body_size, static_cast<size_t>(net::kMaxBytesToSniff));
+ net::SniffMimeType(response.data() + header_size, bytes_to_sniff,
create_loader_params_->request.url, "",
net::ForceSniffFileUrlsForHtml::kDisabled,
&head->mime_type);
@@ -952,9 +956,12 @@ Response InterceptionJob::ProcessResponseOverride(const std::string& response) {
head->request_start = start_ticks_;
head->response_start = base::TimeTicks::Now();
- std::string location_url;
- if (head->headers->IsRedirect(&location_url))
- return ProcessRedirectByClient(location_url);
+ std::string location;
+ if (head->headers->IsRedirect(&location)) {
+ GURL redirect_url = create_loader_params_->request.url.Resolve(location);
+ if (redirect_url.is_valid())
+ return ProcessRedirectByClient(redirect_url);
+ }
response_metadata_->transfer_size = body_size;
@@ -967,9 +974,7 @@ Response InterceptionJob::ProcessResponseOverride(const std::string& response) {
return Response::OK();
}
-Response InterceptionJob::ProcessRedirectByClient(const std::string& location) {
- GURL redirect_url = create_loader_params_->request.url.Resolve(location);
-
+Response InterceptionJob::ProcessRedirectByClient(const GURL& redirect_url) {
if (!redirect_url.is_valid())
return Response::Error("Invalid redirect URL in overriden headers");
@@ -987,8 +992,8 @@ Response InterceptionJob::ProcessRedirectByClient(const std::string& location) {
request.method, request.url, request.site_for_cookies,
first_party_url_policy, request.referrer_policy,
request.referrer.spec(), &headers, headers.response_code(),
- redirect_url, false /* token_binding_negotiated */,
- false /* insecure_scheme_was_upgraded */, false /* copy_fragment */));
+ redirect_url, false /* insecure_scheme_was_upgraded */,
+ true /* copy_fragment */));
client_->OnReceiveRedirect(*response_metadata_->redirect_info,
response_metadata_->head);
@@ -1097,8 +1102,8 @@ std::unique_ptr<InterceptedRequestInfo> InterceptionJob::BuildRequestInfo(
void InterceptionJob::NotifyClient(
std::unique_ptr<InterceptedRequestInfo> request_info) {
waiting_for_resolution_ = true;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(interceptor_->request_intercepted_callback_,
std::move(request_info)));
}
@@ -1250,8 +1255,8 @@ void InterceptionJob::OnStartLoadingResponseBody(
if (pending_response_body_pipe_callback_) {
DCHECK_EQ(State::kResponseTaken, state_);
DCHECK(!body_reader_);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(pending_response_body_pipe_callback_),
Response::OK(), std::move(body),
response_metadata_->head.mime_type));
diff --git a/chromium/content/browser/devtools/devtools_url_request_interceptor.cc b/chromium/content/browser/devtools/devtools_url_request_interceptor.cc
index e6bf677b05b..870cb80ec79 100644
--- a/chromium/content/browser/devtools/devtools_url_request_interceptor.cc
+++ b/chromium/content/browser/devtools/devtools_url_request_interceptor.cc
@@ -6,9 +6,11 @@
#include "base/strings/pattern.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "content/browser/devtools/devtools_interceptor_controller.h"
#include "content/browser/devtools/devtools_url_interceptor_request_job.h"
#include "content/browser/devtools/protocol/network_handler.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_request_info.h"
#include "net/url_request/url_request.h"
@@ -27,8 +29,8 @@ DevToolsURLRequestInterceptor::DevToolsURLRequestInterceptor(
: next_id_(0), weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto target_registry = std::make_unique<DevToolsTargetRegistry>(
- content::BrowserThread::GetTaskRunnerForThread(
- content::BrowserThread::IO));
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {content::BrowserThread::IO}));
target_resolver_ = target_registry->CreateResolver();
// Controller lifetime is managed by the browser context.
auto* controller = new DevToolsInterceptorController(
@@ -58,8 +60,8 @@ void DevToolsURLRequestInterceptor::ContinueInterceptedRequest(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DevToolsURLInterceptorRequestJob* job = GetJob(interception_id);
if (!job) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&ContinueInterceptedRequestCallback::sendFailure,
std::move(callback),
@@ -97,8 +99,8 @@ void DevToolsURLRequestInterceptor::GetResponseBody(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DevToolsURLInterceptorRequestJob* job = GetJob(interception_id);
if (!job) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&GetResponseBodyForInterceptionCallback::sendFailure,
std::move(callback),
@@ -144,8 +146,8 @@ net::URLRequestJob* DevToolsURLRequestInterceptor::InnerMaybeInterceptRequest(
std::string interception_id = base::StringPrintf("id-%zu", ++next_id_);
if (IsNavigationRequest(resource_type)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DevToolsInterceptorController::NavigationStarted,
controller_, interception_id,
resource_request_info->GetGlobalRequestID()));
@@ -275,8 +277,8 @@ void DevToolsURLRequestInterceptor::JobFinished(
interception_id_to_job_map_.erase(interception_id);
if (!is_navigation)
return;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DevToolsInterceptorController::NavigationFinished,
controller_, interception_id));
}
diff --git a/chromium/content/browser/devtools/devtools_video_consumer.cc b/chromium/content/browser/devtools/devtools_video_consumer.cc
index e6316a8681c..e7bbf3843a7 100644
--- a/chromium/content/browser/devtools/devtools_video_consumer.cc
+++ b/chromium/content/browser/devtools/devtools_video_consumer.cc
@@ -57,7 +57,7 @@ SkBitmap DevToolsVideoConsumer::GetSkBitmapFromFrame(
skbitmap.allocN32Pixels(frame->visible_rect().width(),
frame->visible_rect().height());
cc::SkiaPaintCanvas canvas(skbitmap);
- renderer.Copy(frame, &canvas, media::Context3D());
+ renderer.Copy(frame, &canvas, media::Context3D(), nullptr);
return skbitmap;
}
@@ -171,6 +171,8 @@ void DevToolsVideoConsumer::OnFrameCaptured(
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) {},
std::move(mapping), std::move(callbacks)));
frame->metadata()->MergeInternalValuesFrom(info->metadata);
+ if (info->color_space.has_value())
+ frame->set_color_space(info->color_space.value());
callback_.Run(std::move(frame));
}
diff --git a/chromium/content/browser/devtools/devtools_video_consumer_unittest.cc b/chromium/content/browser/devtools/devtools_video_consumer_unittest.cc
index 6aefd60ca68..496a3e8b057 100644
--- a/chromium/content/browser/devtools/devtools_video_consumer_unittest.cc
+++ b/chromium/content/browser/devtools/devtools_video_consumer_unittest.cc
@@ -6,7 +6,7 @@
#include <vector>
#include "base/memory/read_only_shared_memory_region.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "content/browser/devtools/devtools_video_consumer.h"
#include "content/public/test/test_utils.h"
#include "media/base/limits.h"
@@ -50,7 +50,7 @@ class MockFrameSinkVideoCapturer : public viz::mojom::FrameSinkVideoCapturer {
// This is never called.
MOCK_METHOD2(SetFormat,
void(media::VideoPixelFormat format,
- media::ColorSpace color_space));
+ const gfx::ColorSpace& color_space));
void SetMinCapturePeriod(base::TimeDelta min_capture_period) final {
min_capture_period_ = min_capture_period;
MockSetMinCapturePeriod(min_capture_period_);
@@ -181,7 +181,8 @@ class DevToolsVideoConsumerTest : public testing::Test {
media::mojom::VideoFrameInfoPtr info = media::mojom::VideoFrameInfo::New(
base::TimeDelta(), base::Value(base::Value::Type::DICTIONARY), kFormat,
- kResolution, gfx::Rect(kResolution));
+ kResolution, gfx::Rect(kResolution), gfx::ColorSpace::CreateREC709(),
+ nullptr);
consumer_->OnFrameCaptured(std::move(data), std::move(info),
gfx::Rect(kResolution), gfx::Rect(kResolution),
@@ -230,7 +231,7 @@ class DevToolsVideoConsumerTest : public testing::Test {
weak_factory_.GetWeakPtr()));
}
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
base::WeakPtrFactory<DevToolsVideoConsumerTest> weak_factory_;
};
diff --git a/chromium/content/browser/devtools/forwarding_agent_host.cc b/chromium/content/browser/devtools/forwarding_agent_host.cc
index 1682f1cc880..44970981ede 100644
--- a/chromium/content/browser/devtools/forwarding_agent_host.cc
+++ b/chromium/content/browser/devtools/forwarding_agent_host.cc
@@ -51,8 +51,9 @@ ForwardingAgentHost::ForwardingAgentHost(
ForwardingAgentHost::~ForwardingAgentHost() {
}
-void ForwardingAgentHost::AttachClient(DevToolsAgentHostClient* client) {
+bool ForwardingAgentHost::AttachClient(DevToolsAgentHostClient* client) {
session_proxies_[client].reset(new SessionProxy(this, client));
+ return true;
}
bool ForwardingAgentHost::DetachClient(DevToolsAgentHostClient* client) {
diff --git a/chromium/content/browser/devtools/forwarding_agent_host.h b/chromium/content/browser/devtools/forwarding_agent_host.h
index 3368c916f36..e3aec78e772 100644
--- a/chromium/content/browser/devtools/forwarding_agent_host.h
+++ b/chromium/content/browser/devtools/forwarding_agent_host.h
@@ -27,7 +27,7 @@ class ForwardingAgentHost : public DevToolsAgentHostImpl {
~ForwardingAgentHost() override;
// DevToolsAgentHost implementation
- void AttachClient(DevToolsAgentHostClient* client) override;
+ bool AttachClient(DevToolsAgentHostClient* client) override;
bool DetachClient(DevToolsAgentHostClient* client) override;
bool DispatchProtocolMessage(DevToolsAgentHostClient* client,
const std::string& message) override;
diff --git a/chromium/content/browser/devtools/protocol/browser_handler.cc b/chromium/content/browser/devtools/protocol/browser_handler.cc
index 2c57058886f..193dcdbd454 100644
--- a/chromium/content/browser/devtools/protocol/browser_handler.cc
+++ b/chromium/content/browser/devtools/protocol/browser_handler.cc
@@ -268,5 +268,10 @@ Response BrowserHandler::GetBrowserCommandLine(
}
}
+Response BrowserHandler::Crash() {
+ CHECK(false);
+ return Response::OK();
+}
+
} // namespace protocol
} // namespace content
diff --git a/chromium/content/browser/devtools/protocol/browser_handler.h b/chromium/content/browser/devtools/protocol/browser_handler.h
index 5175b0ffb41..3b8515a9ea0 100644
--- a/chromium/content/browser/devtools/protocol/browser_handler.h
+++ b/chromium/content/browser/devtools/protocol/browser_handler.h
@@ -53,6 +53,8 @@ class BrowserHandler : public DevToolsDomainHandler, public Browser::Backend {
Response ResetPermissions(Maybe<std::string> browser_context_id) override;
+ Response Crash() override;
+
private:
Response FindBrowserContext(const Maybe<std::string>& browser_context_id,
BrowserContext** browser_context);
diff --git a/chromium/content/browser/devtools/protocol/devtools_download_manager_delegate.cc b/chromium/content/browser/devtools/protocol/devtools_download_manager_delegate.cc
index bfaa525d37e..3ef417e6211 100644
--- a/chromium/content/browser/devtools/protocol/devtools_download_manager_delegate.cc
+++ b/chromium/content/browser/devtools/protocol/devtools_download_manager_delegate.cc
@@ -7,9 +7,9 @@
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/task/post_task.h"
-#include "base/threading/thread_restrictions.h"
#include "content/browser/devtools/protocol/devtools_download_manager_helper.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/browser/download_manager.h"
@@ -159,7 +159,6 @@ void DevToolsDownloadManagerDelegate::GenerateFilename(
const std::string& mime_type,
const base::FilePath& suggested_directory,
const FilenameDeterminedCallback& callback) {
- base::AssertBlockingAllowed();
base::FilePath generated_name =
net::GenerateFileName(url, content_disposition, std::string(),
suggested_filename, mime_type, "download");
@@ -168,8 +167,8 @@ void DevToolsDownloadManagerDelegate::GenerateFilename(
base::CreateDirectory(suggested_directory);
base::FilePath suggested_path(suggested_directory.Append(generated_name));
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- base::BindOnce(callback, suggested_path));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(callback, suggested_path));
}
void DevToolsDownloadManagerDelegate::OnDownloadPathGenerated(
diff --git a/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
index c66b3c9454a..57a749755b9 100644
--- a/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -11,6 +11,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
+#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
@@ -1356,6 +1357,48 @@ IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CertificateError) {
->GetURL());
}
+IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest,
+ CertificateErrorRequestInterception) {
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
+ ASSERT_TRUE(https_server.Start());
+ GURL test_url = https_server.GetURL("/devtools/navigation.html");
+
+ shell()->LoadURL(GURL("about:blank"));
+ WaitForLoadStop(shell()->web_contents());
+
+ Attach();
+ SendCommand("Network.enable", nullptr, true);
+ SendCommand("Security.enable", nullptr, false);
+ SendCommand(
+ "Network.setRequestInterception",
+ base::JSONReader::Read("{\"patterns\": [{\"urlPattern\": \"*\"}]}"),
+ true);
+
+ SendCommand("Security.setIgnoreCertificateErrors",
+ base::JSONReader::Read("{\"ignore\": true}"), true);
+
+ SendCommand("Network.clearBrowserCache", nullptr, true);
+ SendCommand("Network.clearBrowserCookies", nullptr, true);
+ TestNavigationObserver continue_observer(shell()->web_contents(), 1);
+ shell()->LoadURL(test_url);
+ std::unique_ptr<base::DictionaryValue> params =
+ WaitForNotification("Network.requestIntercepted", false);
+ std::string interceptionId;
+ EXPECT_TRUE(params->GetString("interceptionId", &interceptionId));
+ SendCommand("Network.continueInterceptedRequest",
+ base::JSONReader::Read("{\"interceptionId\": \"" +
+ interceptionId + "\"}"),
+ false);
+ continue_observer.Wait();
+ EXPECT_EQ(test_url, shell()
+ ->web_contents()
+ ->GetController()
+ .GetLastCommittedEntry()
+ ->GetURL());
+}
+
IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, CertificateErrorBrowserTarget) {
net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
diff --git a/chromium/content/browser/devtools/protocol/devtools_protocol_test_support.cc b/chromium/content/browser/devtools/protocol/devtools_protocol_test_support.cc
index 41ba4bc6448..14d94c8a26b 100644
--- a/chromium/content/browser/devtools/protocol/devtools_protocol_test_support.cc
+++ b/chromium/content/browser/devtools/protocol/devtools_protocol_test_support.cc
@@ -47,7 +47,7 @@ bool DevToolsProtocolTest::DidAddMessageToConsole(
base::DictionaryValue* DevToolsProtocolTest::SendCommand(
const std::string& method,
- std::unique_ptr<base::DictionaryValue> params,
+ std::unique_ptr<base::Value> params,
bool wait) {
in_dispatch_ = true;
base::DictionaryValue command;
diff --git a/chromium/content/browser/devtools/protocol/devtools_protocol_test_support.h b/chromium/content/browser/devtools/protocol/devtools_protocol_test_support.h
index 15e5d23afce..cb8a49967f9 100644
--- a/chromium/content/browser/devtools/protocol/devtools_protocol_test_support.h
+++ b/chromium/content/browser/devtools/protocol/devtools_protocol_test_support.h
@@ -40,16 +40,14 @@ class DevToolsProtocolTest : public ContentBrowserTest,
content::WebContents* web_contents,
content::SecurityStyleExplanations* security_style_explanations) override;
- base::DictionaryValue* SendCommand(
- const std::string& method,
- std::unique_ptr<base::DictionaryValue> params) {
+ base::DictionaryValue* SendCommand(const std::string& method,
+ std::unique_ptr<base::Value> params) {
return SendCommand(method, std::move(params), true);
}
- base::DictionaryValue* SendCommand(
- const std::string& method,
- std::unique_ptr<base::DictionaryValue> params,
- bool wait);
+ base::DictionaryValue* SendCommand(const std::string& method,
+ std::unique_ptr<base::Value> params,
+ bool wait);
void WaitForResponse();
diff --git a/chromium/content/browser/devtools/protocol/emulation_handler.cc b/chromium/content/browser/devtools/protocol/emulation_handler.cc
index af6d9a2b197..8df358c3af9 100644
--- a/chromium/content/browser/devtools/protocol/emulation_handler.cc
+++ b/chromium/content/browser/devtools/protocol/emulation_handler.cc
@@ -8,12 +8,12 @@
#include "base/strings/string_number_conversions.h"
#include "build/build_config.h"
-#include "content/browser/devtools/devtools_session.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/input/touch_emulator.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/common/url_constants.h"
#include "net/http/http_util.h"
#include "services/device/public/cpp/geolocation/geoposition.h"
@@ -69,19 +69,19 @@ EmulationHandler::~EmulationHandler() {
// static
std::vector<EmulationHandler*> EmulationHandler::ForAgentHost(
DevToolsAgentHostImpl* host) {
- return DevToolsSession::HandlersForAgentHost<EmulationHandler>(
- host, Emulation::Metainfo::domainName);
+ return host->HandlersByName<EmulationHandler>(
+ Emulation::Metainfo::domainName);
}
void EmulationHandler::SetRenderer(int process_host_id,
RenderFrameHostImpl* frame_host) {
if (host_ == frame_host)
return;
-
host_ = frame_host;
if (touch_emulation_enabled_)
UpdateTouchEventEmulationState();
- UpdateDeviceEmulationState();
+ if (device_emulation_enabled_)
+ UpdateDeviceEmulationState();
}
void EmulationHandler::Wire(UberDispatcher* dispatcher) {
@@ -94,8 +94,10 @@ Response EmulationHandler::Disable() {
UpdateTouchEventEmulationState();
}
user_agent_ = std::string();
- device_emulation_enabled_ = false;
- UpdateDeviceEmulationState();
+ if (device_emulation_enabled_) {
+ device_emulation_enabled_ = false;
+ UpdateDeviceEmulationState();
+ }
return Response::OK();
}
@@ -387,14 +389,14 @@ void EmulationHandler::UpdateDeviceEmulationState() {
// emulation params were applied. That way, we can avoid having to handle
// Set/ClearDeviceMetricsOverride in the renderer. With the old IPC system,
// this is tricky since we'd have to track the DevTools message id with the
- // ViewMsg and acknowledgment, as well as plump the acknowledgment back to the
- // EmulationHandler somehow. Mojo callbacks should make this much simpler.
+ // WidgetMsg and acknowledgment, as well as plump the acknowledgment back to
+ // the EmulationHandler somehow. Mojo callbacks should make this much simpler.
if (device_emulation_enabled_) {
- host_->GetRenderWidgetHost()->Send(new ViewMsg_EnableDeviceEmulation(
+ host_->GetRenderWidgetHost()->Send(new WidgetMsg_EnableDeviceEmulation(
host_->GetRenderWidgetHost()->GetRoutingID(),
device_emulation_params_));
} else {
- host_->GetRenderWidgetHost()->Send(new ViewMsg_DisableDeviceEmulation(
+ host_->GetRenderWidgetHost()->Send(new WidgetMsg_DisableDeviceEmulation(
host_->GetRenderWidgetHost()->GetRoutingID()));
}
}
diff --git a/chromium/content/browser/devtools/protocol/input_handler.cc b/chromium/content/browser/devtools/protocol/input_handler.cc
index d89856b04b3..d6fbc0110f4 100644
--- a/chromium/content/browser/devtools/protocol/input_handler.cc
+++ b/chromium/content/browser/devtools/protocol/input_handler.cc
@@ -10,7 +10,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
-#include "content/browser/devtools/devtools_session.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/protocol/native_input_event_builder.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/input/touch_emulator.h"
@@ -414,8 +414,7 @@ InputHandler::~InputHandler() {
// static
std::vector<InputHandler*> InputHandler::ForAgentHost(
DevToolsAgentHostImpl* host) {
- return DevToolsSession::HandlersForAgentHost<InputHandler>(
- host, Input::Metainfo::domainName);
+ return host->HandlersByName<InputHandler>(Input::Metainfo::domainName);
}
void InputHandler::SetRenderer(int process_host_id,
diff --git a/chromium/content/browser/devtools/protocol/inspector_handler.cc b/chromium/content/browser/devtools/protocol/inspector_handler.cc
index ae8e11f7472..31eb6d428f7 100644
--- a/chromium/content/browser/devtools/protocol/inspector_handler.cc
+++ b/chromium/content/browser/devtools/protocol/inspector_handler.cc
@@ -4,7 +4,7 @@
#include "content/browser/devtools/protocol/inspector_handler.h"
-#include "content/browser/devtools/devtools_session.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
namespace content {
@@ -21,8 +21,8 @@ InspectorHandler::~InspectorHandler() {
// static
std::vector<InspectorHandler*> InspectorHandler::ForAgentHost(
DevToolsAgentHostImpl* host) {
- return DevToolsSession::HandlersForAgentHost<InspectorHandler>(
- host, Inspector::Metainfo::domainName);
+ return host->HandlersByName<InspectorHandler>(
+ Inspector::Metainfo::domainName);
}
void InspectorHandler::Wire(UberDispatcher* dispatcher) {
diff --git a/chromium/content/browser/devtools/protocol/memory_handler.cc b/chromium/content/browser/devtools/protocol/memory_handler.cc
index 328ecd8aeea..49e5453ac31 100644
--- a/chromium/content/browser/devtools/protocol/memory_handler.cc
+++ b/chromium/content/browser/devtools/protocol/memory_handler.cc
@@ -61,7 +61,7 @@ Response MemoryHandler::GetBrowserSamplingProfile(
for (const auto* module : module_cache.GetModules()) {
modules->addItem(Memory::Module::Create()
.SetName(base::StringPrintf(
- "%" PRIsFP, module->filename.value().c_str()))
+ "%" PRFilePath, module->filename.value().c_str()))
.SetUuid(module->id)
.SetBaseAddress(base::StringPrintf(
"0x%" PRIxPTR, module->base_address))
diff --git a/chromium/content/browser/devtools/protocol/network_handler.cc b/chromium/content/browser/devtools/protocol/network_handler.cc
index 905fe910beb..1ba2c3016bf 100644
--- a/chromium/content/browser/devtools/protocol/network_handler.cc
+++ b/chromium/content/browser/devtools/protocol/network_handler.cc
@@ -16,11 +16,12 @@
#include "base/process/process_handle.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "content/browser/background_sync/background_sync_manager.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/devtools_interceptor_controller.h"
#include "content/browser/devtools/devtools_io_context.h"
-#include "content/browser/devtools/devtools_session.h"
#include "content/browser/devtools/devtools_stream_pipe.h"
#include "content/browser/devtools/devtools_url_loader_interceptor.h"
#include "content/browser/devtools/protocol/page.h"
@@ -35,6 +36,7 @@
#include "content/browser/web_package/signed_exchange_error.h"
#include "content/common/navigation_params.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/content_browser_client.h"
@@ -100,7 +102,7 @@ Network::CertificateTransparencyCompliance SerializeCTPolicyCompliance(
case net::ct::CTPolicyCompliance::
CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE:
return Network::CertificateTransparencyComplianceEnum::Unknown;
- case net::ct::CTPolicyCompliance::CT_POLICY_MAX:
+ case net::ct::CTPolicyCompliance::CT_POLICY_COUNT:
NOTREACHED();
return Network::CertificateTransparencyComplianceEnum::Unknown;
}
@@ -208,8 +210,8 @@ class CookieRetriever : public base::RefCountedThreadSafe<CookieRetriever> {
for (const auto& pair : cookies_)
master_cookie_list.push_back(pair.second);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&CookieRetriever::SendCookiesResponseOnUI, this,
master_cookie_list));
}
@@ -286,8 +288,8 @@ void ClearedCookiesOnIO(std::unique_ptr<ClearBrowserCookiesCallback> callback,
uint32_t num_deleted) {
DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ClearBrowserCookiesCallback::sendSuccess,
std::move(callback)));
}
@@ -304,7 +306,7 @@ void ClearCookiesOnIO(net::URLRequestContextGetter* context_getter,
void DeletedCookiesOnIO(base::OnceClosure callback, uint32_t num_deleted) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(callback));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(callback));
}
std::vector<net::CanonicalCookie> FilterCookies(
@@ -368,9 +370,9 @@ void DeleteCookiesOnIO(net::URLRequestContextGetter* context_getter,
void CookieSetOnIO(std::unique_ptr<SetCookieCallback> callback, bool success) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&SetCookieCallback::sendSuccess,
- std::move(callback), success));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&SetCookieCallback::sendSuccess,
+ std::move(callback), success));
}
void DeleteFilteredCookies(network::mojom::CookieManager* cookie_manager,
@@ -455,8 +457,8 @@ void SetCookieOnIO(net::URLRequestContextGetter* context_getter,
void CookiesSetOnIO(std::unique_ptr<SetCookiesCallback> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SetCookiesCallback::sendSuccess, std::move(callback)));
}
@@ -663,48 +665,49 @@ String NetErrorToString(int net_error) {
bool AddInterceptedResourceType(
const std::string& resource_type,
base::flat_set<ResourceType>* intercepted_resource_types) {
- if (resource_type == protocol::Page::ResourceTypeEnum::Document) {
+ if (resource_type == protocol::Network::ResourceTypeEnum::Document) {
intercepted_resource_types->insert(RESOURCE_TYPE_MAIN_FRAME);
intercepted_resource_types->insert(RESOURCE_TYPE_SUB_FRAME);
return true;
}
- if (resource_type == protocol::Page::ResourceTypeEnum::Stylesheet) {
+ if (resource_type == protocol::Network::ResourceTypeEnum::Stylesheet) {
intercepted_resource_types->insert(RESOURCE_TYPE_STYLESHEET);
return true;
}
- if (resource_type == protocol::Page::ResourceTypeEnum::Image) {
+ if (resource_type == protocol::Network::ResourceTypeEnum::Image) {
intercepted_resource_types->insert(RESOURCE_TYPE_IMAGE);
return true;
}
- if (resource_type == protocol::Page::ResourceTypeEnum::Media) {
+ if (resource_type == protocol::Network::ResourceTypeEnum::Media) {
intercepted_resource_types->insert(RESOURCE_TYPE_MEDIA);
return true;
}
- if (resource_type == protocol::Page::ResourceTypeEnum::Font) {
+ if (resource_type == protocol::Network::ResourceTypeEnum::Font) {
intercepted_resource_types->insert(RESOURCE_TYPE_FONT_RESOURCE);
return true;
}
- if (resource_type == protocol::Page::ResourceTypeEnum::Script) {
+ if (resource_type == protocol::Network::ResourceTypeEnum::Script) {
intercepted_resource_types->insert(RESOURCE_TYPE_SCRIPT);
return true;
}
- if (resource_type == protocol::Page::ResourceTypeEnum::XHR) {
+ if (resource_type == protocol::Network::ResourceTypeEnum::XHR) {
intercepted_resource_types->insert(RESOURCE_TYPE_XHR);
return true;
}
- if (resource_type == protocol::Page::ResourceTypeEnum::Fetch) {
+ if (resource_type == protocol::Network::ResourceTypeEnum::Fetch) {
intercepted_resource_types->insert(RESOURCE_TYPE_PREFETCH);
return true;
}
- if (resource_type == protocol::Page::ResourceTypeEnum::CSPViolationReport) {
+ if (resource_type ==
+ protocol::Network::ResourceTypeEnum::CSPViolationReport) {
intercepted_resource_types->insert(RESOURCE_TYPE_CSP_REPORT);
return true;
}
- if (resource_type == protocol::Page::ResourceTypeEnum::Ping) {
+ if (resource_type == protocol::Network::ResourceTypeEnum::Ping) {
intercepted_resource_types->insert(RESOURCE_TYPE_PING);
return true;
}
- if (resource_type == protocol::Page::ResourceTypeEnum::Other) {
+ if (resource_type == protocol::Network::ResourceTypeEnum::Other) {
intercepted_resource_types->insert(RESOURCE_TYPE_SUB_RESOURCE);
intercepted_resource_types->insert(RESOURCE_TYPE_OBJECT);
intercepted_resource_types->insert(RESOURCE_TYPE_WORKER);
@@ -773,7 +776,7 @@ String GetProtocol(const GURL& url, const network::ResourceResponseInfo& info) {
std::string protocol = info.alpn_negotiated_protocol;
if (protocol.empty() || protocol == "unknown") {
if (info.was_fetched_via_spdy) {
- protocol = "spdy";
+ protocol = "h2";
} else if (url.SchemeIsHTTPOrHTTPS()) {
protocol = "http";
if (info.headers->GetHttpVersion() == net::HttpVersion(0, 9))
@@ -929,8 +932,8 @@ class BackgroundSyncRestorer {
scoped_refptr<BackgroundSyncContext> sync_context =
static_cast<StoragePartitionImpl*>(storage_partition_)
->GetBackgroundSyncContext();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&SetServiceWorkerOfflineOnIO, sync_context,
base::RetainedRef(static_cast<ServiceWorkerContextWrapper*>(
@@ -984,8 +987,7 @@ NetworkHandler::~NetworkHandler() {
// static
std::vector<NetworkHandler*> NetworkHandler::ForAgentHost(
DevToolsAgentHostImpl* host) {
- return DevToolsSession::HandlersForAgentHost<NetworkHandler>(
- host, Network::Metainfo::domainName);
+ return host->HandlersByName<NetworkHandler>(Network::Metainfo::domainName);
}
void NetworkHandler::Wire(UberDispatcher* dispatcher) {
@@ -1075,8 +1077,8 @@ void NetworkHandler::ClearBrowserCookies(
}
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ClearCookiesOnIO,
base::Unretained(storage_partition_->GetURLRequestContext()),
@@ -1103,8 +1105,8 @@ void NetworkHandler::GetCookies(Maybe<Array<String>> protocol_urls,
scoped_refptr<CookieRetriever> retriever =
new CookieRetriever(std::move(callback));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&CookieRetriever::RetrieveCookiesOnIO, retriever,
base::Unretained(storage_partition_->GetURLRequestContext()),
@@ -1127,8 +1129,8 @@ void NetworkHandler::GetAllCookies(
scoped_refptr<CookieRetriever> retriever =
new CookieRetriever(std::move(callback));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&CookieRetriever::RetrieveAllCookiesOnIO, retriever,
base::Unretained(storage_partition_->GetURLRequestContext())));
@@ -1177,8 +1179,8 @@ void NetworkHandler::SetCookie(const std::string& name,
}
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&SetCookieOnIO,
base::Unretained(storage_partition_->GetURLRequestContext()),
@@ -1217,8 +1219,8 @@ void NetworkHandler::SetCookies(
}
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&SetCookiesOnIO,
base::Unretained(storage_partition_->GetURLRequestContext()),
@@ -1269,8 +1271,8 @@ void NetworkHandler::DeleteCookies(
}
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&DeleteCookiesOnIO,
base::Unretained(storage_partition_->GetURLRequestContext()), name,
@@ -1602,7 +1604,7 @@ void NetworkHandler::NavigationRequestWillBeSent(
frontend_->RequestWillBeSent(
id, id, url_without_fragment, std::move(request), current_ticks,
current_wall_time, std::move(initiator), std::move(redirect_response),
- std::string(Page::ResourceTypeEnum::Document), std::move(frame_token),
+ std::string(Network::ResourceTypeEnum::Document), std::move(frame_token),
common_params.has_user_gesture);
}
@@ -1639,7 +1641,7 @@ void NetworkHandler::RequestSent(const std::string& request_id,
static_cast<double>(base::Time::kMicrosecondsPerSecond),
base::Time::Now().ToDoubleT(), std::move(initiator),
std::unique_ptr<Network::Response>(),
- std::string(Page::ResourceTypeEnum::Other),
+ std::string(Network::ResourceTypeEnum::Other),
Maybe<std::string>() /* frame_id */, request.has_user_gesture);
}
@@ -1839,7 +1841,6 @@ void NetworkHandler::ContinueInterceptedRequest(
}
base::Optional<net::Error> error;
- bool mark_as_canceled = false;
if (error_reason.isJust()) {
bool ok;
error = NetErrorFromString(error_reason.fromJust(), &ok);
@@ -1847,15 +1848,13 @@ void NetworkHandler::ContinueInterceptedRequest(
callback->sendFailure(Response::InvalidParams("Invalid errorReason."));
return;
}
-
- mark_as_canceled = true;
}
auto modifications =
std::make_unique<DevToolsNetworkInterceptor::Modifications>(
std::move(error), std::move(raw_response), std::move(url),
std::move(method), std::move(post_data), std::move(headers),
- std::move(auth_challenge_response), mark_as_canceled);
+ std::move(auth_challenge_response));
if (url_loader_interceptor_) {
url_loader_interceptor_->ContinueInterceptedRequest(
@@ -2040,43 +2039,43 @@ namespace {
const char* ResourceTypeToString(ResourceType resource_type) {
switch (resource_type) {
case RESOURCE_TYPE_MAIN_FRAME:
- return protocol::Page::ResourceTypeEnum::Document;
+ return protocol::Network::ResourceTypeEnum::Document;
case RESOURCE_TYPE_SUB_FRAME:
- return protocol::Page::ResourceTypeEnum::Document;
+ return protocol::Network::ResourceTypeEnum::Document;
case RESOURCE_TYPE_STYLESHEET:
- return protocol::Page::ResourceTypeEnum::Stylesheet;
+ return protocol::Network::ResourceTypeEnum::Stylesheet;
case RESOURCE_TYPE_SCRIPT:
- return protocol::Page::ResourceTypeEnum::Script;
+ return protocol::Network::ResourceTypeEnum::Script;
case RESOURCE_TYPE_IMAGE:
- return protocol::Page::ResourceTypeEnum::Image;
+ return protocol::Network::ResourceTypeEnum::Image;
case RESOURCE_TYPE_FONT_RESOURCE:
- return protocol::Page::ResourceTypeEnum::Font;
+ return protocol::Network::ResourceTypeEnum::Font;
case RESOURCE_TYPE_SUB_RESOURCE:
- return protocol::Page::ResourceTypeEnum::Other;
+ return protocol::Network::ResourceTypeEnum::Other;
case RESOURCE_TYPE_OBJECT:
- return protocol::Page::ResourceTypeEnum::Other;
+ return protocol::Network::ResourceTypeEnum::Other;
case RESOURCE_TYPE_MEDIA:
- return protocol::Page::ResourceTypeEnum::Media;
+ return protocol::Network::ResourceTypeEnum::Media;
case RESOURCE_TYPE_WORKER:
- return protocol::Page::ResourceTypeEnum::Other;
+ return protocol::Network::ResourceTypeEnum::Other;
case RESOURCE_TYPE_SHARED_WORKER:
- return protocol::Page::ResourceTypeEnum::Other;
+ return protocol::Network::ResourceTypeEnum::Other;
case RESOURCE_TYPE_PREFETCH:
- return protocol::Page::ResourceTypeEnum::Fetch;
+ return protocol::Network::ResourceTypeEnum::Fetch;
case RESOURCE_TYPE_FAVICON:
- return protocol::Page::ResourceTypeEnum::Other;
+ return protocol::Network::ResourceTypeEnum::Other;
case RESOURCE_TYPE_XHR:
- return protocol::Page::ResourceTypeEnum::XHR;
+ return protocol::Network::ResourceTypeEnum::XHR;
case RESOURCE_TYPE_PING:
- return protocol::Page::ResourceTypeEnum::Ping;
+ return protocol::Network::ResourceTypeEnum::Ping;
case RESOURCE_TYPE_SERVICE_WORKER:
- return protocol::Page::ResourceTypeEnum::Other;
+ return protocol::Network::ResourceTypeEnum::Other;
case RESOURCE_TYPE_CSP_REPORT:
- return protocol::Page::ResourceTypeEnum::CSPViolationReport;
+ return protocol::Network::ResourceTypeEnum::CSPViolationReport;
case RESOURCE_TYPE_PLUGIN_RESOURCE:
- return protocol::Page::ResourceTypeEnum::Other;
+ return protocol::Network::ResourceTypeEnum::Other;
default:
- return protocol::Page::ResourceTypeEnum::Other;
+ return protocol::Network::ResourceTypeEnum::Other;
}
}
diff --git a/chromium/content/browser/devtools/protocol/page_handler.cc b/chromium/content/browser/devtools/protocol/page_handler.cc
index 92d78224bbe..2f0ea698213 100644
--- a/chromium/content/browser/devtools/protocol/page_handler.cc
+++ b/chromium/content/browser/devtools/protocol/page_handler.cc
@@ -23,7 +23,7 @@
#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
-#include "content/browser/devtools/devtools_session.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/protocol/devtools_download_manager_delegate.h"
#include "content/browser/devtools/protocol/devtools_download_manager_helper.h"
#include "content/browser/devtools/protocol/emulation_handler.h"
@@ -34,7 +34,7 @@
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_view.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
@@ -175,16 +175,11 @@ void GetMetadataFromFrame(const media::VideoFrame& frame,
media::VideoFrameMetadata::ROOT_SCROLL_OFFSET_X, &root_scroll_offset_x);
success &= frame.metadata()->GetDouble(
media::VideoFrameMetadata::ROOT_SCROLL_OFFSET_Y, &root_scroll_offset_y);
-#if defined(OS_ANDROID)
success &= frame.metadata()->GetDouble(
media::VideoFrameMetadata::TOP_CONTROLS_HEIGHT, top_controls_height);
success &= frame.metadata()->GetDouble(
media::VideoFrameMetadata::TOP_CONTROLS_SHOWN_RATIO,
top_controls_shown_ratio);
-#else
- *top_controls_height = 0.;
- *top_controls_shown_ratio = 0.;
-#endif // defined(OS_ANDROID)
DCHECK(success);
root_scroll_offset->set_x(root_scroll_offset_x);
@@ -193,7 +188,8 @@ void GetMetadataFromFrame(const media::VideoFrame& frame,
} // namespace
-PageHandler::PageHandler(EmulationHandler* emulation_handler)
+PageHandler::PageHandler(EmulationHandler* emulation_handler,
+ bool allow_set_download_behavior)
: DevToolsDomainHandler(Page::Metainfo::domainName),
enabled_(false),
screencast_enabled_(false),
@@ -210,6 +206,7 @@ PageHandler::PageHandler(EmulationHandler* emulation_handler)
last_surface_size_(gfx::Size()),
host_(nullptr),
emulation_handler_(emulation_handler),
+ allow_set_download_behavior_(allow_set_download_behavior),
observer_(this),
weak_factory_(this) {
bool create_video_consumer = true;
@@ -247,8 +244,7 @@ std::vector<PageHandler*> PageHandler::EnabledForWebContents(
// static
std::vector<PageHandler*> PageHandler::ForAgentHost(
DevToolsAgentHostImpl* host) {
- return DevToolsSession::HandlersForAgentHost<PageHandler>(
- host, Page::Metainfo::domainName);
+ return host->HandlersByName<PageHandler>(Page::Metainfo::domainName);
}
void PageHandler::SetRenderer(int process_host_id,
@@ -404,7 +400,7 @@ Response PageHandler::Close() {
WebContentsImpl* web_contents = GetWebContents();
if (!web_contents)
return Response::Error("Not attached to a page");
- web_contents->DispatchBeforeUnload();
+ web_contents->DispatchBeforeUnload(false /* auto_cancel */);
return Response::OK();
}
@@ -448,6 +444,8 @@ void PageHandler::Navigate(const std::string& url,
type = ui::PAGE_TRANSITION_LINK;
else if (transition_type == Page::TransitionTypeEnum::Typed)
type = ui::PAGE_TRANSITION_TYPED;
+ else if (transition_type == Page::TransitionTypeEnum::Address_bar)
+ type = ui::PAGE_TRANSITION_FROM_ADDRESS_BAR;
else if (transition_type == Page::TransitionTypeEnum::Auto_bookmark)
type = ui::PAGE_TRANSITION_AUTO_BOOKMARK;
else if (transition_type == Page::TransitionTypeEnum::Auto_subframe)
@@ -605,7 +603,8 @@ void PageHandler::CaptureScreenshot(
Maybe<Page::Viewport> clip,
Maybe<bool> from_surface,
std::unique_ptr<CaptureScreenshotCallback> callback) {
- if (!host_ || !host_->GetRenderWidgetHost()) {
+ if (!host_ || !host_->GetRenderWidgetHost() ||
+ !host_->GetRenderWidgetHost()->GetView()) {
callback->sendFailure(Response::InternalError());
return;
}
@@ -791,7 +790,8 @@ Response PageHandler::StartScreencast(Maybe<std::string> format,
if (has_compositor_frame_metadata_) {
InnerSwapCompositorFrame();
} else {
- widget_host->Send(new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), 0));
+ widget_host->Send(
+ new WidgetMsg_ForceRedraw(widget_host->GetRoutingID(), 0));
}
return Response::FallThrough();
}
@@ -857,6 +857,9 @@ Response PageHandler::BringToFront() {
Response PageHandler::SetDownloadBehavior(const std::string& behavior,
Maybe<std::string> download_path) {
+ if (!allow_set_download_behavior_)
+ return Response::Error("Not allowed.");
+
WebContentsImpl* web_contents = GetWebContents();
if (!web_contents)
return Response::InternalError();
@@ -945,13 +948,11 @@ void PageHandler::InnerSwapCompositorFrame() {
if (snapshot_size.IsEmpty())
return;
- double top_controls_height = 0.;
- double top_controls_shown_ratio = 0.;
-#if defined(OS_ANDROID)
- top_controls_height = last_compositor_frame_metadata_.top_controls_height;
- top_controls_shown_ratio =
+ double top_controls_height =
+ last_compositor_frame_metadata_.top_controls_height;
+ double top_controls_shown_ratio =
last_compositor_frame_metadata_.top_controls_shown_ratio;
-#endif
+
std::unique_ptr<Page::ScreencastFrameMetadata> page_metadata =
BuildScreencastFrameMetadata(
surface_size, last_compositor_frame_metadata_.device_scale_factor,
diff --git a/chromium/content/browser/devtools/protocol/page_handler.h b/chromium/content/browser/devtools/protocol/page_handler.h
index ea8e3b17f31..ba523ccc282 100644
--- a/chromium/content/browser/devtools/protocol/page_handler.h
+++ b/chromium/content/browser/devtools/protocol/page_handler.h
@@ -58,7 +58,7 @@ class PageHandler : public DevToolsDomainHandler,
public Page::Backend,
public RenderWidgetHostObserver {
public:
- explicit PageHandler(EmulationHandler* handler);
+ PageHandler(EmulationHandler* handler, bool allow_set_download_behavior);
~PageHandler() override;
static std::vector<PageHandler*> EnabledForWebContents(
@@ -212,6 +212,7 @@ class PageHandler : public DevToolsDomainHandler,
RenderFrameHostImpl* host_;
EmulationHandler* emulation_handler_;
+ bool allow_set_download_behavior_;
std::unique_ptr<Page::Frontend> frontend_;
ScopedObserver<RenderWidgetHost, RenderWidgetHostObserver> observer_;
JavaScriptDialogCallback pending_dialog_;
diff --git a/chromium/content/browser/devtools/protocol/security_handler.cc b/chromium/content/browser/devtools/protocol/security_handler.cc
index bdc3c63acb8..29e074d4c76 100644
--- a/chromium/content/browser/devtools/protocol/security_handler.cc
+++ b/chromium/content/browser/devtools/protocol/security_handler.cc
@@ -10,7 +10,7 @@
#include <vector>
#include "base/base64.h"
-#include "content/browser/devtools/devtools_session.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
@@ -104,8 +104,7 @@ void AddExplanations(
// static
std::vector<SecurityHandler*> SecurityHandler::ForAgentHost(
DevToolsAgentHostImpl* host) {
- return DevToolsSession::HandlersForAgentHost<SecurityHandler>(
- host, Security::Metainfo::domainName);
+ return host->HandlersByName<SecurityHandler>(Security::Metainfo::domainName);
}
SecurityHandler::SecurityHandler()
diff --git a/chromium/content/browser/devtools/protocol/service_worker_handler.cc b/chromium/content/browser/devtools/protocol/service_worker_handler.cc
index 06c7cf436fd..0164e28d6f4 100644
--- a/chromium/content/browser/devtools/protocol/service_worker_handler.cc
+++ b/chromium/content/browser/devtools/protocol/service_worker_handler.cc
@@ -8,6 +8,7 @@
#include "base/containers/flat_set.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "content/browser/background_sync/background_sync_context.h"
#include "content/browser/background_sync/background_sync_manager.h"
#include "content/browser/devtools/service_worker_devtools_agent_host.h"
@@ -22,6 +23,7 @@
#include "content/browser/storage_partition_impl_map.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/render_process_host.h"
@@ -89,8 +91,8 @@ void GetDevToolsRouteInfoOnIO(
const base::Callback<void(int, int)>& callback) {
if (content::ServiceWorkerVersion* version =
context->GetLiveVersion(version_id)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
callback, version->embedded_worker()->process_id(),
version->embedded_worker()->worker_devtools_agent_route_id()));
@@ -173,6 +175,7 @@ void ServiceWorkerHandler::SetRenderer(int process_host_id,
storage_partition_ =
static_cast<StoragePartitionImpl*>(process_host->GetStoragePartition());
DCHECK(storage_partition_);
+ browser_context_ = process_host->GetBrowserContext();
context_ = static_cast<ServiceWorkerContextWrapper*>(
storage_partition_->GetServiceWorkerContext());
}
@@ -243,8 +246,9 @@ Response ServiceWorkerHandler::StopWorker(const std::string& version_id) {
int64_t id = 0;
if (!base::StringToInt64(version_id, &id))
return CreateInvalidVersionIdErrorResponse();
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&StopServiceWorkerOnIO, context_, id));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&StopServiceWorkerOnIO, context_, id));
return Response::OK();
}
@@ -281,8 +285,8 @@ Response ServiceWorkerHandler::InspectWorker(const std::string& version_id) {
int64_t id = blink::mojom::kInvalidServiceWorkerVersionId;
if (!base::StringToInt64(version_id, &id))
return CreateInvalidVersionIdErrorResponse();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&GetDevToolsRouteInfoOnIO, context_, id,
base::Bind(&ServiceWorkerHandler::OpenNewDevToolsWindow,
weak_factory_.GetWeakPtr())));
@@ -334,10 +338,10 @@ Response ServiceWorkerHandler::DispatchSyncEvent(
BackgroundSyncContext* sync_context =
storage_partition_->GetBackgroundSyncContext();
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&DispatchSyncEventOnIO, context_,
- base::WrapRefCounted(sync_context),
- GURL(origin), id, tag, last_chance));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&DispatchSyncEventOnIO, context_,
+ base::WrapRefCounted(sync_context),
+ GURL(origin), id, tag, last_chance));
return Response::OK();
}
diff --git a/chromium/content/browser/devtools/protocol/storage_handler.cc b/chromium/content/browser/devtools/protocol/storage_handler.cc
index ad5bb6d37ed..436be9bb7ff 100644
--- a/chromium/content/browser/devtools/protocol/storage_handler.cc
+++ b/chromium/content/browser/devtools/protocol/storage_handler.cc
@@ -10,8 +10,10 @@
#include <vector>
#include "base/strings/string_split.h"
+#include "base/task/post_task.h"
#include "content/browser/cache_storage/cache_storage_context_impl.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
@@ -76,19 +78,19 @@ void GotUsageAndQuotaDataCallback(
int64_t quota,
base::flat_map<storage::QuotaClient::ID, int64_t> usage_breakdown) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(ReportUsageAndQuotaDataOnUIThread, std::move(callback),
code, usage, quota, std::move(usage_breakdown)));
}
void GetUsageAndQuotaOnIOThread(
storage::QuotaManager* manager,
- const GURL& url,
+ const url::Origin& origin,
std::unique_ptr<StorageHandler::GetUsageAndQuotaCallback> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
manager->GetUsageAndQuotaWithBreakdown(
- url, blink::mojom::StorageType::kTemporary,
+ origin, blink::mojom::StorageType::kTemporary,
base::BindOnce(&GotUsageAndQuotaDataCallback, std::move(callback)));
}
} // namespace
@@ -103,8 +105,8 @@ class StorageHandler::CacheStorageObserver : CacheStorageContextImpl::Observer {
CacheStorageObserver(base::WeakPtr<StorageHandler> owner_storage_handler,
CacheStorageContextImpl* cache_storage_context)
: owner_(owner_storage_handler), context_(cache_storage_context) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CacheStorageObserver::AddObserverOnIOThread,
base::Unretained(this)));
}
@@ -130,8 +132,8 @@ class StorageHandler::CacheStorageObserver : CacheStorageContextImpl::Observer {
auto found = origins_.find(origin);
if (found == origins_.end())
return;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&StorageHandler::NotifyCacheStorageListChanged, owner_,
origin.Serialize()));
}
@@ -140,8 +142,8 @@ class StorageHandler::CacheStorageObserver : CacheStorageContextImpl::Observer {
const std::string& cache_name) override {
if (origins_.find(origin) == origins_.end())
return;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&StorageHandler::NotifyCacheStorageContentChanged,
owner_, origin.Serialize(), cache_name));
}
@@ -198,8 +200,8 @@ class StorageHandler::IndexedDBObserver : IndexedDBContextImpl::Observer {
auto found = origins_.find(origin);
if (found == origins_.end())
return;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&StorageHandler::NotifyIndexedDBListChanged, owner_,
origin.Serialize()));
}
@@ -211,8 +213,8 @@ class StorageHandler::IndexedDBObserver : IndexedDBContextImpl::Observer {
auto found = origins_.find(origin);
if (found == origins_.end())
return;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&StorageHandler::NotifyIndexedDBContentChanged, owner_,
origin.Serialize(), database_name, object_store_name));
}
@@ -330,10 +332,10 @@ void StorageHandler::GetUsageAndQuota(
}
storage::QuotaManager* manager = storage_partition_->GetQuotaManager();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&GetUsageAndQuotaOnIOThread, base::RetainedRef(manager),
- origin_url, std::move(callback)));
+ url::Origin::Create(origin_url), std::move(callback)));
}
Response StorageHandler::TrackCacheStorageForOrigin(const std::string& origin) {
@@ -344,8 +346,8 @@ Response StorageHandler::TrackCacheStorageForOrigin(const std::string& origin) {
if (!origin_url.is_valid())
return Response::InvalidParams(origin + " is not a valid URL");
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CacheStorageObserver::TrackOriginOnIOThread,
base::Unretained(GetCacheStorageObserver()),
url::Origin::Create(origin_url)));
@@ -361,8 +363,8 @@ Response StorageHandler::UntrackCacheStorageForOrigin(
if (!origin_url.is_valid())
return Response::InvalidParams(origin + " is not a valid URL");
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CacheStorageObserver::UntrackOriginOnIOThread,
base::Unretained(GetCacheStorageObserver()),
url::Origin::Create(origin_url)));
diff --git a/chromium/content/browser/devtools/protocol/system_info_handler.cc b/chromium/content/browser/devtools/protocol/system_info_handler.cc
index c0c84ef83f8..def5f6bf0ee 100644
--- a/chromium/content/browser/devtools/protocol/system_info_handler.cc
+++ b/chromium/content/browser/devtools/protocol/system_info_handler.cc
@@ -11,10 +11,12 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
+#include "content/public/browser/browser_task_traits.h"
#include "gpu/config/gpu_feature_type.h"
#include "gpu/config/gpu_info.h"
#include "gpu/config/gpu_switches.h"
@@ -88,6 +90,10 @@ class AuxGPUInfoEnumerator : public gpu::GPUInfo::Enumerator {
void EndOverlayCapability() override {}
+ void BeginDx12VulkanVersionInfo() override {}
+
+ void EndDx12VulkanVersionInfo() override {}
+
void BeginAuxAttributes() override {
in_aux_attributes_ = true;
}
@@ -164,8 +170,8 @@ class SystemInfoHandlerGpuObserver : public content::GpuDataManagerObserver {
std::unique_ptr<GetInfoCallback> callback)
: callback_(std::move(callback)),
weak_factory_(this) {
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SystemInfoHandlerGpuObserver::ObserverWatchdogCallback,
weak_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(kGPUInfoWatchdogTimeoutMs));
diff --git a/chromium/content/browser/devtools/protocol/target_handler.cc b/chromium/content/browser/devtools/protocol/target_handler.cc
index f24ac4f28e2..3e03ef9164e 100644
--- a/chromium/content/browser/devtools/protocol/target_handler.cc
+++ b/chromium/content/browser/devtools/protocol/target_handler.cc
@@ -13,8 +13,8 @@
#include "base/values.h"
#include "build/build_config.h"
#include "content/browser/devtools/browser_devtools_agent_host.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/devtools_manager.h"
-#include "content/browser/devtools/devtools_session.h"
#include "content/browser/devtools/target_registry.h"
#include "content/browser/frame_host/navigation_handle_impl.h"
#include "content/public/browser/browser_context.h"
@@ -27,6 +27,8 @@ namespace protocol {
namespace {
+const char kNotAllowedError[] = "Not allowed.";
+
static const char kInitializerScript[] = R"(
(function() {
const bindingName = "%s";
@@ -99,14 +101,37 @@ base::LazyInstance<base::flat_map<DevToolsAgentHost*,
std::unique_ptr<BrowserToPageConnector>>>::
Leaky g_browser_to_page_connectors;
-class BrowserToPageConnector : public DevToolsAgentHostClient {
+class BrowserToPageConnector {
public:
+ class BrowserConnectorHostClient : public DevToolsAgentHostClient {
+ public:
+ BrowserConnectorHostClient(BrowserToPageConnector* connector,
+ DevToolsAgentHost* host)
+ : connector_(connector) {
+ // TODO(dgozman): handle return value of AttachClient.
+ host->AttachClient(this);
+ }
+ void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
+ const std::string& message) override {
+ connector_->DispatchProtocolMessage(agent_host, message);
+ }
+ void AgentHostClosed(DevToolsAgentHost* agent_host) override {
+ connector_->AgentHostClosed(agent_host);
+ }
+
+ private:
+ BrowserToPageConnector* connector_;
+ DISALLOW_COPY_AND_ASSIGN(BrowserConnectorHostClient);
+ };
+
BrowserToPageConnector(const std::string& binding_name,
DevToolsAgentHost* page_host)
: binding_name_(binding_name), page_host_(page_host) {
browser_host_ = BrowserDevToolsAgentHost::CreateForDiscovery();
- browser_host_->AttachClient(this);
- page_host_->AttachClient(this);
+ browser_host_client_ =
+ std::make_unique<BrowserConnectorHostClient>(this, browser_host_.get());
+ page_host_client_ =
+ std::make_unique<BrowserConnectorHostClient>(this, page_host_.get());
SendProtocolMessageToPage("Page.enable", std::make_unique<base::Value>());
SendProtocolMessageToPage("Runtime.enable",
@@ -143,11 +168,11 @@ class BrowserToPageConnector : public DevToolsAgentHostClient {
message.Set("params", std::move(params));
std::string json_message;
base::JSONWriter::Write(message, &json_message);
- page_host_->DispatchProtocolMessage(this, json_message);
+ page_host_->DispatchProtocolMessage(page_host_client_.get(), json_message);
}
void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
- const std::string& message) override {
+ const std::string& message) {
if (agent_host == page_host_.get()) {
std::unique_ptr<base::Value> value = base::JSONReader::Read(message);
if (!value || !value->is_dict())
@@ -166,7 +191,8 @@ class BrowserToPageConnector : public DevToolsAgentHostClient {
base::Value* payload = params->FindKey("payload");
if (!payload || !payload->is_string())
return;
- browser_host_->DispatchProtocolMessage(this, payload->GetString());
+ browser_host_->DispatchProtocolMessage(browser_host_client_.get(),
+ payload->GetString());
return;
}
DCHECK(agent_host == browser_host_.get());
@@ -185,12 +211,12 @@ class BrowserToPageConnector : public DevToolsAgentHostClient {
SendProtocolMessageToPage("Runtime.evaluate", std::move(params));
}
- void AgentHostClosed(DevToolsAgentHost* agent_host) override {
+ void AgentHostClosed(DevToolsAgentHost* agent_host) {
if (agent_host == browser_host_.get()) {
- page_host_->DetachClient(this);
+ page_host_->DetachClient(page_host_client_.get());
} else {
DCHECK(agent_host == page_host_.get());
- browser_host_->DetachClient(this);
+ browser_host_->DetachClient(browser_host_client_.get());
}
g_browser_to_page_connectors.Get().erase(page_host_.get());
}
@@ -198,6 +224,8 @@ class BrowserToPageConnector : public DevToolsAgentHostClient {
std::string binding_name_;
scoped_refptr<DevToolsAgentHost> browser_host_;
scoped_refptr<DevToolsAgentHost> page_host_;
+ std::unique_ptr<BrowserConnectorHostClient> browser_host_client_;
+ std::unique_ptr<BrowserConnectorHostClient> page_host_client_;
int page_message_id_ = 0;
DISALLOW_COPY_AND_ASSIGN(BrowserToPageConnector);
@@ -391,7 +419,7 @@ void TargetHandler::Throttle::Clear() {
}
}
-TargetHandler::TargetHandler(bool browser_only,
+TargetHandler::TargetHandler(AccessMode access_mode,
const std::string& owner_target_id,
TargetRegistry* target_registry)
: DevToolsDomainHandler(Target::Metainfo::domainName),
@@ -399,7 +427,7 @@ TargetHandler::TargetHandler(bool browser_only,
base::Bind(&TargetHandler::AutoAttach, base::Unretained(this)),
base::Bind(&TargetHandler::AutoDetach, base::Unretained(this))),
discover_(false),
- browser_only_(browser_only),
+ access_mode_(access_mode),
owner_target_id_(owner_target_id),
target_registry_(target_registry),
weak_factory_(this) {}
@@ -410,8 +438,7 @@ TargetHandler::~TargetHandler() {
// static
std::vector<TargetHandler*> TargetHandler::ForAgentHost(
DevToolsAgentHostImpl* host) {
- return DevToolsSession::HandlersForAgentHost<TargetHandler>(
- host, Target::Metainfo::domainName);
+ return host->HandlersByName<TargetHandler>(Target::Metainfo::domainName);
}
void TargetHandler::Wire(UberDispatcher* dispatcher) {
@@ -470,7 +497,7 @@ Response TargetHandler::FindSession(Maybe<std::string> session_id,
Session** session,
bool fall_through) {
*session = nullptr;
- fall_through &= !browser_only_;
+ fall_through &= access_mode_ != AccessMode::kBrowser;
if (session_id.isJust()) {
auto it = attached_sessions_.find(session_id.fromJust());
if (it == attached_sessions_.end()) {
@@ -504,6 +531,8 @@ Response TargetHandler::FindSession(Maybe<std::string> session_id,
// ----------------- Protocol ----------------------
Response TargetHandler::SetDiscoverTargets(bool discover) {
+ if (access_mode_ == AccessMode::kAutoAttachOnly)
+ return Response::Error(kNotAllowedError);
if (discover_ == discover)
return Response::OK();
discover_ = discover;
@@ -519,11 +548,16 @@ Response TargetHandler::SetDiscoverTargets(bool discover) {
Response TargetHandler::SetAutoAttach(bool auto_attach,
bool wait_for_debugger_on_start,
Maybe<bool> flatten) {
+ if (flatten.fromMaybe(false) && !target_registry_) {
+ return Response::InvalidParams(
+ "Will only provide flatten access for browser endpoint");
+ }
flatten_auto_attach_ = flatten.fromMaybe(false);
auto_attacher_.SetAutoAttach(auto_attach, wait_for_debugger_on_start);
if (!auto_attacher_.ShouldThrottleFramesNavigation())
ClearThrottles();
- return browser_only_ ? Response::OK() : Response::FallThrough();
+ return access_mode_ == AccessMode::kBrowser ? Response::OK()
+ : Response::FallThrough();
}
Response TargetHandler::SetRemoteLocations(
@@ -534,6 +568,8 @@ Response TargetHandler::SetRemoteLocations(
Response TargetHandler::AttachToTarget(const std::string& target_id,
Maybe<bool> flatten,
std::string* out_session_id) {
+ if (access_mode_ == AccessMode::kAutoAttachOnly)
+ return Response::Error(kNotAllowedError);
// TODO(dgozman): only allow reported hosts.
scoped_refptr<DevToolsAgentHost> agent_host =
DevToolsAgentHost::GetForId(target_id);
@@ -549,6 +585,8 @@ Response TargetHandler::AttachToTarget(const std::string& target_id,
}
Response TargetHandler::AttachToBrowserTarget(std::string* out_session_id) {
+ if (access_mode_ != AccessMode::kBrowser)
+ return Response::Error(kNotAllowedError);
scoped_refptr<DevToolsAgentHost> agent_host =
DevToolsAgentHost::CreateForBrowser(
nullptr, DevToolsAgentHost::CreateServerSocketCallback());
@@ -558,6 +596,8 @@ Response TargetHandler::AttachToBrowserTarget(std::string* out_session_id) {
Response TargetHandler::DetachFromTarget(Maybe<std::string> session_id,
Maybe<std::string> target_id) {
+ if (access_mode_ == AccessMode::kAutoAttachOnly)
+ return Response::Error(kNotAllowedError);
Session* session = nullptr;
Response response =
FindSession(std::move(session_id), std::move(target_id), &session, false);
@@ -587,6 +627,8 @@ Response TargetHandler::SendMessageToTarget(const std::string& message,
Response TargetHandler::GetTargetInfo(
Maybe<std::string> maybe_target_id,
std::unique_ptr<Target::TargetInfo>* target_info) {
+ if (access_mode_ == AccessMode::kAutoAttachOnly)
+ return Response::Error(kNotAllowedError);
const std::string& target_id =
maybe_target_id.isJust() ? maybe_target_id.fromJust() : owner_target_id_;
// TODO(dgozman): only allow reported hosts.
@@ -599,6 +641,8 @@ Response TargetHandler::GetTargetInfo(
}
Response TargetHandler::ActivateTarget(const std::string& target_id) {
+ if (access_mode_ == AccessMode::kAutoAttachOnly)
+ return Response::Error(kNotAllowedError);
// TODO(dgozman): only allow reported hosts.
scoped_refptr<DevToolsAgentHost> agent_host(
DevToolsAgentHost::GetForId(target_id));
@@ -610,6 +654,8 @@ Response TargetHandler::ActivateTarget(const std::string& target_id) {
Response TargetHandler::CloseTarget(const std::string& target_id,
bool* out_success) {
+ if (access_mode_ == AccessMode::kAutoAttachOnly)
+ return Response::Error(kNotAllowedError);
scoped_refptr<DevToolsAgentHost> agent_host =
DevToolsAgentHost::GetForId(target_id);
if (!agent_host)
@@ -621,10 +667,8 @@ Response TargetHandler::CloseTarget(const std::string& target_id,
Response TargetHandler::ExposeDevToolsProtocol(
const std::string& target_id,
Maybe<std::string> binding_name) {
- if (!browser_only_) {
- return Response::InvalidParams(
- "Cannot grant remote debugging capability from non-browser session.");
- }
+ if (access_mode_ != AccessMode::kBrowser)
+ return Response::InvalidParams(kNotAllowedError);
scoped_refptr<DevToolsAgentHost> agent_host =
DevToolsAgentHost::GetForId(target_id);
if (!agent_host)
@@ -650,6 +694,8 @@ Response TargetHandler::CreateTarget(const std::string& url,
Maybe<std::string> context_id,
Maybe<bool> enable_begin_frame_control,
std::string* out_target_id) {
+ if (access_mode_ == AccessMode::kAutoAttachOnly)
+ return Response::Error(kNotAllowedError);
DevToolsManagerDelegate* delegate =
DevToolsManager::GetInstance()->delegate();
if (!delegate)
@@ -664,6 +710,8 @@ Response TargetHandler::CreateTarget(const std::string& url,
Response TargetHandler::GetTargets(
std::unique_ptr<protocol::Array<Target::TargetInfo>>* target_infos) {
+ if (access_mode_ == AccessMode::kAutoAttachOnly)
+ return Response::Error(kNotAllowedError);
*target_infos = protocol::Array<Target::TargetInfo>::create();
for (const auto& host : DevToolsAgentHost::GetOrCreateAll())
(*target_infos)->addItem(CreateInfo(host.get()));
@@ -720,8 +768,12 @@ void TargetHandler::DevToolsAgentHostCrashed(DevToolsAgentHost* host,
: 0);
}
+// ----------------- More protocol methods -------------------
+
protocol::Response TargetHandler::CreateBrowserContext(
std::string* out_context_id) {
+ if (access_mode_ != AccessMode::kBrowser)
+ return Response::Error(kNotAllowedError);
DevToolsManagerDelegate* delegate =
DevToolsManager::GetInstance()->delegate();
if (!delegate)
@@ -730,11 +782,13 @@ protocol::Response TargetHandler::CreateBrowserContext(
if (!context)
return Response::Error("Failed to create browser context.");
*out_context_id = context->UniqueId();
- return protocol::Response::OK();
+ return Response::OK();
}
protocol::Response TargetHandler::GetBrowserContexts(
std::unique_ptr<protocol::Array<protocol::String>>* browser_context_ids) {
+ if (access_mode_ != AccessMode::kBrowser)
+ return Response::Error(kNotAllowedError);
DevToolsManagerDelegate* delegate =
DevToolsManager::GetInstance()->delegate();
if (!delegate)
@@ -744,17 +798,21 @@ protocol::Response TargetHandler::GetBrowserContexts(
*browser_context_ids = std::make_unique<protocol::Array<protocol::String>>();
for (auto* context : contexts)
(*browser_context_ids)->addItem(context->UniqueId());
- return protocol::Response::OK();
+ return Response::OK();
}
void TargetHandler::DisposeBrowserContext(
const std::string& context_id,
std::unique_ptr<DisposeBrowserContextCallback> callback) {
+ if (access_mode_ != AccessMode::kBrowser) {
+ callback->sendFailure(Response::Error(kNotAllowedError));
+ return;
+ }
DevToolsManagerDelegate* delegate =
DevToolsManager::GetInstance()->delegate();
if (!delegate) {
- callback->sendFailure(protocol::Response::Error(
- "Browser context management is not supported."));
+ callback->sendFailure(
+ Response::Error("Browser context management is not supported."));
return;
}
std::vector<content::BrowserContext*> contexts =
@@ -765,8 +823,8 @@ void TargetHandler::DisposeBrowserContext(
return context->UniqueId() == context_id;
});
if (context_it == contexts.end()) {
- callback->sendFailure(protocol::Response::Error(
- "Failed to find context with id " + context_id));
+ callback->sendFailure(
+ Response::Error("Failed to find context with id " + context_id));
return;
}
delegate->DisposeBrowserContext(
@@ -777,7 +835,7 @@ void TargetHandler::DisposeBrowserContext(
if (success)
callback->sendSuccess();
else
- callback->sendFailure(protocol::Response::Error(error));
+ callback->sendFailure(Response::Error(error));
},
std::move(callback)));
}
diff --git a/chromium/content/browser/devtools/protocol/target_handler.h b/chromium/content/browser/devtools/protocol/target_handler.h
index 06a9bbb9ca5..d7e449411c4 100644
--- a/chromium/content/browser/devtools/protocol/target_handler.h
+++ b/chromium/content/browser/devtools/protocol/target_handler.h
@@ -29,7 +29,17 @@ class TargetHandler : public DevToolsDomainHandler,
public Target::Backend,
public DevToolsAgentHostObserver {
public:
- TargetHandler(bool browser_only,
+ enum class AccessMode {
+ // Only setAutoAttach is supported. Any non-related target are not
+ // accessible.
+ kAutoAttachOnly,
+ // Standard mode of operation: both auto-attach and discovery.
+ kRegular,
+ // This mode also allows advanced method like Target.exposeDevToolsProtocol,
+ // which should not be exposed on a non-browser-wide connection.
+ kBrowser
+ };
+ TargetHandler(AccessMode access_mode,
const std::string& owner_target_id,
TargetRegistry* target_registry);
~TargetHandler() override;
@@ -115,7 +125,7 @@ class TargetHandler : public DevToolsDomainHandler,
std::map<std::string, std::unique_ptr<Session>> attached_sessions_;
std::map<DevToolsAgentHost*, Session*> auto_attached_sessions_;
std::set<DevToolsAgentHost*> reported_hosts_;
- bool browser_only_;
+ AccessMode access_mode_;
std::string owner_target_id_;
TargetRegistry* target_registry_;
base::flat_set<Throttle*> throttles_;
diff --git a/chromium/content/browser/devtools/protocol/tethering_handler.cc b/chromium/content/browser/devtools/protocol/tethering_handler.cc
index 4640abe9ff0..66f0dac1f6b 100644
--- a/chromium/content/browser/devtools/protocol/tethering_handler.cc
+++ b/chromium/content/browser/devtools/protocol/tethering_handler.cc
@@ -6,6 +6,8 @@
#include <map>
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_address.h"
@@ -105,7 +107,7 @@ class SocketPump {
void Pump(net::StreamSocket* from, net::StreamSocket* to) {
scoped_refptr<net::IOBuffer> buffer =
- new net::IOBuffer(kSocketPumpBufferSize);
+ base::MakeRefCounted<net::IOBuffer>(kSocketPumpBufferSize);
int result =
from->Read(buffer.get(), kSocketPumpBufferSize,
base::BindOnce(&SocketPump::OnRead, base::Unretained(this),
@@ -285,8 +287,8 @@ TetheringHandler::TetheringImpl::~TetheringImpl() = default;
void TetheringHandler::TetheringImpl::Bind(
uint16_t port, std::unique_ptr<BindCallback> callback) {
if (bound_sockets_.find(port) != bound_sockets_.end()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&BindCallback::sendFailure, std::move(callback),
Response::Error("Port already bound")));
return;
@@ -297,16 +299,16 @@ void TetheringHandler::TetheringImpl::Bind(
std::unique_ptr<BoundSocket> bound_socket =
std::make_unique<BoundSocket>(std::move(accepted), socket_callback_);
if (!bound_socket->Listen(port)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&BindCallback::sendFailure, std::move(callback),
Response::Error("Could not bind port")));
return;
}
bound_sockets_[port] = std::move(bound_socket);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&BindCallback::sendSuccess, std::move(callback)));
}
@@ -314,23 +316,23 @@ void TetheringHandler::TetheringImpl::Unbind(
uint16_t port, std::unique_ptr<UnbindCallback> callback) {
auto it = bound_sockets_.find(port);
if (it == bound_sockets_.end()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&UnbindCallback::sendFailure, std::move(callback),
Response::InvalidParams("Port is not bound")));
return;
}
bound_sockets_.erase(it);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&UnbindCallback::sendSuccess, std::move(callback)));
}
void TetheringHandler::TetheringImpl::Accepted(uint16_t port,
const std::string& name) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&TetheringHandler::Accepted, handler_, port, name));
}
diff --git a/chromium/content/browser/devtools/protocol/tracing_handler.cc b/chromium/content/browser/devtools/protocol/tracing_handler.cc
index a93a43faa7c..fd1dcd82417 100644
--- a/chromium/content/browser/devtools/protocol/tracing_handler.cc
+++ b/chromium/content/browser/devtools/protocol/tracing_handler.cc
@@ -18,15 +18,16 @@
#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event_impl.h"
#include "base/trace_event/tracing_agent.h"
#include "components/tracing/common/trace_startup_config.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/devtools_frame_trace_recorder.h"
#include "content/browser/devtools/devtools_io_context.h"
-#include "content/browser/devtools/devtools_session.h"
#include "content/browser/devtools/devtools_stream_file.h"
#include "content/browser/devtools/devtools_traceable_screenshot.h"
#include "content/browser/devtools/devtools_video_consumer.h"
@@ -37,6 +38,7 @@
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/tracing/tracing_controller_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
#include "services/tracing/public/mojom/constants.mojom.h"
@@ -134,8 +136,8 @@ class DevToolsStreamEndpoint : public TracingController::TraceDataEndpoint {
void ReceiveTraceChunk(std::unique_ptr<std::string> chunk) override {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DevToolsStreamEndpoint::ReceiveTraceChunk, this,
std::move(chunk)));
return;
@@ -147,8 +149,8 @@ class DevToolsStreamEndpoint : public TracingController::TraceDataEndpoint {
void ReceiveTraceFinalContents(
std::unique_ptr<const base::DictionaryValue> metadata) override {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DevToolsStreamEndpoint::ReceiveTraceFinalContents,
this, std::move(metadata)));
return;
@@ -235,8 +237,7 @@ TracingHandler::~TracingHandler() = default;
// static
std::vector<TracingHandler*> TracingHandler::ForAgentHost(
DevToolsAgentHostImpl* host) {
- return DevToolsSession::HandlersForAgentHost<TracingHandler>(
- host, Tracing::Metainfo::domainName);
+ return host->HandlersByName<TracingHandler>(Tracing::Metainfo::domainName);
}
void TracingHandler::SetRenderer(int process_host_id,
@@ -406,8 +407,8 @@ void TracingHandler::Start(Maybe<std::string> categories,
}
// GPU process id can only be retrieved on IO thread. Do some thread hopping.
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::IO, FROM_HERE, base::BindOnce([]() {
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::IO}, base::BindOnce([]() {
GpuProcessHost* gpu_process_host =
GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
/* force_create */ false);
@@ -431,9 +432,9 @@ void TracingHandler::StartTracingWithGpuPid(
SetupProcessFilter(gpu_pid, nullptr);
TracingController::GetInstance()->StartTracing(
- trace_config_, base::BindRepeating(&TracingHandler::OnRecordingEnabled,
- weak_factory_.GetWeakPtr(),
- base::Passed(std::move(callback))));
+ trace_config_,
+ base::BindOnce(&TracingHandler::OnRecordingEnabled,
+ weak_factory_.GetWeakPtr(), std::move(callback)));
}
void TracingHandler::SetupProcessFilter(
@@ -484,7 +485,7 @@ void TracingHandler::OnProcessReady(RenderProcessHost* process_host) {
base::trace_event::TraceConfig::ProcessFilterConfig(
included_process_ids));
TracingController::GetInstance()->StartTracing(
- trace_config_, base::RepeatingCallback<void()>());
+ trace_config_, TracingController::StartTracingDoneCallback());
}
Response TracingHandler::End() {
@@ -518,9 +519,8 @@ Response TracingHandler::End() {
void TracingHandler::GetCategories(
std::unique_ptr<GetCategoriesCallback> callback) {
TracingController::GetInstance()->GetCategories(
- base::Bind(&TracingHandler::OnCategoriesReceived,
- weak_factory_.GetWeakPtr(),
- base::Passed(std::move(callback))));
+ base::BindOnce(&TracingHandler::OnCategoriesReceived,
+ weak_factory_.GetWeakPtr(), std::move(callback)));
}
void TracingHandler::OnRecordingEnabled(
@@ -573,8 +573,8 @@ void TracingHandler::RequestMemoryDump(
}
auto on_memory_dump_finished =
- base::Bind(&TracingHandler::OnMemoryDumpFinished,
- weak_factory_.GetWeakPtr(), base::Passed(std::move(callback)));
+ base::BindOnce(&TracingHandler::OnMemoryDumpFinished,
+ weak_factory_.GetWeakPtr(), std::move(callback));
memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDumpAndAppendToTrace(
base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED,
@@ -684,7 +684,7 @@ void TracingHandler::ReadyToCommitNavigation(
SetupProcessFilter(base::kNullProcessId,
navigation_handle->GetRenderFrameHost());
TracingController::GetInstance()->StartTracing(
- trace_config_, base::RepeatingCallback<void()>());
+ trace_config_, TracingController::StartTracingDoneCallback());
}
void TracingHandler::FrameDeleted(RenderFrameHostImpl* frame_host) {
diff --git a/chromium/content/browser/devtools/protocol_config.json b/chromium/content/browser/devtools/protocol_config.json
index 1c779296c95..98c9cee7ec0 100644
--- a/chromium/content/browser/devtools/protocol_config.json
+++ b/chromium/content/browser/devtools/protocol_config.json
@@ -11,7 +11,7 @@
"options": [
{
"domain": "Browser",
- "include": ["getVersion", "getHistograms", "getHistogram", "getBrowserCommandLine", "grantPermissions", "resetPermissions"]
+ "include": ["getVersion", "getHistograms", "getHistogram", "getBrowserCommandLine", "grantPermissions", "resetPermissions", "crash"]
},
{
"domain": "DOM",
diff --git a/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc b/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc
index f80fb077ae0..7c9bfca5847 100644
--- a/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -11,11 +11,13 @@
#include "base/lazy_instance.h"
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/devtools_frame_trace_recorder.h"
#include "content/browser/devtools/devtools_manager.h"
+#include "content/browser/devtools/devtools_renderer_channel.h"
#include "content/browser/devtools/devtools_session.h"
#include "content/browser/devtools/protocol/browser_handler.h"
#include "content/browser/devtools/protocol/dom_handler.h"
@@ -43,6 +45,7 @@
#include "content/browser/web_package/signed_exchange_envelope.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/navigation_handle.h"
@@ -56,6 +59,7 @@
#include "net/ssl/ssl_info.h"
#include "services/network/public/cpp/features.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/web/devtools_agent.mojom.h"
#if defined(OS_ANDROID)
#include "content/browser/renderer_host/compositor_impl_android.h"
@@ -209,7 +213,7 @@ void RenderFrameDevToolsAgentHost::OnNavigationResponseReceived(
std::string frame_id = ftn->devtools_frame_token().ToString();
GURL url = nav_request.common_params().url;
DispatchToAgents(ftn, &protocol::NetworkHandler::ResponseReceived, id, id,
- url, protocol::Page::ResourceTypeEnum::Document,
+ url, protocol::Network::ResourceTypeEnum::Document,
response.head, frame_id);
}
@@ -220,7 +224,7 @@ void RenderFrameDevToolsAgentHost::OnNavigationRequestFailed(
FrameTreeNode* ftn = nav_request.frame_tree_node();
std::string id = nav_request.devtools_navigation_token().ToString();
DispatchToAgents(ftn, &protocol::NetworkHandler::LoadingComplete, id,
- protocol::Page::ResourceTypeEnum::Document, status);
+ protocol::Network::ResourceTypeEnum::Document, status);
}
// static
@@ -261,7 +265,7 @@ void RenderFrameDevToolsAgentHost::OnSignedExchangeCertificateResponseReceived(
const network::ResourceResponseHead& head) {
DispatchToAgents(frame_tree_node, &protocol::NetworkHandler::ResponseReceived,
request_id.ToString(), loader_id.ToString(), url,
- protocol::Page::ResourceTypeEnum::Other, head,
+ protocol::Network::ResourceTypeEnum::Other, head,
protocol::Maybe<std::string>());
}
@@ -272,7 +276,7 @@ void RenderFrameDevToolsAgentHost::OnSignedExchangeCertificateRequestCompleted(
const network::URLLoaderCompletionStatus& status) {
DispatchToAgents(frame_tree_node, &protocol::NetworkHandler::LoadingComplete,
request_id.ToString(),
- protocol::Page::ResourceTypeEnum::Other, status);
+ protocol::Network::ResourceTypeEnum::Other, status);
}
// static
@@ -427,13 +431,9 @@ WebContents* RenderFrameDevToolsAgentHost::GetWebContents() {
bool RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session,
TargetRegistry* registry) {
- if (!ShouldAllowSession(session, frame_host_))
+ if (!ShouldAllowSession(session))
return false;
- session->SetRenderer(frame_host_ ? frame_host_->GetProcess()->GetID()
- : ChildProcessHost::kInvalidUniqueID,
- frame_host_);
-
protocol::EmulationHandler* emulation_handler =
new protocol::EmulationHandler();
session->AddHandler(base::WrapUnique(new protocol::BrowserHandler()));
@@ -452,22 +452,20 @@ bool RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session,
session->AddHandler(base::WrapUnique(new protocol::SchemaHandler()));
session->AddHandler(base::WrapUnique(new protocol::ServiceWorkerHandler()));
session->AddHandler(base::WrapUnique(new protocol::StorageHandler()));
- if (!session->restricted()) {
- session->AddHandler(base::WrapUnique(new protocol::TargetHandler(
- false /* browser_only */, GetId(), registry)));
- }
- session->AddHandler(
- base::WrapUnique(new protocol::PageHandler(emulation_handler)));
+ session->AddHandler(base::WrapUnique(new protocol::TargetHandler(
+ session->client()->MayDiscoverTargets()
+ ? protocol::TargetHandler::AccessMode::kRegular
+ : protocol::TargetHandler::AccessMode::kAutoAttachOnly,
+ GetId(), registry)));
+ session->AddHandler(base::WrapUnique(new protocol::PageHandler(
+ emulation_handler, session->client()->MayAffectLocalFiles())));
session->AddHandler(base::WrapUnique(new protocol::SecurityHandler()));
if (!frame_tree_node_ || !frame_tree_node_->parent()) {
session->AddHandler(base::WrapUnique(
new protocol::TracingHandler(frame_tree_node_, GetIOContext())));
}
- if (EnsureAgent())
- session->AttachToAgent(agent_ptr_);
-
- if (sessions().size() == 1) {
+ if (sessions().empty()) {
bool use_video_capture_api = true;
#ifdef OS_ANDROID
// Video capture API cannot be used on Android WebView.
@@ -515,9 +513,7 @@ void RenderFrameDevToolsAgentHost::InspectElement(RenderFrameHost* frame_host,
view->TransformRootPointToViewCoordSpace(gfx::PointF(point)));
}
}
-
- if (host->EnsureAgent())
- host->agent_ptr_->InspectElement(point);
+ host->GetRendererChannel()->InspectElement(point);
}
RenderFrameDevToolsAgentHost::~RenderFrameDevToolsAgentHost() {
@@ -574,7 +570,7 @@ void RenderFrameDevToolsAgentHost::UpdateFrameHost(
render_frame_alive_ = true;
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
inspector->TargetReloadedAfterCrash();
- MaybeReattachToRenderFrame();
+ UpdateRendererChannel(IsAttached());
}
return;
}
@@ -589,11 +585,10 @@ void RenderFrameDevToolsAgentHost::UpdateFrameHost(
RevokePolicy();
frame_host_ = frame_host;
- agent_ptr_.reset();
std::vector<DevToolsSession*> restricted_sessions;
for (DevToolsSession* session : sessions()) {
- if (!ShouldAllowSession(session, frame_host))
+ if (!ShouldAllowSession(session))
restricted_sessions.push_back(session);
}
if (!restricted_sessions.empty())
@@ -605,21 +600,9 @@ void RenderFrameDevToolsAgentHost::UpdateFrameHost(
inspector->TargetReloadedAfterCrash();
}
- if (IsAttached()) {
+ if (IsAttached())
GrantPolicy();
- for (DevToolsSession* session : sessions()) {
- session->SetRenderer(frame_host ? frame_host->GetProcess()->GetID() : -1,
- frame_host);
- }
- MaybeReattachToRenderFrame();
- }
-}
-
-void RenderFrameDevToolsAgentHost::MaybeReattachToRenderFrame() {
- if (!EnsureAgent())
- return;
- for (DevToolsSession* session : sessions())
- session->AttachToAgent(agent_ptr_);
+ UpdateRendererChannel(IsAttached());
}
void RenderFrameDevToolsAgentHost::GrantPolicy() {
@@ -693,7 +676,7 @@ void RenderFrameDevToolsAgentHost::FrameDeleted(RenderFrameHost* rfh) {
void RenderFrameDevToolsAgentHost::RenderFrameDeleted(RenderFrameHost* rfh) {
if (rfh == frame_host_) {
render_frame_alive_ = false;
- agent_ptr_.reset();
+ UpdateRendererChannel(IsAttached());
}
}
@@ -703,7 +686,7 @@ void RenderFrameDevToolsAgentHost::DestroyOnRenderFrameGone() {
RevokePolicy();
ForceDetachAllSessions();
frame_host_ = nullptr;
- agent_ptr_.reset();
+ UpdateRendererChannel(IsAttached());
SetFrameTreeNode(nullptr);
Release();
}
@@ -912,8 +895,8 @@ void RenderFrameDevToolsAgentHost::SignalSynchronousSwapCompositorFrame(
static_cast<RenderFrameHostImpl*>(frame_host)->frame_tree_node()));
if (dtah) {
// Unblock the compositor.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&RenderFrameDevToolsAgentHost::SynchronousSwapCompositorFrame,
dtah.get(), std::move(frame_metadata)));
@@ -936,12 +919,19 @@ void RenderFrameDevToolsAgentHost::SynchronousSwapCompositorFrame(
}
}
-bool RenderFrameDevToolsAgentHost::EnsureAgent() {
- if (!frame_host_ || !render_frame_alive_)
- return false;
- if (!agent_ptr_)
- frame_host_->GetRemoteAssociatedInterfaces()->GetInterface(&agent_ptr_);
- return true;
+void RenderFrameDevToolsAgentHost::UpdateRendererChannel(bool force) {
+ blink::mojom::DevToolsAgentAssociatedPtr agent_ptr;
+ blink::mojom::DevToolsAgentHostAssociatedRequest host_request;
+ if (frame_host_ && render_frame_alive_ && force) {
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host_ptr_info;
+ host_request = mojo::MakeRequest(&host_ptr_info);
+ frame_host_->BindDevToolsAgent(std::move(host_ptr_info),
+ mojo::MakeRequest(&agent_ptr));
+ }
+ int process_id = frame_host_ ? frame_host_->GetProcess()->GetID()
+ : ChildProcessHost::kInvalidUniqueID;
+ GetRendererChannel()->SetRenderer(
+ std::move(agent_ptr), std::move(host_request), process_id, frame_host_);
}
bool RenderFrameDevToolsAgentHost::IsChildFrame() {
@@ -949,16 +939,15 @@ bool RenderFrameDevToolsAgentHost::IsChildFrame() {
}
bool RenderFrameDevToolsAgentHost::ShouldAllowSession(
- DevToolsSession* session,
- RenderFrameHostImpl* frame_host) {
+ DevToolsSession* session) {
DevToolsManager* manager = DevToolsManager::GetInstance();
- if (manager->delegate() && frame_host) {
- if (!manager->delegate()->AllowInspectingRenderFrameHost(frame_host))
+ if (manager->delegate() && frame_host_) {
+ if (!manager->delegate()->AllowInspectingRenderFrameHost(frame_host_))
return false;
}
const bool is_webui =
- frame_host && (frame_host->web_ui() || frame_host->pending_web_ui());
- if (!session->client()->MayAttachToRenderer(frame_host, is_webui))
+ frame_host_ && (frame_host_->web_ui() || frame_host_->pending_web_ui());
+ if (!session->client()->MayAttachToRenderer(frame_host_, is_webui))
return false;
return true;
}
diff --git a/chromium/content/browser/devtools/render_frame_devtools_agent_host.h b/chromium/content/browser/devtools/render_frame_devtools_agent_host.h
index 37f0c8d1e77..42907088fe1 100644
--- a/chromium/content/browser/devtools/render_frame_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -21,7 +21,6 @@
#include "content/public/browser/web_contents_observer.h"
#include "net/base/net_errors.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
-#include "third_party/blink/public/web/devtools_agent.mojom.h"
#if defined(OS_ANDROID)
#include "services/device/public/mojom/wake_lock.mojom.h"
@@ -165,6 +164,7 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
TargetRegistry* registry) override;
void DetachSession(DevToolsSession* session) override;
void InspectElement(RenderFrameHost* frame_host, int x, int y) override;
+ void UpdateRendererChannel(bool force) override;
// WebContentsObserver overrides.
void DidStartNavigation(NavigationHandle* navigation_handle) override;
@@ -185,13 +185,11 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
void OnSwapCompositorFrame(const IPC::Message& message);
void DestroyOnRenderFrameGone();
void UpdateFrameHost(RenderFrameHostImpl* frame_host);
- void MaybeReattachToRenderFrame();
void GrantPolicy();
void RevokePolicy();
void SetFrameTreeNode(FrameTreeNode* frame_tree_node);
- bool ShouldAllowSession(DevToolsSession* session,
- RenderFrameHostImpl* frame_host);
+ bool ShouldAllowSession(DevToolsSession* session);
#if defined(OS_ANDROID)
device::mojom::WakeLock* GetWakeLock();
@@ -199,7 +197,6 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
void SynchronousSwapCompositorFrame(
viz::CompositorFrameMetadata frame_metadata);
- bool EnsureAgent();
std::unique_ptr<DevToolsFrameTraceRecorder> frame_trace_recorder_;
#if defined(OS_ANDROID)
@@ -208,7 +205,6 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
// The active host we are talking to.
RenderFrameHostImpl* frame_host_ = nullptr;
- blink::mojom::DevToolsAgentAssociatedPtr agent_ptr_;
base::flat_set<NavigationHandleImpl*> navigation_handles_;
bool render_frame_alive_ = false;
diff --git a/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc b/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc
index 32f191e75cc..c610a3730b2 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc
@@ -5,6 +5,8 @@
#include "content/browser/devtools/service_worker_devtools_agent_host.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
+#include "content/browser/devtools/devtools_renderer_channel.h"
#include "content/browser/devtools/devtools_session.h"
#include "content/browser/devtools/protocol/inspector_handler.h"
#include "content/browser/devtools/protocol/network_handler.h"
@@ -13,6 +15,7 @@
#include "content/browser/devtools/service_worker_devtools_manager.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_version.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
@@ -91,8 +94,8 @@ void ServiceWorkerDevToolsAgentHost::Reload() {
}
bool ServiceWorkerDevToolsAgentHost::Close() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&TerminateServiceWorkerOnIO, context_weak_, version_id_));
return true;
}
@@ -117,46 +120,33 @@ ServiceWorkerDevToolsAgentHost::~ServiceWorkerDevToolsAgentHost() {
bool ServiceWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session,
TargetRegistry* registry) {
- if (state_ == WORKER_READY) {
- if (sessions().size() == 1) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&SetDevToolsAttachedOnIO,
- context_weak_, version_id_, true));
- }
- session->SetRenderer(worker_process_id_, nullptr);
- session->AttachToAgent(agent_ptr_);
- }
session->AddHandler(base::WrapUnique(new protocol::InspectorHandler()));
session->AddHandler(base::WrapUnique(new protocol::NetworkHandler(
GetId(), devtools_worker_token_, GetIOContext())));
session->AddHandler(base::WrapUnique(new protocol::SchemaHandler()));
+ if (state_ == WORKER_READY && sessions().empty())
+ UpdateIsAttached(true);
return true;
}
void ServiceWorkerDevToolsAgentHost::DetachSession(DevToolsSession* session) {
// Destroying session automatically detaches in renderer.
- if (state_ == WORKER_READY && sessions().empty()) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&SetDevToolsAttachedOnIO,
- context_weak_, version_id_, false));
- }
+ if (state_ == WORKER_READY && sessions().empty())
+ UpdateIsAttached(false);
}
void ServiceWorkerDevToolsAgentHost::WorkerReadyForInspection(
+ blink::mojom::DevToolsAgentHostAssociatedRequest host_request,
blink::mojom::DevToolsAgentAssociatedPtrInfo devtools_agent_ptr_info) {
DCHECK_EQ(WORKER_NOT_READY, state_);
state_ = WORKER_READY;
- agent_ptr_.Bind(std::move(devtools_agent_ptr_info));
- if (!sessions().empty()) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&SetDevToolsAttachedOnIO,
- context_weak_, version_id_, true));
- }
-
- for (DevToolsSession* session : sessions()) {
- session->SetRenderer(worker_process_id_, nullptr);
- session->AttachToAgent(agent_ptr_);
- }
+ blink::mojom::DevToolsAgentAssociatedPtr agent_ptr;
+ agent_ptr.Bind(std::move(devtools_agent_ptr_info));
+ GetRendererChannel()->SetRenderer(std::move(agent_ptr),
+ std::move(host_request), worker_process_id_,
+ nullptr);
+ if (!sessions().empty())
+ UpdateIsAttached(true);
}
void ServiceWorkerDevToolsAgentHost::WorkerRestarted(int worker_process_id,
@@ -167,18 +157,24 @@ void ServiceWorkerDevToolsAgentHost::WorkerRestarted(int worker_process_id,
worker_route_id_ = worker_route_id;
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
inspector->TargetReloadedAfterCrash();
- for (DevToolsSession* session : sessions())
- session->SetRenderer(worker_process_id_, nullptr);
}
void ServiceWorkerDevToolsAgentHost::WorkerDestroyed() {
DCHECK_NE(WORKER_TERMINATED, state_);
state_ = WORKER_TERMINATED;
- agent_ptr_.reset();
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
inspector->TargetCrashed();
- for (DevToolsSession* session : sessions())
- session->SetRenderer(-1, nullptr);
+ GetRendererChannel()->SetRenderer(
+ nullptr, nullptr, ChildProcessHost::kInvalidUniqueID, nullptr);
+ if (!sessions().empty())
+ UpdateIsAttached(false);
+}
+
+void ServiceWorkerDevToolsAgentHost::UpdateIsAttached(bool attached) {
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&SetDevToolsAttachedOnIO, context_weak_, version_id_,
+ attached));
}
} // namespace content
diff --git a/chromium/content/browser/devtools/service_worker_devtools_agent_host.h b/chromium/content/browser/devtools/service_worker_devtools_agent_host.h
index b2612093058..0b0d0a2bbef 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/service_worker_devtools_agent_host.h
@@ -46,13 +46,9 @@ class ServiceWorkerDevToolsAgentHost : public DevToolsAgentHostImpl {
void Reload() override;
bool Close() override;
- // DevToolsAgentHostImpl overrides.
- bool AttachSession(DevToolsSession* session,
- TargetRegistry* registry) override;
- void DetachSession(DevToolsSession* session) override;
-
void WorkerRestarted(int worker_process_id, int worker_route_id);
void WorkerReadyForInspection(
+ blink::mojom::DevToolsAgentHostAssociatedRequest host_request,
blink::mojom::DevToolsAgentAssociatedPtrInfo devtools_agent_ptr_info);
void WorkerDestroyed();
void WorkerVersionInstalled();
@@ -77,6 +73,12 @@ class ServiceWorkerDevToolsAgentHost : public DevToolsAgentHostImpl {
private:
~ServiceWorkerDevToolsAgentHost() override;
+ void UpdateIsAttached(bool attached);
+
+ // DevToolsAgentHostImpl overrides.
+ bool AttachSession(DevToolsSession* session,
+ TargetRegistry* registry) override;
+ void DetachSession(DevToolsSession* session) override;
enum WorkerState {
WORKER_NOT_READY,
@@ -94,7 +96,6 @@ class ServiceWorkerDevToolsAgentHost : public DevToolsAgentHostImpl {
GURL scope_;
base::Time version_installed_time_;
base::Time version_doomed_time_;
- blink::mojom::DevToolsAgentAssociatedPtr agent_ptr_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDevToolsAgentHost);
};
diff --git a/chromium/content/browser/devtools/service_worker_devtools_manager.cc b/chromium/content/browser/devtools/service_worker_devtools_manager.cc
index 60007e08358..a91474c696a 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_manager.cc
+++ b/chromium/content/browser/devtools/service_worker_devtools_manager.cc
@@ -91,6 +91,7 @@ void ServiceWorkerDevToolsManager::WorkerCreated(
void ServiceWorkerDevToolsManager::WorkerReadyForInspection(
int worker_process_id,
int worker_route_id,
+ blink::mojom::DevToolsAgentHostAssociatedRequest host_request,
blink::mojom::DevToolsAgentAssociatedPtrInfo devtools_agent_ptr_info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
const WorkerId worker_id(worker_process_id, worker_route_id);
@@ -98,7 +99,8 @@ void ServiceWorkerDevToolsManager::WorkerReadyForInspection(
if (it == live_hosts_.end())
return;
scoped_refptr<ServiceWorkerDevToolsAgentHost> host = it->second;
- host->WorkerReadyForInspection(std::move(devtools_agent_ptr_info));
+ host->WorkerReadyForInspection(std::move(host_request),
+ std::move(devtools_agent_ptr_info));
// Bring up UI for the ones not picked by other clients.
if (debug_service_worker_on_start_ && !host->IsAttached())
host->Inspect();
@@ -205,7 +207,7 @@ void ServiceWorkerDevToolsManager::NavigationPreloadResponseReceived(
return;
for (auto* network : protocol::NetworkHandler::ForAgentHost(it->second.get()))
network->ResponseReceived(request_id, std::string(), url,
- protocol::Page::ResourceTypeEnum::Other, head,
+ protocol::Network::ResourceTypeEnum::Other, head,
protocol::Maybe<std::string>());
}
@@ -219,8 +221,8 @@ void ServiceWorkerDevToolsManager::NavigationPreloadCompleted(
if (it == live_hosts_.end())
return;
for (auto* network : protocol::NetworkHandler::ForAgentHost(it->second.get()))
- network->LoadingComplete(request_id,
- protocol::Page::ResourceTypeEnum::Other, status);
+ network->LoadingComplete(
+ request_id, protocol::Network::ResourceTypeEnum::Other, status);
}
} // namespace content
diff --git a/chromium/content/browser/devtools/service_worker_devtools_manager.h b/chromium/content/browser/devtools/service_worker_devtools_manager.h
index 0153f487adb..6745d910ccc 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_manager.h
+++ b/chromium/content/browser/devtools/service_worker_devtools_manager.h
@@ -71,6 +71,7 @@ class CONTENT_EXPORT ServiceWorkerDevToolsManager {
void WorkerReadyForInspection(
int worker_process_id,
int worker_route_id,
+ blink::mojom::DevToolsAgentHostAssociatedRequest host_request,
blink::mojom::DevToolsAgentAssociatedPtrInfo devtools_agent_ptr_info);
void WorkerVersionInstalled(int worker_process_id, int worker_route_id);
void WorkerVersionDoomed(int worker_process_id, int worker_route_id);
diff --git a/chromium/content/browser/devtools/shared_worker_devtools_agent_host.cc b/chromium/content/browser/devtools/shared_worker_devtools_agent_host.cc
index c09e04a0717..9d4dd11b83d 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/shared_worker_devtools_agent_host.cc
@@ -4,6 +4,7 @@
#include "content/browser/devtools/shared_worker_devtools_agent_host.h"
+#include "content/browser/devtools/devtools_renderer_channel.h"
#include "content/browser/devtools/devtools_session.h"
#include "content/browser/devtools/protocol/inspector_handler.h"
#include "content/browser/devtools/protocol/network_handler.h"
@@ -15,6 +16,7 @@
#include "content/browser/shared_worker/shared_worker_service_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
+#include "third_party/blink/public/web/devtools_agent.mojom.h"
namespace content {
@@ -72,9 +74,6 @@ bool SharedWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session,
session->AddHandler(std::make_unique<protocol::NetworkHandler>(
GetId(), devtools_worker_token_, GetIOContext()));
session->AddHandler(std::make_unique<protocol::SchemaHandler>());
- session->SetRenderer(worker_host_ ? worker_host_->process_id() : -1, nullptr);
- if (state_ == WORKER_READY)
- session->AttachToAgent(EnsureAgent());
return true;
}
@@ -90,8 +89,7 @@ void SharedWorkerDevToolsAgentHost::WorkerReadyForInspection() {
DCHECK_EQ(WORKER_NOT_READY, state_);
DCHECK(worker_host_);
state_ = WORKER_READY;
- for (DevToolsSession* session : sessions())
- session->AttachToAgent(EnsureAgent());
+ UpdateRendererChannel(IsAttached());
}
void SharedWorkerDevToolsAgentHost::WorkerRestarted(
@@ -102,8 +100,7 @@ void SharedWorkerDevToolsAgentHost::WorkerRestarted(
worker_host_ = worker_host;
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
inspector->TargetReloadedAfterCrash();
- for (DevToolsSession* session : sessions())
- session->SetRenderer(worker_host_->process_id(), nullptr);
+ UpdateRendererChannel(IsAttached());
}
void SharedWorkerDevToolsAgentHost::WorkerDestroyed() {
@@ -112,19 +109,25 @@ void SharedWorkerDevToolsAgentHost::WorkerDestroyed() {
state_ = WORKER_TERMINATED;
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
inspector->TargetCrashed();
- for (DevToolsSession* session : sessions())
- session->SetRenderer(-1, nullptr);
worker_host_ = nullptr;
- agent_ptr_.reset();
-}
-
-const blink::mojom::DevToolsAgentAssociatedPtr&
-SharedWorkerDevToolsAgentHost::EnsureAgent() {
- DCHECK_EQ(WORKER_READY, state_);
- DCHECK(worker_host_);
- if (!agent_ptr_)
- worker_host_->BindDevToolsAgent(mojo::MakeRequest(&agent_ptr_));
- return agent_ptr_;
+ UpdateRendererChannel(IsAttached());
+}
+
+void SharedWorkerDevToolsAgentHost::UpdateRendererChannel(bool force) {
+ if (state_ == WORKER_READY && force) {
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host_ptr_info;
+ blink::mojom::DevToolsAgentHostAssociatedRequest host_request =
+ mojo::MakeRequest(&host_ptr_info);
+ blink::mojom::DevToolsAgentAssociatedPtr agent_ptr;
+ worker_host_->BindDevToolsAgent(std::move(host_ptr_info),
+ mojo::MakeRequest(&agent_ptr));
+ GetRendererChannel()->SetRenderer(std::move(agent_ptr),
+ std::move(host_request),
+ worker_host_->process_id(), nullptr);
+ } else {
+ GetRendererChannel()->SetRenderer(
+ nullptr, nullptr, ChildProcessHost::kInvalidUniqueID, nullptr);
+ }
}
} // namespace content
diff --git a/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h b/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h
index c0a867de030..09a66d806c2 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h
@@ -8,7 +8,6 @@
#include "base/macros.h"
#include "base/unguessable_token.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
-#include "third_party/blink/public/web/devtools_agent.mojom.h"
namespace content {
@@ -32,11 +31,6 @@ class SharedWorkerDevToolsAgentHost : public DevToolsAgentHostImpl {
void Reload() override;
bool Close() override;
- // DevToolsAgentHostImpl overrides.
- bool AttachSession(DevToolsSession* session,
- TargetRegistry* registry) override;
- void DetachSession(DevToolsSession* session) override;
-
bool Matches(SharedWorkerHost* worker_host);
void WorkerReadyForInspection();
void WorkerRestarted(SharedWorkerHost* worker_host);
@@ -48,7 +42,12 @@ class SharedWorkerDevToolsAgentHost : public DevToolsAgentHostImpl {
private:
~SharedWorkerDevToolsAgentHost() override;
- const blink::mojom::DevToolsAgentAssociatedPtr& EnsureAgent();
+
+ // DevToolsAgentHostImpl overrides.
+ bool AttachSession(DevToolsSession* session,
+ TargetRegistry* registry) override;
+ void DetachSession(DevToolsSession* session) override;
+ void UpdateRendererChannel(bool force) override;
enum WorkerState {
WORKER_NOT_READY,
@@ -57,7 +56,6 @@ class SharedWorkerDevToolsAgentHost : public DevToolsAgentHostImpl {
};
WorkerState state_;
SharedWorkerHost* worker_host_;
- blink::mojom::DevToolsAgentAssociatedPtr agent_ptr_;
base::UnguessableToken devtools_worker_token_;
std::unique_ptr<SharedWorkerInstance> instance_;
diff --git a/chromium/content/browser/do_not_track_browsertest.cc b/chromium/content/browser/do_not_track_browsertest.cc
index 1aa00dc5b57..f6bfed9f741 100644
--- a/chromium/content/browser/do_not_track_browsertest.cc
+++ b/chromium/content/browser/do_not_track_browsertest.cc
@@ -79,6 +79,10 @@ class DoNotTrackTest : public ContentBrowserTest {
return value;
}
+ GURL GetURL(std::string relative_url) {
+ return embedded_test_server()->GetURL(relative_url);
+ }
+
private:
ContentBrowserClient* original_client_ = nullptr;
MockContentBrowserClient client_;
@@ -101,8 +105,7 @@ std::unique_ptr<net::test_server::HttpResponse> CaptureHeaderHandler(
// Checks that the DNT header is not sent by default.
IN_PROC_BROWSER_TEST_F(DoNotTrackTest, NotEnabled) {
ASSERT_TRUE(embedded_test_server()->Start());
- GURL url = embedded_test_server()->GetURL("/echoheader?DNT");
- EXPECT_TRUE(NavigateToURL(shell(), url));
+ EXPECT_TRUE(NavigateToURL(shell(), GetURL("/echoheader?DNT")));
ExpectPageTextEq("None");
// And the DOM property is not set.
EXPECT_EQ("", GetDOMDoNotTrackProperty());
@@ -113,17 +116,15 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest, Simple) {
ASSERT_TRUE(embedded_test_server()->Start());
if (!EnableDoNotTrack())
return;
- GURL url = embedded_test_server()->GetURL("/echoheader?DNT");
- EXPECT_TRUE(NavigateToURL(shell(), url));
+ EXPECT_TRUE(NavigateToURL(shell(), GetURL("/echoheader?DNT")));
ExpectPageTextEq("1");
}
// Checks that the DNT header is preserved during redirects.
IN_PROC_BROWSER_TEST_F(DoNotTrackTest, Redirect) {
ASSERT_TRUE(embedded_test_server()->Start());
- GURL final_url = embedded_test_server()->GetURL("/echoheader?DNT");
- GURL url = embedded_test_server()->GetURL(std::string("/server-redirect?") +
- final_url.spec());
+ GURL final_url = GetURL("/echoheader?DNT");
+ GURL url = GetURL("/server-redirect?" + final_url.spec());
if (!EnableDoNotTrack())
return;
// We don't check the result NavigateToURL as it returns true only if the
@@ -135,10 +136,9 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest, Redirect) {
// Checks that the DOM property is set when the corresponding preference is set.
IN_PROC_BROWSER_TEST_F(DoNotTrackTest, DOMProperty) {
ASSERT_TRUE(embedded_test_server()->Start());
- GURL url = embedded_test_server()->GetURL("/echo");
if (!EnableDoNotTrack())
return;
- EXPECT_TRUE(NavigateToURL(shell(), url));
+ EXPECT_TRUE(NavigateToURL(shell(), GetURL("/echo")));
EXPECT_EQ("1", GetDOMDoNotTrackProperty());
}
@@ -152,9 +152,8 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest, Worker) {
ASSERT_TRUE(embedded_test_server()->Start());
if (!EnableDoNotTrack())
return;
- const GURL url = embedded_test_server()->GetURL(
- std::string("/workers/create_worker.html?worker_url=/capture"));
- NavigateToURL(shell(), url);
+ NavigateToURL(shell(),
+ GetURL("/workers/create_worker.html?worker_url=/capture"));
loop.Run();
EXPECT_TRUE(header_map.find("DNT") != header_map.end());
@@ -177,9 +176,9 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest, MAYBE_SharedWorker) {
ASSERT_TRUE(embedded_test_server()->Start());
if (!EnableDoNotTrack())
return;
- const GURL url = embedded_test_server()->GetURL(
- std::string("/workers/create_shared_worker.html?worker_url=/capture"));
- NavigateToURL(shell(), url);
+ NavigateToURL(
+ shell(),
+ GetURL("/workers/create_shared_worker.html?worker_url=/capture"));
loop.Run();
EXPECT_TRUE(header_map.find("DNT") != header_map.end());
@@ -196,9 +195,10 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest, ServiceWorker) {
ASSERT_TRUE(embedded_test_server()->Start());
if (!EnableDoNotTrack())
return;
- const GURL url = embedded_test_server()->GetURL(std::string(
- "/service_worker/create_service_worker.html?worker_url=/capture"));
- NavigateToURL(shell(), url);
+ NavigateToURL(shell(), GetURL("/service_worker/create_service_worker.html"));
+ // We only verify the request for the worker script so we don't check the
+ // result of register().
+ EXPECT_TRUE(ExecJs(shell(), "register('/capture');"));
loop.Run();
EXPECT_TRUE(header_map.find("DNT") != header_map.end());
@@ -211,16 +211,8 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest, FetchFromWorker) {
ASSERT_TRUE(embedded_test_server()->Start());
if (!EnableDoNotTrack())
return;
- const GURL fetch_url = embedded_test_server()->GetURL("/echoheader?DNT");
- const GURL url = embedded_test_server()->GetURL(
- std::string("/workers/fetch_from_worker.html?url=") + fetch_url.spec());
- NavigateToURL(shell(), url);
-
- const base::string16 title = base::ASCIIToUTF16("DONE");
- TitleWatcher watcher(shell()->web_contents(), title);
- EXPECT_EQ(title, watcher.WaitAndGetTitle());
-
- ExpectPageTextEq("1");
+ NavigateToURL(shell(), GetURL("/workers/fetch_from_worker.html"));
+ EXPECT_EQ("1", EvalJs(shell(), "fetch_from_worker('/echoheader?DNT');"));
}
// Checks that the DNT header is preserved when fetching from a shared worker.
@@ -236,17 +228,10 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest, MAYBE_FetchFromSharedWorker) {
ASSERT_TRUE(embedded_test_server()->Start());
if (!EnableDoNotTrack())
return;
- const GURL fetch_url = embedded_test_server()->GetURL("/echoheader?DNT");
- const GURL url = embedded_test_server()->GetURL(
- std::string("/workers/fetch_from_shared_worker.html?url=") +
- fetch_url.spec());
- NavigateToURL(shell(), url);
-
- const base::string16 title = base::ASCIIToUTF16("DONE");
- TitleWatcher watcher(shell()->web_contents(), title);
- EXPECT_EQ(title, watcher.WaitAndGetTitle());
+ NavigateToURL(shell(), GetURL("/workers/fetch_from_shared_worker.html"));
- ExpectPageTextEq("1");
+ EXPECT_EQ("1",
+ EvalJs(shell(), "fetch_from_shared_worker('/echoheader?DNT');"));
}
// Checks that the DNT header is preserved when fetching from a service worker.
@@ -254,17 +239,12 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest, FetchFromServiceWorker) {
ASSERT_TRUE(embedded_test_server()->Start());
if (!EnableDoNotTrack())
return;
- const GURL fetch_url = embedded_test_server()->GetURL("/echoheader?DNT");
- const GURL url = embedded_test_server()->GetURL(
- std::string("/service_worker/fetch_from_service_worker.html?url=") +
- fetch_url.spec());
- NavigateToURL(shell(), url);
-
- const base::string16 title = base::ASCIIToUTF16("DONE");
- TitleWatcher watcher(shell()->web_contents(), title);
- EXPECT_EQ(title, watcher.WaitAndGetTitle());
+ NavigateToURL(shell(),
+ GetURL("/service_worker/fetch_from_service_worker.html"));
- ExpectPageTextEq("1");
+ EXPECT_EQ("ready", EvalJs(shell(), "setup();"));
+ EXPECT_EQ("1",
+ EvalJs(shell(), "fetch_from_service_worker('/echoheader?DNT');"));
}
// Checks that the DNT header is preserved when fetching from a page controlled
@@ -276,28 +256,15 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest,
if (!EnableDoNotTrack())
return;
- {
- // Register a service worker which controls /service_worker.
- const GURL url = embedded_test_server()->GetURL(
- "/service_worker/create_service_worker.html?"
- "worker_url=/service_worker/empty.js");
- EXPECT_TRUE(NavigateToURL(shell(), url));
- const base::string16 title = base::ASCIIToUTF16("DONE");
- TitleWatcher watcher(shell()->web_contents(), title);
- EXPECT_EQ(title, watcher.WaitAndGetTitle());
- }
-
- {
- // Issue a request from a controlled page.
- const GURL url = embedded_test_server()->GetURL(
- "/service_worker/fetch_from_page.html?url=/echoheader?DNT");
- EXPECT_TRUE(NavigateToURL(shell(), url));
- const base::string16 title = base::ASCIIToUTF16("DONE");
- TitleWatcher watcher(shell()->web_contents(), title);
- EXPECT_EQ(title, watcher.WaitAndGetTitle());
- }
+ // Register a service worker which controls /service_worker.
+ EXPECT_TRUE(NavigateToURL(
+ shell(), GetURL("/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE", EvalJs(shell(), "register('empty.js');"));
- ExpectPageTextEq("1");
+ // Issue a request from a controlled page.
+ EXPECT_TRUE(
+ NavigateToURL(shell(), GetURL("/service_worker/fetch_from_page.html")));
+ EXPECT_EQ("1", EvalJs(shell(), "fetch_from_page('/echoheader?DNT');"));
}
// Checks that the DNT header is preserved when fetching from a page controlled
@@ -308,28 +275,16 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest,
if (!EnableDoNotTrack())
return;
- {
- // Register a service worker which controls /service_worker.
- const GURL url = embedded_test_server()->GetURL(
- "/service_worker/create_service_worker.html?"
- "worker_url=/service_worker/fetch_event_pass_through.js");
- EXPECT_TRUE(NavigateToURL(shell(), url));
- const base::string16 title = base::ASCIIToUTF16("DONE");
- TitleWatcher watcher(shell()->web_contents(), title);
- EXPECT_EQ(title, watcher.WaitAndGetTitle());
- }
+ // Register a service worker which controls /service_worker.
+ EXPECT_TRUE(NavigateToURL(
+ shell(), GetURL("/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE",
+ EvalJs(shell(), "register('fetch_event_pass_through.js');"));
- {
- // Issue a request from a controlled page.
- const GURL url = embedded_test_server()->GetURL(
- "/service_worker/fetch_from_page.html?url=/echoheader?DNT");
- EXPECT_TRUE(NavigateToURL(shell(), url));
- const base::string16 title = base::ASCIIToUTF16("DONE");
- TitleWatcher watcher(shell()->web_contents(), title);
- EXPECT_EQ(title, watcher.WaitAndGetTitle());
- }
-
- ExpectPageTextEq("1");
+ // Issue a request from a controlled page.
+ EXPECT_TRUE(
+ NavigateToURL(shell(), GetURL("/service_worker/fetch_from_page.html")));
+ EXPECT_EQ("1", EvalJs(shell(), "fetch_from_page('/echoheader?DNT');"));
}
// Checks that the DNT header is preserved when fetching from a page controlled
@@ -340,28 +295,16 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest,
if (!EnableDoNotTrack())
return;
- {
- // Register a service worker which controls /service_worker.
- const GURL url = embedded_test_server()->GetURL(
- "/service_worker/create_service_worker.html?"
- "worker_url=/service_worker/fetch_event_respond_with_fetch.js");
- EXPECT_TRUE(NavigateToURL(shell(), url));
- const base::string16 title = base::ASCIIToUTF16("DONE");
- TitleWatcher watcher(shell()->web_contents(), title);
- EXPECT_EQ(title, watcher.WaitAndGetTitle());
- }
-
- {
- // Issue a request from a controlled page.
- const GURL url = embedded_test_server()->GetURL(
- "/service_worker/fetch_from_page.html?url=/echoheader?DNT");
- EXPECT_TRUE(NavigateToURL(shell(), url));
- const base::string16 title = base::ASCIIToUTF16("DONE");
- TitleWatcher watcher(shell()->web_contents(), title);
- EXPECT_EQ(title, watcher.WaitAndGetTitle());
- }
+ // Register a service worker which controls /service_worker.
+ EXPECT_TRUE(NavigateToURL(
+ shell(), GetURL("/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE",
+ EvalJs(shell(), "register('fetch_event_respond_with_fetch.js');"));
- ExpectPageTextEq("1");
+ // Issue a request from a controlled page.
+ EXPECT_TRUE(
+ NavigateToURL(shell(), GetURL("/service_worker/fetch_from_page.html")));
+ EXPECT_EQ("1", EvalJs(shell(), "fetch_from_page('/echoheader?DNT');"));
}
} // namespace
diff --git a/chromium/content/browser/dom_storage/dom_storage_area_unittest.cc b/chromium/content/browser/dom_storage/dom_storage_area_unittest.cc
index e4520d7c8a4..204d00895d3 100644
--- a/chromium/content/browser/dom_storage/dom_storage_area_unittest.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_area_unittest.cc
@@ -10,10 +10,10 @@
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
@@ -74,7 +74,7 @@ class DOMStorageAreaTest : public testing::Test {
}
private:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
};
class DOMStorageAreaParamTest : public DOMStorageAreaTest,
diff --git a/chromium/content/browser/dom_storage/dom_storage_context_impl.cc b/chromium/content/browser/dom_storage/dom_storage_context_impl.cc
index f8e1b0ec7ad..16c0e2835c5 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_impl.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_context_impl.cc
@@ -12,7 +12,6 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
-#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/guid.h"
#include "base/location.h"
@@ -28,7 +27,6 @@
#include "content/browser/dom_storage/dom_storage_namespace.h"
#include "content/browser/dom_storage/dom_storage_task_runner.h"
#include "content/browser/dom_storage/session_storage_database.h"
-#include "content/common/dom_storage/dom_storage_namespace_ids.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/public/browser/dom_storage_context.h"
#include "content/public/browser/local_storage_usage_info.h"
@@ -110,7 +108,7 @@ DOMStorageNamespace* DOMStorageContextImpl::GetStorageNamespace(
const std::string& namespace_id) {
if (is_shutdown_)
return nullptr;
- StorageNamespaceMap::iterator found = namespaces_.find(namespace_id);
+ auto found = namespaces_.find(namespace_id);
if (found == namespaces_.end())
return nullptr;
return found->second.get();
@@ -302,7 +300,7 @@ void DOMStorageContextImpl::CloneSessionNamespace(
return;
DCHECK(!existing_id.empty());
DCHECK(!new_id.empty());
- StorageNamespaceMap::iterator found = namespaces_.find(existing_id);
+ auto found = namespaces_.find(existing_id);
if (found != namespaces_.end()) {
namespaces_[new_id] = found->second->Clone(new_id);
return;
diff --git a/chromium/content/browser/dom_storage/dom_storage_context_impl_unittest.cc b/chromium/content/browser/dom_storage/dom_storage_context_impl_unittest.cc
index ffb4fc3abeb..1bdd28675ae 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_impl_unittest.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_context_impl_unittest.cc
@@ -7,9 +7,9 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/build_config.h"
@@ -58,7 +58,7 @@ class DOMStorageContextImplTest : public testing::Test {
}
protected:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
base::ScopedTempDir temp_dir_;
scoped_refptr<MockSpecialStoragePolicy> storage_policy_;
scoped_refptr<MockDOMStorageTaskRunner> task_runner_;
diff --git a/chromium/content/browser/dom_storage/dom_storage_context_wrapper.cc b/chromium/content/browser/dom_storage/dom_storage_context_wrapper.cc
index 1f5335f00de..ae4d0f92cbb 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_wrapper.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_context_wrapper.cc
@@ -28,6 +28,7 @@
#include "content/browser/dom_storage/local_storage_context_mojo.h"
#include "content/browser/dom_storage/session_storage_context_mojo.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/local_storage_usage_info.h"
@@ -46,7 +47,7 @@ const char kSessionStorageDirectory[] = "Session Storage";
void GetLegacyLocalStorageUsage(
const base::FilePath& directory,
scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner,
- const DOMStorageContext::GetLocalStorageUsageCallback& callback) {
+ DOMStorageContext::GetLocalStorageUsageCallback callback) {
std::vector<LocalStorageUsageInfo> infos;
base::FileEnumerator enumerator(directory, false,
base::FileEnumerator::FILES);
@@ -61,14 +62,14 @@ void GetLegacyLocalStorageUsage(
infos.push_back(info);
}
}
- reply_task_runner->PostTask(FROM_HERE,
- base::BindOnce(callback, std::move(infos)));
+ reply_task_runner->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), std::move(infos)));
}
void InvokeLocalStorageUsageCallbackHelper(
- const DOMStorageContext::GetLocalStorageUsageCallback& callback,
+ DOMStorageContext::GetLocalStorageUsageCallback callback,
std::unique_ptr<std::vector<LocalStorageUsageInfo>> infos) {
- callback.Run(*infos);
+ std::move(callback).Run(*infos);
}
void GetSessionStorageUsageHelper(
@@ -83,7 +84,7 @@ void GetSessionStorageUsageHelper(
void CollectLocalStorageUsage(
std::vector<LocalStorageUsageInfo>* out_info,
- base::Closure done_callback,
+ base::OnceClosure done_callback,
const std::vector<LocalStorageUsageInfo>& in_info) {
out_info->insert(out_info->end(), in_info.begin(), in_info.end());
std::move(done_callback).Run();
@@ -97,10 +98,10 @@ void GotMojoDeletionCallback(
void GotMojoLocalStorageUsage(
scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner,
- const DOMStorageContext::GetLocalStorageUsageCallback& callback,
+ DOMStorageContext::GetLocalStorageUsageCallback callback,
std::vector<LocalStorageUsageInfo> usage) {
- reply_task_runner->PostTask(FROM_HERE,
- base::BindOnce(callback, std::move(usage)));
+ reply_task_runner->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), std::move(usage)));
}
void GotMojoSessionStorageUsage(
@@ -147,7 +148,8 @@ DOMStorageContextWrapper::DOMStorageContextWrapper(
storage_dir = local_partition_path.AppendASCII(kLocalStorageDirectory);
// TODO(dmurph): Change this to a sequenced task runner after
// https://crbug.com/809255 is fixed.
- mojo_task_runner_ = BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+ mojo_task_runner_ =
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
mojo_state_ = new LocalStorageContextMojo(
mojo_task_runner_, connector, context_->task_runner(),
legacy_localstorage_path_, storage_dir, special_storage_policy);
@@ -185,13 +187,13 @@ DOMStorageContextWrapper::~DOMStorageContextWrapper() {
}
void DOMStorageContextWrapper::GetLocalStorageUsage(
- const GetLocalStorageUsageCallback& callback) {
+ GetLocalStorageUsageCallback callback) {
DCHECK(context_.get());
auto infos = std::make_unique<std::vector<LocalStorageUsageInfo>>();
auto* infos_ptr = infos.get();
base::RepeatingClosure got_local_storage_usage = base::BarrierClosure(
- 2, base::BindOnce(&InvokeLocalStorageUsageCallbackHelper, callback,
- std::move(infos)));
+ 2, base::BindOnce(&InvokeLocalStorageUsageCallbackHelper,
+ std::move(callback), std::move(infos)));
auto collect_callback = base::BindRepeating(
CollectLocalStorageUsage, infos_ptr, std::move(got_local_storage_usage));
// base::Unretained is safe here, because the mojo_state_ won't be deleted
diff --git a/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h b/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h
index ac7e069f4c7..17a2aa8d815 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h
+++ b/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h
@@ -14,6 +14,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
#include "components/services/leveldb/public/interfaces/leveldb.mojom.h"
#include "content/browser/dom_storage/dom_storage_context_impl.h"
#include "content/common/content_export.h"
@@ -57,8 +58,7 @@ class CONTENT_EXPORT DOMStorageContextWrapper
storage::SpecialStoragePolicy* special_storage_policy);
// DOMStorageContext implementation.
- void GetLocalStorageUsage(
- const GetLocalStorageUsageCallback& callback) override;
+ void GetLocalStorageUsage(GetLocalStorageUsageCallback callback) override;
void GetSessionStorageUsage(GetSessionStorageUsageCallback callback) override;
void DeleteLocalStorage(const GURL& origin,
base::OnceClosure callback) override;
@@ -143,7 +143,8 @@ class CONTENT_EXPORT DOMStorageContextWrapper
// Profile wasn't destructed. This map allows the restored session to re-use
// the SessionStorageNamespaceImpl objects that are still alive thanks to the
// sessions component.
- std::map<std::string, SessionStorageNamespaceImpl*> alive_namespaces_;
+ std::map<std::string, SessionStorageNamespaceImpl*> alive_namespaces_
+ GUARDED_BY(alive_namespaces_lock_);
mutable base::Lock alive_namespaces_lock_;
base::FilePath legacy_localstorage_path_;
diff --git a/chromium/content/browser/dom_storage/dom_storage_database.cc b/chromium/content/browser/dom_storage/dom_storage_database.cc
index 2609b896ee6..376f1ac5ea3 100644
--- a/chromium/content/browser/dom_storage/dom_storage_database.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_database.cc
@@ -81,7 +81,7 @@ bool DOMStorageDatabase::CommitChanges(bool clear_all_first,
bool did_delete = false;
bool did_insert = false;
- DOMStorageValuesMap::const_iterator it = changes.begin();
+ auto it = changes.begin();
for(; it != changes.end(); ++it) {
sql::Statement statement;
base::string16 key = it->first;
diff --git a/chromium/content/browser/dom_storage/dom_storage_database_unittest.cc b/chromium/content/browser/dom_storage/dom_storage_database_unittest.cc
index 7c83def70b8..de24b0f790a 100644
--- a/chromium/content/browser/dom_storage/dom_storage_database_unittest.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_database_unittest.cc
@@ -128,7 +128,7 @@ TEST(DOMStorageDatabaseTest, CloseEmptyDatabaseDeletesFile) {
{
DOMStorageDatabase db(file_name);
ASSERT_TRUE(db.CommitChanges(false, storage));
- DOMStorageValuesMap::iterator it = storage.begin();
+ auto it = storage.begin();
for (; it != storage.end(); ++it)
it->second = base::NullableString16();
ASSERT_TRUE(db.CommitChanges(false, storage));
diff --git a/chromium/content/browser/dom_storage/dom_storage_namespace.cc b/chromium/content/browser/dom_storage/dom_storage_namespace.cc
index d78f30fb98e..2f1f8559193 100644
--- a/chromium/content/browser/dom_storage/dom_storage_namespace.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_namespace.cc
@@ -98,7 +98,7 @@ void DOMStorageNamespace::DeleteSessionStorageOrigin(
}
void DOMStorageNamespace::PurgeMemory(bool aggressively) {
- AreaMap::iterator it = areas_.begin();
+ auto it = areas_.begin();
while (it != areas_.end()) {
const AreaHolder& holder = it->second;
@@ -148,7 +148,7 @@ void DOMStorageNamespace::Flush() {
DOMStorageNamespace::UsageStatistics DOMStorageNamespace::GetUsageStatistics()
const {
UsageStatistics stats = {0};
- for (AreaMap::const_iterator it = areas_.begin(); it != areas_.end(); ++it) {
+ for (auto it = areas_.begin(); it != areas_.end(); ++it) {
if (it->second.area_->map_memory_used()) {
stats.total_cache_size += it->second.area_->map_memory_used();
++stats.total_area_count;
@@ -182,7 +182,7 @@ int DOMStorageNamespace::GetAreaOpenCount(const url::Origin& origin) const {
DOMStorageNamespace::AreaHolder* DOMStorageNamespace::GetAreaHolder(
const url::Origin& origin) {
- AreaMap::iterator found = areas_.find(origin);
+ auto found = areas_.find(origin);
if (found == areas_.end())
return nullptr;
return &(found->second);
diff --git a/chromium/content/browser/dom_storage/session_storage_context_mojo.cc b/chromium/content/browser/dom_storage/session_storage_context_mojo.cc
index f64bab5bd63..e90a108e005 100644
--- a/chromium/content/browser/dom_storage/session_storage_context_mojo.cc
+++ b/chromium/content/browser/dom_storage/session_storage_context_mojo.cc
@@ -540,8 +540,7 @@ void SessionStorageContextMojo::RegisterShallowClonedNamespace(
}
}
- SessionStorageMetadata::NamespaceEntry namespace_entry =
- metadata_.GetOrCreateNamespaceEntry(new_namespace_id);
+ auto namespace_entry = metadata_.GetOrCreateNamespaceEntry(new_namespace_id);
metadata_.RegisterShallowClonedNamespace(source_namespace_entry,
namespace_entry, &save_operations);
database_->Write(std::move(save_operations),
diff --git a/chromium/content/browser/dom_storage/session_storage_database.cc b/chromium/content/browser/dom_storage/session_storage_database.cc
index 2a8d889e3a4..4c660ab4917 100644
--- a/chromium/content/browser/dom_storage/session_storage_database.cc
+++ b/chromium/content/browser/dom_storage/session_storage_database.cc
@@ -730,9 +730,7 @@ bool SessionStorageDatabase::ReadMap(const std::string& map_id,
void SessionStorageDatabase::WriteValuesToMap(const std::string& map_id,
const DOMStorageValuesMap& values,
leveldb::WriteBatch* batch) {
- for (DOMStorageValuesMap::const_iterator it = values.begin();
- it != values.end();
- ++it) {
+ for (auto it = values.begin(); it != values.end(); ++it) {
base::NullableString16 value = it->second;
std::string key = MapKey(map_id, base::UTF16ToUTF8(it->first));
if (value.is_null()) {
diff --git a/chromium/content/browser/dom_storage/session_storage_database.h b/chromium/content/browser/dom_storage/session_storage_database.h
index e1ec30e83d3..c541d532c8c 100644
--- a/chromium/content/browser/dom_storage/session_storage_database.h
+++ b/chromium/content/browser/dom_storage/session_storage_database.h
@@ -21,6 +21,7 @@
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
#include "content/common/content_export.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"
@@ -230,16 +231,16 @@ class CONTENT_EXPORT SessionStorageDatabase
base::Lock db_lock_;
// True if a database error has occurred (e.g., cannot read data).
- bool db_error_;
+ bool db_error_ GUARDED_BY(db_lock_);
// True if the database is in an inconsistent state.
- bool is_inconsistent_;
+ bool is_inconsistent_ GUARDED_BY(db_lock_);
// True if the database is in a failed or inconsistent state, and we have
// already deleted it (as an attempt to recover later).
- bool invalid_db_deleted_;
+ bool invalid_db_deleted_ GUARDED_BY(db_lock_);
// The number of database operations in progress. We need this so that we can
// delete an inconsistent database at the right moment.
- int operation_count_;
+ int operation_count_ GUARDED_BY(db_lock_);
// Used to check methods that run on the commit sequence.
SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chromium/content/browser/dom_storage/session_storage_database_unittest.cc b/chromium/content/browser/dom_storage/session_storage_database_unittest.cc
index af7de589318..c8f00281424 100644
--- a/chromium/content/browser/dom_storage/session_storage_database_unittest.cc
+++ b/chromium/content/browser/dom_storage/session_storage_database_unittest.cc
@@ -336,8 +336,7 @@ void SessionStorageDatabaseTest::CompareValuesMaps(
const DOMStorageValuesMap& map1,
const DOMStorageValuesMap& map2) const {
ASSERT_EQ(map2.size(), map1.size());
- for (DOMStorageValuesMap::const_iterator it = map1.begin();
- it != map1.end(); ++it) {
+ for (auto it = map1.begin(); it != map1.end(); ++it) {
base::string16 key = it->first;
ASSERT_TRUE(map2.find(key) != map2.end());
base::NullableString16 val1 = it->second;
diff --git a/chromium/content/browser/dom_storage/session_storage_metadata.cc b/chromium/content/browser/dom_storage/session_storage_metadata.cc
index 515bbac0b12..772fa0de050 100644
--- a/chromium/content/browser/dom_storage/session_storage_metadata.cc
+++ b/chromium/content/browser/dom_storage/session_storage_metadata.cc
@@ -8,7 +8,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "components/services/leveldb/public/cpp/util.h"
-#include "content/common/dom_storage/dom_storage_namespace_ids.h"
+#include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h"
#include "url/gurl.h"
namespace content {
@@ -43,7 +43,7 @@ constexpr const size_t kNamespacePrefixLength =
constexpr const uint8_t kNamespaceOriginSeperatorByte = '-';
constexpr const size_t kNamespaceOriginSeperatorLength = 1;
constexpr const size_t kPrefixBeforeOriginLength =
- kNamespacePrefixLength + kSessionStorageNamespaceIdLength +
+ kNamespacePrefixLength + blink::kSessionStorageNamespaceIdLength +
kNamespaceOriginSeperatorLength;
bool ValueToNumber(const std::vector<uint8_t>& value, int64_t* out) {
@@ -169,7 +169,7 @@ bool SessionStorageMetadata::ParseNamespaces(
continue;
base::StringPiece namespace_id = key_as_string.substr(
- kNamespacePrefixLength, kSessionStorageNamespaceIdLength);
+ kNamespacePrefixLength, blink::kSessionStorageNamespaceIdLength);
base::StringPiece origin_str =
key_as_string.substr(kPrefixBeforeOriginLength);
@@ -347,7 +347,7 @@ void SessionStorageMetadata::DeleteArea(
const std::string& namespace_id,
const url::Origin& origin,
std::vector<BatchedOperationPtr>* delete_operations) {
- NamespaceEntry ns_entry = namespace_origin_map_.find(namespace_id);
+ auto ns_entry = namespace_origin_map_.find(namespace_id);
if (ns_entry == namespace_origin_map_.end())
return;
diff --git a/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc b/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc
index 81c1d91c755..9c22eb557da 100644
--- a/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc
+++ b/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc
@@ -11,13 +11,15 @@
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/sequenced_task_runner.h"
+#include "base/task/post_task.h"
#include "content/browser/dom_storage/dom_storage_context_impl.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/dom_storage_task_runner.h"
#include "content/browser/dom_storage/session_storage_context_mojo.h"
-#include "content/common/dom_storage/dom_storage_namespace_ids.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
+#include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h"
namespace content {
@@ -25,7 +27,7 @@ namespace content {
scoped_refptr<SessionStorageNamespaceImpl> SessionStorageNamespaceImpl::Create(
scoped_refptr<DOMStorageContextWrapper> context) {
return SessionStorageNamespaceImpl::Create(
- std::move(context), AllocateSessionStorageNamespaceId());
+ std::move(context), blink::AllocateSessionStorageNamespaceId());
}
// static
@@ -100,7 +102,7 @@ bool SessionStorageNamespaceImpl::should_persist() const {
scoped_refptr<SessionStorageNamespaceImpl>
SessionStorageNamespaceImpl::Clone() {
- return CloneFrom(context_wrapper_, AllocateSessionStorageNamespaceId(),
+ return CloneFrom(context_wrapper_, blink::AllocateSessionStorageNamespaceId(),
namespace_id_, true);
}
@@ -150,8 +152,8 @@ SessionStorageNamespaceImpl::~SessionStorageNamespaceImpl() {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
// If this fails to post then that's fine, as the mojo state should
// already be destructed.
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- deleteNamespaceRunner.Release());
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ deleteNamespaceRunner.Release());
}
}
}
diff --git a/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo_unittest.cc b/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo_unittest.cc
index 5080467a908..fb9e5c439a5 100644
--- a/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo_unittest.cc
+++ b/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo_unittest.cc
@@ -59,8 +59,7 @@ class SessionStorageNamespaceImplMojoTest
// Create a database that already has a namespace saved.
metadata_.SetupNewDatabase();
std::vector<leveldb::mojom::BatchedOperationPtr> save_operations;
- NamespaceEntry entry =
- metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_);
+ auto entry = metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_);
auto map_id =
metadata_.RegisterNewMap(entry, test_origin1_, &save_operations);
DCHECK(map_id->KeyPrefix() == StdStringToUint8Vector("map-0-"));
@@ -130,7 +129,7 @@ class SessionStorageNamespaceImplMojoTest
const SessionStorageNamespaceImplMojo::OriginAreas& areas_to_clone)
override {
std::vector<leveldb::mojom::BatchedOperationPtr> save_operations;
- NamespaceEntry namespace_entry =
+ auto namespace_entry =
metadata_.GetOrCreateNamespaceEntry(destination_namespace);
metadata_.RegisterShallowClonedNamespace(source_namespace, namespace_entry,
&save_operations);
diff --git a/chromium/content/browser/dom_storage/storage_area_impl.cc b/chromium/content/browser/dom_storage/storage_area_impl.cc
index 63930ec6b94..b5cff87bd5f 100644
--- a/chromium/content/browser/dom_storage/storage_area_impl.cc
+++ b/chromium/content/browser/dom_storage/storage_area_impl.cc
@@ -284,7 +284,7 @@ void StorageAreaImpl::Put(
new_item_memory = key.size() + sizeof(size_t);
} else {
DCHECK_EQ(map_state_, MapState::LOADED_KEYS_AND_VALUES);
- ValueMap::iterator found = keys_values_map_.find(key);
+ auto found = keys_values_map_.find(key);
if (found != keys_values_map_.end()) {
if (found->second == value) {
std::move(callback).Run(true); // Key already has this value.
@@ -398,7 +398,7 @@ void StorageAreaImpl::Delete(
commit_batch_->changed_values[key] = std::vector<uint8_t>();
} else {
DCHECK_EQ(map_state_, MapState::LOADED_KEYS_AND_VALUES);
- ValueMap::iterator found = keys_values_map_.find(key);
+ auto found = keys_values_map_.find(key);
if (found == keys_values_map_.end()) {
std::move(callback).Run(true);
return;
diff --git a/chromium/content/browser/download/download_browsertest.cc b/chromium/content/browser/download/download_browsertest.cc
index 3ae60d75623..97421cd8745 100644
--- a/chromium/content/browser/download/download_browsertest.cc
+++ b/chromium/content/browser/download/download_browsertest.cc
@@ -24,6 +24,7 @@
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/test/mock_entropy_provider.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/platform_thread.h"
@@ -39,6 +40,7 @@
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_request_utils.h"
#include "content/public/browser/resource_throttle.h"
@@ -942,6 +944,12 @@ class DownloadContentTest : public ContentBrowserTest {
return inject_error_callback_;
}
+ void RegisterServiceWorker(Shell* shell, const std::string& worker_url) {
+ NavigateToURL(
+ shell, embedded_test_server()->GetURL("/register_service_worker.html"));
+ EXPECT_EQ("DONE", EvalJs(shell, "register('" + worker_url + "')"));
+ }
+
private:
// Location of the downloads directory for these tests
base::ScopedTempDir downloads_directory_;
@@ -1183,6 +1191,7 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, MultiDownload) {
#if BUILDFLAG(ENABLE_PLUGINS)
// Content served with a MIME type of application/octet-stream should be
// downloaded even when a plugin can be found that handles the file type.
+// See https://crbug.com/104331 for the details.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadOctetStream) {
const char kTestPluginName[] = "TestPlugin";
const char kTestMimeType[] = "application/x-test-mime-type";
@@ -1197,9 +1206,90 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadOctetStream) {
// The following is served with a Content-Type of application/octet-stream.
NavigateToURLAndWaitForDownload(
- shell(), embedded_test_server()->GetURL("/download/download-test.lib"),
+ shell(), embedded_test_server()->GetURL("/download/octet-stream.abc"),
+ download::DownloadItem::COMPLETE);
+}
+
+// Content served with a MIME type of application/octet-stream should be
+// downloaded even when a plugin can be found that handles the file type.
+// See https://crbug.com/104331 for the details.
+// In this test, the url is in scope of a service worker but the response is
+// served from network.
+// This is regression test for https://crbug.com/896696.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest,
+ DownloadOctetStream_PassThroughServiceWorker) {
+ const char kTestPluginName[] = "TestPlugin";
+ const char kTestMimeType[] = "application/x-test-mime-type";
+ const char kTestFileType[] = "abc";
+
+ RegisterServiceWorker(shell(), "/fetch_event_passthrough.js");
+
+ WebPluginInfo plugin_info;
+ plugin_info.name = base::ASCIIToUTF16(kTestPluginName);
+ plugin_info.mime_types.push_back(
+ WebPluginMimeType(kTestMimeType, kTestFileType, ""));
+ plugin_info.type = WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS;
+ PluginServiceImpl::GetInstance()->RegisterInternalPlugin(plugin_info, false);
+
+ // The following is served with a Content-Type of application/octet-stream.
+ NavigateToURLAndWaitForDownload(
+ shell(), embedded_test_server()->GetURL("/download/octet-stream.abc"),
download::DownloadItem::COMPLETE);
}
+
+// Content served with a MIME type of application/octet-stream should be
+// downloaded even when a plugin can be found that handles the file type.
+// See https://crbug.com/104331 for the details.
+// In this test, the response will be served from a service worker.
+// This is regression test for https://crbug.com/896696.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest,
+ DownloadOctetStream_OctetStreamServiceWorker) {
+ const char kTestPluginName[] = "TestPlugin";
+ const char kTestMimeType[] = "application/x-test-mime-type";
+ const char kTestFileType[] = "abc";
+
+ RegisterServiceWorker(shell(), "/fetch_event_octet_stream.js");
+
+ WebPluginInfo plugin_info;
+ plugin_info.name = base::ASCIIToUTF16(kTestPluginName);
+ plugin_info.mime_types.push_back(
+ WebPluginMimeType(kTestMimeType, kTestFileType, ""));
+ plugin_info.type = WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS;
+ PluginServiceImpl::GetInstance()->RegisterInternalPlugin(plugin_info, false);
+
+ // The following is served with a Content-Type of application/octet-stream.
+ NavigateToURLAndWaitForDownload(
+ shell(), embedded_test_server()->GetURL("/download/octet-stream.abc"),
+ download::DownloadItem::COMPLETE);
+}
+
+// Content served with a MIME type of application/octet-stream should be
+// downloaded even when a plugin can be found that handles the file type.
+// See https://crbug.com/104331 for the details.
+// In this test, the url is in scope of a service worker and the response is
+// served from the network via service worker.
+// This is regression test for https://crbug.com/896696.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest,
+ DownloadOctetStream_RespondWithFetchServiceWorker) {
+ const char kTestPluginName[] = "TestPlugin";
+ const char kTestMimeType[] = "application/x-test-mime-type";
+ const char kTestFileType[] = "abc";
+
+ RegisterServiceWorker(shell(), "/fetch_event_respond_with_fetch.js");
+
+ WebPluginInfo plugin_info;
+ plugin_info.name = base::ASCIIToUTF16(kTestPluginName);
+ plugin_info.mime_types.push_back(
+ WebPluginMimeType(kTestMimeType, kTestFileType, ""));
+ plugin_info.type = WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS;
+ PluginServiceImpl::GetInstance()->RegisterInternalPlugin(plugin_info, false);
+
+ // The following is served with a Content-Type of application/octet-stream.
+ NavigateToURLAndWaitForDownload(
+ shell(), embedded_test_server()->GetURL("/download/octet-stream.abc"),
+ download::DownloadItem::COMPLETE);
+}
+
#endif
// Try to cancel just before we release the download file, by delaying final
@@ -1344,13 +1434,13 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) {
// a chance to get the second stall onto the IO thread queue after the cancel
// message created by Shutdown and before the notification callback
// created by the IO thread in canceling the request.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&base::PlatformThread::Sleep,
base::TimeDelta::FromMilliseconds(25)));
DownloadManagerForShell(shell())->Shutdown();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&base::PlatformThread::Sleep,
base::TimeDelta::FromMilliseconds(25)));
}
diff --git a/chromium/content/browser/download/download_manager_impl.cc b/chromium/content/browser/download/download_manager_impl.cc
index 37cabf2c9ff..a0220133cd2 100644
--- a/chromium/content/browser/download/download_manager_impl.cc
+++ b/chromium/content/browser/download/download_manager_impl.cc
@@ -20,6 +20,7 @@
#include "base/strings/sys_string_conversions.h"
#include "base/supports_user_data.h"
#include "base/synchronization/lock.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "components/download/database/in_progress/download_entry.h"
#include "components/download/database/in_progress/in_progress_cache_impl.h"
@@ -56,6 +57,7 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/throttling_url_loader.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/browser/download_manager_delegate.h"
@@ -139,8 +141,8 @@ void CreateInterruptedDownload(
failed_created_info->url_chain.push_back(params->url());
failed_created_info->result = reason;
std::unique_ptr<ByteStreamReader> empty_byte_stream;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&DownloadManager::StartDownload, download_manager,
std::move(failed_created_info),
@@ -148,11 +150,13 @@ void CreateInterruptedDownload(
nullptr, params->callback()));
}
-void BeginDownload(std::unique_ptr<download::DownloadUrlParameters> params,
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
- content::ResourceContext* resource_context,
- bool is_new_download,
- base::WeakPtr<DownloadManagerImpl> download_manager) {
+void BeginDownload(
+ std::unique_ptr<download::DownloadUrlParameters> params,
+ std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
+ content::ResourceContext* resource_context,
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+ bool is_new_download,
+ base::WeakPtr<DownloadManagerImpl> download_manager) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
download::UrlDownloadHandler::UniqueUrlDownloadHandlerPtr downloader(
@@ -161,8 +165,8 @@ void BeginDownload(std::unique_ptr<download::DownloadUrlParameters> params,
params->set_blob_storage_context_getter(
base::BindOnce(&BlobStorageContextGetter, resource_context));
std::unique_ptr<net::URLRequest> url_request =
- DownloadRequestCore::CreateRequestOnIOThread(is_new_download,
- params.get());
+ DownloadRequestCore::CreateRequestOnIOThread(
+ is_new_download, params.get(), std::move(url_request_context_getter));
if (blob_data_handle) {
storage::BlobProtocolHandler::SetRequestedBlobDataHandle(
url_request.get(), std::move(blob_data_handle));
@@ -190,8 +194,8 @@ void BeginDownload(std::unique_ptr<download::DownloadUrlParameters> params,
params.get(), false)
.release());
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&download::UrlDownloadHandler::Delegate::OnUrlDownloadHandlerCreated,
download_manager, std::move(downloader)));
@@ -304,7 +308,7 @@ DownloadManagerImpl::DownloadManagerImpl(BrowserContext* browser_context)
weak_factory_(this) {
DCHECK(browser_context);
download::SetIOTaskRunner(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
download::UrlDownloadHandlerFactory::Install(new UrlDownloaderFactory());
@@ -1256,14 +1260,13 @@ void DownloadManagerImpl::BeginDownloadInternal(
} else {
StoragePartition* storage_partition =
BrowserContext::GetStoragePartitionForSite(browser_context_, site_url);
- params->set_url_request_context_getter(
- storage_partition->GetURLRequestContext());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&BeginDownload, std::move(params),
- std::move(blob_data_handle),
- browser_context_->GetResourceContext(), is_new_download,
- weak_factory_.GetWeakPtr()));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(
+ &BeginDownload, std::move(params), std::move(blob_data_handle),
+ browser_context_->GetResourceContext(),
+ base::WrapRefCounted(storage_partition->GetURLRequestContext()),
+ is_new_download, weak_factory_.GetWeakPtr()));
}
}
diff --git a/chromium/content/browser/download/download_manager_impl_unittest.cc b/chromium/content/browser/download/download_manager_impl_unittest.cc
index 7df5b5b6539..fa6bd708f10 100644
--- a/chromium/content/browser/download/download_manager_impl_unittest.cc
+++ b/chromium/content/browser/download/download_manager_impl_unittest.cc
@@ -188,8 +188,7 @@ download::MockDownloadItemImpl* MockDownloadItemFactory::PopItem() {
if (items_.empty())
return nullptr;
- std::map<uint32_t, download::MockDownloadItemImpl*>::iterator first_item =
- items_.begin();
+ auto first_item = items_.begin();
download::MockDownloadItemImpl* result = first_item->second;
items_.erase(first_item);
return result;
diff --git a/chromium/content/browser/download/download_request_core.cc b/chromium/content/browser/download/download_request_core.cc
index a4cdc54c64b..2a707e8b7aa 100644
--- a/chromium/content/browser/download/download_request_core.cc
+++ b/chromium/content/browser/download/download_request_core.cc
@@ -40,6 +40,7 @@
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
+#include "net/url_request/url_request_context_getter.h"
#include "services/device/public/mojom/constants.mojom.h"
#include "services/device/public/mojom/wake_lock_provider.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
@@ -126,12 +127,14 @@ const int DownloadRequestCore::kDownloadByteStreamSize = 100 * 1024;
// static
std::unique_ptr<net::URLRequest> DownloadRequestCore::CreateRequestOnIOThread(
bool is_new_download,
- download::DownloadUrlParameters* params) {
+ download::DownloadUrlParameters* params,
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(is_new_download || !params->content_initiated())
<< "Content initiated downloads should be a new download";
- std::unique_ptr<net::URLRequest> request = CreateURLRequestOnIOThread(params);
+ std::unique_ptr<net::URLRequest> request =
+ CreateURLRequestOnIOThread(params, std::move(url_request_context_getter));
DownloadRequestData::Attach(request.get(), params, is_new_download);
return request;
@@ -340,7 +343,7 @@ bool DownloadRequestCore::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
DCHECK(!read_buffer_.get());
*buf_size = kReadBufSize;
- read_buffer_ = new net::IOBuffer(*buf_size);
+ read_buffer_ = base::MakeRefCounted<net::IOBuffer>(*buf_size);
*buf = read_buffer_.get();
return true;
}
diff --git a/chromium/content/browser/download/download_request_core.h b/chromium/content/browser/download/download_request_core.h
index 0a4a2db6000..93d43917a25 100644
--- a/chromium/content/browser/download/download_request_core.h
+++ b/chromium/content/browser/download/download_request_core.h
@@ -13,6 +13,7 @@
#include "base/callback.h"
#include "base/macros.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "components/download/public/common/download_interrupt_reasons.h"
#include "components/download/public/common/download_save_info.h"
@@ -27,6 +28,7 @@ struct DownloadCreateInfo;
namespace net {
class HttpResponseHeaders;
class URLRequest;
+class URLRequestContextGetter;
class URLRequestStatus;
} // namespace net
@@ -71,7 +73,7 @@ class CONTENT_EXPORT DownloadRequestCore
// redirect to be followed if the return value is true.
bool OnRequestRedirected();
- // Starts a read cycle. Creates a new IOBuffer which can be passed into
+ // Starts a read cycle. Creates an IOBuffer which can be passed into
// URLRequest::Read(). Call OnReadCompleted() when the Read operation
// completes.
bool OnWillRead(scoped_refptr<net::IOBuffer>* buf,
@@ -110,7 +112,8 @@ class CONTENT_EXPORT DownloadRequestCore
static std::unique_ptr<net::URLRequest> CreateRequestOnIOThread(
bool is_new_download,
- download::DownloadUrlParameters* params);
+ download::DownloadUrlParameters* params,
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
// Size of the buffer used between the DownloadRequestCore and the
// downstream receiver of its output.
diff --git a/chromium/content/browser/download/download_request_core_unittest.cc b/chromium/content/browser/download/download_request_core_unittest.cc
index 5c6fb4e426b..6a07198b9c6 100644
--- a/chromium/content/browser/download/download_request_core_unittest.cc
+++ b/chromium/content/browser/download/download_request_core_unittest.cc
@@ -5,9 +5,11 @@
#include <memory>
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "components/download/public/common/download_item.h"
#include "components/download/public/common/download_url_parameters.h"
#include "content/browser/download/download_request_core.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/http/http_request_headers.h"
@@ -29,7 +31,7 @@ class DownloadRequestCoreTest : public testing::Test {
const std::string& url) const {
GURL gurl(url);
return std::make_unique<download::DownloadUrlParameters>(
- gurl, request_context_getter_.get(), TRAFFIC_ANNOTATION_FOR_TESTS);
+ gurl, TRAFFIC_ANNOTATION_FOR_TESTS);
}
void CheckRequestHeaders(const std::string& name,
@@ -46,14 +48,15 @@ class DownloadRequestCoreTest : public testing::Test {
}
void CreateRequestOnIOThread(download::DownloadUrlParameters* params) {
- url_request_ = DownloadRequestCore::CreateRequestOnIOThread(true, params);
+ url_request_ = DownloadRequestCore::CreateRequestOnIOThread(
+ true, params, request_context_getter_);
DCHECK(url_request_.get());
}
void SetUp() override {
request_context_getter_ = new net::TestURLRequestContextGetter(
- content::BrowserThread::GetTaskRunnerForThread(
- content::BrowserThread::UI));
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {content::BrowserThread::UI}));
}
void TearDown() override {
diff --git a/chromium/content/browser/download/download_request_handle.cc b/chromium/content/browser/download/download_request_handle.cc
index b0d903260d0..d0e09f7cf2e 100644
--- a/chromium/content/browser/download/download_request_handle.cc
+++ b/chromium/content/browser/download/download_request_handle.cc
@@ -6,8 +6,10 @@
#include "base/bind.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@@ -31,20 +33,20 @@ WebContents* DownloadRequestHandle::GetWebContents() const {
}
void DownloadRequestHandle::PauseRequest() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DownloadResourceHandler::PauseRequest, handler_));
}
void DownloadRequestHandle::ResumeRequest() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DownloadResourceHandler::ResumeRequest, handler_));
}
void DownloadRequestHandle::CancelRequest(bool user_cancel) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&DownloadResourceHandler::CancelRequest, handler_));
}
diff --git a/chromium/content/browser/download/download_request_utils.cc b/chromium/content/browser/download/download_request_utils.cc
index 2c2a29228dc..86de66d1a75 100644
--- a/chromium/content/browser/download/download_request_utils.cc
+++ b/chromium/content/browser/download/download_request_utils.cc
@@ -8,7 +8,6 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
namespace content {
@@ -20,14 +19,11 @@ DownloadRequestUtils::CreateDownloadForWebContentsMainFrame(
const GURL& url,
const net::NetworkTrafficAnnotationTag& traffic_annotation) {
RenderFrameHost* render_frame_host = web_contents->GetMainFrame();
- StoragePartition* storage_partition = BrowserContext::GetStoragePartition(
- web_contents->GetBrowserContext(), render_frame_host->GetSiteInstance());
return std::unique_ptr<download::DownloadUrlParameters>(
new download::DownloadUrlParameters(
url, render_frame_host->GetProcess()->GetID(),
render_frame_host->GetRenderViewHost()->GetRoutingID(),
- render_frame_host->GetRoutingID(),
- storage_partition->GetURLRequestContext(), traffic_annotation));
+ render_frame_host->GetRoutingID(), traffic_annotation));
}
} // namespace content
diff --git a/chromium/content/browser/download/download_resource_handler.cc b/chromium/content/browser/download/download_resource_handler.cc
index 752cc1af42d..d022b897f75 100644
--- a/chromium/content/browser/download/download_resource_handler.cc
+++ b/chromium/content/browser/download/download_resource_handler.cc
@@ -11,6 +11,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "components/download/public/common/download_create_info.h"
#include "components/download/public/common/download_interrupt_reasons.h"
#include "components/download/public/common/download_interrupt_reasons_utils.h"
@@ -25,6 +26,7 @@
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_request_utils.h"
#include "content/public/browser/navigation_entry.h"
@@ -57,9 +59,9 @@ static void StartOnUIThread(
RenderFrameHost* frame_host =
RenderFrameHost::FromID(render_process_id, render_frame_id);
- // PlzNavigate: navigations don't have associated RenderFrameHosts. Get the
- // SiteInstance from the FrameTreeNode.
- if (!frame_host && IsBrowserSideNavigationEnabled()) {
+ // Navigations don't have associated RenderFrameHosts. Get the SiteInstance
+ // from the FrameTreeNode.
+ if (!frame_host) {
FrameTreeNode* frame_tree_node =
FrameTreeNode::GloballyFindByID(frame_tree_node_id);
if (frame_tree_node)
@@ -155,8 +157,8 @@ DownloadResourceHandler::DownloadResourceHandler(
// will occur via PostTask() as well, which will serialized behind this
// PostTask()
const ResourceRequestInfoImpl* request_info = GetRequestInfo();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&InitializeDownloadTabInfoOnUIThread,
DownloadRequestHandle(AsWeakPtr(),
@@ -166,8 +168,8 @@ DownloadResourceHandler::DownloadResourceHandler(
DownloadResourceHandler::~DownloadResourceHandler() {
if (tab_info_) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DeleteOnUIThread, std::move(tab_info_)));
}
}
@@ -200,8 +202,8 @@ void DownloadResourceHandler::OnRequestRedirected(
url::Origin new_origin(url::Origin::Create(redirect_info.new_url));
if (!follow_cross_origin_redirects_ &&
!first_origin_.IsSameOriginWith(new_origin)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&NavigateOnUIThread, redirect_info.new_url, request()->url_chain(),
Referrer(GURL(redirect_info.new_referrer),
@@ -296,8 +298,8 @@ void DownloadResourceHandler::OnStart(
download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED &&
create_info->is_new_download) {
if (!callback.is_null())
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(callback, nullptr, create_info->result));
return;
}
@@ -313,8 +315,8 @@ void DownloadResourceHandler::OnStart(
int render_frame_id = -1;
request_info->GetAssociatedRenderFrame(&render_process_id, &render_frame_id);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&StartOnUIThread, std::move(create_info),
std::move(tab_info_), std::move(stream_reader),
render_process_id, render_frame_id,
diff --git a/chromium/content/browser/download/download_utils.cc b/chromium/content/browser/download/download_utils.cc
index 0fd9009103d..89d3af0f95a 100644
--- a/chromium/content/browser/download/download_utils.cc
+++ b/chromium/content/browser/download/download_utils.cc
@@ -28,6 +28,7 @@
#include "net/base/upload_bytes_element_reader.h"
#include "net/http/http_request_headers.h"
#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
namespace content {
@@ -40,7 +41,8 @@ storage::BlobStorageContext* BlobStorageContextGetter(
}
std::unique_ptr<net::URLRequest> CreateURLRequestOnIOThread(
- download::DownloadUrlParameters* params) {
+ download::DownloadUrlParameters* params,
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(params->offset() >= 0);
@@ -49,10 +51,9 @@ std::unique_ptr<net::URLRequest> CreateURLRequestOnIOThread(
// resource_dispatcher_host_impl.h, so we must down cast. RDHI is the only
// subclass of RDH as of 2012 May 4.
std::unique_ptr<net::URLRequest> request(
- params->url_request_context_getter()
- ->GetURLRequestContext()
- ->CreateRequest(params->url(), net::DEFAULT_PRIORITY, nullptr,
- params->GetNetworkTrafficAnnotation()));
+ url_request_context_getter->GetURLRequestContext()->CreateRequest(
+ params->url(), net::DEFAULT_PRIORITY, nullptr,
+ params->GetNetworkTrafficAnnotation()));
request->set_method(params->method());
if (params->post_body()) {
diff --git a/chromium/content/browser/download/download_utils.h b/chromium/content/browser/download/download_utils.h
index df86cad0db7..a0328942793 100644
--- a/chromium/content/browser/download/download_utils.h
+++ b/chromium/content/browser/download/download_utils.h
@@ -7,6 +7,7 @@
#include <memory>
+#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "content/common/content_export.h"
@@ -16,6 +17,7 @@ class DownloadUrlParameters;
namespace net {
class URLRequest;
+class URLRequestContextGetter;
} // namespace net
namespace storage {
@@ -26,9 +28,11 @@ namespace content {
class ResourceContext;
-// Create a URLRequest from |params|.
-std::unique_ptr<net::URLRequest> CONTENT_EXPORT
-CreateURLRequestOnIOThread(download::DownloadUrlParameters* params);
+// Create a URLRequest from |params| using the specified
+// URLRequestContextGetter.
+std::unique_ptr<net::URLRequest> CONTENT_EXPORT CreateURLRequestOnIOThread(
+ download::DownloadUrlParameters* params,
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
storage::BlobStorageContext* BlobStorageContextGetter(
ResourceContext* resource_context);
diff --git a/chromium/content/browser/download/drag_download_file.cc b/chromium/content/browser/download/drag_download_file.cc
index 8c6b6c1ff7f..c15e78c9ef1 100644
--- a/chromium/content/browser/download/drag_download_file.cc
+++ b/chromium/content/browser/download/drag_download_file.cc
@@ -11,12 +11,14 @@
#include "base/location.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/download/public/common/download_item.h"
#include "components/download/public/common/download_stats.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_request_utils.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
@@ -214,8 +216,8 @@ DragDownloadFile::~DragDownloadFile() {
// the UI thread so that it calls RemoveObserver on the right thread, and so
// that this task will run after the InitiateDownload task runs on the UI
// thread.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DragDownloadFileUI::Delete, base::Unretained(drag_ui_)));
drag_ui_ = nullptr;
}
@@ -231,8 +233,8 @@ void DragDownloadFile::Start(ui::DownloadFileObserver* observer) {
observer_ = observer;
DCHECK(observer_.get());
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DragDownloadFileUI::InitiateDownload,
base::Unretained(drag_ui_), std::move(file_), file_path_));
}
@@ -247,9 +249,9 @@ bool DragDownloadFile::Wait() {
void DragDownloadFile::Stop() {
CheckThread();
if (drag_ui_) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&DragDownloadFileUI::Cancel,
- base::Unretained(drag_ui_)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&DragDownloadFileUI::Cancel,
+ base::Unretained(drag_ui_)));
}
}
diff --git a/chromium/content/browser/download/drag_download_file_browsertest.cc b/chromium/content/browser/download/drag_download_file_browsertest.cc
index c267b435449..6fbae0942e7 100644
--- a/chromium/content/browser/download/drag_download_file_browsertest.cc
+++ b/chromium/content/browser/download/drag_download_file_browsertest.cc
@@ -8,10 +8,12 @@
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/drag_download_file.h"
#include "content/browser/download/drag_download_util.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
@@ -52,8 +54,8 @@ class DragDownloadFileTest : public ContentBrowserTest {
~DragDownloadFileTest() override {}
void Succeed() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::RunLoop::QuitCurrentWhenIdleClosureDeprecated());
}
diff --git a/chromium/content/browser/download/drag_download_util.cc b/chromium/content/browser/download/drag_download_util.cc
index 0996ac70e2c..a91ec48853c 100644
--- a/chromium/content/browser/download/drag_download_util.cc
+++ b/chromium/content/browser/download/drag_download_util.cc
@@ -15,8 +15,10 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"
@@ -96,13 +98,15 @@ PromiseFileFinalizer::PromiseFileFinalizer(
void PromiseFileFinalizer::OnDownloadCompleted(
const base::FilePath& file_path) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&PromiseFileFinalizer::Cleanup, this));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&PromiseFileFinalizer::Cleanup, this));
}
void PromiseFileFinalizer::OnDownloadAborted() {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&PromiseFileFinalizer::Cleanup, this));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&PromiseFileFinalizer::Cleanup, this));
}
PromiseFileFinalizer::~PromiseFileFinalizer() {}
diff --git a/chromium/content/browser/download/mhtml_generation_browsertest.cc b/chromium/content/browser/download/mhtml_generation_browsertest.cc
index 5d8e517f459..def931d9e8f 100644
--- a/chromium/content/browser/download/mhtml_generation_browsertest.cc
+++ b/chromium/content/browser/download/mhtml_generation_browsertest.cc
@@ -13,11 +13,13 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_restrictions.h"
#include "components/download/public/common/download_task_runner.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/common/frame_messages.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/mhtml_extra_parts.h"
#include "content/public/browser/render_frame_host.h"
@@ -34,7 +36,6 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/web/web_find_options.h"
#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h"
using testing::ContainsRegex;
@@ -56,12 +57,12 @@ class FindTrackingDelegate : public WebContentsDelegate {
WebContentsDelegate* old_delegate = web_contents->GetDelegate();
web_contents->SetDelegate(this);
- blink::WebFindOptions options;
- options.run_synchronously_for_testing = true;
- options.match_case = false;
+ auto options = blink::mojom::FindOptions::New();
+ options->run_synchronously_for_testing = true;
+ options->match_case = false;
web_contents->Find(global_request_id++, base::UTF8ToUTF16(search_),
- options);
+ std::move(options));
run_loop_.Run();
web_contents->SetDelegate(old_delegate);
@@ -329,8 +330,8 @@ class GenerateMHTMLAndExitRendererMessageFilter : public BrowserMessageFilter {
// execution at (Y?) and (Z?) instead is possible. In practice,
// bouncing off of UI and download sequence does mean (Z) happens
// after (1).
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&GenerateMHTMLAndExitRendererMessageFilter::TaskX,
base::Unretained(this)));
}
@@ -346,8 +347,8 @@ class GenerateMHTMLAndExitRendererMessageFilter : public BrowserMessageFilter {
}
void TaskY() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&GenerateMHTMLAndExitRendererMessageFilter::TaskZ,
base::Unretained(this)));
}
diff --git a/chromium/content/browser/download/save_file_manager.cc b/chromium/content/browser/download/save_file_manager.cc
index 96c463e4471..685b462e10c 100644
--- a/chromium/content/browser/download/save_file_manager.cc
+++ b/chromium/content/browser/download/save_file_manager.cc
@@ -4,7 +4,9 @@
#include "build/build_config.h"
+#include "base/task/post_task.h"
#include "content/browser/download/save_file_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "base/bind.h"
#include "base/files/file_util.h"
@@ -325,9 +327,9 @@ void SaveFileManager::StartSave(std::unique_ptr<SaveFileCreateInfo> info) {
DCHECK(!LookupSaveFile(save_file->save_item_id()));
save_file_map_[save_file->save_item_id()] = std::move(save_file);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&SaveFileManager::OnStartSave, this,
- save_file_create_info));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&SaveFileManager::OnStartSave, this,
+ save_file_create_info));
}
// We do forward an update to the UI thread here, since we do not use timer to
@@ -343,8 +345,8 @@ void SaveFileManager::UpdateSaveProgress(SaveItemId save_item_id,
download::DownloadInterruptReason reason =
save_file->AppendDataToFile(data.data(), data.size());
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SaveFileManager::OnUpdateSaveProgress, this,
save_file->save_item_id(), save_file->BytesSoFar(),
reason == download::DOWNLOAD_INTERRUPT_REASON_NONE));
@@ -374,8 +376,8 @@ void SaveFileManager::SaveFinished(SaveItemId save_item_id,
save_file->Detach();
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SaveFileManager::OnSaveFinished, this, save_item_id,
bytes_so_far, is_success));
}
@@ -437,8 +439,8 @@ void SaveFileManager::CancelSave(SaveItemId save_item_id) {
base::DeleteFile(save_file->FullPath(), false);
} else if (save_file->save_source() ==
SaveFileCreateInfo::SAVE_FILE_FROM_NET) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SaveFileManager::ClearURLLoader, this, save_item_id));
}
@@ -486,8 +488,8 @@ void SaveFileManager::RenameAllFiles(const FinalNamesMap& final_names,
}
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SaveFileManager::OnFinishSavePageJob, this,
render_process_id, render_frame_routing_id,
save_package_id));
diff --git a/chromium/content/browser/download/save_package.cc b/chromium/content/browser/download/save_package.cc
index 187d62297d0..cba288ad68e 100644
--- a/chromium/content/browser/download/save_package.cc
+++ b/chromium/content/browser/download/save_package.cc
@@ -441,7 +441,7 @@ bool SavePackage::GenerateFileName(const std::string& disposition,
base::FilePath::StringType file_name = base_name + file_name_ext;
// Check whether we already have same name in a case insensitive manner.
- FileNameSet::const_iterator iter = file_name_set_.find(file_name);
+ auto iter = file_name_set_.find(file_name);
if (iter == file_name_set_.end()) {
DCHECK(!file_name.empty());
file_name_set_.insert(file_name);
@@ -463,7 +463,7 @@ bool SavePackage::GenerateFileName(const std::string& disposition,
// Prepare the new ordinal number.
uint32_t ordinal_number;
- FileNameCountMap::iterator it = file_name_count_map_.find(base_file_name);
+ auto it = file_name_count_map_.find(base_file_name);
if (it == file_name_count_map_.end()) {
// First base-name-conflict resolving, use 1 as initial ordinal number.
file_name_count_map_[base_file_name] = 1;
diff --git a/chromium/content/browser/download/url_downloader.cc b/chromium/content/browser/download/url_downloader.cc
index e44234a31f5..15b46abdb33 100644
--- a/chromium/content/browser/download/url_downloader.cc
+++ b/chromium/content/browser/download/url_downloader.cc
@@ -8,6 +8,7 @@
#include "base/location.h"
#include "base/macros.h"
#include "base/sequenced_task_runner.h"
+#include "base/task/post_task.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "components/download/public/common/download_create_info.h"
#include "components/download/public/common/download_interrupt_reasons.h"
@@ -16,6 +17,7 @@
#include "components/download/public/common/url_download_request_handle.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/byte_stream_input_stream.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
@@ -188,8 +190,8 @@ void UrlDownloader::OnStart(
create_info->request_handle.reset(new download::UrlDownloadRequestHandle(
weak_ptr_factory_.GetWeakPtr(), base::SequencedTaskRunnerHandle::Get()));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&download::UrlDownloadHandler::Delegate::OnUrlDownloadStarted,
delegate_, std::move(create_info),
@@ -214,8 +216,8 @@ void UrlDownloader::CancelRequest() {
}
void UrlDownloader::Destroy() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&download::UrlDownloadHandler::Delegate::OnUrlDownloadStopped,
delegate_, this));
diff --git a/chromium/content/browser/download/url_downloader_factory.cc b/chromium/content/browser/download/url_downloader_factory.cc
index 5a66bd2b9fa..c6a915457d2 100644
--- a/chromium/content/browser/download/url_downloader_factory.cc
+++ b/chromium/content/browser/download/url_downloader_factory.cc
@@ -8,6 +8,7 @@
#include "components/download/public/common/download_url_loader_factory_getter.h"
#include "content/browser/download/download_request_core.h"
#include "content/browser/download/url_downloader.h"
+#include "net/url_request/url_request_context_getter.h"
namespace content {
@@ -21,9 +22,11 @@ UrlDownloaderFactory::CreateUrlDownloadHandler(
base::WeakPtr<download::UrlDownloadHandler::Delegate> delegate,
scoped_refptr<download::DownloadURLLoaderFactoryGetter>
url_loader_factory_getter,
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
std::unique_ptr<net::URLRequest> url_request =
- DownloadRequestCore::CreateRequestOnIOThread(true, params.get());
+ DownloadRequestCore::CreateRequestOnIOThread(
+ true, params.get(), std::move(url_request_context_getter));
return download::UrlDownloadHandler::UniqueUrlDownloadHandlerPtr(
UrlDownloader::BeginDownload(delegate, std::move(url_request),
diff --git a/chromium/content/browser/download/url_downloader_factory.h b/chromium/content/browser/download/url_downloader_factory.h
index ae908ecaeca..bda99732608 100644
--- a/chromium/content/browser/download/url_downloader_factory.h
+++ b/chromium/content/browser/download/url_downloader_factory.h
@@ -5,11 +5,16 @@
#ifndef CONTENT_BROWSER_DOWNLOAD_URL_DOWNLOADER_FACTORY_H_
#define CONTENT_BROWSER_DOWNLOAD_URL_DOWNLOADER_FACTORY_H_
+#include "base/memory/ref_counted.h"
#include "components/download/public/common/url_download_handler_factory.h"
namespace download {
class DownloadURLLoaderFactoryGetter;
-};
+}
+
+namespace net {
+class URLRequestContextGetter;
+}
namespace content {
@@ -27,6 +32,7 @@ class UrlDownloaderFactory : public download::UrlDownloadHandlerFactory {
base::WeakPtr<download::UrlDownloadHandler::Delegate> delegate,
scoped_refptr<download::DownloadURLLoaderFactoryGetter>
shared_url_loader_factory,
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) override;
};
diff --git a/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc b/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc
index c4873157c81..cbf07e8a6a3 100644
--- a/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc
+++ b/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc
@@ -4,6 +4,8 @@
#include "content/browser/download/web_ui_download_url_loader_factory_getter.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_ui_url_loader_factory.h"
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
@@ -20,7 +22,7 @@ WebUIDownloadURLLoaderFactoryGetter::WebUIDownloadURLLoaderFactoryGetter(
}
WebUIDownloadURLLoaderFactoryGetter::~WebUIDownloadURLLoaderFactoryGetter() {
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})
->DeleteSoon(FROM_HERE, std::move(factory_));
}
diff --git a/chromium/content/browser/file_url_loader_factory.cc b/chromium/content/browser/file_url_loader_factory.cc
index ea4d8eee977..389fd1962ae 100644
--- a/chromium/content/browser/file_url_loader_factory.cc
+++ b/chromium/content/browser/file_url_loader_factory.cc
@@ -25,6 +25,7 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/file_url_loader.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/content_switches.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/file_data_pipe_producer.h"
@@ -38,7 +39,9 @@
#include "net/http/http_byte_range.h"
#include "net/http/http_util.h"
#include "net/url_request/redirect_info.h"
+#include "services/network/public/cpp/cors/cors_error_status.h"
#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/mojom/cors.mojom-shared.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "storage/common/fileapi/file_system_util.h"
#include "url/gurl.h"
@@ -93,6 +96,25 @@ GURL AppendUrlSeparator(const GURL& url) {
return url.ReplaceComponents(replacements);
}
+bool ShouldFailRequestDueToCORS(const network::ResourceRequest& request) {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableWebSecurity)) {
+ return false;
+ }
+
+ const auto mode = request.fetch_request_mode;
+ if (mode == network::mojom::FetchRequestMode::kNavigate ||
+ mode == network::mojom::FetchRequestMode::kNoCORS) {
+ return false;
+ }
+
+ if (!request.request_initiator)
+ return true;
+
+ return !request.request_initiator->IsSameOriginWith(
+ url::Origin::Create(request.url));
+}
+
class FileURLDirectoryLoader
: public network::mojom::URLLoader,
public net::DirectoryLister::DirectoryListerDelegate {
@@ -560,8 +582,6 @@ class FileURLLoader : public network::mojom::URLLoader {
size_t first_byte_to_send = 0;
size_t total_bytes_to_send = static_cast<size_t>(info.size);
- total_bytes_written_ = static_cast<size_t>(info.size);
-
if (byte_range.IsValid()) {
first_byte_to_send =
static_cast<size_t>(byte_range.first_byte_position());
@@ -570,6 +590,8 @@ class FileURLLoader : public network::mojom::URLLoader {
first_byte_to_send + 1;
}
+ total_bytes_written_ = static_cast<size_t>(total_bytes_to_send);
+
head.content_length = base::saturated_cast<int64_t>(total_bytes_to_send);
if (first_byte_to_send < initial_read_size) {
@@ -677,7 +699,9 @@ class FileURLLoader : public network::mojom::URLLoader {
network::mojom::URLLoaderClientPtr client_;
std::unique_ptr<RedirectData> redirect_data_;
- // In case of successful loads, this holds the total of bytes written.
+ // In case of successful loads, this holds the total number of bytes written
+ // to the response (this may be smaller than the total size of the file when
+ // a byte range was requested).
// It is used to set some of the URLLoaderCompletionStatus data passed back
// to the URLLoaderClients (eg SimpleURLLoader).
size_t total_bytes_written_ = 0;
@@ -708,6 +732,16 @@ void FileURLLoaderFactory::CreateLoaderAndStart(
network::URLLoaderCompletionStatus(net::ERR_INVALID_URL));
return;
}
+
+ // FileURLLoader doesn't support CORS and it's not covered by CORSURLLoader,
+ // so we need to reject requests that need CORS manually.
+ if (ShouldFailRequestDueToCORS(request)) {
+ client->OnComplete(
+ network::URLLoaderCompletionStatus(network::CORSErrorStatus(
+ network::mojom::CORSError::kCORSDisabledScheme)));
+ return;
+ }
+
if (file_path.EndsWithSeparator() && file_path.IsAbsolute()) {
task_runner_->PostTask(
FROM_HERE,
diff --git a/chromium/content/browser/fileapi/README.md b/chromium/content/browser/fileapi/README.md
new file mode 100644
index 00000000000..470736189bf
--- /dev/null
+++ b/chromium/content/browser/fileapi/README.md
@@ -0,0 +1,23 @@
+# FileSystem API
+
+This directory contains part of the browser side implementation of various
+filesystem related APIs.
+
+## Related directories
+
+[`//storage/browser/fileapi/`](../../../storage/browser/fileapi) contains the
+rest of the browser side implementation, while
+[`blink/renderer/modules/filesystem`](../../../third_party/blink/renderer/modules/filesystem)
+contains the renderer side implementation and
+[`blink/public/mojom/filesystem`](../../../third_party/blink/public/mojom/filesystem)
+contains the mojom interfaces for these APIs.
+
+## In this directory
+
+[`FileSystemManagerImpl`](file_system_manager_impl.h) is the main entry point
+for calls from the renderer, it mostly redirects incoming mojom calls to a
+`storage::FileSystemContext` instance.
+
+[`FileSystemChooser`](file_system_chooser.h) uses ui::SelectFileDialog to show
+a file or directory picker, and is responsible for granting a process the right
+permissions for actually accessing the files that were selected.
diff --git a/chromium/content/browser/fileapi/browser_file_system_helper.cc b/chromium/content/browser/fileapi/browser_file_system_helper.cc
index 7227c691e73..f3d73489ec9 100644
--- a/chromium/content/browser/fileapi/browser_file_system_helper.cc
+++ b/chromium/content/browser/fileapi/browser_file_system_helper.cc
@@ -15,8 +15,10 @@
#include "base/sequenced_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/lazy_task_runner.h"
+#include "base/task/post_task.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/content_browser_client.h"
@@ -89,7 +91,8 @@ scoped_refptr<storage::FileSystemContext> CreateFileSystemContext(
scoped_refptr<storage::FileSystemContext> file_system_context =
new storage::FileSystemContext(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO).get(),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})
+ .get(),
g_fileapi_task_runner.Get().get(),
BrowserContext::GetMountPoints(browser_context),
browser_context->GetSpecialStoragePolicy(), quota_manager_proxy,
diff --git a/chromium/content/browser/fileapi/file_system_browsertest.cc b/chromium/content/browser/fileapi/file_system_browsertest.cc
index cce4e1155d0..3ff81a5aada 100644
--- a/chromium/content/browser/fileapi/file_system_browsertest.cc
+++ b/chromium/content/browser/fileapi/file_system_browsertest.cc
@@ -10,9 +10,11 @@
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/test/thread_test_helper.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_switches.h"
@@ -62,8 +64,8 @@ class FileSystemBrowserTestWithLowQuota : public FileSystemBrowserTest {
static void SetLowQuota(scoped_refptr<QuotaManager> qm) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&FileSystemBrowserTestWithLowQuota::SetLowQuota, qm));
return;
}
diff --git a/chromium/content/browser/fileapi/file_system_chooser.cc b/chromium/content/browser/fileapi/file_system_chooser.cc
index 0c8ae67d894..e36025673d1 100644
--- a/chromium/content/browser/fileapi/file_system_chooser.cc
+++ b/chromium/content/browser/fileapi/file_system_chooser.cc
@@ -5,6 +5,10 @@
#include "content/browser/fileapi/file_system_chooser.h"
#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/content_browser_client.h"
@@ -15,25 +19,108 @@
namespace content {
+namespace {
+
+bool GetFileTypesFromAcceptsOption(
+ const blink::mojom::ChooseFileSystemEntryAcceptsOption& option,
+ std::vector<base::FilePath::StringType>* extensions,
+ base::string16* description) {
+ std::set<base::FilePath::StringType> extension_set;
+
+ for (const std::string& extension : option.extensions) {
+#if defined(OS_WIN)
+ extension_set.insert(base::UTF8ToWide(extension));
+#else
+ extension_set.insert(extension);
+#endif
+ }
+
+ for (const std::string& mime_type : option.mime_types) {
+ std::vector<base::FilePath::StringType> inner;
+ net::GetExtensionsForMimeType(mime_type, &inner);
+ if (inner.empty())
+ continue;
+ extension_set.insert(inner.begin(), inner.end());
+ }
+
+ extensions->assign(extension_set.begin(), extension_set.end());
+
+ if (extensions->empty())
+ return false;
+
+ *description = option.description;
+ return true;
+}
+
+void ConvertAcceptsToFileTypeInfo(
+ const std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr>& accepts,
+ bool include_accepts_all,
+ ui::SelectFileDialog::FileTypeInfo* file_types) {
+ file_types->include_all_files = include_accepts_all;
+
+ for (const auto& option : accepts) {
+ std::vector<base::FilePath::StringType> extensions;
+ base::string16 description;
+
+ if (!GetFileTypesFromAcceptsOption(*option, &extensions, &description))
+ continue; // No extensions were found for this option, skip it.
+
+ file_types->extensions.push_back(extensions);
+ // FileTypeInfo expects each set of extension to have a corresponding
+ // description. A blank description will result in a system generated
+ // description to be used.
+ file_types->extension_description_overrides.push_back(description);
+ }
+
+ if (file_types->extensions.empty())
+ file_types->include_all_files = true;
+}
+
+} // namespace
+
// static
void FileSystemChooser::CreateAndShow(
int render_process_id,
int frame_id,
+ blink::mojom::ChooseFileSystemEntryType type,
+ std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr> accepts,
+ bool include_accepts_all,
ResultCallback callback,
scoped_refptr<base::TaskRunner> callback_runner) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderFrameHost* rfh = RenderFrameHost::FromID(render_process_id, frame_id);
WebContents* web_contents = WebContents::FromRenderFrameHost(rfh);
- auto* listener = new FileSystemChooser(render_process_id, std::move(callback),
- std::move(callback_runner));
+ auto* listener = new FileSystemChooser(
+ render_process_id, type, std::move(callback), std::move(callback_runner));
listener->dialog_ = ui::SelectFileDialog::Create(
listener,
GetContentClient()->browser()->CreateSelectFilePolicy(web_contents));
// TODO(https://crbug.com/878581): Better/more specific options to pass to
// SelectFile.
+
+ ui::SelectFileDialog::Type dialog_type = ui::SelectFileDialog::SELECT_NONE;
+ switch (type) {
+ case blink::mojom::ChooseFileSystemEntryType::kOpenFile:
+ dialog_type = ui::SelectFileDialog::SELECT_OPEN_FILE;
+ break;
+ case blink::mojom::ChooseFileSystemEntryType::kOpenMultipleFiles:
+ dialog_type = ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE;
+ break;
+ case blink::mojom::ChooseFileSystemEntryType::kSaveFile:
+ dialog_type = ui::SelectFileDialog::SELECT_SAVEAS_FILE;
+ break;
+ case blink::mojom::ChooseFileSystemEntryType::kOpenDirectory:
+ dialog_type = ui::SelectFileDialog::SELECT_FOLDER;
+ break;
+ }
+ DCHECK_NE(dialog_type, ui::SelectFileDialog::SELECT_NONE);
+
+ ui::SelectFileDialog::FileTypeInfo file_types;
+ ConvertAcceptsToFileTypeInfo(accepts, include_accepts_all, &file_types);
+
listener->dialog_->SelectFile(
- ui::SelectFileDialog::SELECT_OPEN_FILE, /*title=*/base::string16(),
- /*default_path=*/base::FilePath(), /*file_types=*/nullptr,
+ dialog_type, /*title=*/base::string16(),
+ /*default_path=*/base::FilePath(), &file_types,
/*file_type_index=*/0,
/*default_extension=*/base::FilePath::StringType(),
web_contents ? web_contents->GetTopLevelNativeWindow() : nullptr,
@@ -42,11 +129,13 @@ void FileSystemChooser::CreateAndShow(
FileSystemChooser::FileSystemChooser(
int render_process_id,
+ blink::mojom::ChooseFileSystemEntryType type,
ResultCallback callback,
scoped_refptr<base::TaskRunner> callback_runner)
: render_process_id_(render_process_id),
callback_(std::move(callback)),
- callback_runner_(std::move(callback_runner)) {}
+ callback_runner_(std::move(callback_runner)),
+ type_(type) {}
FileSystemChooser::~FileSystemChooser() {
if (dialog_)
@@ -73,21 +162,72 @@ void FileSystemChooser::MultiFilesSelected(
for (const auto& path : files) {
auto entry = blink::mojom::FileSystemEntry::New();
entry->file_system_id = isolated_context->RegisterFileSystemForPath(
- storage::kFileSystemTypeNativeForPlatformApp, std::string(), path,
+ storage::kFileSystemTypeNativeLocal, std::string(), path,
&entry->base_name);
- // TODO(https://crbug.com/878585): Determine if we always want to grant
- // write permission.
security_policy->GrantReadFileSystem(render_process_id_,
entry->file_system_id);
- security_policy->GrantWriteFileSystem(render_process_id_,
- entry->file_system_id);
- security_policy->GrantDeleteFromFileSystem(render_process_id_,
- entry->file_system_id);
+ // TODO(https://crbug.com/878585): Don't grant write/modify permissions
+ // unless a website already has the appropriate permissions.
+ if (type_ == blink::mojom::ChooseFileSystemEntryType::kOpenDirectory) {
+ // Only grant Create permissions if we're opening a directory. And
+ // just granting Create permissions on top of Write and Delete does not
+ // actually grant the same permissions as calling this method.
+ security_policy->GrantCreateReadWriteFileSystem(render_process_id_,
+ entry->file_system_id);
+ } else {
+ security_policy->GrantWriteFileSystem(render_process_id_,
+ entry->file_system_id);
+ security_policy->GrantDeleteFromFileSystem(render_process_id_,
+ entry->file_system_id);
+ }
result.push_back(std::move(entry));
}
+ if (type_ == blink::mojom::ChooseFileSystemEntryType::kSaveFile) {
+ // Create files if they don't yet exist.
+ // TODO(mek): If we change FileSystemFileHandle to be able to represent a
+ // file that doesn't exist on disk, we should be able to get rid of this
+ // step and make the whole API slightly more robust.
+ base::PostTaskWithTraits(
+ FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()},
+ base::BindOnce(
+ [](const std::vector<base::FilePath>& files,
+ std::vector<blink::mojom::FileSystemEntryPtr> result,
+ scoped_refptr<base::TaskRunner> callback_runner,
+ ResultCallback callback) {
+ for (const auto& path : files) {
+ // Checking if a path exists, and then creating it if it doesn't
+ // is of course racy, but external applications could just as
+ // well be deleting the entire directory, or similar problematic
+ // cases, so no matter what we do there are always going to be
+ // race conditions and websites will just have to deal with any
+ // method being able to fail in unexpected ways.
+ if (base::PathExists(path))
+ continue;
+ int creation_flags =
+ base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ;
+ base::File file(path, creation_flags);
+
+ if (!file.IsValid()) {
+ callback_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ std::move(callback), base::File::FILE_ERROR_FAILED,
+ std::vector<blink::mojom::FileSystemEntryPtr>()));
+ return;
+ }
+ }
+ callback_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), base::File::FILE_OK,
+ std::move(result)));
+ },
+ files, std::move(result), callback_runner_, std::move(callback_)));
+ delete this;
+ return;
+ }
callback_runner_->PostTask(
FROM_HERE, base::BindOnce(std::move(callback_), base::File::FILE_OK,
std::move(result)));
diff --git a/chromium/content/browser/fileapi/file_system_chooser.h b/chromium/content/browser/fileapi/file_system_chooser.h
index 2283a6725e3..56a2498bccc 100644
--- a/chromium/content/browser/fileapi/file_system_chooser.h
+++ b/chromium/content/browser/fileapi/file_system_chooser.h
@@ -7,6 +7,7 @@
#include "base/files/file.h"
#include "base/task_runner.h"
+#include "content/common/content_export.h"
#include "third_party/blink/public/mojom/filesystem/file_system.mojom.h"
#include "ui/shell_dialogs/select_file_dialog.h"
@@ -17,18 +18,23 @@ namespace content {
// a callback on a specific task runner. Furthermore the listener will delete
// itself when any of its listener methods are called.
// All of this class has to be called on the UI thread.
-class FileSystemChooser : public ui::SelectFileDialog::Listener {
+class CONTENT_EXPORT FileSystemChooser : public ui::SelectFileDialog::Listener {
public:
using ResultCallback =
base::OnceCallback<void(base::File::Error,
std::vector<blink::mojom::FileSystemEntryPtr>)>;
- static void CreateAndShow(int render_process_id,
- int frame_id,
- ResultCallback callback,
- scoped_refptr<base::TaskRunner> callback_runner);
+ static void CreateAndShow(
+ int render_process_id,
+ int frame_id,
+ blink::mojom::ChooseFileSystemEntryType type,
+ std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr> accepts,
+ bool include_accepts_all,
+ ResultCallback callback,
+ scoped_refptr<base::TaskRunner> callback_runner);
FileSystemChooser(int render_process_id,
+ blink::mojom::ChooseFileSystemEntryType type,
ResultCallback callback,
scoped_refptr<base::TaskRunner> callback_runner);
@@ -46,6 +52,7 @@ class FileSystemChooser : public ui::SelectFileDialog::Listener {
int render_process_id_;
ResultCallback callback_;
scoped_refptr<base::TaskRunner> callback_runner_;
+ blink::mojom::ChooseFileSystemEntryType type_;
scoped_refptr<ui::SelectFileDialog> dialog_;
};
diff --git a/chromium/content/browser/fileapi/file_system_chooser_browsertest.cc b/chromium/content/browser/fileapi/file_system_chooser_browsertest.cc
new file mode 100644
index 00000000000..3c323eeae4d
--- /dev/null
+++ b/chromium/content/browser/fileapi/file_system_chooser_browsertest.cc
@@ -0,0 +1,195 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/threading/thread_restrictions.h"
+#include "content/browser/fileapi/file_system_chooser_test_helpers.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "third_party/blink/public/common/features.h"
+#include "ui/shell_dialogs/select_file_dialog.h"
+#include "ui/shell_dialogs/select_file_dialog_factory.h"
+#include "ui/shell_dialogs/select_file_policy.h"
+
+namespace content {
+
+// This browser test implements end-to-end tests for the chooseFileSystemEntry
+// API.
+class FileSystemChooserBrowserTest : public ContentBrowserTest {
+ public:
+ void SetUp() override {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ scoped_feature_list_.InitAndEnableFeature(
+ blink::features::kWritableFilesAPI);
+ ContentBrowserTest::SetUp();
+ }
+
+ void TearDown() override {
+ ContentBrowserTest::TearDown();
+ ASSERT_TRUE(temp_dir_.Delete());
+ ui::SelectFileDialog::SetFactory(nullptr);
+ }
+
+ base::FilePath CreateTestFile(const std::string& contents) {
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ base::FilePath result;
+ EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &result));
+ EXPECT_EQ(int{contents.size()},
+ base::WriteFile(result, contents.data(), contents.size()));
+ return result;
+ }
+
+ base::FilePath CreateTestDir() {
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ base::FilePath result;
+ EXPECT_TRUE(base::CreateTemporaryDirInDir(
+ temp_dir_.GetPath(), FILE_PATH_LITERAL("test"), &result));
+ return result;
+ }
+
+ protected:
+ const std::string kBlankHtml = "<!DOCTYPE html><html><body>";
+ const GURL kTestUrl = GURL("https://foobar.com/");
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+ base::ScopedTempDir temp_dir_;
+};
+
+IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, CancelDialog) {
+ ui::SelectFileDialog::SetFactory(new CancellingSelectFileDialogFactory);
+ LoadDataWithBaseURL(shell(), kTestUrl, kBlankHtml, kTestUrl);
+ auto result = EvalJs(shell(), "self.chooseFileSystemEntries()");
+ EXPECT_TRUE(result.error.find("AbortError") != std::string::npos)
+ << result.error;
+}
+
+IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, OpenFile) {
+ const std::string file_contents = "hello world!";
+ const base::FilePath test_file = CreateTestFile(file_contents);
+ SelectFileDialogParams dialog_params;
+ ui::SelectFileDialog::SetFactory(
+ new FakeSelectFileDialogFactory({test_file}, &dialog_params));
+ LoadDataWithBaseURL(shell(), kTestUrl, kBlankHtml, kTestUrl);
+ EXPECT_EQ(test_file.BaseName().AsUTF8Unsafe(),
+ EvalJs(shell(),
+ "(async () => {"
+ " let e = await self.chooseFileSystemEntries();"
+ " self.selected_entry = e;"
+ " return e.name; })()"));
+ EXPECT_EQ(ui::SelectFileDialog::SELECT_OPEN_FILE, dialog_params.type);
+ EXPECT_EQ(
+ file_contents,
+ EvalJs(shell(),
+ "(async () => { const file = await self.selected_entry.getFile(); "
+ "return await new Response(file).text(); })()"));
+}
+
+IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, SaveFile) {
+ const std::string file_contents = "file contents to write";
+ const base::FilePath test_file = CreateTestFile("");
+ {
+ // Delete file, since SaveFile should be able to deal with non-existing
+ // files.
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ ASSERT_TRUE(base::DeleteFile(test_file, false));
+ }
+ SelectFileDialogParams dialog_params;
+ ui::SelectFileDialog::SetFactory(
+ new FakeSelectFileDialogFactory({test_file}, &dialog_params));
+ LoadDataWithBaseURL(shell(), kTestUrl, kBlankHtml, kTestUrl);
+ EXPECT_EQ(test_file.BaseName().AsUTF8Unsafe(),
+ EvalJs(shell(),
+ "(async () => {"
+ " let e = await self.chooseFileSystemEntries("
+ " {type: 'saveFile'});"
+ " self.entry = e;"
+ " return e.name; })()"));
+ EXPECT_EQ(ui::SelectFileDialog::SELECT_SAVEAS_FILE, dialog_params.type);
+ EXPECT_EQ(int{file_contents.size()},
+ EvalJs(shell(),
+ JsReplace("(async () => {"
+ " const w = await self.entry.createWriter();"
+ " await w.write(0, new Blob([$1]));"
+ " return (await self.entry.getFile()).size; })()",
+ file_contents)));
+ {
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ std::string read_contents;
+ EXPECT_TRUE(base::ReadFileToString(test_file, &read_contents));
+ EXPECT_EQ(file_contents, read_contents);
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, OpenMultipleFiles) {
+ const base::FilePath test_file1 = CreateTestFile("file1");
+ const base::FilePath test_file2 = CreateTestFile("file2");
+ SelectFileDialogParams dialog_params;
+ ui::SelectFileDialog::SetFactory(new FakeSelectFileDialogFactory(
+ {test_file1, test_file2}, &dialog_params));
+ LoadDataWithBaseURL(shell(), kTestUrl, kBlankHtml, kTestUrl);
+ EXPECT_EQ(ListValueOf(test_file1.BaseName().AsUTF8Unsafe(),
+ test_file2.BaseName().AsUTF8Unsafe()),
+ EvalJs(shell(),
+ "(async () => {"
+ " let e = await self.chooseFileSystemEntries("
+ " {multiple: true});"
+ " return e.map(x => x.name); })()"));
+ EXPECT_EQ(ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE, dialog_params.type);
+}
+
+IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, OpenDirectory) {
+ base::FilePath test_dir = CreateTestDir();
+ SelectFileDialogParams dialog_params;
+ ui::SelectFileDialog::SetFactory(
+ new FakeSelectFileDialogFactory({test_dir}, &dialog_params));
+ LoadDataWithBaseURL(shell(), kTestUrl, kBlankHtml, kTestUrl);
+ EXPECT_EQ(test_dir.BaseName().AsUTF8Unsafe(),
+ EvalJs(shell(),
+ "(async () => {"
+ " let e = await self.chooseFileSystemEntries("
+ " {type: 'openDirectory'});"
+ " self.selected_entry = e;"
+ " return e.name; })()"));
+ EXPECT_EQ(ui::SelectFileDialog::SELECT_FOLDER, dialog_params.type);
+}
+
+IN_PROC_BROWSER_TEST_F(FileSystemChooserBrowserTest, AcceptsOptions) {
+ SelectFileDialogParams dialog_params;
+ ui::SelectFileDialog::SetFactory(
+ new CancellingSelectFileDialogFactory(&dialog_params));
+ LoadDataWithBaseURL(shell(), kTestUrl, kBlankHtml, kTestUrl);
+ auto result = EvalJs(shell(),
+ "self.chooseFileSystemEntries({accepts: ["
+ " {description: 'no-extensions'},"
+ " {description: 'foo', extensions: ['txt', 'Js']},"
+ " {mimeTypes: ['image/jpeg']}"
+ "]})");
+ EXPECT_TRUE(result.error.find("AbortError") != std::string::npos)
+ << result.error;
+
+ ASSERT_TRUE(dialog_params.file_types);
+ EXPECT_TRUE(dialog_params.file_types->include_all_files);
+ ASSERT_EQ(2u, dialog_params.file_types->extensions.size());
+ ASSERT_EQ(2u, dialog_params.file_types->extensions[0].size());
+ EXPECT_EQ(FILE_PATH_LITERAL("Js"),
+ dialog_params.file_types->extensions[0][0]);
+ EXPECT_EQ(FILE_PATH_LITERAL("txt"),
+ dialog_params.file_types->extensions[0][1]);
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[1],
+ FILE_PATH_LITERAL("jpg")));
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[1],
+ FILE_PATH_LITERAL("jpeg")));
+
+ ASSERT_EQ(2u,
+ dialog_params.file_types->extension_description_overrides.size());
+ EXPECT_EQ(base::ASCIIToUTF16("foo"),
+ dialog_params.file_types->extension_description_overrides[0]);
+ EXPECT_EQ(base::ASCIIToUTF16(""),
+ dialog_params.file_types->extension_description_overrides[1]);
+}
+
+} // namespace content \ No newline at end of file
diff --git a/chromium/content/browser/fileapi/file_system_chooser_test_helpers.cc b/chromium/content/browser/fileapi/file_system_chooser_test_helpers.cc
new file mode 100644
index 00000000000..958f652817c
--- /dev/null
+++ b/chromium/content/browser/fileapi/file_system_chooser_test_helpers.cc
@@ -0,0 +1,126 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "file_system_chooser_test_helpers.h"
+
+namespace content {
+
+namespace {
+
+class CancellingSelectFileDialog : public ui::SelectFileDialog {
+ public:
+ CancellingSelectFileDialog(SelectFileDialogParams* out_params,
+ Listener* listener,
+ std::unique_ptr<ui::SelectFilePolicy> policy)
+ : ui::SelectFileDialog(listener, std::move(policy)),
+ out_params_(out_params) {}
+
+ protected:
+ void SelectFileImpl(Type type,
+ const base::string16& title,
+ const base::FilePath& default_path,
+ const FileTypeInfo* file_types,
+ int file_type_index,
+ const base::FilePath::StringType& default_extension,
+ gfx::NativeWindow owning_window,
+ void* params) override {
+ if (out_params_) {
+ out_params_->type = type;
+ if (file_types)
+ out_params_->file_types = *file_types;
+ else
+ out_params_->file_types = base::nullopt;
+ }
+ listener_->FileSelectionCanceled(params);
+ }
+
+ bool IsRunning(gfx::NativeWindow owning_window) const override {
+ return false;
+ }
+ void ListenerDestroyed() override {}
+ bool HasMultipleFileTypeChoicesImpl() override { return false; }
+
+ private:
+ ~CancellingSelectFileDialog() override = default;
+ SelectFileDialogParams* out_params_;
+};
+
+class FakeSelectFileDialog : public ui::SelectFileDialog {
+ public:
+ FakeSelectFileDialog(std::vector<base::FilePath> result,
+ SelectFileDialogParams* out_params,
+ Listener* listener,
+ std::unique_ptr<ui::SelectFilePolicy> policy)
+ : ui::SelectFileDialog(listener, std::move(policy)),
+ result_(std::move(result)),
+ out_params_(out_params) {}
+
+ protected:
+ void SelectFileImpl(Type type,
+ const base::string16& title,
+ const base::FilePath& default_path,
+ const FileTypeInfo* file_types,
+ int file_type_index,
+ const base::FilePath::StringType& default_extension,
+ gfx::NativeWindow owning_window,
+ void* params) override {
+ if (out_params_) {
+ out_params_->type = type;
+ if (file_types)
+ out_params_->file_types = *file_types;
+ else
+ out_params_->file_types = base::nullopt;
+ }
+ if (result_.size() == 1)
+ listener_->FileSelected(result_[0], 0, params);
+ else
+ listener_->MultiFilesSelected(result_, params);
+ }
+
+ bool IsRunning(gfx::NativeWindow owning_window) const override {
+ return false;
+ }
+ void ListenerDestroyed() override {}
+ bool HasMultipleFileTypeChoicesImpl() override { return false; }
+
+ private:
+ ~FakeSelectFileDialog() override = default;
+ std::vector<base::FilePath> result_;
+ SelectFileDialogParams* out_params_;
+};
+
+} // namespace
+
+SelectFileDialogParams::SelectFileDialogParams() = default;
+SelectFileDialogParams::~SelectFileDialogParams() = default;
+
+CancellingSelectFileDialogFactory::CancellingSelectFileDialogFactory(
+ SelectFileDialogParams* out_params)
+ : out_params_(out_params) {}
+
+CancellingSelectFileDialogFactory::~CancellingSelectFileDialogFactory() =
+ default;
+
+ui::SelectFileDialog* CancellingSelectFileDialogFactory::Create(
+ ui::SelectFileDialog::Listener* listener,
+ std::unique_ptr<ui::SelectFilePolicy> policy) {
+ return new CancellingSelectFileDialog(out_params_, listener,
+ std::move(policy));
+}
+
+FakeSelectFileDialogFactory::FakeSelectFileDialogFactory(
+ std::vector<base::FilePath> result,
+ SelectFileDialogParams* out_params)
+ : result_(std::move(result)), out_params_(out_params) {}
+
+FakeSelectFileDialogFactory::~FakeSelectFileDialogFactory() = default;
+
+ui::SelectFileDialog* FakeSelectFileDialogFactory::Create(
+ ui::SelectFileDialog::Listener* listener,
+ std::unique_ptr<ui::SelectFilePolicy> policy) {
+ return new FakeSelectFileDialog(result_, out_params_, listener,
+ std::move(policy));
+}
+
+} // namespace content \ No newline at end of file
diff --git a/chromium/content/browser/fileapi/file_system_chooser_test_helpers.h b/chromium/content/browser/fileapi/file_system_chooser_test_helpers.h
new file mode 100644
index 00000000000..a26fc2d71b7
--- /dev/null
+++ b/chromium/content/browser/fileapi/file_system_chooser_test_helpers.h
@@ -0,0 +1,60 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_FILEAPI_FILE_SYSTEM_CHOOSER_TEST_HELPERS_H_
+#define CONTENT_BROWSER_FILEAPI_FILE_SYSTEM_CHOOSER_TEST_HELPERS_H_
+
+#include "base/optional.h"
+#include "ui/shell_dialogs/select_file_dialog.h"
+#include "ui/shell_dialogs/select_file_dialog_factory.h"
+#include "ui/shell_dialogs/select_file_policy.h"
+
+namespace content {
+
+// Struct used to report what parameters one of the (fake) SelectFileDialog
+// implementations below was created with.
+struct SelectFileDialogParams {
+ SelectFileDialogParams();
+ ~SelectFileDialogParams();
+
+ ui::SelectFileDialog::Type type = ui::SelectFileDialog::SELECT_NONE;
+ base::Optional<ui::SelectFileDialog::FileTypeInfo> file_types;
+};
+
+// A fake ui::SelectFileDialog, which will cancel the file selection instead of
+// selecting a file.
+class CancellingSelectFileDialogFactory : public ui::SelectFileDialogFactory {
+ public:
+ explicit CancellingSelectFileDialogFactory(
+ SelectFileDialogParams* out_params = nullptr);
+ ~CancellingSelectFileDialogFactory() override;
+
+ ui::SelectFileDialog* Create(
+ ui::SelectFileDialog::Listener* listener,
+ std::unique_ptr<ui::SelectFilePolicy> policy) override;
+
+ private:
+ SelectFileDialogParams* out_params_;
+};
+
+// A fake ui::SelectFileDialog, which will select one or more pre-determined
+// files.
+class FakeSelectFileDialogFactory : public ui::SelectFileDialogFactory {
+ public:
+ FakeSelectFileDialogFactory(std::vector<base::FilePath> result,
+ SelectFileDialogParams* out_params = nullptr);
+ ~FakeSelectFileDialogFactory() override;
+
+ ui::SelectFileDialog* Create(
+ ui::SelectFileDialog::Listener* listener,
+ std::unique_ptr<ui::SelectFilePolicy> policy) override;
+
+ private:
+ std::vector<base::FilePath> result_;
+ SelectFileDialogParams* out_params_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_FILEAPI_FILE_SYSTEM_CHOOSER_TEST_HELPERS_H_ \ No newline at end of file
diff --git a/chromium/content/browser/fileapi/file_system_chooser_unittest.cc b/chromium/content/browser/fileapi/file_system_chooser_unittest.cc
new file mode 100644
index 00000000000..b95cb53404b
--- /dev/null
+++ b/chromium/content/browser/fileapi/file_system_chooser_unittest.cc
@@ -0,0 +1,168 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/fileapi/file_system_chooser.h"
+
+#include "base/run_loop.h"
+#include "base/stl_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/bind_test_util.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "content/browser/fileapi/file_system_chooser_test_helpers.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/shell_dialogs/select_file_dialog.h"
+#include "ui/shell_dialogs/select_file_dialog_factory.h"
+#include "ui/shell_dialogs/select_file_policy.h"
+
+namespace content {
+
+class FileSystemChooserTest : public testing::Test {
+ public:
+ void TearDown() override { ui::SelectFileDialog::SetFactory(nullptr); }
+
+ void SyncShowDialog(
+ std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr> accepts,
+ bool include_accepts_all) {
+ base::RunLoop loop;
+ FileSystemChooser::CreateAndShow(
+ 0, 0, blink::mojom::ChooseFileSystemEntryType::kOpenFile,
+ std::move(accepts), include_accepts_all,
+ base::BindLambdaForTesting(
+ [&](base::File::Error,
+ std::vector<blink::mojom::FileSystemEntryPtr>) {
+ loop.Quit();
+ }),
+ base::SequencedTaskRunnerHandle::Get());
+ loop.Run();
+ }
+
+ private:
+ content::TestBrowserThreadBundle thread_bundle_;
+};
+
+TEST_F(FileSystemChooserTest, EmptyAccepts) {
+ SelectFileDialogParams dialog_params;
+ ui::SelectFileDialog::SetFactory(
+ new CancellingSelectFileDialogFactory(&dialog_params));
+ SyncShowDialog({}, /*include_accepts_all=*/true);
+
+ ASSERT_TRUE(dialog_params.file_types);
+ EXPECT_TRUE(dialog_params.file_types->include_all_files);
+ EXPECT_EQ(0u, dialog_params.file_types->extensions.size());
+ EXPECT_EQ(0u,
+ dialog_params.file_types->extension_description_overrides.size());
+}
+
+TEST_F(FileSystemChooserTest, EmptyAcceptsIgnoresIncludeAcceptsAll) {
+ SelectFileDialogParams dialog_params;
+ ui::SelectFileDialog::SetFactory(
+ new CancellingSelectFileDialogFactory(&dialog_params));
+ SyncShowDialog({}, /*include_accepts_all=*/false);
+
+ // Should still include_all_files, even though include_accepts_all was false.
+ ASSERT_TRUE(dialog_params.file_types);
+ EXPECT_TRUE(dialog_params.file_types->include_all_files);
+ EXPECT_EQ(0u, dialog_params.file_types->extensions.size());
+ EXPECT_EQ(0u,
+ dialog_params.file_types->extension_description_overrides.size());
+}
+
+TEST_F(FileSystemChooserTest, AcceptsMimeTypes) {
+ SelectFileDialogParams dialog_params;
+ ui::SelectFileDialog::SetFactory(
+ new CancellingSelectFileDialogFactory(&dialog_params));
+ std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr> accepts;
+ accepts.emplace_back(blink::mojom::ChooseFileSystemEntryAcceptsOption::New(
+ base::ASCIIToUTF16(""), std::vector<std::string>({"tExt/Plain"}),
+ std::vector<std::string>({})));
+ accepts.emplace_back(blink::mojom::ChooseFileSystemEntryAcceptsOption::New(
+ base::ASCIIToUTF16("Images"), std::vector<std::string>({"image/*"}),
+ std::vector<std::string>({})));
+ SyncShowDialog(std::move(accepts), /*include_accepts_all=*/true);
+
+ ASSERT_TRUE(dialog_params.file_types);
+ EXPECT_TRUE(dialog_params.file_types->include_all_files);
+ ASSERT_EQ(2u, dialog_params.file_types->extensions.size());
+
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[0],
+ FILE_PATH_LITERAL("text")));
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[0],
+ FILE_PATH_LITERAL("txt")));
+
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[1],
+ FILE_PATH_LITERAL("gif")));
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[1],
+ FILE_PATH_LITERAL("jpg")));
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[1],
+ FILE_PATH_LITERAL("jpeg")));
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[1],
+ FILE_PATH_LITERAL("png")));
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[1],
+ FILE_PATH_LITERAL("tiff")));
+
+ ASSERT_EQ(2u,
+ dialog_params.file_types->extension_description_overrides.size());
+ EXPECT_EQ(base::ASCIIToUTF16(""),
+ dialog_params.file_types->extension_description_overrides[0]);
+ EXPECT_EQ(base::ASCIIToUTF16("Images"),
+ dialog_params.file_types->extension_description_overrides[1]);
+}
+
+TEST_F(FileSystemChooserTest, AcceptsExtensions) {
+ SelectFileDialogParams dialog_params;
+ ui::SelectFileDialog::SetFactory(
+ new CancellingSelectFileDialogFactory(&dialog_params));
+ std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr> accepts;
+ accepts.emplace_back(blink::mojom::ChooseFileSystemEntryAcceptsOption::New(
+ base::ASCIIToUTF16(""), std::vector<std::string>({}),
+ std::vector<std::string>({"text", "js", "text"})));
+ SyncShowDialog(std::move(accepts), /*include_accepts_all=*/true);
+
+ ASSERT_TRUE(dialog_params.file_types);
+ EXPECT_TRUE(dialog_params.file_types->include_all_files);
+ ASSERT_EQ(1u, dialog_params.file_types->extensions.size());
+
+ EXPECT_EQ(2u, dialog_params.file_types->extensions[0].size());
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[0],
+ FILE_PATH_LITERAL("text")));
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[0],
+ FILE_PATH_LITERAL("js")));
+
+ ASSERT_EQ(1u,
+ dialog_params.file_types->extension_description_overrides.size());
+ EXPECT_EQ(base::ASCIIToUTF16(""),
+ dialog_params.file_types->extension_description_overrides[0]);
+}
+
+TEST_F(FileSystemChooserTest, AcceptsExtensionsAndMimeTypes) {
+ SelectFileDialogParams dialog_params;
+ ui::SelectFileDialog::SetFactory(
+ new CancellingSelectFileDialogFactory(&dialog_params));
+ std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr> accepts;
+ accepts.emplace_back(blink::mojom::ChooseFileSystemEntryAcceptsOption::New(
+ base::ASCIIToUTF16(""), std::vector<std::string>({"image/*"}),
+ std::vector<std::string>({"text", "jpg"})));
+ SyncShowDialog(std::move(accepts), /*include_accepts_all=*/false);
+
+ ASSERT_TRUE(dialog_params.file_types);
+ EXPECT_FALSE(dialog_params.file_types->include_all_files);
+ ASSERT_EQ(1u, dialog_params.file_types->extensions.size());
+
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[0],
+ FILE_PATH_LITERAL("text")));
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[0],
+ FILE_PATH_LITERAL("gif")));
+ EXPECT_TRUE(base::ContainsValue(dialog_params.file_types->extensions[0],
+ FILE_PATH_LITERAL("jpeg")));
+ EXPECT_EQ(1, base::STLCount(dialog_params.file_types->extensions[0],
+ FILE_PATH_LITERAL("jpg")));
+
+ ASSERT_EQ(1u,
+ dialog_params.file_types->extension_description_overrides.size());
+ EXPECT_EQ(base::ASCIIToUTF16(""),
+ dialog_params.file_types->extension_description_overrides[0]);
+}
+
+} // namespace content \ No newline at end of file
diff --git a/chromium/content/browser/fileapi/file_system_manager_impl.cc b/chromium/content/browser/fileapi/file_system_manager_impl.cc
index e8b7272c921..c11ea6c1905 100644
--- a/chromium/content/browser/fileapi/file_system_manager_impl.cc
+++ b/chromium/content/browser/fileapi/file_system_manager_impl.cc
@@ -16,6 +16,7 @@
#include "base/metrics/user_metrics.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_util.h"
+#include "base/task/post_task.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "build/build_config.h"
@@ -26,6 +27,7 @@
#include "content/browser/fileapi/browser_file_system_helper.h"
#include "content/browser/fileapi/file_system_chooser.h"
#include "content/common/fileapi/webblob_messages.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "ipc/ipc_platform_file.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
@@ -121,9 +123,11 @@ struct FileSystemManagerImpl::ReadDirectorySyncCallbackEntry {
FileSystemManagerImpl::FileSystemManagerImpl(
int process_id,
+ int frame_id,
storage::FileSystemContext* file_system_context,
scoped_refptr<ChromeBlobStorageContext> blob_storage_context)
: process_id_(process_id),
+ frame_id_(frame_id),
context_(file_system_context),
security_policy_(ChildProcessSecurityPolicyImpl::GetInstance()),
blob_storage_context_(blob_storage_context),
@@ -588,19 +592,23 @@ void FileSystemManagerImpl::CreateWriter(const GURL& file_path,
std::move(callback).Run(base::File::FILE_OK, std::move(writer));
}
-void FileSystemManagerImpl::ChooseEntry(int32_t render_frame_id,
- ChooseEntryCallback callback) {
+void FileSystemManagerImpl::ChooseEntry(
+ blink::mojom::ChooseFileSystemEntryType type,
+ std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr> accepts,
+ bool include_accepts_all,
+ ChooseEntryCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!base::FeatureList::IsEnabled(blink::features::kWritableFilesAPI)) {
bindings_.ReportBadMessage("FSMI_WRITABLE_FILES_DISABLED");
return;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&FileSystemChooser::CreateAndShow, process_id_,
- render_frame_id, std::move(callback),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(
+ &FileSystemChooser::CreateAndShow, process_id_, frame_id_, type,
+ std::move(accepts), include_accepts_all, std::move(callback),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})));
}
void FileSystemManagerImpl::Cancel(
@@ -741,8 +749,11 @@ void FileSystemManagerImpl::DidResolveURL(
type == storage::FileSystemContext::RESOLVED_ENTRY_NOT_FOUND)
result = base::File::FILE_ERROR_NOT_FOUND;
+ base::FilePath normalized_path(
+ storage::VirtualPath::GetNormalizedFilePath(file_path));
std::move(callback).Run(
- mojo::ConvertTo<blink::mojom::FileSystemInfoPtr>(info), file_path,
+ mojo::ConvertTo<blink::mojom::FileSystemInfoPtr>(info),
+ std::move(normalized_path),
type == storage::FileSystemContext::RESOLVED_ENTRY_DIRECTORY, result);
// For ResolveURL we do not create a new operation, so no unregister here.
}
@@ -818,8 +829,8 @@ void FileSystemManagerImpl::GetPlatformPathOnFileThread(
GetPlatformPathCallback callback) {
base::FilePath platform_path;
SyncGetPlatformPath(context, process_id, path, &platform_path);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&FileSystemManagerImpl::DidGetPlatformPath,
file_system_manager, std::move(callback), platform_path));
}
diff --git a/chromium/content/browser/fileapi/file_system_manager_impl.h b/chromium/content/browser/fileapi/file_system_manager_impl.h
index f5e4cbf7f4c..fa0fd86b63a 100644
--- a/chromium/content/browser/fileapi/file_system_manager_impl.h
+++ b/chromium/content/browser/fileapi/file_system_manager_impl.h
@@ -57,9 +57,12 @@ class ChromeBlobStorageContext;
class CONTENT_EXPORT FileSystemManagerImpl
: public blink::mojom::FileSystemManager {
public:
- // Used by the renderer process host on the UI thread.
+ // Constructed and held by the render frame host and render process host on
+ // the UI thread. Used by render frames (via the render frame host), workers
+ // and pepper (via the render process host).
FileSystemManagerImpl(
int process_id,
+ int frame_id,
storage::FileSystemContext* file_system_context,
scoped_refptr<ChromeBlobStorageContext> blob_storage_context);
~FileSystemManagerImpl() override;
@@ -122,8 +125,11 @@ class CONTENT_EXPORT FileSystemManagerImpl
GetPlatformPathCallback callback) override;
void CreateWriter(const GURL& file_path,
CreateWriterCallback callback) override;
- void ChooseEntry(int32_t render_frame_id,
- ChooseEntryCallback callback) override;
+ void ChooseEntry(
+ blink::mojom::ChooseFileSystemEntryType type,
+ std::vector<blink::mojom::ChooseFileSystemEntryAcceptsOptionPtr> accepts,
+ bool include_accepts_all,
+ ChooseEntryCallback callback) override;
private:
class FileSystemCancellableOperationImpl;
@@ -206,6 +212,7 @@ class CONTENT_EXPORT FileSystemManagerImpl
void OnConnectionErrorForOpListeners(OperationListenerID listener_id);
const int process_id_;
+ const int frame_id_;
storage::FileSystemContext* const context_;
ChildProcessSecurityPolicyImpl* const security_policy_;
const scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
diff --git a/chromium/content/browser/fileapi/file_system_url_loader_factory.cc b/chromium/content/browser/fileapi/file_system_url_loader_factory.cc
index 3e55c0fa785..4357a05be56 100644
--- a/chromium/content/browser/fileapi/file_system_url_loader_factory.cc
+++ b/chromium/content/browser/fileapi/file_system_url_loader_factory.cc
@@ -20,6 +20,7 @@
#include "build/build_config.h"
#include "components/services/filesystem/public/interfaces/types.mojom.h"
#include "content/browser/child_process_security_policy_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@@ -473,7 +474,8 @@ class FileSystemFileURLLoader : public FileSystemEntryURLLoader {
data_producer_ = std::make_unique<mojo::StringDataPipeProducer>(
std::move(pipe.producer_handle));
- file_data_ = new net::IOBuffer(kDefaultFileSystemUrlPipeSize);
+ file_data_ =
+ base::MakeRefCounted<net::IOBuffer>(kDefaultFileSystemUrlPipeSize);
ReadMoreFileData();
}
@@ -638,7 +640,7 @@ CreateFileSystemURLLoaderFactory(
return std::make_unique<FileSystemURLLoaderFactory>(
std::move(params),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
}
} // namespace content
diff --git a/chromium/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc b/chromium/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc
index 980fddbef0f..548f4532a64 100644
--- a/chromium/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc
+++ b/chromium/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc
@@ -12,10 +12,12 @@
#include "base/files/scoped_temp_dir.h"
#include "base/i18n/unicodestring.h"
#include "base/rand_util.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/fileapi/file_system_url_loader_factory.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/content_browser_test.h"
#include "content/shell/browser/shell.h"
#include "net/base/mime_util.h"
@@ -181,8 +183,8 @@ class FileSystemURLLoaderFactoryTest : public ContentBrowserTest {
void TearDownOnMainThread() override {
loader_.reset();
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&ShutdownFileSystemContextOnIOThread,
std::move(file_system_context_)));
special_storage_policy_ = nullptr;
diff --git a/chromium/content/browser/find_request_manager.cc b/chromium/content/browser/find_request_manager.cc
index 9ae22e14473..e650a39d96a 100644
--- a/chromium/content/browser/find_request_manager.cc
+++ b/chromium/content/browser/find_request_manager.cc
@@ -12,7 +12,6 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
#include "content/public/browser/guest_mode.h"
-#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
namespace content {
@@ -215,6 +214,29 @@ class FindRequestManager::FrameObserver : public WebContentsObserver {
DISALLOW_COPY_AND_ASSIGN(FrameObserver);
};
+FindRequestManager::FindRequest::FindRequest() {}
+
+FindRequestManager::FindRequest::FindRequest(
+ int id,
+ const base::string16& search_text,
+ blink::mojom::FindOptionsPtr options)
+ : id(id), search_text(search_text), options(std::move(options)) {}
+
+FindRequestManager::FindRequest::FindRequest(const FindRequest& request)
+ : id(request.id),
+ search_text(request.search_text),
+ options(request.options.Clone()) {}
+
+FindRequestManager::FindRequest::~FindRequest() {}
+
+FindRequestManager::FindRequest& FindRequestManager::FindRequest::operator=(
+ const FindRequest& request) {
+ id = request.id;
+ search_text = request.search_text;
+ options = request.options.Clone();
+ return *this;
+}
+
#if defined(OS_ANDROID)
FindRequestManager::ActivateNearestFindResultState::
ActivateNearestFindResultState() = default;
@@ -252,7 +274,7 @@ FindRequestManager::~FindRequestManager() {}
void FindRequestManager::Find(int request_id,
const base::string16& search_text,
- const blink::WebFindOptions& options) {
+ blink::mojom::FindOptionsPtr options) {
// Every find request must have a unique ID, and these IDs must strictly
// increase so that newer requests always have greater IDs than older
// requests.
@@ -260,10 +282,10 @@ void FindRequestManager::Find(int request_id,
DCHECK_GT(request_id, current_session_id_);
// If this is a new find session, clear any queued requests from last session.
- if (!options.find_next)
+ if (!options->find_next)
find_request_queue_ = base::queue<FindRequest>();
- find_request_queue_.emplace(request_id, search_text, options);
+ find_request_queue_.emplace(request_id, search_text, std::move(options));
if (find_request_queue_.size() == 1)
FindInternal(find_request_queue_.front());
}
@@ -306,7 +328,7 @@ void FindRequestManager::HandleFinalUpdateForFrame(RenderFrameHostImpl* rfh,
// This is the final update for all frames for the current find operation.
if (request_id == current_request_.id && request_id != current_session_id_) {
- DCHECK(current_request_.options.find_next);
+ DCHECK(current_request_.options->find_next);
DCHECK_EQ(pending_find_next_reply_, rfh);
pending_find_next_reply_ = nullptr;
}
@@ -546,7 +568,7 @@ void FindRequestManager::FindInternal(const FindRequest& request) {
DCHECK_GT(request.id, current_request_.id);
DCHECK_GT(request.id, current_session_id_);
- if (request.options.find_next) {
+ if (request.options->find_next) {
// This is a find next operation.
// This implies that there is an ongoing find session with the same search
@@ -559,7 +581,7 @@ void FindRequestManager::FindInternal(const FindRequest& request) {
RenderFrameHost* target_rfh =
contents_->GetFocusedWebContents()->GetFocusedFrame();
if (!target_rfh || !CheckFrame(target_rfh))
- target_rfh = GetInitialFrame(request.options.forward);
+ target_rfh = GetInitialFrame(request.options->forward);
SendFindRequest(request, target_rfh);
current_request_ = request;
@@ -593,20 +615,14 @@ void FindRequestManager::SendFindRequest(const FindRequest& request,
DCHECK(CheckFrame(rfh));
DCHECK(rfh->IsRenderFrameLive());
- if (request.options.find_next)
+ if (request.options->find_next)
pending_find_next_reply_ = rfh;
else
pending_initial_replies_.insert(rfh);
- blink::mojom::FindOptionsPtr options(blink::mojom::FindOptions::New());
- options->forward = request.options.forward;
- options->match_case = request.options.match_case;
- options->find_next = request.options.find_next;
- options->force = request.options.force;
- options->run_synchronously_for_testing =
- request.options.run_synchronously_for_testing;
static_cast<RenderFrameHostImpl*>(rfh)->GetFindInPage()->Find(
- request.id, base::UTF16ToUTF8(request.search_text), std::move(options));
+ request.id, base::UTF16ToUTF8(request.search_text),
+ request.options.Clone());
}
void FindRequestManager::NotifyFindReply(int request_id, bool final_update) {
@@ -674,8 +690,8 @@ void FindRequestManager::AddFrame(RenderFrameHost* rfh, bool force) {
FindRequest request = current_request_;
request.id = current_session_id_;
- request.options.find_next = false;
- request.options.force = force;
+ request.options->find_next = false;
+ request.options->force = force;
SendFindRequest(request, rfh);
}
@@ -722,40 +738,42 @@ void FindRequestManager::FinalUpdateReceived(int request_id,
// request must be sent.
RenderFrameHost* target_rfh;
- if (request_id == current_request_.id && current_request_.options.find_next) {
+ if (request_id == current_request_.id &&
+ current_request_.options->find_next) {
// If this was a find next operation, then the active match will be in the
// next frame with matches after this one.
- target_rfh = Traverse(rfh,
- current_request_.options.forward,
- true /* matches_only */,
- true /* wrap */);
+ target_rfh = Traverse(rfh, current_request_.options->forward,
+ true /* matches_only */, true /* wrap */);
} else if ((target_rfh =
contents_->GetFocusedWebContents()->GetFocusedFrame()) !=
nullptr) {
// Otherwise, if there is a focused frame, then the active match will be in
// the next frame with matches after that one.
- target_rfh = Traverse(target_rfh,
- current_request_.options.forward,
- true /* matches_only */,
- true /* wrap */);
+ target_rfh = Traverse(target_rfh, current_request_.options->forward,
+ true /* matches_only */, true /* wrap */);
} else {
// Otherwise, the first frame with matches will have the active match.
- target_rfh = GetInitialFrame(current_request_.options.forward);
+ target_rfh = GetInitialFrame(current_request_.options->forward);
if (!CheckFrame(target_rfh) ||
!find_in_page_clients_[target_rfh]->number_of_matches()) {
- target_rfh = Traverse(target_rfh,
- current_request_.options.forward,
- true /* matches_only */,
- false /* wrap */);
+ target_rfh = Traverse(target_rfh, current_request_.options->forward,
+ true /* matches_only */, false /* wrap */);
}
}
- DCHECK(target_rfh);
+ if (!target_rfh) {
+ // Sometimes when the WebContents is deleted/navigated, we got into this
+ // situation. We don't care about this WebContents anyways so it's ok to
+ // just not ask for the active match and return immediately.
+ // TODO(rakina): Understand what leads to this situation.
+ // See: https://crbug.com/884679.
+ return;
+ }
// Forward the find reply without |final_update| set because the active match
// has not yet been found.
NotifyFindReply(request_id, false /* final_update */);
- current_request_.options.find_next = true;
+ current_request_.options->find_next = true;
SendFindRequest(current_request_, target_rfh);
}
diff --git a/chromium/content/browser/find_request_manager.h b/chromium/content/browser/find_request_manager.h
index 62050f4611a..1031dfe915c 100644
--- a/chromium/content/browser/find_request_manager.h
+++ b/chromium/content/browser/find_request_manager.h
@@ -14,7 +14,7 @@
#include "content/common/content_export.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/stop_find_action.h"
-#include "third_party/blink/public/web/web_find_options.h"
+#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
@@ -40,7 +40,7 @@ class CONTENT_EXPORT FindRequestManager {
// |options|. |request_id| uniquely identifies the find request.
void Find(int request_id,
const base::string16& search_text,
- const blink::WebFindOptions& options);
+ blink::mojom::FindOptionsPtr options);
// Stops the active find session and clears the general highlighting of the
// matches. |action| determines whether the last active match (if any) will be
@@ -116,13 +116,16 @@ class CONTENT_EXPORT FindRequestManager {
base::string16 search_text;
// The set of find options in effect for this find request.
- blink::WebFindOptions options;
+ blink::mojom::FindOptionsPtr options;
- FindRequest() = default;
+ FindRequest();
FindRequest(int id,
const base::string16& search_text,
- const blink::WebFindOptions& options)
- : id(id), search_text(search_text), options(options) {}
+ blink::mojom::FindOptionsPtr options);
+ FindRequest(const FindRequest& request);
+ ~FindRequest();
+
+ FindRequest& operator=(const FindRequest& request);
};
// Resets all of the per-session state for a new find-in-page session.
diff --git a/chromium/content/browser/find_request_manager_browsertest.cc b/chromium/content/browser/find_request_manager_browsertest.cc
index 0217e5ac7d0..e8c0f18a412 100644
--- a/chromium/content/browser/find_request_manager_browsertest.cc
+++ b/chromium/content/browser/find_request_manager_browsertest.cc
@@ -17,7 +17,6 @@
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
-#include "third_party/blink/public/web/web_find_options.h"
namespace content {
@@ -86,11 +85,10 @@ class FindRequestManagerTest : public ContentBrowserTest,
}
void Find(const std::string& search_text,
- const blink::WebFindOptions& options) {
+ blink::mojom::FindOptionsPtr options) {
delegate()->UpdateLastRequest(++last_request_id_);
- contents()->Find(last_request_id_,
- base::UTF8ToUTF16(search_text),
- options);
+ contents()->Find(last_request_id_, base::UTF8ToUTF16(search_text),
+ std::move(options));
}
WebContentsImpl* contents() const {
@@ -167,9 +165,9 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(Basic)) {
if (GetParam())
MakeChildFrameCrossProcess();
- blink::WebFindOptions options;
- options.run_synchronously_for_testing = true;
- Find("result", options);
+ auto options = blink::mojom::FindOptions::New();
+ options->run_synchronously_for_testing = true;
+ Find("result", options->Clone());
delegate()->WaitForFinalReply();
FindResults results = delegate()->GetFindResults();
@@ -177,9 +175,9 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(Basic)) {
EXPECT_EQ(19, results.number_of_matches);
EXPECT_EQ(1, results.active_match_ordinal);
- options.find_next = true;
+ options->find_next = true;
for (int i = 2; i <= 10; ++i) {
- Find("result", options);
+ Find("result", options->Clone());
delegate()->WaitForFinalReply();
results = delegate()->GetFindResults();
@@ -188,9 +186,9 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(Basic)) {
EXPECT_EQ(i, results.active_match_ordinal);
}
- options.forward = false;
+ options->forward = false;
for (int i = 9; i >= 5; --i) {
- Find("result", options);
+ Find("result", options->Clone());
delegate()->WaitForFinalReply();
results = delegate()->GetFindResults();
@@ -251,9 +249,9 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, ScrollAndZoomIntoView) {
ASSERT_TRUE(ExecuteScript(root, "window.scrollTo(3500, 1500);"));
// Search for a result further down in the iframe.
- blink::WebFindOptions options;
- options.run_synchronously_for_testing = true;
- Find("result 17", options);
+ auto options = blink::mojom::FindOptions::New();
+ options->run_synchronously_for_testing = true;
+ Find("result 17", options->Clone());
delegate()->WaitForFinalReply();
// gBCR of result box in iframe.
@@ -313,14 +311,14 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(CharacterByCharacter)) {
if (GetParam())
MakeChildFrameCrossProcess();
- blink::WebFindOptions default_options;
- default_options.run_synchronously_for_testing = true;
- Find("r", default_options);
- Find("re", default_options);
- Find("res", default_options);
- Find("resu", default_options);
- Find("resul", default_options);
- Find("result", default_options);
+ auto default_options = blink::mojom::FindOptions::New();
+ default_options->run_synchronously_for_testing = true;
+ Find("r", default_options->Clone());
+ Find("re", default_options->Clone());
+ Find("res", default_options->Clone());
+ Find("resu", default_options->Clone());
+ Find("resul", default_options->Clone());
+ Find("result", default_options->Clone());
delegate()->WaitForFinalReply();
FindResults results = delegate()->GetFindResults();
@@ -338,13 +336,13 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, DISABLED_RapidFire) {
if (GetParam())
MakeChildFrameCrossProcess();
- blink::WebFindOptions options;
- options.run_synchronously_for_testing = true;
- Find("result", options);
+ auto options = blink::mojom::FindOptions::New();
+ options->run_synchronously_for_testing = true;
+ Find("result", options.Clone());
- options.find_next = true;
+ options->find_next = true;
for (int i = 2; i <= 1000; ++i)
- Find("result", options);
+ Find("result", options.Clone());
delegate()->WaitForFinalReply();
FindResults results = delegate()->GetFindResults();
@@ -359,17 +357,17 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, DISABLED_RapidFire) {
IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, DISABLED_RemoveFrame) {
LoadMultiFramePage(2 /* height */, GetParam() /* cross_process */);
- blink::WebFindOptions options;
- options.run_synchronously_for_testing = true;
- Find("result", options);
+ auto options = blink::mojom::FindOptions::New();
+ options->run_synchronously_for_testing = true;
+ Find("result", options->Clone());
delegate()->WaitForFinalReply();
- options.find_next = true;
- options.forward = false;
- Find("result", options);
- Find("result", options);
- Find("result", options);
- Find("result", options);
- Find("result", options);
+ options->find_next = true;
+ options->forward = false;
+ Find("result", options->Clone());
+ Find("result", options->Clone());
+ Find("result", options->Clone());
+ Find("result", options->Clone());
+ Find("result", options->Clone());
delegate()->WaitForFinalReply();
FindResults results = delegate()->GetFindResults();
@@ -379,7 +377,7 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, DISABLED_RemoveFrame) {
// Remove a frame.
FrameTreeNode* root = contents()->GetFrameTree()->root();
- root->RemoveChild(root->child_at(0));
+ root->current_frame_host()->RemoveChild(root->child_at(0));
// The number of matches and active match ordinal should update automatically
// to exclude the matches from the removed frame.
@@ -393,14 +391,14 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, DISABLED_RemoveFrame) {
IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, DISABLED_AddFrame) {
LoadMultiFramePage(2 /* height */, GetParam() /* cross_process */);
- blink::WebFindOptions options;
- options.run_synchronously_for_testing = true;
- Find("result", options);
- options.find_next = true;
- Find("result", options);
- Find("result", options);
- Find("result", options);
- Find("result", options);
+ auto options = blink::mojom::FindOptions::New();
+ options->run_synchronously_for_testing = true;
+ Find("result", options.Clone());
+ options->find_next = true;
+ Find("result", options.Clone());
+ Find("result", options.Clone());
+ Find("result", options.Clone());
+ Find("result", options.Clone());
delegate()->WaitForFinalReply();
FindResults results = delegate()->GetFindResults();
@@ -433,9 +431,9 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(AddFrameAfterNoMatches)) {
NavigateToURL(shell(), GURL("about:blank"));
EXPECT_TRUE(navigation_observer.last_navigation_succeeded());
- blink::WebFindOptions default_options;
- default_options.run_synchronously_for_testing = true;
- Find("result", default_options);
+ auto default_options = blink::mojom::FindOptions::New();
+ default_options->run_synchronously_for_testing = true;
+ Find("result", default_options.Clone());
delegate()->WaitForFinalReply();
// Initially, there are no matches on the page.
@@ -466,14 +464,14 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(AddFrameAfterNoMatches)) {
IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(NavigateFrame)) {
LoadMultiFramePage(2 /* height */, GetParam() /* cross_process */);
- blink::WebFindOptions options;
- options.run_synchronously_for_testing = true;
- Find("result", options);
- options.find_next = true;
- options.forward = false;
- Find("result", options);
- Find("result", options);
- Find("result", options);
+ auto options = blink::mojom::FindOptions::New();
+ options->run_synchronously_for_testing = true;
+ Find("result", options.Clone());
+ options->find_next = true;
+ options->forward = false;
+ Find("result", options.Clone());
+ Find("result", options.Clone());
+ Find("result", options.Clone());
delegate()->WaitForFinalReply();
FindResults results = delegate()->GetFindResults();
@@ -515,9 +513,9 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(NavigateFrame)) {
IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(HiddenFrame)) {
LoadAndWait("/find_in_hidden_frame.html");
- blink::WebFindOptions default_options;
- default_options.run_synchronously_for_testing = true;
- Find("hello", default_options);
+ auto default_options = blink::mojom::FindOptions::New();
+ default_options->run_synchronously_for_testing = true;
+ Find("hello", default_options.Clone());
delegate()->WaitForFinalReply();
FindResults results = delegate()->GetFindResults();
@@ -530,12 +528,12 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(HiddenFrame)) {
IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(FindNewMatches)) {
LoadAndWait("/find_in_dynamic_page.html");
- blink::WebFindOptions options;
- options.run_synchronously_for_testing = true;
- Find("result", options);
- options.find_next = true;
- Find("result", options);
- Find("result", options);
+ auto options = blink::mojom::FindOptions::New();
+ options->run_synchronously_for_testing = true;
+ Find("result", options.Clone());
+ options->find_next = true;
+ Find("result", options.Clone());
+ Find("result", options.Clone());
delegate()->WaitForFinalReply();
FindResults results = delegate()->GetFindResults();
@@ -547,7 +545,7 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(FindNewMatches)) {
// "result".
ASSERT_TRUE(ExecuteScript(contents()->GetMainFrame(), "addNewText()"));
- Find("result", options);
+ Find("result", options.Clone());
delegate()->WaitForFinalReply();
results = delegate()->GetFindResults();
@@ -568,9 +566,9 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(FindNewMatches)) {
IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE_FindInPage_Issue627799) {
LoadAndWait("/find_in_long_page.html");
- blink::WebFindOptions options;
- options.run_synchronously_for_testing = true;
- Find("42", options);
+ auto options = blink::mojom::FindOptions::New();
+ options->run_synchronously_for_testing = true;
+ Find("42", options.Clone());
delegate()->WaitForFinalReply();
FindResults results = delegate()->GetFindResults();
@@ -579,9 +577,9 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE_FindInPage_Issue627799) {
EXPECT_EQ(1, results.active_match_ordinal);
delegate()->StartReplyRecord();
- options.find_next = true;
- options.forward = false;
- Find("42", options);
+ options->find_next = true;
+ options->forward = false;
+ Find("42", options.Clone());
delegate()->WaitForFinalReply();
// This is the crux of the issue that this test guards against. Searching
@@ -600,9 +598,9 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(FindInPage_Issue644448)) {
NavigateToURL(shell(), GURL("about:blank"));
EXPECT_TRUE(navigation_observer.last_navigation_succeeded());
- blink::WebFindOptions default_options;
- default_options.run_synchronously_for_testing = true;
- Find("result", default_options);
+ auto default_options = blink::mojom::FindOptions::New();
+ default_options->run_synchronously_for_testing = true;
+ Find("result", default_options.Clone());
delegate()->WaitForFinalReply();
// Initially, there are no matches on the page.
@@ -614,7 +612,7 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(FindInPage_Issue644448)) {
// Load a page with matches.
LoadAndWait("/find_in_simple_page.html");
- Find("result", default_options);
+ Find("result", default_options.Clone());
delegate()->WaitForFinalReply();
// There should now be matches found. When the bug was present, there were
@@ -629,9 +627,9 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(FindInPage_Issue644448)) {
IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(FindMatchRects)) {
LoadAndWait("/find_in_page.html");
- blink::WebFindOptions default_options;
- default_options.run_synchronously_for_testing = true;
- Find("result", default_options);
+ auto default_options = blink::mojom::FindOptions::New();
+ default_options->run_synchronously_for_testing = true;
+ Find("result", default_options.Clone());
delegate()->WaitForFinalReply();
EXPECT_EQ(19, delegate()->GetFindResults().number_of_matches);
@@ -712,9 +710,9 @@ IN_PROC_BROWSER_TEST_F(FindRequestManagerTest,
MAYBE(ActivateNearestFindMatch)) {
LoadAndWait("/find_in_page.html");
- blink::WebFindOptions default_options;
- default_options.run_synchronously_for_testing = true;
- Find("result", default_options);
+ auto default_options = blink::mojom::FindOptions::New();
+ default_options->run_synchronously_for_testing = true;
+ Find("result", default_options.Clone());
delegate()->WaitForFinalReply();
EXPECT_EQ(19, delegate()->GetFindResults().number_of_matches);
diff --git a/chromium/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc b/chromium/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc
index 4708110a0f7..8e370e5dbab 100644
--- a/chromium/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc
+++ b/chromium/content/browser/font_unique_name_lookup/font_unique_name_browsertest.cc
@@ -16,6 +16,7 @@
namespace content {
namespace {
+#if defined(OS_ANDROID)
const char* kExpectedFontFamilyNames[] = {"AndroidClock",
"Roboto",
"Droid Sans Mono",
@@ -59,6 +60,45 @@ const char* kExpectedFontFamilyNames[] = {"AndroidClock",
"Roboto Condensed",
"Roboto Condensed",
"Roboto"};
+#elif defined(OS_LINUX)
+const char* kExpectedFontFamilyNames[] = {"Ahem",
+ "Arimo",
+ "Arimo",
+ "Arimo",
+ "Arimo",
+ "Cousine",
+ "Cousine",
+ "Cousine",
+ "Cousine",
+ "DejaVu Sans",
+ "DejaVu Sans",
+ "Garuda",
+ "Gelasio",
+ "Gelasio",
+ "Gelasio",
+ "Gelasio",
+ "Lohit Devanagari",
+ "Lohit Gurmukhi",
+ "Lohit Tamil",
+ "Noto Sans Khmer",
+ "Tinos",
+ "Tinos",
+ "Tinos",
+ "Tinos",
+ "Mukti Narrow",
+ "Tinos"};
+#elif defined(OS_MACOSX)
+const char* kExpectedFontFamilyNames[] = {"American Typewriter",
+ "Arial Narrow",
+ "Baskerville",
+ "Devanagari MT",
+ "DIN Alternate",
+ "Gill Sans",
+ "Iowan Old Style",
+ "Malayalam Sangam MN",
+ "Hiragino Maru Gothic Pro",
+ "Hiragino Kaku Gothic StdN"};
+#endif
} // namespace
@@ -80,13 +120,9 @@ class FontUniqueNameBrowserTest : public DevToolsProtocolTest {
base::test::ScopedFeatureList feature_list_;
};
-#if defined(OS_ANDROID)
-#define MAYBE_ContentLocalFontsMatching ContentLocalFontsMatching
-#else
-#define MAYBE_ContentLocalFontsMatching DISABLED_ContentLocalFontsMatching
-#endif
-IN_PROC_BROWSER_TEST_F(FontUniqueNameBrowserTest,
- MAYBE_ContentLocalFontsMatching) {
+// TODO(drott): Enable this on all platforms.
+#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_MACOSX)
+IN_PROC_BROWSER_TEST_F(FontUniqueNameBrowserTest, ContentLocalFontsMatching) {
LoadAndWait("/font_src_local_matching.html");
Attach();
@@ -125,16 +161,22 @@ IN_PROC_BROWSER_TEST_F(FontUniqueNameBrowserTest,
params->SetInteger("nodeId", nodeId.GetInt());
base::Value* font_info =
SendCommand("CSS.getPlatformFontsForNode", std::move(params));
+ ASSERT_TRUE(font_info);
ASSERT_TRUE(font_info->is_dict());
base::Value* font_list = font_info->FindKey("fonts");
+ ASSERT_TRUE(font_list);
ASSERT_TRUE(font_list->is_list());
- base::Value& first_font_info = font_list->GetList()[0];
+ std::vector<base::Value>& font_info_list = font_list->GetList();
+ ASSERT_TRUE(font_info_list.size());
+ base::Value& first_font_info = font_info_list[0];
ASSERT_TRUE(first_font_info.is_dict());
base::Value* first_font_name = first_font_info.FindKey("familyName");
+ ASSERT_TRUE(first_font_name);
ASSERT_TRUE(first_font_name->is_string());
ASSERT_GT(first_font_name->GetString().size(), 0u);
ASSERT_EQ(first_font_name->GetString(), kExpectedFontFamilyNames[i]);
}
}
+#endif
} // namespace content
diff --git a/chromium/content/browser/font_unique_name_lookup/font_unique_name_lookup_service.cc b/chromium/content/browser/font_unique_name_lookup/font_unique_name_lookup_service.cc
index 79c4fa1ac5e..bd0d45d7166 100644
--- a/chromium/content/browser/font_unique_name_lookup/font_unique_name_lookup_service.cc
+++ b/chromium/content/browser/font_unique_name_lookup/font_unique_name_lookup_service.cc
@@ -8,6 +8,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/no_destructor.h"
#include "base/task/post_task.h"
#include "content/browser/font_unique_name_lookup/font_unique_name_lookup.h"
#include "content/public/common/content_features.h"
@@ -32,12 +33,11 @@ void FontUniqueNameLookupService::Create(
// static
scoped_refptr<base::SequencedTaskRunner>
FontUniqueNameLookupService::GetTaskRunner() {
- CR_DEFINE_STATIC_LOCAL(
- scoped_refptr<base::SequencedTaskRunner>, runner,
- (base::CreateSequencedTaskRunnerWithTraits(
+ static base::NoDestructor<scoped_refptr<base::SequencedTaskRunner>> runner(
+ base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
- base::TaskPriority::USER_BLOCKING})));
- return runner;
+ base::TaskPriority::USER_BLOCKING}));
+ return *runner;
}
void FontUniqueNameLookupService::GetUniqueNameLookupTable(
diff --git a/chromium/content/browser/frame_host/cross_process_frame_connector.cc b/chromium/content/browser/frame_host/cross_process_frame_connector.cc
index 4bd20a223cd..5cf646286eb 100644
--- a/chromium/content/browser/frame_host/cross_process_frame_connector.cc
+++ b/chromium/content/browser/frame_host/cross_process_frame_connector.cc
@@ -34,6 +34,37 @@
namespace content {
+namespace {
+
+// If |frame| is an iframe or a GuestView, returns its parent, null otherwise.
+RenderFrameHostImpl* ParentRenderFrameHost(RenderFrameHostImpl* frame) {
+ // Find the parent in the FrameTree (iframe).
+ if (frame->GetParent())
+ return frame->GetParent();
+
+ // Find the parent in the WebContentsTree (GuestView).
+ FrameTreeNode* frame_in_embedder =
+ frame->frame_tree_node()->render_manager()->GetOuterDelegateNode();
+ if (frame_in_embedder)
+ return frame_in_embedder->current_frame_host()->GetParent();
+
+ // No parent found.
+ return nullptr;
+}
+
+// Return the root RenderFrameHost in the outermost WebContents.
+RenderFrameHostImpl* RootRenderFrameHost(RenderFrameHostImpl* frame) {
+ RenderFrameHostImpl* current = frame;
+ while (true) {
+ RenderFrameHostImpl* parent = ParentRenderFrameHost(current);
+ if (!parent)
+ return current;
+ current = parent;
+ };
+}
+
+} // namespace
+
CrossProcessFrameConnector::CrossProcessFrameConnector(
RenderFrameProxyHost* frame_proxy_in_parent_renderer)
: FrameConnectorDelegate(IsUseZoomForDSFEnabled()),
@@ -114,12 +145,13 @@ void CrossProcessFrameConnector::SetView(RenderWidgetHostViewChildFrame* view) {
MaybeLogCrash(CrashVisibility::kNeverVisibleAfterCrash);
}
is_crash_already_logged_ = has_crashed_ = false;
+ delegate_was_shown_after_crash_ = false;
view_->SetFrameConnectorDelegate(this);
if (is_hidden_)
OnVisibilityChanged(false);
FrameMsg_ViewChanged_Params params;
- if (!features::IsUsingWindowService())
+ if (!features::IsMultiProcessMash())
params.frame_sink_id = view_->GetFrameSinkId();
frame_proxy_in_parent_renderer_->Send(new FrameMsg_ViewChanged(
frame_proxy_in_parent_renderer_->GetRoutingID(), params));
@@ -341,20 +373,19 @@ void CrossProcessFrameConnector::OnUpdateViewportIntersection(
viewport_intersection, compositor_visible_rect, occluded_or_obscured);
if (IsVisible()) {
- // MaybeLogCrash will check 1) if there was a crash or not and 2) if the
- // crash might have been already logged earlier as kCrashedWhileVisible or
- // kShownAfterCrashing.
- MaybeLogCrash(CrashVisibility::kShownAfterCrashing);
+ // Record metrics if a crashed subframe became visible as a result of this
+ // viewport intersection update. For example, this might happen if a user
+ // scrolls to a crashed subframe.
+ MaybeLogShownCrash(ShownAfterCrashingReason::kViewportIntersection);
}
}
void CrossProcessFrameConnector::OnVisibilityChanged(bool visible) {
is_hidden_ = !visible;
if (IsVisible()) {
- // MaybeLogCrash will check 1) if there was a crash or not and 2) if the
- // crash might have been already logged earlier as kCrashedWhileVisible or
- // kShownAfterCrashing.
- MaybeLogCrash(CrashVisibility::kShownAfterCrashing);
+ // Record metrics if a crashed subframe became visible as a result of this
+ // visibility change.
+ MaybeLogShownCrash(ShownAfterCrashingReason::kVisibility);
}
if (!view_)
return;
@@ -396,40 +427,19 @@ CrossProcessFrameConnector::GetRootRenderWidgetHostView() {
if (!frame_proxy_in_parent_renderer_)
return nullptr;
- RenderFrameHostImpl* top_host = frame_proxy_in_parent_renderer_->
- frame_tree_node()->frame_tree()->root()->current_frame_host();
-
- // This method should return the root RWHV from the top-level WebContents,
- // in the case of nested WebContents.
- while (top_host->frame_tree_node()->render_manager()->ForInnerDelegate()) {
- top_host = top_host->frame_tree_node()->render_manager()->
- GetOuterDelegateNode()->frame_tree()->root()->current_frame_host();
- }
-
- return static_cast<RenderWidgetHostViewBase*>(top_host->GetView());
+ RenderFrameHostImpl* current =
+ frame_proxy_in_parent_renderer_->frame_tree_node()->current_frame_host();
+ RenderFrameHostImpl* root = RootRenderFrameHost(current);
+ return static_cast<RenderWidgetHostViewBase*>(root->GetView());
}
RenderWidgetHostViewBase*
CrossProcessFrameConnector::GetParentRenderWidgetHostView() {
- FrameTreeNode* parent =
- frame_proxy_in_parent_renderer_->frame_tree_node()->parent();
-
- if (!parent &&
- frame_proxy_in_parent_renderer_->frame_tree_node()
- ->render_manager()
- ->GetOuterDelegateNode()) {
- parent = frame_proxy_in_parent_renderer_->frame_tree_node()
- ->render_manager()
- ->GetOuterDelegateNode()
- ->parent();
- }
-
- if (parent) {
- return static_cast<RenderWidgetHostViewBase*>(
- parent->current_frame_host()->GetView());
- }
-
- return nullptr;
+ RenderFrameHostImpl* current =
+ frame_proxy_in_parent_renderer_->frame_tree_node()->current_frame_host();
+ RenderFrameHostImpl* parent = ParentRenderFrameHost(current);
+ return parent ? static_cast<RenderWidgetHostViewBase*>(parent->GetView())
+ : nullptr;
}
void CrossProcessFrameConnector::EnableAutoResize(const gfx::Size& min_size,
@@ -538,27 +548,53 @@ bool CrossProcessFrameConnector::IsSubtreeThrottled() const {
return subtree_throttled_;
}
-void CrossProcessFrameConnector::MaybeLogCrash(CrashVisibility visibility) {
+bool CrossProcessFrameConnector::MaybeLogCrash(CrashVisibility visibility) {
if (!has_crashed_)
- return;
+ return false;
// Only log once per renderer crash.
if (is_crash_already_logged_)
- return;
+ return false;
is_crash_already_logged_ = true;
// Actually log the UMA.
UMA_HISTOGRAM_ENUMERATION("Stability.ChildFrameCrash.Visibility", visibility);
- if (visibility == CrashVisibility::kShownAfterCrashing) {
- auto* rfh = frame_proxy_in_parent_renderer_->frame_tree_node()
- ->current_frame_host();
- if (rfh->GetParent() && rfh->is_local_root()) {
- UMA_HISTOGRAM_BOOLEAN(
- "RenderFrameHostImpl.ReceivedPostMessageFromNonDescendant",
- rfh->received_post_message_from_non_descendant());
- }
+ return true;
+}
+
+void CrossProcessFrameConnector::MaybeLogShownCrash(
+ ShownAfterCrashingReason reason) {
+ if (!MaybeLogCrash(CrashVisibility::kShownAfterCrashing))
+ return;
+
+ // Identify cases where the sad frame was initially in a hidden tab, then the
+ // tab became visible, and finally the sad frame became visible because it
+ // was scrolled into view or its visibility changed. Record these cases
+ // separately, since they might be avoided by reloading the tab when it
+ // becomes visible.
+ if (delegate_was_shown_after_crash_) {
+ if (reason == ShownAfterCrashingReason::kViewportIntersection)
+ reason = ShownAfterCrashingReason::kViewportIntersectionAfterTabWasShown;
+ else if (reason == ShownAfterCrashingReason::kVisibility)
+ reason = ShownAfterCrashingReason::kVisibilityAfterTabWasShown;
+ }
+
+ UMA_HISTOGRAM_ENUMERATION(
+ "Stability.ChildFrameCrash.ShownAfterCrashingReason", reason);
+}
+
+void CrossProcessFrameConnector::DelegateWasShown() {
+ if (IsVisible()) {
+ // MaybeLogShownCrash will check 1) if there was a crash or not and 2) if
+ // the crash might have been already logged earlier as
+ // kCrashedWhileVisible.
+ MaybeLogShownCrash(
+ CrossProcessFrameConnector::ShownAfterCrashingReason::kTabWasShown);
}
+
+ if (has_crashed_)
+ delegate_was_shown_after_crash_ = true;
}
bool CrossProcessFrameConnector::IsVisible() {
diff --git a/chromium/content/browser/frame_host/cross_process_frame_connector.h b/chromium/content/browser/frame_host/cross_process_frame_connector.h
index 203b8a42831..d99a64eb7c3 100644
--- a/chromium/content/browser/frame_host/cross_process_frame_connector.h
+++ b/chromium/content/browser/frame_host/cross_process_frame_connector.h
@@ -130,26 +130,35 @@ class CONTENT_EXPORT CrossProcessFrameConnector
return GetRootRenderWidgetHostView();
}
- // This enum backs a histogram - please do not modify or remove the existing
- // enum values below (adding new values is okay, but please remember to also
- // update enums.xml in this case). See enums.xml for descriptions of enum
- // values.
+ // These enums back crashed frame histograms - see MaybeLogCrash() and
+ // MaybeLogShownCrash() below. Please do not modify or remove existing enum
+ // values. When adding new values, please also update enums.xml. See
+ // enums.xml for descriptions of enum values.
enum class CrashVisibility {
kCrashedWhileVisible = 0,
kShownAfterCrashing = 1,
kNeverVisibleAfterCrash = 2,
kMaxValue = kNeverVisibleAfterCrash
};
- // Logs the Stability.ChildFrameCrash.Visibility metric after checking that a
- // crash has indeed happened and checking that the crash has not already been
- // logged in UMA.
- void MaybeLogCrash(CrashVisibility visibility);
+
+ enum class ShownAfterCrashingReason {
+ kTabWasShown = 0,
+ kViewportIntersection = 1,
+ kVisibility = 2,
+ kViewportIntersectionAfterTabWasShown = 3,
+ kVisibilityAfterTabWasShown = 4,
+ kMaxValue = kVisibilityAfterTabWasShown
+ };
// Returns whether the child widget is actually visible to the user. This is
// different from the IsHidden override, and takes into account viewport
// intersection as well as the visibility of the RenderFrameHostDelegate.
bool IsVisible();
+ // This function is called by the RenderFrameHostDelegate to signal that it
+ // became visible.
+ void DelegateWasShown();
+
private:
friend class MockCrossProcessFrameConnector;
@@ -157,6 +166,15 @@ class CONTENT_EXPORT CrossProcessFrameConnector
// unguessable surface ID is not reused after a cross-process navigation.
void ResetScreenSpaceRect();
+ // Logs the Stability.ChildFrameCrash.Visibility metric after checking that a
+ // crash has indeed happened and checking that the crash has not already been
+ // logged in UMA. Returns true if this metric was actually logged.
+ bool MaybeLogCrash(CrashVisibility visibility);
+
+ // Check if a crashed child frame has become visible, and if so, log the
+ // Stability.ChildFrameCrash.Visibility.ShownAfterCrashing* metrics.
+ void MaybeLogShownCrash(ShownAfterCrashingReason reason);
+
// Handlers for messages received from the parent frame.
void OnSynchronizeVisualProperties(
const viz::SurfaceId& surface_id,
@@ -195,6 +213,10 @@ class CONTENT_EXPORT CrossProcessFrameConnector
// CrossProcessFrameConnector or when WebContentsImpl::WasShown is called).
bool has_crashed_ = false;
+ // Remembers whether or not the RenderFrameHostDelegate (i.e., tab) was
+ // shown after a crash. This is only used when recording renderer crashes.
+ bool delegate_was_shown_after_crash_ = false;
+
// The last pre-transform frame size received from the parent renderer.
// |last_received_local_frame_size_| may be in DIP if use zoom for DSF is
// off.
diff --git a/chromium/content/browser/frame_host/debug_urls.cc b/chromium/content/browser/frame_host/debug_urls.cc
index 78868e2664b..85db4c8396c 100644
--- a/chromium/content/browser/frame_host/debug_urls.cc
+++ b/chromium/content/browser/frame_host/debug_urls.cc
@@ -11,10 +11,12 @@
#include "base/debug/profiler.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "content/browser/gpu/gpu_process_host.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/url_constants.h"
@@ -57,8 +59,7 @@ void HandlePpapiFlashDebugURL(const GURL& url) {
std::vector<PpapiPluginProcessHost*> hosts;
PpapiPluginProcessHost::FindByName(
base::UTF8ToUTF16(kFlashPluginName), &hosts);
- for (std::vector<PpapiPluginProcessHost*>::iterator iter = hosts.begin();
- iter != hosts.end(); ++iter) {
+ for (auto iter = hosts.begin(); iter != hosts.end(); ++iter) {
if (crash)
(*iter)->Send(new PpapiMsg_Crash());
else
@@ -162,9 +163,9 @@ bool HandleDebugURL(const GURL& url, ui::PageTransition transition) {
if (url == kChromeUIDelayedBrowserUIHang) {
// Webdriver-safe url to hang the ui thread. Webdriver waits for the onload
// event in javascript which needs a little more time to fire.
- BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&HangCurrentThread),
- base::TimeDelta::FromSeconds(2));
+ base::PostDelayedTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&HangCurrentThread),
+ base::TimeDelta::FromSeconds(2));
return true;
}
@@ -211,8 +212,8 @@ bool HandleDebugURL(const GURL& url, ui::PageTransition transition) {
}
if (url == kChromeUIPpapiFlashCrashURL || url == kChromeUIPpapiFlashHangURL) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&HandlePpapiFlashDebugURL, url));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&HandlePpapiFlashDebugURL, url));
return true;
}
diff --git a/chromium/content/browser/frame_host/form_submission_throttle.cc b/chromium/content/browser/frame_host/form_submission_throttle.cc
index 893445d5ebe..46c737ac673 100644
--- a/chromium/content/browser/frame_host/form_submission_throttle.cc
+++ b/chromium/content/browser/frame_host/form_submission_throttle.cc
@@ -19,9 +19,6 @@ std::unique_ptr<NavigationThrottle>
FormSubmissionThrottle::MaybeCreateThrottleFor(NavigationHandle* handle) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (!IsBrowserSideNavigationEnabled())
- return nullptr;
-
if (!handle->IsFormSubmission())
return nullptr;
@@ -33,12 +30,12 @@ FormSubmissionThrottle::~FormSubmissionThrottle() {}
NavigationThrottle::ThrottleCheckResult
FormSubmissionThrottle::WillStartRequest() {
- return CheckContentSecurityPolicyFormAction(false /* is_redirect */);
+ return CheckContentSecurityPolicyFormAction(false /* was_server_redirect */);
}
NavigationThrottle::ThrottleCheckResult
FormSubmissionThrottle::WillRedirectRequest() {
- return CheckContentSecurityPolicyFormAction(true /* is_redirect */);
+ return CheckContentSecurityPolicyFormAction(true /* was_server_redirect */);
}
const char* FormSubmissionThrottle::GetNameForLogging() {
@@ -46,7 +43,8 @@ const char* FormSubmissionThrottle::GetNameForLogging() {
}
NavigationThrottle::ThrottleCheckResult
-FormSubmissionThrottle::CheckContentSecurityPolicyFormAction(bool is_redirect) {
+FormSubmissionThrottle::CheckContentSecurityPolicyFormAction(
+ bool was_server_redirect) {
// TODO(arthursonzogni): form-action is enforced on the wrong RenderFrameHost.
// The navigating one is used instead of the one that has initiated the form
// submission. The renderer side checks are still in place and are used for
@@ -62,7 +60,7 @@ FormSubmissionThrottle::CheckContentSecurityPolicyFormAction(bool is_redirect) {
// compromised) renderer being responsible for enforcing the CSP of another
// (victim) renderer. Therefore it is okay to return early and do no further
// browser-side checks.
- if (!is_redirect)
+ if (!was_server_redirect)
return NavigationThrottle::PROCEED;
NavigationHandleImpl* handle =
@@ -83,7 +81,7 @@ FormSubmissionThrottle::CheckContentSecurityPolicyFormAction(bool is_redirect) {
// check report-only CSP, (2) upgrade request if needed, (3) check enforced
// CSP to match how frame-src works. https://crbug.com/713388
if (render_frame->IsAllowedByCsp(
- CSPDirective::FormAction, url, is_redirect,
+ CSPDirective::FormAction, url, was_server_redirect,
false /* is_response_check */, handle->source_location(),
CSPContext::CHECK_ALL_CSP, true /* is_form_submission */)) {
return NavigationThrottle::PROCEED;
diff --git a/chromium/content/browser/frame_host/form_submission_throttle.h b/chromium/content/browser/frame_host/form_submission_throttle.h
index 9c11df352a5..eb95c848f07 100644
--- a/chromium/content/browser/frame_host/form_submission_throttle.h
+++ b/chromium/content/browser/frame_host/form_submission_throttle.h
@@ -36,7 +36,7 @@ class CONTENT_EXPORT FormSubmissionThrottle : public NavigationThrottle {
private:
explicit FormSubmissionThrottle(NavigationHandle* handle);
NavigationThrottle::ThrottleCheckResult CheckContentSecurityPolicyFormAction(
- bool is_redirect);
+ bool was_server_redirect);
DISALLOW_COPY_AND_ASSIGN(FormSubmissionThrottle);
};
diff --git a/chromium/content/browser/frame_host/frame_tree.cc b/chromium/content/browser/frame_host/frame_tree.cc
index ed5a3d823ac..d5d00549b91 100644
--- a/chromium/content/browser/frame_host/frame_tree.cc
+++ b/chromium/content/browser/frame_host/frame_tree.cc
@@ -100,9 +100,6 @@ FrameTree::FrameTree(Navigator* navigator,
manager_delegate_(manager_delegate),
root_(new FrameTreeNode(this,
navigator,
- render_frame_delegate,
- render_widget_delegate,
- manager_delegate,
nullptr,
// The top-level frame must always be in a
// document scope.
@@ -195,10 +192,8 @@ bool FrameTree::AddFrame(
return false;
std::unique_ptr<FrameTreeNode> new_node = base::WrapUnique(new FrameTreeNode(
- this, parent->navigator(), render_frame_delegate_,
- render_widget_delegate_, manager_delegate_, parent, scope, frame_name,
- frame_unique_name, is_created_by_script, devtools_frame_token,
- frame_owner_properties));
+ this, parent->navigator(), parent, scope, frame_name, frame_unique_name,
+ is_created_by_script, devtools_frame_token, frame_owner_properties));
// Set sandbox flags and container policy and make them effective immediately,
// since initial sandbox flags and feature policy should apply to the initial
@@ -212,8 +207,8 @@ bool FrameTree::AddFrame(
new_node->set_was_discarded();
// Add the new node to the FrameTree, creating the RenderFrameHost.
- FrameTreeNode* added_node =
- parent->AddChild(std::move(new_node), process_id, new_routing_id);
+ FrameTreeNode* added_node = parent->current_frame_host()->AddChild(
+ std::move(new_node), process_id, new_routing_id);
DCHECK(interface_provider_request.is_pending());
added_node->current_frame_host()->BindInterfaceProviderRequest(
@@ -244,7 +239,7 @@ void FrameTree::RemoveFrame(FrameTreeNode* child) {
return;
}
- parent->RemoveChild(child);
+ parent->current_frame_host()->RemoveChild(child);
}
void FrameTree::CreateProxiesForSiteInstance(
@@ -356,8 +351,7 @@ RenderViewHostImpl* FrameTree::CreateRenderViewHost(
int32_t widget_routing_id,
bool swapped_out,
bool hidden) {
- RenderViewHostMap::iterator iter =
- render_view_host_map_.find(site_instance->GetId());
+ auto iter = render_view_host_map_.find(site_instance->GetId());
if (iter != render_view_host_map_.end())
return iter->second;
@@ -372,8 +366,7 @@ RenderViewHostImpl* FrameTree::CreateRenderViewHost(
}
RenderViewHostImpl* FrameTree::GetRenderViewHost(SiteInstance* site_instance) {
- RenderViewHostMap::iterator iter =
- render_view_host_map_.find(site_instance->GetId());
+ auto iter = render_view_host_map_.find(site_instance->GetId());
if (iter != render_view_host_map_.end())
return iter->second;
@@ -382,8 +375,7 @@ RenderViewHostImpl* FrameTree::GetRenderViewHost(SiteInstance* site_instance) {
void FrameTree::AddRenderViewHostRef(RenderViewHostImpl* render_view_host) {
SiteInstance* site_instance = render_view_host->GetSiteInstance();
- RenderViewHostMap::iterator iter =
- render_view_host_map_.find(site_instance->GetId());
+ auto iter = render_view_host_map_.find(site_instance->GetId());
CHECK(iter != render_view_host_map_.end());
CHECK(iter->second == render_view_host);
@@ -393,8 +385,7 @@ void FrameTree::AddRenderViewHostRef(RenderViewHostImpl* render_view_host) {
void FrameTree::ReleaseRenderViewHostRef(RenderViewHostImpl* render_view_host) {
SiteInstance* site_instance = render_view_host->GetSiteInstance();
int32_t site_instance_id = site_instance->GetId();
- RenderViewHostMap::iterator iter =
- render_view_host_map_.find(site_instance_id);
+ auto iter = render_view_host_map_.find(site_instance_id);
CHECK(iter != render_view_host_map_.end());
CHECK_EQ(iter->second, render_view_host);
diff --git a/chromium/content/browser/frame_host/frame_tree.h b/chromium/content/browser/frame_host/frame_tree.h
index 248489e5aa5..6aa4ee1b318 100644
--- a/chromium/content/browser/frame_host/frame_tree.h
+++ b/chromium/content/browser/frame_host/frame_tree.h
@@ -102,6 +102,23 @@ class CONTENT_EXPORT FrameTree {
FrameTreeNode* root() const { return root_; }
+ // Delegates for RenderFrameHosts, RenderViewHosts, RenderWidgetHosts and
+ // RenderFrameHostManagers. These can be kept centrally on the FrameTree
+ // because they are expected to be the same for all frames on a given
+ // FrameTree.
+ RenderFrameHostDelegate* render_frame_delegate() {
+ return render_frame_delegate_;
+ }
+ RenderViewHostDelegate* render_view_delegate() {
+ return render_view_delegate_;
+ }
+ RenderWidgetHostDelegate* render_widget_delegate() {
+ return render_widget_delegate_;
+ }
+ RenderFrameHostManager::Delegate* manager_delegate() {
+ return manager_delegate_;
+ }
+
// Returns the FrameTreeNode with the given |frame_tree_node_id| if it is part
// of this FrameTree.
FrameTreeNode* FindByID(int frame_tree_node_id);
diff --git a/chromium/content/browser/frame_host/frame_tree_browsertest.cc b/chromium/content/browser/frame_host/frame_tree_browsertest.cc
index e0be5c94511..7159859c470 100644
--- a/chromium/content/browser/frame_host/frame_tree_browsertest.cc
+++ b/chromium/content/browser/frame_host/frame_tree_browsertest.cc
@@ -32,7 +32,7 @@ namespace content {
namespace {
EvalJsResult GetOriginFromRenderer(FrameTreeNode* node) {
- return EvalJs(node, "document.origin");
+ return EvalJs(node, "self.origin");
}
} // namespace
@@ -275,7 +275,7 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, OriginSetOnNavigation) {
// Navigating to a data URL should set a unique origin. This is represented
// as "null" per RFC 6454.
EXPECT_EQ("null", root->current_origin().Serialize());
- EXPECT_TRUE(contents->GetMainFrame()->GetLastCommittedOrigin().unique());
+ EXPECT_TRUE(contents->GetMainFrame()->GetLastCommittedOrigin().opaque());
EXPECT_EQ("null", GetOriginFromRenderer(root));
// Re-navigating to a normal URL should update the origin.
@@ -285,7 +285,7 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, OriginSetOnNavigation) {
EXPECT_EQ(
main_url.GetOrigin().spec(),
contents->GetMainFrame()->GetLastCommittedOrigin().Serialize() + '/');
- EXPECT_FALSE(contents->GetMainFrame()->GetLastCommittedOrigin().unique());
+ EXPECT_FALSE(contents->GetMainFrame()->GetLastCommittedOrigin().opaque());
EXPECT_EQ(root->current_origin().Serialize(), GetOriginFromRenderer(root));
}
@@ -315,7 +315,7 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, NavigateGrandchildToBlob) {
std::string html =
"<html><body><div>This is blob content.</div>"
"<script>"
- "window.parent.parent.postMessage('HI', document.origin);"
+ "window.parent.parent.postMessage('HI', self.origin);"
"</script></body></html>";
std::string script = JsReplace(
"new Promise((resolve) => {"
@@ -334,7 +334,7 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, NavigateGrandchildToBlob) {
deleted_observer.WaitUntilDeleted();
EXPECT_EQ(GURL(blob_url_string), target->current_url());
EXPECT_EQ(url::kBlobScheme, target->current_url().scheme());
- EXPECT_FALSE(target->current_origin().unique());
+ EXPECT_FALSE(target->current_origin().opaque());
EXPECT_EQ("a.com", target->current_origin().host());
EXPECT_EQ(url::kHttpScheme, target->current_origin().scheme());
EXPECT_EQ("This is blob content.",
@@ -373,13 +373,13 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, NavigateChildToAboutBlank) {
" frames[0].document.write('Hi from ' + document.domain);"
" } catch (e) { return; }"
" clearInterval(intervalID);"
- " resolve(frames[0].document.origin);"
+ " resolve(frames[0].self.origin);"
" }, 16);"
"});");
EXPECT_EQ(target->current_origin(), about_blank_origin);
EXPECT_EQ(GURL(url::kAboutBlankURL), target->current_url());
EXPECT_EQ(url::kAboutScheme, target->current_url().scheme());
- EXPECT_FALSE(target->current_origin().unique());
+ EXPECT_FALSE(target->current_origin().opaque());
EXPECT_EQ("b.com", target->current_origin().host());
EXPECT_EQ(url::kHttpScheme, target->current_origin().scheme());
@@ -421,13 +421,13 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest,
" frames[0][0].document.write('Hi from ' + document.domain);"
" } catch (e) { return; }"
" clearInterval(intervalID);"
- " resolve(frames[0][0].document.origin);"
+ " resolve(frames[0][0].self.origin);"
" }, 16);"
"});");
EXPECT_EQ(target->current_origin(), about_blank_origin);
EXPECT_EQ(GURL(url::kAboutBlankURL), target->current_url());
EXPECT_EQ(url::kAboutScheme, target->current_url().scheme());
- EXPECT_FALSE(target->current_origin().unique());
+ EXPECT_FALSE(target->current_origin().opaque());
EXPECT_EQ("a.com", target->current_origin().host());
EXPECT_EQ(url::kHttpScheme, target->current_origin().scheme());
@@ -446,7 +446,7 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, ChildFrameWithSrcdoc) {
EXPECT_EQ(1U, root->child_count());
FrameTreeNode* child = root->child_at(0);
- std::string frame_origin = EvalJs(child, "document.origin;").ExtractString();
+ std::string frame_origin = EvalJs(child, "self.origin;").ExtractString();
EXPECT_TRUE(
child->current_frame_host()->GetLastCommittedOrigin().IsSameOriginWith(
url::Origin::Create(GURL(frame_origin))));
@@ -466,7 +466,7 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, ChildFrameWithSrcdoc) {
observer.Wait();
EXPECT_EQ(GURL(kAboutSrcDocURL), root->child_at(1)->current_url());
- EvalJsResult frame_origin = EvalJs(root->child_at(1), "document.origin");
+ EvalJsResult frame_origin = EvalJs(root->child_at(1), "self.origin");
EXPECT_EQ(root->current_frame_host()->GetLastCommittedURL().GetOrigin(),
GURL(frame_origin.ExtractString()));
EXPECT_NE(child->current_frame_host()->GetLastCommittedURL().GetOrigin(),
@@ -486,7 +486,7 @@ IN_PROC_BROWSER_TEST_F(FrameTreeBrowserTest, ChildFrameWithSrcdoc) {
EXPECT_EQ(
url::Origin::Create(root->current_frame_host()->GetLastCommittedURL())
.Serialize(),
- EvalJs(child, "document.origin"));
+ EvalJs(child, "self.origin"));
}
}
diff --git a/chromium/content/browser/frame_host/frame_tree_node.cc b/chromium/content/browser/frame_host/frame_tree_node.cc
index 46e3d2a7678..24f5fbb94a6 100644
--- a/chromium/content/browser/frame_host/frame_tree_node.cc
+++ b/chromium/content/browser/frame_host/frame_tree_node.cc
@@ -82,15 +82,12 @@ int FrameTreeNode::next_frame_tree_node_id_ = 1;
FrameTreeNode* FrameTreeNode::GloballyFindByID(int frame_tree_node_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
FrameTreeNodeIdMap* nodes = g_frame_tree_node_id_map.Pointer();
- FrameTreeNodeIdMap::iterator it = nodes->find(frame_tree_node_id);
+ auto it = nodes->find(frame_tree_node_id);
return it == nodes->end() ? nullptr : it->second;
}
FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
Navigator* navigator,
- RenderFrameHostDelegate* render_frame_delegate,
- RenderWidgetHostDelegate* render_widget_delegate,
- RenderFrameHostManager::Delegate* manager_delegate,
FrameTreeNode* parent,
blink::WebTreeScopeType scope,
const std::string& name,
@@ -100,10 +97,7 @@ FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
const FrameOwnerProperties& frame_owner_properties)
: frame_tree_(frame_tree),
navigator_(navigator),
- render_manager_(this,
- render_frame_delegate,
- render_widget_delegate,
- manager_delegate),
+ render_manager_(this, frame_tree->manager_delegate()),
frame_tree_node_id_(next_frame_tree_node_id_++),
parent_(parent),
depth_(parent ? parent->depth_ + 1 : 0u),
@@ -136,9 +130,8 @@ FrameTreeNode::FrameTreeNode(FrameTree* frame_tree,
}
FrameTreeNode::~FrameTreeNode() {
- // Remove the children. See https://crbug.com/612450 for explanation why we
- // don't just call the std::vector::clear method.
- std::vector<std::unique_ptr<FrameTreeNode>>().swap(children_);
+ // Remove the children.
+ current_frame_host()->ResetChildren();
// If the removed frame was created by a script, then its history entry will
// never be reused - we can save some memory by removing the history entry.
@@ -183,47 +176,8 @@ bool FrameTreeNode::IsMainFrame() const {
return frame_tree_->root() == this;
}
-FrameTreeNode* FrameTreeNode::AddChild(std::unique_ptr<FrameTreeNode> child,
- int process_id,
- int frame_routing_id) {
- // Child frame must always be created in the same process as the parent.
- CHECK_EQ(process_id, render_manager_.current_host()->GetProcess()->GetID());
-
- // Initialize the RenderFrameHost for the new node. We always create child
- // frames in the same SiteInstance as the current frame, and they can swap to
- // a different one if they navigate away.
- child->render_manager()->Init(
- render_manager_.current_host()->GetSiteInstance(),
- render_manager_.current_host()->GetRoutingID(), frame_routing_id,
- MSG_ROUTING_NONE, false);
-
- // Other renderer processes in this BrowsingInstance may need to find out
- // about the new frame. Create a proxy for the child frame in all
- // SiteInstances that have a proxy for the frame's parent, since all frames
- // in a frame tree should have the same set of proxies.
- render_manager_.CreateProxiesForChildFrame(child.get());
-
- children_.push_back(std::move(child));
- return children_.back().get();
-}
-
-void FrameTreeNode::RemoveChild(FrameTreeNode* child) {
- for (auto iter = children_.begin(); iter != children_.end(); ++iter) {
- if (iter->get() == child) {
- // Subtle: we need to make sure the node is gone from the tree before
- // observers are notified of its deletion.
- std::unique_ptr<FrameTreeNode> node_to_delete(std::move(*iter));
- children_.erase(iter);
- node_to_delete.reset();
- return;
- }
- }
-}
-
void FrameTreeNode::ResetForNewProcess() {
- // Remove child nodes from the tree, then delete them. This destruction
- // operation will notify observers.
- std::vector<std::unique_ptr<FrameTreeNode>>().swap(children_);
+ current_frame_host()->ResetChildren();
}
void FrameTreeNode::ResetForNavigation() {
@@ -359,18 +313,6 @@ void FrameTreeNode::SetPendingFramePolicy(blink::FramePolicy frame_policy) {
}
}
-bool FrameTreeNode::IsDescendantOf(FrameTreeNode* other) const {
- if (!other || !other->child_count())
- return false;
-
- for (FrameTreeNode* node = parent(); node; node = node->parent()) {
- if (node == other)
- return true;
- }
-
- return false;
-}
-
FrameTreeNode* FrameTreeNode::PreviousSibling() const {
return GetSibling(-1);
}
@@ -421,8 +363,6 @@ void FrameTreeNode::TransferNavigationRequestOwnership(
void FrameTreeNode::CreatedNavigationRequest(
std::unique_ptr<NavigationRequest> navigation_request) {
- CHECK(IsBrowserSideNavigationEnabled());
-
// This is never called when navigating to a Javascript URL. For the loading
// state, this matches what Blink is doing: Blink doesn't send throbber
// notifications for Javascript URLS.
@@ -458,7 +398,6 @@ void FrameTreeNode::CreatedNavigationRequest(
void FrameTreeNode::ResetNavigationRequest(bool keep_state,
bool inform_renderer) {
- CHECK(IsBrowserSideNavigationEnabled());
if (!navigation_request_)
return;
@@ -503,6 +442,9 @@ void FrameTreeNode::ResetNavigationRequest(bool keep_state,
void FrameTreeNode::DidStartLoading(bool to_different_document,
bool was_previously_loading) {
+ TRACE_EVENT2("navigation", "FrameTreeNode::DidStartLoading",
+ "frame_tree_node", frame_tree_node_id(), "to different document",
+ to_different_document);
// Any main frame load to a new document should reset the load progress since
// it will replace the current page and any frames. The WebContents will
// be notified when DidChangeLoadProgress is called.
@@ -522,6 +464,8 @@ void FrameTreeNode::DidStartLoading(bool to_different_document,
}
void FrameTreeNode::DidStopLoading() {
+ TRACE_EVENT1("navigation", "FrameTreeNode::DidStopLoading", "frame_tree_node",
+ frame_tree_node_id());
// Set final load progress and update overall progress. This will notify
// the WebContents of the load progress change.
DidChangeLoadProgress(kLoadingProgressDone);
@@ -549,19 +493,17 @@ void FrameTreeNode::DidChangeLoadProgress(double load_progress) {
}
bool FrameTreeNode::StopLoading() {
- if (IsBrowserSideNavigationEnabled()) {
- if (navigation_request_) {
- int expected_pending_nav_entry_id = navigation_request_->nav_entry_id();
- if (navigation_request_->navigation_handle()) {
- navigation_request_->navigation_handle()->set_net_error_code(
- net::ERR_ABORTED);
- expected_pending_nav_entry_id =
- navigation_request_->navigation_handle()->pending_nav_entry_id();
- }
- navigator_->DiscardPendingEntryIfNeeded(expected_pending_nav_entry_id);
+ if (navigation_request_) {
+ int expected_pending_nav_entry_id = navigation_request_->nav_entry_id();
+ if (navigation_request_->navigation_handle()) {
+ navigation_request_->navigation_handle()->set_net_error_code(
+ net::ERR_ABORTED);
+ expected_pending_nav_entry_id =
+ navigation_request_->navigation_handle()->pending_nav_entry_id();
}
- ResetNavigationRequest(false, true);
+ navigator_->DiscardPendingEntryIfNeeded(expected_pending_nav_entry_id);
}
+ ResetNavigationRequest(false, true);
// TODO(nasko): see if child frames should send IPCs in site-per-process
// mode.
diff --git a/chromium/content/browser/frame_host/frame_tree_node.h b/chromium/content/browser/frame_host/frame_tree_node.h
index cee8a19d6dd..5952a070b60 100644
--- a/chromium/content/browser/frame_host/frame_tree_node.h
+++ b/chromium/content/browser/frame_host/frame_tree_node.h
@@ -39,6 +39,14 @@ struct ContentSecurityPolicyHeader;
// of those frames. We are mirroring this tree in the browser process. This
// class represents a node in this tree and is a wrapper for all objects that
// are frame-specific (as opposed to page-specific).
+//
+// Each FrameTreeNode has a current RenderFrameHost, which can change over
+// time as the frame is navigated. Any immediate subframes of the current
+// document are tracked using FrameTreeNodes owned by the current
+// RenderFrameHost, rather than as children of FrameTreeNode itself. This
+// allows subframe FrameTreeNodes to stay alive while a RenderFrameHost is
+// still alive - for example while pending deletion, after a new current
+// RenderFrameHost has replaced it.
class CONTENT_EXPORT FrameTreeNode {
public:
class Observer {
@@ -62,9 +70,6 @@ class CONTENT_EXPORT FrameTreeNode {
// calling the constructor.
FrameTreeNode(FrameTree* frame_tree,
Navigator* navigator,
- RenderFrameHostDelegate* render_frame_delegate,
- RenderWidgetHostDelegate* render_widget_delegate,
- RenderFrameHostManager::Delegate* manager_delegate,
FrameTreeNode* parent,
blink::WebTreeScopeType scope,
const std::string& name,
@@ -80,11 +85,6 @@ class CONTENT_EXPORT FrameTreeNode {
bool IsMainFrame() const;
- FrameTreeNode* AddChild(std::unique_ptr<FrameTreeNode> child,
- int process_id,
- int frame_routing_id);
- void RemoveChild(FrameTreeNode* child);
-
// Clears process specific-state in this node to prepare for a new process.
void ResetForNewProcess();
@@ -124,9 +124,7 @@ class CONTENT_EXPORT FrameTreeNode {
return devtools_frame_token_;
}
- size_t child_count() const {
- return children_.size();
- }
+ size_t child_count() const { return current_frame_host()->child_count(); }
unsigned int depth() const { return depth_; }
@@ -149,7 +147,7 @@ class CONTENT_EXPORT FrameTreeNode {
void SetOriginalOpener(FrameTreeNode* opener);
FrameTreeNode* child_at(size_t index) const {
- return children_[index].get();
+ return current_frame_host()->child_at(index);
}
// Returns the URL of the last committed page in the current frame.
@@ -269,8 +267,6 @@ class CONTENT_EXPORT FrameTreeNode {
return render_manager_.current_frame_host();
}
- bool IsDescendantOf(FrameTreeNode* other) const;
-
// Return the node immediately preceding this node in its parent's
// |children_|, or nullptr if there is no such node.
FrameTreeNode* PreviousSibling() const;
@@ -380,6 +376,12 @@ class CONTENT_EXPORT FrameTreeNode {
return replication_state_.has_received_user_gesture;
}
+ // Returns whether the frame received a user gesture on a previous navigation
+ // on the same eTLD+1.
+ bool has_received_user_gesture_before_nav() const {
+ return replication_state_.has_received_user_gesture_before_nav;
+ }
+
// When a tab is discarded, WebContents sets was_discarded on its
// root FrameTreeNode.
// In addition, when a child frame is created, this bit is passed on from
@@ -387,6 +389,7 @@ class CONTENT_EXPORT FrameTreeNode {
// When a navigation request is created, was_discarded is passed on to the
// request and reset to false in FrameTreeNode.
void set_was_discarded() { was_discarded_ = true; }
+ bool was_discarded() const { return was_discarded_; }
// Returns the sticky bit of the User Activation v2 state of the
// |FrameTreeNode|.
@@ -460,9 +463,6 @@ class CONTENT_EXPORT FrameTreeNode {
// destroyed.
std::unique_ptr<OpenerDestroyedObserver> original_opener_observer_;
- // The immediate children of this specific frame.
- std::vector<std::unique_ptr<FrameTreeNode>> children_;
-
// Whether this frame has committed any real load, replacing its initial
// about:blank page.
bool has_committed_real_load_;
diff --git a/chromium/content/browser/frame_host/interstitial_page_impl.cc b/chromium/content/browser/frame_host/interstitial_page_impl.cc
index 6a26f13d246..f206f1e547a 100644
--- a/chromium/content/browser/frame_host/interstitial_page_impl.cc
+++ b/chromium/content/browser/frame_host/interstitial_page_impl.cc
@@ -92,7 +92,7 @@ class InterstitialPageImpl::InterstitialPageRVHDelegateView
void TakeFocus(bool reverse) override;
int GetTopControlsHeight() const override;
int GetBottomControlsHeight() const override;
- bool DoBrowserControlsShrinkBlinkSize() const override;
+ bool DoBrowserControlsShrinkRendererSize() const override;
virtual void OnFindReply(int request_id,
int number_of_matches,
const gfx::Rect& selection_rect,
@@ -310,8 +310,7 @@ void InterstitialPageImpl::Hide() {
static_cast<WebContentsImpl*>(web_contents_)->DidChangeVisibleSecurityState();
- InterstitialPageMap::iterator iter =
- g_web_contents_to_interstitial_page->find(web_contents_);
+ auto iter = g_web_contents_to_interstitial_page->find(web_contents_);
DCHECK(iter != g_web_contents_to_interstitial_page->end());
if (iter != g_web_contents_to_interstitial_page->end())
g_web_contents_to_interstitial_page->erase(iter);
@@ -805,8 +804,7 @@ Visibility InterstitialPageImpl::GetVisibility() const {
void InterstitialPageImpl::CreateNewWidget(int32_t render_process_id,
int32_t route_id,
- mojom::WidgetPtr widget,
- blink::WebPopupType popup_type) {
+ mojom::WidgetPtr widget) {
NOTREACHED() << "InterstitialPage does not support showing drop-downs.";
}
@@ -1026,14 +1024,14 @@ int InterstitialPageImpl::InterstitialPageRVHDelegateView::
}
bool InterstitialPageImpl::InterstitialPageRVHDelegateView::
- DoBrowserControlsShrinkBlinkSize() const {
+ DoBrowserControlsShrinkRendererSize() const {
if (!interstitial_page_->web_contents())
return false;
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(interstitial_page_->web_contents());
if (!web_contents || !web_contents->GetDelegateView())
return false;
- return web_contents->GetDelegateView()->DoBrowserControlsShrinkBlinkSize();
+ return web_contents->GetDelegateView()->DoBrowserControlsShrinkRendererSize();
}
void InterstitialPageImpl::InterstitialPageRVHDelegateView::OnFindReply(
diff --git a/chromium/content/browser/frame_host/interstitial_page_impl.h b/chromium/content/browser/frame_host/interstitial_page_impl.h
index bb4b5f7771d..1bd73270b29 100644
--- a/chromium/content/browser/frame_host/interstitial_page_impl.h
+++ b/chromium/content/browser/frame_host/interstitial_page_impl.h
@@ -155,8 +155,7 @@ class CONTENT_EXPORT InterstitialPageImpl : public InterstitialPage,
BrowserContext* browser_context) const override;
void CreateNewWidget(int32_t render_process_id,
int32_t route_id,
- mojom::WidgetPtr widget,
- blink::WebPopupType popup_type) override;
+ mojom::WidgetPtr widget) override;
void CreateNewFullscreenWidget(int32_t render_process_id,
int32_t route_id,
mojom::WidgetPtr widget) override;
diff --git a/chromium/content/browser/frame_host/interstitial_page_navigator_impl.cc b/chromium/content/browser/frame_host/interstitial_page_navigator_impl.cc
index fb641d2bd68..7f4c7de9e39 100644
--- a/chromium/content/browser/frame_host/interstitial_page_navigator_impl.cc
+++ b/chromium/content/browser/frame_host/interstitial_page_navigator_impl.cc
@@ -28,16 +28,6 @@ NavigationController* InterstitialPageNavigatorImpl::GetController() {
return controller_;
}
-void InterstitialPageNavigatorImpl::DidStartProvisionalLoad(
- RenderFrameHostImpl* render_frame_host,
- const GURL& url,
- const std::vector<GURL>& redirect_chain,
- const base::TimeTicks& navigation_start) {
- // Do not proceed if the interstitial itself has been disabled.
- if (!enabled_)
- return;
-}
-
void InterstitialPageNavigatorImpl::DidNavigate(
RenderFrameHostImpl* render_frame_host,
const FrameHostMsg_DidCommitProvisionalLoad_Params& input_params,
diff --git a/chromium/content/browser/frame_host/interstitial_page_navigator_impl.h b/chromium/content/browser/frame_host/interstitial_page_navigator_impl.h
index e96489eb086..3ed1141c887 100644
--- a/chromium/content/browser/frame_host/interstitial_page_navigator_impl.h
+++ b/chromium/content/browser/frame_host/interstitial_page_navigator_impl.h
@@ -27,11 +27,6 @@ class CONTENT_EXPORT InterstitialPageNavigatorImpl : public Navigator {
// Navigator implementation.
NavigatorDelegate* GetDelegate() override;
NavigationController* GetController() override;
- void DidStartProvisionalLoad(
- RenderFrameHostImpl* render_frame_host,
- const GURL& url,
- const std::vector<GURL>& redirect_chain,
- const base::TimeTicks& navigation_start) override;
void DidNavigate(
RenderFrameHostImpl* render_frame_host,
const FrameHostMsg_DidCommitProvisionalLoad_Params& input_params,
diff --git a/chromium/content/browser/frame_host/keep_alive_handle_factory.cc b/chromium/content/browser/frame_host/keep_alive_handle_factory.cc
index 068c8ec250d..6edc4562a5c 100644
--- a/chromium/content/browser/frame_host/keep_alive_handle_factory.cc
+++ b/chromium/content/browser/frame_host/keep_alive_handle_factory.cc
@@ -6,6 +6,8 @@
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_features.h"
@@ -39,8 +41,8 @@ class KeepAliveHandleFactory::Context final : public base::RefCounted<Context> {
void DetachLater(base::TimeDelta timeout) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Context::Detach, AsWeakPtr()), timeout);
}
diff --git a/chromium/content/browser/frame_host/mixed_content_navigation_throttle.cc b/chromium/content/browser/frame_host/mixed_content_navigation_throttle.cc
index 24042867287..218c6f74c53 100644
--- a/chromium/content/browser/frame_host/mixed_content_navigation_throttle.cc
+++ b/chromium/content/browser/frame_host/mixed_content_navigation_throttle.cc
@@ -19,6 +19,7 @@
#include "content/public/common/origin_util.h"
#include "content/public/common/web_preferences.h"
#include "net/base/url_util.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"
#include "url/url_constants.h"
@@ -94,16 +95,12 @@ void UpdateRendererOnMixedContentFound(NavigationHandleImpl* navigation_handle,
std::unique_ptr<NavigationThrottle>
MixedContentNavigationThrottle::CreateThrottleForNavigation(
NavigationHandle* navigation_handle) {
- if (IsBrowserSideNavigationEnabled())
- return base::WrapUnique(
- new MixedContentNavigationThrottle(navigation_handle));
- return nullptr;
+ return std::make_unique<MixedContentNavigationThrottle>(navigation_handle);
}
MixedContentNavigationThrottle::MixedContentNavigationThrottle(
NavigationHandle* navigation_handle)
: NavigationThrottle(navigation_handle) {
- DCHECK(IsBrowserSideNavigationEnabled());
}
MixedContentNavigationThrottle::~MixedContentNavigationThrottle() {}
@@ -298,7 +295,7 @@ void MixedContentNavigationThrottle::MaybeSendBlinkFeatureUsageReport() {
// Based off of MixedContentChecker::count.
void MixedContentNavigationThrottle::ReportBasicMixedContentFeatures(
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
blink::WebMixedContentContextType mixed_content_context_type,
const WebPreferences& prefs) {
mixed_content_features_.insert(MIXED_CONTENT_PRESENT);
@@ -315,19 +312,19 @@ void MixedContentNavigationThrottle::ReportBasicMixedContentFeatures(
// ever be found here.
UseCounterFeature feature;
switch (request_context_type) {
- case REQUEST_CONTEXT_TYPE_INTERNAL:
+ case blink::mojom::RequestContextType::INTERNAL:
feature = MIXED_CONTENT_INTERNAL;
break;
- case REQUEST_CONTEXT_TYPE_PREFETCH:
+ case blink::mojom::RequestContextType::PREFETCH:
feature = MIXED_CONTENT_PREFETCH;
break;
- case REQUEST_CONTEXT_TYPE_AUDIO:
- case REQUEST_CONTEXT_TYPE_DOWNLOAD:
- case REQUEST_CONTEXT_TYPE_FAVICON:
- case REQUEST_CONTEXT_TYPE_IMAGE:
- case REQUEST_CONTEXT_TYPE_PLUGIN:
- case REQUEST_CONTEXT_TYPE_VIDEO:
+ case blink::mojom::RequestContextType::AUDIO:
+ case blink::mojom::RequestContextType::DOWNLOAD:
+ case blink::mojom::RequestContextType::FAVICON:
+ case blink::mojom::RequestContextType::IMAGE:
+ case blink::mojom::RequestContextType::PLUGIN:
+ case blink::mojom::RequestContextType::VIDEO:
default:
NOTREACHED() << "RequestContextType has value " << request_context_type
<< " and has WebMixedContentContextType of "
diff --git a/chromium/content/browser/frame_host/mixed_content_navigation_throttle.h b/chromium/content/browser/frame_host/mixed_content_navigation_throttle.h
index 4c884abf890..152ce976eef 100644
--- a/chromium/content/browser/frame_host/mixed_content_navigation_throttle.h
+++ b/chromium/content/browser/frame_host/mixed_content_navigation_throttle.h
@@ -12,7 +12,7 @@
#include "content/common/content_export.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/navigation_throttle.h"
-#include "content/public/common/request_context_type.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/web_mixed_content_context_type.h"
namespace content {
@@ -71,7 +71,7 @@ class MixedContentNavigationThrottle : public NavigationThrottle {
// Records basic mixed content "feature" usage when any kind of mixed content
// is found.
void ReportBasicMixedContentFeatures(
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
blink::WebMixedContentContextType mixed_content_context_type,
const WebPreferences& prefs);
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl.cc b/chromium/content/browser/frame_host/navigation_controller_impl.cc
index d8aca9e2cbf..bd5221ce36f 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl.cc
@@ -930,7 +930,7 @@ bool NavigationControllerImpl::RendererDidNavigate(
for (size_t i = 0; i < params.redirects.size(); ++i) {
redirect_chain_size += params.redirects[i].spec().length();
}
- UMA_HISTOGRAM_COUNTS("Navigation.RedirectChainSize", redirect_chain_size);
+ UMA_HISTOGRAM_COUNTS_1M("Navigation.RedirectChainSize", redirect_chain_size);
// Once it is committed, we no longer need to track several pieces of state on
// the entry.
@@ -1661,10 +1661,8 @@ void NavigationControllerImpl::CopyStateFrom(const NavigationController& temp,
needs_reload_ = needs_reload;
InsertEntriesFrom(source, source.GetEntryCount());
- for (SessionStorageNamespaceMap::const_iterator it =
- source.session_storage_namespace_map_.begin();
- it != source.session_storage_namespace_map_.end();
- ++it) {
+ for (auto it = source.session_storage_namespace_map_.begin();
+ it != source.session_storage_namespace_map_.end(); ++it) {
SessionStorageNamespaceImpl* source_namespace =
static_cast<SessionStorageNamespaceImpl*>(it->second.get());
session_storage_namespace_map_[it->first] = source_namespace->Clone();
@@ -1840,15 +1838,16 @@ bool NavigationControllerImpl::StartHistoryNavigationInNewSubframe(
const char kFramePathPrefix[] = "<!--framePath ";
if (base::StartsWith(unique_name, kFramePathPrefix,
base::CompareCase::SENSITIVE)) {
- UMA_HISTOGRAM_COUNTS("SessionRestore.RestoreSubframeFramePathLength",
- unique_name.size());
+ UMA_HISTOGRAM_COUNTS_1M("SessionRestore.RestoreSubframeFramePathLength",
+ unique_name.size());
}
}
std::unique_ptr<NavigationRequest> request = CreateNavigationRequest(
render_frame_host->frame_tree_node(), *entry, frame_entry,
ReloadType::NONE, false /* is_same_document_history_load */,
- true /* is_history_navigation_in_new_child */, nullptr, nullptr);
+ true /* is_history_navigation_in_new_child */, nullptr, nullptr,
+ base::TimeTicks() /* input_start */, WasActivatedOption::kUnknown);
if (!request)
return false;
@@ -1938,7 +1937,8 @@ void NavigationControllerImpl::NavigateFromFrameProxy(
std::unique_ptr<NavigationRequest> request = CreateNavigationRequest(
render_frame_host->frame_tree_node(), *entry, frame_entry.get(),
ReloadType::NONE, false /* is_same_document_history_load */,
- false /* is_history_navigation_in_new_child */, post_body, nullptr);
+ false /* is_history_navigation_in_new_child */, post_body, nullptr,
+ base::TimeTicks() /* input_start */, WasActivatedOption::kUnknown);
if (!request)
return;
@@ -2195,7 +2195,8 @@ void NavigationControllerImpl::NavigateToExistingPendingEntry(
CreateNavigationRequest(
root, *pending_entry_, pending_entry_->GetFrameEntry(root),
reload_type, false /* is_same_document_history_load */,
- false /* is_history_navigation_in_new_child */, nullptr, nullptr);
+ false /* is_history_navigation_in_new_child */, nullptr, nullptr,
+ base::TimeTicks() /* input_start */, WasActivatedOption::kUnknown);
if (!navigation_request) {
// This navigation cannot start (e.g. the URL is invalid), delete the
// pending NavigationEntry.
@@ -2271,7 +2272,9 @@ void NavigationControllerImpl::FindFramesToNavigate(
CreateNavigationRequest(
frame, *pending_entry_, new_item, reload_type,
true /* is_same_document_history_load */,
- false /* is_history_navigation_in_new_child */, nullptr, nullptr);
+ false /* is_history_navigation_in_new_child */, nullptr, nullptr,
+ base::TimeTicks() /* input_start */,
+ WasActivatedOption::kUnknown);
if (navigation_request) {
// Only add the request if was properly created. It's possible for the
// creation to fail in certain cases, e.g. when the URL is invalid.
@@ -2297,7 +2300,9 @@ void NavigationControllerImpl::FindFramesToNavigate(
CreateNavigationRequest(
frame, *pending_entry_, new_item, reload_type,
false /* is_same_document_history_load */,
- false /* is_history_navigation_in_new_child */, nullptr, nullptr);
+ false /* is_history_navigation_in_new_child */, nullptr, nullptr,
+ base::TimeTicks() /* input_start */,
+ WasActivatedOption::kUnknown);
if (navigation_request) {
// Only add the request if was properly created. It's possible for the
// creation to fail in certain cases, e.g. when the URL is invalid.
@@ -2381,7 +2386,8 @@ void NavigationControllerImpl::NavigateWithoutEntry(
node, *pending_entry_, pending_entry_->GetFrameEntry(node), reload_type,
false /* is_same_document_history_load */,
false /* is_history_navigation_in_new_child */, nullptr,
- params.navigation_ui_data ? params.navigation_ui_data->Clone() : nullptr);
+ params.navigation_ui_data ? params.navigation_ui_data->Clone() : nullptr,
+ params.input_start, params.was_activated);
// If the navigation couldn't start, return immediately and discard the
// pending NavigationEntry.
@@ -2543,7 +2549,9 @@ NavigationControllerImpl::CreateNavigationRequest(
bool is_same_document_history_load,
bool is_history_navigation_in_new_child,
const scoped_refptr<network::ResourceRequestBody>& post_body,
- std::unique_ptr<NavigationUIData> navigation_ui_data) {
+ std::unique_ptr<NavigationUIData> navigation_ui_data,
+ base::TimeTicks input_start,
+ WasActivatedOption was_activated) {
GURL dest_url = frame_entry->url();
Referrer dest_referrer = frame_entry->referrer();
if (reload_type == ReloadType::ORIGINAL_REQUEST_URL &&
@@ -2616,7 +2624,7 @@ NavigationControllerImpl::CreateNavigationRequest(
frame_tree_node, dest_url, dest_referrer, *frame_entry, entry,
navigation_type, previews_state, is_same_document_history_load,
is_history_navigation_in_new_child, post_body, navigation_start, this,
- std::move(navigation_ui_data));
+ std::move(navigation_ui_data), input_start, was_activated);
}
void NavigationControllerImpl::NotifyNavigationEntryCommitted(
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl.h b/chromium/content/browser/frame_host/navigation_controller_impl.h
index 8b3502ccbc1..b4ef12e86d6 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl.h
+++ b/chromium/content/browser/frame_host/navigation_controller_impl.h
@@ -26,6 +26,7 @@
struct FrameHostMsg_DidCommitProvisionalLoad_Params;
namespace content {
+enum class WasActivatedOption;
class FrameTreeNode;
class RenderFrameHostImpl;
class NavigationEntryScreenshotManager;
@@ -293,7 +294,9 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController {
bool is_same_document_history_load,
bool is_history_navigation_in_new_child,
const scoped_refptr<network::ResourceRequestBody>& post_body,
- std::unique_ptr<NavigationUIData> navigation_ui_data);
+ std::unique_ptr<NavigationUIData> navigation_ui_data,
+ base::TimeTicks input_start,
+ WasActivatedOption was_activated);
// Returns whether there is a pending NavigationEntry whose unique ID matches
// the given NavigationHandle's pending_nav_entry_id.
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc
index 06e52b458db..6979a2f11f3 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -18,6 +18,7 @@
#include "base/sequenced_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_restrictions.h"
@@ -28,7 +29,6 @@
#include "content/browser/frame_host/navigation_handle_impl.h"
#include "content/browser/frame_host/navigation_request.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
-#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/renderer_host/display_util.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -36,6 +36,7 @@
#include "content/common/frame_messages.h"
#include "content/common/page_state_serialization.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/render_view_host.h"
@@ -984,8 +985,8 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
ErrorPageReplacement) {
NavigationController& controller = shell()->web_contents()->GetController();
GURL error_url = embedded_test_server()->GetURL("/close-socket");
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&net::URLRequestFailedJob::AddUrlHandler));
EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL)));
@@ -4912,10 +4913,10 @@ void DoReplaceStateWhilePending(Shell* shell,
EXPECT_TRUE(NavigateToURL(shell, start_url));
// Have the user decide to go to a different page which is very slow.
- NavigationStallDelegate stall_delegate(stalled_url);
- ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
- controller.LoadURL(
- stalled_url, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
+ TestNavigationManager stalled_navigation(shell->web_contents(), stalled_url);
+ controller.LoadURL(stalled_url, Referrer(), ui::PAGE_TRANSITION_LINK,
+ std::string());
+ EXPECT_TRUE(stalled_navigation.WaitForRequestStart());
// That should be the pending entry.
NavigationEntryImpl* entry = controller.GetPendingEntry();
@@ -4936,16 +4937,13 @@ void DoReplaceStateWhilePending(Shell* shell,
EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.navigation_type());
EXPECT_TRUE(capturer.is_same_document());
}
-
- ResourceDispatcherHost::Get()->SetDelegate(nullptr);
}
} // namespace
-// Flaky on Linux TSan: https://crbug.com/847326
IN_PROC_BROWSER_TEST_F(
NavigationControllerBrowserTest,
- DISABLED_NavigationTypeClassification_On1SameDocumentToXWhile2Pending) {
+ NavigationTypeClassification_On1SameDocumentToXWhile2Pending) {
GURL url1(embedded_test_server()->GetURL(
"/navigation_controller/simple_page_1.html"));
GURL url2(embedded_test_server()->GetURL(
@@ -4971,10 +4969,9 @@ IN_PROC_BROWSER_TEST_F(
DoReplaceStateWhilePending(shell(), url, url, "x");
}
-// Flaky on Linux TSan: https://crbug.com/847326
IN_PROC_BROWSER_TEST_F(
NavigationControllerBrowserTest,
- DISABLED_NavigationTypeClassification_On1SameDocumentTo1While1Pending) {
+ NavigationTypeClassification_On1SameDocumentTo1While1Pending) {
GURL url(embedded_test_server()->GetURL(
"/navigation_controller/simple_page_1.html"));
DoReplaceStateWhilePending(shell(), url, url, "simple_page_1.html");
@@ -5003,11 +5000,11 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
// Start a cross-process navigation with replacement, which never completes.
GURL foo_url(embedded_test_server()->GetURL(
"foo.com", "/navigation_controller/page_with_links.html"));
- NavigationStallDelegate stall_delegate(foo_url);
- ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
+ TestNavigationManager stalled_navigation(shell()->web_contents(), foo_url);
NavigationController::LoadURLParams params(foo_url);
params.should_replace_current_entry = true;
controller.LoadURLWithParams(params);
+ EXPECT_TRUE(stalled_navigation.WaitForRequestStart());
// That should be the pending entry.
NavigationEntryImpl* entry = controller.GetPendingEntry();
@@ -5033,8 +5030,6 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_EQ(entry_count + 1, controller.GetEntryCount());
EXPECT_EQ(push_state_url, controller.GetLastCommittedEntry()->GetURL());
EXPECT_EQ(start_url, controller.GetEntryAtIndex(0)->GetURL());
-
- ResourceDispatcherHost::Get()->SetDelegate(nullptr);
}
// This test ensures that if we go back from a page that has a replaceState()
@@ -5275,7 +5270,7 @@ class FailureWatcher : public WebContentsObserver {
} // namespace
IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
- DISABLED_StopCausesFailureDespiteJavaScriptURL) {
+ StopCausesFailureDespiteJavaScriptURL) {
NavigationControllerImpl& controller =
static_cast<NavigationControllerImpl&>(
shell()->web_contents()->GetController());
@@ -5292,9 +5287,9 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
// Have the user decide to go to a different page which will not commit.
GURL url2(embedded_test_server()->GetURL(
"/navigation_controller/simple_page_2.html"));
- NavigationStallDelegate stall_delegate(url2);
- ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
+ TestNavigationManager stalled_navigation(shell()->web_contents(), url2);
controller.LoadURL(url2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
+ EXPECT_TRUE(stalled_navigation.WaitForResponse());
// That should be the pending entry.
NavigationEntryImpl* entry = controller.GetPendingEntry();
@@ -5306,16 +5301,12 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
FailureWatcher watcher(root);
GURL js("javascript:(function(){})()");
controller.LoadURL(js, Referrer(), ui::PAGE_TRANSITION_LINK, std::string());
- // This LoadURL ends up purging the pending entry, which is why this is
- // tricky.
- EXPECT_EQ(nullptr, controller.GetPendingEntry());
+ EXPECT_EQ(entry, controller.GetPendingEntry());
EXPECT_TRUE(shell()->web_contents()->IsLoading());
shell()->web_contents()->Stop();
watcher.Wait();
EXPECT_FALSE(shell()->web_contents()->IsLoading());
}
-
- ResourceDispatcherHost::Get()->SetDelegate(nullptr);
}
namespace {
@@ -6022,6 +6013,21 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
EXPECT_EQ(0, controller.GetCurrentEntryIndex());
}
+// Make sure that a 304 response to a navigation aborts the navigation.
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, NavigateTo304) {
+ // URL that just returns a blank page.
+ GURL initial_url = embedded_test_server()->GetURL("/set-header");
+ // URL that returns a response with a 304 status code.
+ GURL not_modified_url = embedded_test_server()->GetURL("/echo?status=304");
+
+ EXPECT_TRUE(NavigateToURL(shell(), initial_url));
+ EXPECT_EQ(initial_url, shell()->web_contents()->GetVisibleURL());
+
+ // The navigation should be aborted.
+ EXPECT_FALSE(NavigateToURL(shell(), not_modified_url));
+ EXPECT_EQ(initial_url, shell()->web_contents()->GetVisibleURL());
+}
+
// Ensure that we do not corrupt a NavigationEntry's PageState if two forward
// navigations compete in different frames. See https://crbug.com/623319.
IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
@@ -6765,7 +6771,7 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
// Verify the expected origin through JavaScript. It also has the additional
// verification of the process also being still alive.
EXPECT_EQ(url::Origin::Create(start_url).Serialize(),
- EvalJs(web_contents, "document.origin"));
+ EvalJs(web_contents, "self.origin"));
}
// Helper to trigger a history-back navigation in the WebContents after the
@@ -6854,7 +6860,7 @@ IN_PROC_BROWSER_TEST_F(
// Verify the expected origin through JavaScript. It also has the additional
// verification of the process also being still alive.
EXPECT_EQ(url::Origin::Create(start_url).Serialize(),
- EvalJs(web_contents, "document.origin"));
+ EvalJs(web_contents, "self.origin"));
}
// Test that verifies that Referer and Origin http headers are correctly sent
@@ -8206,4 +8212,44 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
}
}
+// history.back() called twice in the renderer process should not make the user
+// navigate back twice.
+// Regression test for https://crbug.com/869710
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
+ HistoryBackTwiceFromRendererWithoutUserGesture) {
+ GURL url1(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ GURL url2(embedded_test_server()->GetURL("b.com", "/title2.html"));
+ GURL url3(embedded_test_server()->GetURL("c.com", "/title3.html"));
+
+ EXPECT_TRUE(NavigateToURL(shell(), url1));
+ EXPECT_TRUE(NavigateToURL(shell(), url2));
+ EXPECT_TRUE(NavigateToURL(shell(), url3));
+
+ EXPECT_TRUE(ExecuteScriptWithoutUserGesture(
+ shell(), "history.back(); history.back();"));
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+ EXPECT_EQ(url2, shell()->web_contents()->GetLastCommittedURL());
+}
+
+// history.back() called twice in the renderer process should not make the user
+// navigate back twice. Even with a user gesture.
+// Regression test for https://crbug.com/869710
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
+ HistoryBackTwiceFromRendererWithUserGesture) {
+ GURL url1(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ GURL url2(embedded_test_server()->GetURL("b.com", "/title2.html"));
+ GURL url3(embedded_test_server()->GetURL("c.com", "/title3.html"));
+
+ EXPECT_TRUE(NavigateToURL(shell(), url1));
+ EXPECT_TRUE(NavigateToURL(shell(), url2));
+ EXPECT_TRUE(NavigateToURL(shell(), url3));
+
+ EXPECT_TRUE(ExecuteScript(shell(), "history.back(); history.back();"));
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+ // TODO(https://crbug.com/869710): This should be url2.
+ EXPECT_EQ(url1, shell()->web_contents()->GetLastCommittedURL());
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc b/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc
index ebff6f11cc9..43af58f9917 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -455,13 +455,10 @@ TEST_F(NavigationControllerTestWithBrowserSideNavigation,
// entry when url_1 fails.
NavigateAndCommit(initial_url);
- // Set the pending entry as url_1 and receive the DidStartProvisionalLoad
- // message, creating the NavigationHandle.
+ // Set the pending entry as url_1 and create the NavigationHandle.
controller.LoadURL(url_1, Referrer(), ui::PAGE_TRANSITION_TYPED,
std::string());
EXPECT_EQ(url_1, controller.GetVisibleEntry()->GetURL());
- main_test_rfh()->SimulateNavigationStart(url_1);
- EXPECT_EQ(url_1, controller.GetVisibleEntry()->GetURL());
// The navigation fails and needs to show an error page. This resets the
// pending entry.
@@ -2738,7 +2735,7 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterSameDocumentNavigation) {
params.transition = ui::PAGE_TRANSITION_LINK;
params.redirects.push_back(url);
params.should_update_history = true;
- params.gesture = NavigationGestureUnknown;
+ params.gesture = NavigationGestureAuto;
params.method = "GET";
params.page_state = PageState::CreateFromURL(url);
@@ -2763,7 +2760,7 @@ TEST_F(NavigationControllerTest, ClientRedirectAfterSameDocumentNavigation) {
params.redirects.push_back(GURL("http://foo2/#a"));
params.redirects.push_back(url);
params.should_update_history = true;
- params.gesture = NavigationGestureUnknown;
+ params.gesture = NavigationGestureAuto;
params.method = "GET";
params.page_state = PageState::CreateFromURL(url);
@@ -3381,8 +3378,6 @@ TEST_F(NavigationControllerTest, ReloadTransient) {
// See http://crbug.com/266922.
TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
NavigationControllerImpl& controller = controller_impl();
- Navigator* navigator =
- contents()->GetFrameTree()->root()->navigator();
const GURL url1("nonexistent:12121");
const GURL url1_fixed("http://nonexistent:12121/");
@@ -3392,8 +3387,6 @@ TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
// can show them in new tabs when it is safe.
main_test_rfh()->SendRendererInitiatedNavigationRequest(url1, false);
main_test_rfh()->PrepareForCommit();
- navigator->DidStartProvisionalLoad(main_test_rfh(), url1, std::vector<GURL>(),
- base::TimeTicks::Now());
// Simulate what happens if a BrowserURLHandler rewrites the URL, causing
// the virtual URL to differ from the URL.
@@ -3407,8 +3400,6 @@ TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
// If the user clicks another link, we should replace the pending entry.
main_test_rfh()->SendRendererInitiatedNavigationRequest(url2, false);
main_test_rfh()->PrepareForCommit();
- navigator->DidStartProvisionalLoad(main_test_rfh(), url2, std::vector<GURL>(),
- base::TimeTicks::Now());
EXPECT_EQ(url2, controller.GetPendingEntry()->GetURL());
EXPECT_EQ(url2, controller.GetPendingEntry()->GetVirtualURL());
@@ -3417,26 +3408,10 @@ TEST_F(NavigationControllerTest, RendererInitiatedPendingEntries) {
EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetVirtualURL());
- // We should not replace the pending entry for an error URL.
- navigator->DidStartProvisionalLoad(main_test_rfh(), url1, std::vector<GURL>(),
- base::TimeTicks::Now());
- EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
- navigator->DidStartProvisionalLoad(
- main_test_rfh(), GURL(kUnreachableWebDataURL), std::vector<GURL>(),
- base::TimeTicks::Now());
- EXPECT_EQ(url1, controller.GetPendingEntry()->GetURL());
-
// We should remember if the pending entry will replace the current one.
// http://crbug.com/308444.
- navigator->DidStartProvisionalLoad(main_test_rfh(), url1, std::vector<GURL>(),
- base::TimeTicks::Now());
- controller.GetPendingEntry()->set_should_replace_entry(true);
-
main_test_rfh()->SendRendererInitiatedNavigationRequest(url2, false);
main_test_rfh()->PrepareForCommit();
- navigator->DidStartProvisionalLoad(main_test_rfh(), url2, std::vector<GURL>(),
- base::TimeTicks::Now());
- EXPECT_TRUE(controller.GetPendingEntry()->should_replace_entry());
main_test_rfh()->SendNavigateWithReplacement(0, false, url2);
EXPECT_EQ(url2, controller.GetLastCommittedEntry()->GetURL());
}
@@ -4029,12 +4004,9 @@ TEST_F(NavigationControllerTest, CopyStateFrom) {
other_controller.GetSessionStorageNamespaceMap();
EXPECT_EQ(session_storage_namespace_map.size(),
other_session_storage_namespace_map.size());
- for (SessionStorageNamespaceMap::const_iterator it =
- session_storage_namespace_map.begin();
- it != session_storage_namespace_map.end();
- ++it) {
- SessionStorageNamespaceMap::const_iterator other =
- other_session_storage_namespace_map.find(it->first);
+ for (auto it = session_storage_namespace_map.begin();
+ it != session_storage_namespace_map.end(); ++it) {
+ auto other = other_session_storage_namespace_map.find(it->first);
EXPECT_TRUE(other != other_session_storage_namespace_map.end());
}
}
@@ -4523,7 +4495,7 @@ TEST_F(NavigationControllerTest, HistoryNavigate) {
process()->sink().ClearMessages();
// Simulate the page calling history.back(). It should create a pending entry.
- contents()->OnGoToEntryAtOffset(test_rvh(), -1);
+ contents()->OnGoToEntryAtOffset(test_rvh(), -1, false);
EXPECT_EQ(0, controller.GetPendingEntryIndex());
// Also make sure we told the page to navigate.
@@ -4533,7 +4505,7 @@ TEST_F(NavigationControllerTest, HistoryNavigate) {
process()->sink().ClearMessages();
// Now test history.forward()
- contents()->OnGoToEntryAtOffset(test_rvh(), 2);
+ contents()->OnGoToEntryAtOffset(test_rvh(), 2, false);
EXPECT_EQ(2, controller.GetPendingEntryIndex());
nav_url = GetLastNavigationURL();
@@ -4544,7 +4516,7 @@ TEST_F(NavigationControllerTest, HistoryNavigate) {
controller.DiscardNonCommittedEntries();
// Make sure an extravagant history.go() doesn't break.
- contents()->OnGoToEntryAtOffset(test_rvh(), 120); // Out of bounds.
+ contents()->OnGoToEntryAtOffset(test_rvh(), 120, false); // Out of bounds.
EXPECT_EQ(-1, controller.GetPendingEntryIndex());
EXPECT_FALSE(HasNavigationRequest());
}
diff --git a/chromium/content/browser/frame_host/navigation_entry_impl.cc b/chromium/content/browser/frame_host/navigation_entry_impl.cc
index aa9c80e2ce7..bece9448ba6 100644
--- a/chromium/content/browser/frame_host/navigation_entry_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_entry_impl.cc
@@ -613,8 +613,7 @@ void NavigationEntryImpl::SetExtraData(const std::string& key,
bool NavigationEntryImpl::GetExtraData(const std::string& key,
base::string16* data) const {
- std::map<std::string, base::string16>::const_iterator iter =
- extra_data_.find(key);
+ auto iter = extra_data_.find(key);
if (iter == extra_data_.end())
return false;
*data = iter->second;
@@ -686,17 +685,15 @@ CommonNavigationParams NavigationEntryImpl::ConstructCommonNavigationParams(
const Referrer& dest_referrer,
FrameMsg_Navigate_Type::Value navigation_type,
PreviewsState previews_state,
- const base::TimeTicks& navigation_start) const {
+ base::TimeTicks navigation_start,
+ base::TimeTicks input_start) const {
return CommonNavigationParams(
dest_url, dest_referrer, GetTransitionType(), navigation_type,
!IsViewSourceMode(), should_replace_entry(), GetBaseURLForDataURL(),
GetHistoryURLForDataURL(), previews_state, navigation_start,
frame_entry.method(), post_body ? post_body : post_data_,
- base::Optional<SourceLocation>(),
- CSPDisposition::CHECK /* should_check_main_world_csp */,
- has_started_from_context_menu(), has_user_gesture(),
- std::vector<ContentSecurityPolicy>() /* initiator_csp */,
- CSPSource() /* initiator_self_source */);
+ base::Optional<SourceLocation>(), has_started_from_context_menu(),
+ has_user_gesture(), InitiatorCSPInfo(), input_start);
}
RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams(
diff --git a/chromium/content/browser/frame_host/navigation_entry_impl.h b/chromium/content/browser/frame_host/navigation_entry_impl.h
index 8c398afe158..858d2af410c 100644
--- a/chromium/content/browser/frame_host/navigation_entry_impl.h
+++ b/chromium/content/browser/frame_host/navigation_entry_impl.h
@@ -187,7 +187,8 @@ class CONTENT_EXPORT NavigationEntryImpl : public NavigationEntry {
const Referrer& dest_referrer,
FrameMsg_Navigate_Type::Value navigation_type,
PreviewsState previews_state,
- const base::TimeTicks& navigation_start) const;
+ base::TimeTicks navigation_start,
+ base::TimeTicks input_start) const;
RequestNavigationParams ConstructRequestNavigationParams(
const FrameNavigationEntry& frame_entry,
const GURL& original_url,
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl.cc b/chromium/content/browser/frame_host/navigation_handle_impl.cc
index 6bc8930b7d8..f8a86851d33 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_handle_impl.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/optional.h"
#include "base/time/time.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
#include "content/browser/appcache/appcache_service_impl.h"
@@ -34,6 +35,7 @@
#include "content/common/frame_messages.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/navigation_ui_data.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_client.h"
@@ -72,29 +74,49 @@ void UpdateThrottleCheckResult(
*to_update = result;
}
+// LOG_NAVIGATION_TIMING_HISTOGRAM logs |value| for "Navigation.<histogram>" UMA
+// as well as supplementary UMAs (depending on |transition| and |is_background|)
+// for BackForward/Reload/NewNavigation variants.
+//
+// kMaxTime and kBuckets constants are consistent with
+// UMA_HISTOGRAM_MEDIUM_TIMES, but a custom kMinTime is used for high fidelity
+// near the low end of measured values.
+//
// TODO(csharrison,nasko): This macro is incorrect for subframe navigations,
// which will only have subframe-specific transition types. This means that all
// subframes currently are tagged as NewNavigations.
-#define LOG_NAVIGATION_TIMING_HISTOGRAM(histogram, transition, value, \
- max_time) \
- do { \
- const base::TimeDelta kMinTime = base::TimeDelta::FromMilliseconds(1); \
- const int kBuckets = 50; \
- UMA_HISTOGRAM_CUSTOM_TIMES("Navigation." histogram, value, kMinTime, \
- max_time, kBuckets); \
- if (transition & ui::PAGE_TRANSITION_FORWARD_BACK) { \
- UMA_HISTOGRAM_CUSTOM_TIMES("Navigation." histogram ".BackForward", \
- value, kMinTime, max_time, kBuckets); \
- } else if (ui::PageTransitionCoreTypeIs(transition, \
- ui::PAGE_TRANSITION_RELOAD)) { \
- UMA_HISTOGRAM_CUSTOM_TIMES("Navigation." histogram ".Reload", value, \
- kMinTime, max_time, kBuckets); \
- } else if (ui::PageTransitionIsNewNavigation(transition)) { \
- UMA_HISTOGRAM_CUSTOM_TIMES("Navigation." histogram ".NewNavigation", \
- value, kMinTime, max_time, kBuckets); \
- } else { \
- NOTREACHED() << "Invalid page transition: " << transition; \
- } \
+#define LOG_NAVIGATION_TIMING_HISTOGRAM(histogram, transition, is_background, \
+ duration) \
+ do { \
+ const base::TimeDelta kMinTime = base::TimeDelta::FromMilliseconds(1); \
+ const base::TimeDelta kMaxTime = base::TimeDelta::FromMinutes(3); \
+ const int kBuckets = 50; \
+ UMA_HISTOGRAM_CUSTOM_TIMES("Navigation." histogram, duration, kMinTime, \
+ kMaxTime, kBuckets); \
+ if (transition & ui::PAGE_TRANSITION_FORWARD_BACK) { \
+ UMA_HISTOGRAM_CUSTOM_TIMES("Navigation." histogram ".BackForward", \
+ duration, kMinTime, kMaxTime, kBuckets); \
+ } else if (ui::PageTransitionCoreTypeIs(transition, \
+ ui::PAGE_TRANSITION_RELOAD)) { \
+ UMA_HISTOGRAM_CUSTOM_TIMES("Navigation." histogram ".Reload", duration, \
+ kMinTime, kMaxTime, kBuckets); \
+ } else if (ui::PageTransitionIsNewNavigation(transition)) { \
+ UMA_HISTOGRAM_CUSTOM_TIMES("Navigation." histogram ".NewNavigation", \
+ duration, kMinTime, kMaxTime, kBuckets); \
+ } else { \
+ NOTREACHED() << "Invalid page transition: " << transition; \
+ } \
+ if (is_background.has_value()) { \
+ if (is_background.value()) { \
+ UMA_HISTOGRAM_CUSTOM_TIMES("Navigation." histogram \
+ ".BackgroundProcessPriority", \
+ duration, kMinTime, kMaxTime, kBuckets); \
+ } else { \
+ UMA_HISTOGRAM_CUSTOM_TIMES("Navigation." histogram \
+ ".ForegroundProcessPriority", \
+ duration, kMinTime, kMaxTime, kBuckets); \
+ } \
+ } \
} while (0)
void LogIsSameProcess(ui::PageTransition transition, bool is_same_process) {
@@ -140,7 +162,7 @@ std::unique_ptr<NavigationHandleImpl> NavigationHandleImpl::Create(
bool has_user_gesture,
ui::PageTransition transition,
bool is_external_protocol,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
blink::WebMixedContentContextType mixed_content_context_type,
base::TimeTicks input_start) {
return std::unique_ptr<NavigationHandleImpl>(new NavigationHandleImpl(
@@ -172,7 +194,7 @@ NavigationHandleImpl::NavigationHandleImpl(
bool has_user_gesture,
ui::PageTransition transition,
bool is_external_protocol,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
blink::WebMixedContentContextType mixed_content_context_type,
base::TimeTicks input_start)
: url_(url),
@@ -207,11 +229,11 @@ NavigationHandleImpl::NavigationHandleImpl(
navigation_type_(NAVIGATION_TYPE_UNKNOWN),
should_check_main_world_csp_(should_check_main_world_csp),
expected_render_process_host_id_(ChildProcessHost::kInvalidUniqueID),
- is_transferring_(false),
is_form_submission_(is_form_submission),
should_replace_current_entry_(false),
is_download_(false),
is_stream_(false),
+ is_signed_exchange_inner_response_(false),
started_from_context_menu_(started_from_context_menu),
is_same_process_(true),
weak_factory_(this) {
@@ -537,7 +559,10 @@ NavigationHandleImpl::CallWillProcessResponseForTesting(
WillProcessResponse(static_cast<RenderFrameHostImpl*>(render_frame_host),
headers, net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
net::HostPortPair(), net::SSLInfo(), GlobalRequestID(),
- false, false, false,
+ /* should_replace_current_entry=*/false,
+ /* is_download=*/false,
+ /* is_stream=*/false,
+ /* is_signed_exchange_inner_response=*/false,
base::Bind(&UpdateThrottleCheckResult, &result));
// Reset the callback to ensure it will not be called later.
@@ -554,8 +579,6 @@ void NavigationHandleImpl::CallDidCommitNavigationForTesting(const GURL& url) {
params.transition = ui::PAGE_TRANSITION_TYPED;
params.redirects = std::vector<GURL>();
params.should_update_history = false;
- params.searchable_form_url = GURL();
- params.searchable_form_encoding = std::string();
params.did_create_new_entry = false;
params.gesture = NavigationGestureUser;
params.method = "GET";
@@ -629,6 +652,10 @@ bool NavigationHandleImpl::IsFormSubmission() {
return is_form_submission_;
}
+bool NavigationHandleImpl::IsSignedExchangeInnerResponse() {
+ return is_signed_exchange_inner_response_;
+}
+
void NavigationHandleImpl::InitServiceWorkerHandle(
ServiceWorkerContextWrapper* service_worker_context) {
service_worker_handle_.reset(
@@ -790,6 +817,7 @@ void NavigationHandleImpl::WillProcessResponse(
bool should_replace_current_entry,
bool is_download,
bool is_stream,
+ bool is_signed_exchange_inner_response,
const ThrottleChecksFinishedCallback& callback) {
TRACE_EVENT_ASYNC_STEP_INTO0("navigation", "NavigationHandle", this,
"WillProcessResponse");
@@ -802,6 +830,7 @@ void NavigationHandleImpl::WillProcessResponse(
should_replace_current_entry_ = should_replace_current_entry;
is_download_ = is_download;
is_stream_ = is_stream;
+ is_signed_exchange_inner_response_ = is_signed_exchange_inner_response;
state_ = WILL_PROCESS_RESPONSE;
ssl_info_ = ssl_info;
socket_address_ = socket_address;
@@ -857,30 +886,28 @@ void NavigationHandleImpl::ReadyToCommitNavigation(
frame_tree_node_->current_frame_host()->GetProcess()->GetID();
LogIsSameProcess(transition_, is_same_process_);
- // TODO(csharrison,nasko): Increase the max value to 3 minutes in M68 or
- // M69.
+ // Don't log process-priority-specific UMAs for TimeToReadyToCommit metric
+ // (which shouldn't be influenced by renderer priority).
+ constexpr base::Optional<bool> kIsBackground = base::nullopt;
+
base::TimeDelta delta = ready_to_commit_time_ - navigation_start_;
- LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit", transition_, delta,
- base::TimeDelta::FromSeconds(10));
+ LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit", transition_,
+ kIsBackground, delta);
if (IsInMainFrame()) {
LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit.MainFrame",
- transition_, delta,
- base::TimeDelta::FromSeconds(10));
+ transition_, kIsBackground, delta);
} else {
LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit.Subframe",
- transition_, delta,
- base::TimeDelta::FromSeconds(10));
+ transition_, kIsBackground, delta);
}
if (is_same_process_) {
LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit.SameProcess",
- transition_, delta,
- base::TimeDelta::FromSeconds(10));
+ transition_, kIsBackground, delta);
} else {
LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit.CrossProcess",
- transition_, delta,
- base::TimeDelta::FromSeconds(10));
+ transition_, kIsBackground, delta);
}
}
@@ -932,44 +959,43 @@ void NavigationHandleImpl::DidCommitNavigation(
base::TimeTicks now = base::TimeTicks::Now();
base::TimeDelta delta = now - navigation_start_;
ui::PageTransition transition = GetPageTransition();
- // 3 minutes aligns with UMA_HISTOGRAM_MEDIUM_TIMES.
- const base::TimeDelta kMaxTime = base::TimeDelta::FromMinutes(3);
- LOG_NAVIGATION_TIMING_HISTOGRAM("StartToCommit", transition, delta,
- kMaxTime);
+ base::Optional<bool> is_background =
+ render_frame_host->GetProcess()->IsProcessBackgrounded();
+ LOG_NAVIGATION_TIMING_HISTOGRAM("StartToCommit", transition, is_background,
+ delta);
if (IsInMainFrame()) {
LOG_NAVIGATION_TIMING_HISTOGRAM("StartToCommit.MainFrame", transition,
- delta, kMaxTime);
+ is_background, delta);
} else {
LOG_NAVIGATION_TIMING_HISTOGRAM("StartToCommit.Subframe", transition,
- delta, kMaxTime);
+ is_background, delta);
}
if (is_same_process_) {
LOG_NAVIGATION_TIMING_HISTOGRAM("StartToCommit.SameProcess", transition,
- delta, kMaxTime);
+ is_background, delta);
if (IsInMainFrame()) {
LOG_NAVIGATION_TIMING_HISTOGRAM("StartToCommit.SameProcess.MainFrame",
- transition, delta, kMaxTime);
+ transition, is_background, delta);
} else {
LOG_NAVIGATION_TIMING_HISTOGRAM("StartToCommit.SameProcess.Subframe",
- transition, delta, kMaxTime);
+ transition, is_background, delta);
}
} else {
LOG_NAVIGATION_TIMING_HISTOGRAM("StartToCommit.CrossProcess", transition,
- delta, kMaxTime);
+ is_background, delta);
if (IsInMainFrame()) {
LOG_NAVIGATION_TIMING_HISTOGRAM("StartToCommit.CrossProcess.MainFrame",
- transition, delta, kMaxTime);
+ transition, is_background, delta);
} else {
LOG_NAVIGATION_TIMING_HISTOGRAM("StartToCommit.CrossProcess.Subframe",
- transition, delta, kMaxTime);
+ transition, is_background, delta);
}
}
- // 10 seconds aligns with UMA_HISTOGRAM_TIMES.
if (!ready_to_commit_time_.is_null()) {
LOG_NAVIGATION_TIMING_HISTOGRAM("ReadyToCommitUntilCommit", transition_,
- now - ready_to_commit_time_,
- base::TimeDelta::FromSeconds(10));
+ is_background,
+ now - ready_to_commit_time_);
}
}
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl.h b/chromium/content/browser/frame_host/navigation_handle_impl.h
index 22ecf65f214..56cfa2c17a1 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl.h
+++ b/chromium/content/browser/frame_host/navigation_handle_impl.h
@@ -28,7 +28,7 @@
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/navigation_type.h"
#include "content/public/browser/restore_type.h"
-#include "content/public/common/request_context_type.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/web_mixed_content_context_type.h"
#include "url/gurl.h"
@@ -53,10 +53,8 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
public:
// If |redirect_chain| is empty, then the redirect chain will be created to
// start with |url|. Otherwise |redirect_chain| is used as the starting point.
- // |navigation_start| comes from the DidStartProvisionalLoad IPC, which tracks
- // both renderer-initiated and browser-initiated navigation start.
- // PlzNavigate: This value always comes from the CommonNavigationParams
- // associated with this navigation.
+ // |navigation_start| comes from the CommonNavigationParams associated with
+ // this navigation.
static std::unique_ptr<NavigationHandleImpl> Create(
const GURL& url,
const std::vector<GURL>& redirect_chain,
@@ -77,8 +75,8 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
bool has_user_gesture = false,
ui::PageTransition transition = ui::PAGE_TRANSITION_LINK,
bool is_external_protocol = false,
- RequestContextType request_context_type =
- REQUEST_CONTEXT_TYPE_UNSPECIFIED,
+ blink::mojom::RequestContextType request_context_type =
+ blink::mojom::RequestContextType::UNSPECIFIED,
blink::WebMixedContentContextType mixed_content_context_type =
blink::WebMixedContentContextType::kBlockable,
base::TimeTicks input_start = base::TimeTicks());
@@ -164,6 +162,7 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
const GlobalRequestID& GetGlobalRequestID() override;
bool IsDownload() override;
bool IsFormSubmission() override;
+ bool IsSignedExchangeInnerResponse() override;
const std::string& origin_policy() const { return origin_policy_; }
void set_origin_policy(const std::string& origin_policy) {
@@ -197,7 +196,7 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
// expose the NavigationHandle when navigating to an InterstitialPage.
NavigatorDelegate* GetDelegate() const;
- RequestContextType request_context_type() const {
+ blink::mojom::RequestContextType request_context_type() const {
DCHECK_GE(state_, WILL_SEND_REQUEST);
return request_context_type_;
}
@@ -216,15 +215,6 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
net_error_code_ = net_error_code;
}
- // Returns whether the navigation is currently being transferred from one
- // RenderFrameHost to another. In particular, a DidStartProvisionalLoad IPC
- // for the navigation URL, received in the new RenderFrameHost, should not
- // indicate the start of a new navigation in that case.
- bool is_transferring() const { return is_transferring_; }
- void set_is_transferring(bool is_transferring) {
- is_transferring_ = is_transferring;
- }
-
// Updates the RenderFrameHost that is about to commit the navigation. This
// is used during transfer navigations.
void set_render_frame_host(RenderFrameHostImpl* render_frame_host) {
@@ -306,6 +296,7 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
bool should_replace_current_entry,
bool is_download,
bool is_stream,
+ bool is_signed_exchange_inner_response,
const ThrottleChecksFinishedCallback& callback);
// Returns the FrameTreeNode this navigation is happening in.
@@ -408,7 +399,7 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
bool has_user_gesture,
ui::PageTransition transition,
bool is_external_protocol,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
blink::WebMixedContentContextType mixed_content_context_type,
base::TimeTicks input_start);
@@ -523,7 +514,7 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
int pending_nav_entry_id_;
// The fetch request context type.
- RequestContextType request_context_type_;
+ blink::mojom::RequestContextType request_context_type_;
// The mixed content context type for potential mixed content checks.
blink::WebMixedContentContextType mixed_content_context_type_;
@@ -593,10 +584,6 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
// The origin policy that applies to this navigation. Empty if none applies.
std::string origin_policy_;
- // Whether the navigation is in the middle of a transfer. Set to false when
- // the DidStartProvisionalLoad is received from the new renderer.
- bool is_transferring_;
-
// Whether or not the navigation results from the submission of a form.
bool is_form_submission_;
@@ -607,6 +594,9 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
bool is_download_;
bool is_stream_;
+ // True if the target is an inner response of a signed exchange.
+ bool is_signed_exchange_inner_response_;
+
// False by default unless the navigation started within a context menu.
bool started_from_context_menu_;
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl_browsertest.cc b/chromium/content/browser/frame_host/navigation_handle_impl_browsertest.cc
index 9cd758fa060..6fb9c83c1d4 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl_browsertest.cc
+++ b/chromium/content/browser/frame_host/navigation_handle_impl_browsertest.cc
@@ -6,11 +6,13 @@
#include "base/files/scoped_temp_dir.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "content/browser/frame_host/debug_urls.h"
#include "content/browser/frame_host/navigation_handle_impl.h"
#include "content/browser/frame_host/navigation_request.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/site_isolation_policy.h"
@@ -20,7 +22,6 @@
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
@@ -36,6 +37,7 @@
#include "net/dns/mock_host_resolver.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "ui/base/page_transition_types.h"
#include "url/url_constants.h"
@@ -78,7 +80,9 @@ class TestNavigationThrottle : public NavigationThrottle {
const char* GetNameForLogging() override { return "TestNavigationThrottle"; }
- RequestContextType request_context_type() { return request_context_type_; }
+ blink::mojom::RequestContextType request_context_type() {
+ return request_context_type_;
+ }
// Expose Resume and Cancel to the installer.
void ResumeNavigation() { Resume(); }
@@ -92,11 +96,12 @@ class TestNavigationThrottle : public NavigationThrottle {
NavigationThrottle::ThrottleCheckResult WillStartRequest() override {
NavigationHandleImpl* navigation_handle_impl =
static_cast<NavigationHandleImpl*>(navigation_handle());
- CHECK_NE(REQUEST_CONTEXT_TYPE_UNSPECIFIED,
+ CHECK_NE(blink::mojom::RequestContextType::UNSPECIFIED,
navigation_handle_impl->request_context_type());
request_context_type_ = navigation_handle_impl->request_context_type();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, did_call_will_start_);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ did_call_will_start_);
return will_start_result_;
}
@@ -106,8 +111,8 @@ class TestNavigationThrottle : public NavigationThrottle {
CHECK_EQ(request_context_type_,
navigation_handle_impl->request_context_type());
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- did_call_will_redirect_);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ did_call_will_redirect_);
return will_redirect_result_;
}
@@ -117,7 +122,8 @@ class TestNavigationThrottle : public NavigationThrottle {
CHECK_EQ(request_context_type_,
navigation_handle_impl->request_context_type());
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, did_call_will_fail_);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ did_call_will_fail_);
return will_fail_result_;
}
@@ -127,8 +133,8 @@ class TestNavigationThrottle : public NavigationThrottle {
CHECK_EQ(request_context_type_,
navigation_handle_impl->request_context_type());
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- did_call_will_process_);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ did_call_will_process_);
return will_process_result_;
}
@@ -140,7 +146,8 @@ class TestNavigationThrottle : public NavigationThrottle {
base::Closure did_call_will_redirect_;
base::Closure did_call_will_fail_;
base::Closure did_call_will_process_;
- RequestContextType request_context_type_ = REQUEST_CONTEXT_TYPE_UNSPECIFIED;
+ blink::mojom::RequestContextType request_context_type_ =
+ blink::mojom::RequestContextType::UNSPECIFIED;
};
// Installs a TestNavigationThrottle either on all following requests or on
@@ -1197,7 +1204,7 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
EXPECT_EQ(main_url, url_recorder.urls().back());
EXPECT_EQ(1ul, url_recorder.urls().size());
// Checks the main frame RequestContextType.
- EXPECT_EQ(REQUEST_CONTEXT_TYPE_LOCATION,
+ EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
installer.navigation_throttle()->request_context_type());
// Ditto for frame b navigation.
@@ -1206,7 +1213,7 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
EXPECT_EQ(2, installer.install_count());
EXPECT_EQ(b_url, url_recorder.urls().back());
EXPECT_EQ(2ul, url_recorder.urls().size());
- EXPECT_EQ(REQUEST_CONTEXT_TYPE_LOCATION,
+ EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
installer.navigation_throttle()->request_context_type());
// Ditto for frame c navigation.
@@ -1215,7 +1222,7 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
EXPECT_EQ(3, installer.install_count());
EXPECT_EQ(c_url, url_recorder.urls().back());
EXPECT_EQ(3ul, url_recorder.urls().size());
- EXPECT_EQ(REQUEST_CONTEXT_TYPE_LOCATION,
+ EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
installer.navigation_throttle()->request_context_type());
// Lets the final navigation finish so that we conclude running the
@@ -1253,7 +1260,7 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
EXPECT_TRUE(link_manager.WaitForRequestStart());
EXPECT_EQ(link_url, url_recorder.urls().back());
EXPECT_EQ(2ul, url_recorder.urls().size());
- EXPECT_EQ(REQUEST_CONTEXT_TYPE_HYPERLINK,
+ EXPECT_EQ(blink::mojom::RequestContextType::HYPERLINK,
installer.navigation_throttle()->request_context_type());
// Finishes the last navigation.
@@ -1287,7 +1294,7 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest,
EXPECT_TRUE(post_manager.WaitForRequestStart());
EXPECT_EQ(post_url, url_recorder.urls().back());
EXPECT_EQ(2ul, url_recorder.urls().size());
- EXPECT_EQ(REQUEST_CONTEXT_TYPE_FORM,
+ EXPECT_EQ(blink::mojom::RequestContextType::FORM,
installer.navigation_throttle()->request_context_type());
// Finishes the last navigation.
@@ -1825,8 +1832,8 @@ IN_PROC_BROWSER_TEST_F(PlzNavigateNavigationHandleImplBrowserTest,
GURL start_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
GURL error_url(embedded_test_server()->GetURL("/close-socket"));
EXPECT_NE(start_url.host(), error_url.host());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&net::URLRequestFailedJob::AddUrlHandler));
{
@@ -2077,15 +2084,17 @@ IN_PROC_BROWSER_TEST_F(NavigationHandleImplBrowserTest, StartToCommitMetrics) {
// Add the suffix to all existing histogram names, and append the results to
// |names|.
std::vector<std::string> names{"Navigation.StartToCommit"};
- auto add_suffix = [&names](std::string suffix) {
+ auto add_suffix = [&names](std::vector<std::string> suffixes) {
size_t original_size = names.size();
for (size_t i = 0; i < original_size; i++) {
- names.push_back(names[i] + suffix);
+ for (const std::string& suffix : suffixes)
+ names.push_back(names[i] + suffix);
}
};
- add_suffix(kProcessSuffixes.at(process_type));
- add_suffix(kFrameSuffixes.at(frame_type));
- add_suffix(kTransitionSuffixes.at(transition_type));
+ add_suffix({kProcessSuffixes.at(process_type)});
+ add_suffix({kFrameSuffixes.at(frame_type)});
+ add_suffix({kTransitionSuffixes.at(transition_type),
+ ".ForegroundProcessPriority"});
// Check that all generated histogram names are logged exactly once.
for (const auto& name : names) {
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc b/chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc
index b09f5c258a7..62d5ec1c1ac 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigation_handle_impl_unittest.cc
@@ -8,7 +8,6 @@
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/common/browser_side_navigation_policy.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_side_navigation_test_utils.h"
#include "content/public/test/test_navigation_throttle.h"
@@ -16,6 +15,7 @@
#include "content/test/test_render_frame_host.h"
#include "content/test/test_web_contents.h"
#include "net/ssl/ssl_connection_status_flags.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
namespace content {
@@ -167,7 +167,7 @@ class NavigationHandleImplTest : public RenderViewHostImplTestHarness {
test_handle_->WillProcessResponse(
main_test_rfh(), scoped_refptr<net::HttpResponseHeaders>(),
net::HttpResponseInfo::CONNECTION_INFO_QUIC_35, net::HostPortPair(),
- net::SSLInfo(), GlobalRequestID(), false, false, false,
+ net::SSLInfo(), GlobalRequestID(), false, false, false, false,
base::Bind(&NavigationHandleImplTest::UpdateThrottleCheckResult,
base::Unretained(this)));
}
@@ -265,7 +265,7 @@ class NavigationHandleImplTest : public RenderViewHostImplTestHarness {
false, // has_user_gesture
ui::PAGE_TRANSITION_LINK,
false, // is_external_protocol
- REQUEST_CONTEXT_TYPE_LOCATION);
+ blink::mojom::RequestContextType::LOCATION);
}
private:
@@ -343,19 +343,19 @@ TEST_F(NavigationHandleImplThrottleInsertionTest,
// Note: can be extended to cover more internal members.
TEST_F(NavigationHandleImplTest, SimpleDataChecksRedirectAndProcess) {
SimulateWillStartRequest();
- EXPECT_EQ(REQUEST_CONTEXT_TYPE_LOCATION,
+ EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
test_handle()->request_context_type());
EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
test_handle()->GetConnectionInfo());
SimulateWillRedirectRequest();
- EXPECT_EQ(REQUEST_CONTEXT_TYPE_LOCATION,
+ EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
test_handle()->request_context_type());
EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
test_handle()->GetConnectionInfo());
SimulateWillProcessResponse();
- EXPECT_EQ(REQUEST_CONTEXT_TYPE_LOCATION,
+ EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
test_handle()->request_context_type());
EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_QUIC_35,
test_handle()->GetConnectionInfo());
@@ -373,13 +373,13 @@ TEST_F(NavigationHandleImplTest, SimpleDataCheckNoRedirect) {
TEST_F(NavigationHandleImplTest, SimpleDataChecksFailure) {
SimulateWillStartRequest();
- EXPECT_EQ(REQUEST_CONTEXT_TYPE_LOCATION,
+ EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
test_handle()->request_context_type());
EXPECT_EQ(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN,
test_handle()->GetConnectionInfo());
SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID);
- EXPECT_EQ(REQUEST_CONTEXT_TYPE_LOCATION,
+ EXPECT_EQ(blink::mojom::RequestContextType::LOCATION,
test_handle()->request_context_type());
EXPECT_EQ(net::ERR_CERT_DATE_INVALID, test_handle()->GetNetErrorCode());
}
diff --git a/chromium/content/browser/frame_host/navigation_request.cc b/chromium/content/browser/frame_host/navigation_request.cc
index 701167c2055..3687817b179 100644
--- a/chromium/content/browser/frame_host/navigation_request.cc
+++ b/chromium/content/browser/frame_host/navigation_request.cc
@@ -10,6 +10,7 @@
#include "base/optional.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
#include "content/browser/appcache/chrome_appcache_service.h"
@@ -28,6 +29,7 @@
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/loader/navigation_url_loader.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_navigation_handle.h"
@@ -35,6 +37,7 @@
#include "content/common/appcache_interfaces.h"
#include "content/common/content_constants_internal.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/global_request_id.h"
@@ -52,7 +55,6 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/origin_util.h"
#include "content/public/common/renderer_preferences.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "content/public/common/web_preferences.h"
@@ -67,6 +69,8 @@
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
#include "third_party/blink/public/common/frame/sandbox_flags.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
#include "third_party/blink/public/platform/web_mixed_content_context_type.h"
#include "url/url_constants.h"
@@ -287,9 +291,11 @@ std::unique_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated(
bool is_same_document_history_load,
bool is_history_navigation_in_new_child,
const scoped_refptr<network::ResourceRequestBody>& post_body,
- const base::TimeTicks& navigation_start,
+ base::TimeTicks navigation_start,
NavigationControllerImpl* controller,
- std::unique_ptr<NavigationUIData> navigation_ui_data) {
+ std::unique_ptr<NavigationUIData> navigation_ui_data,
+ base::TimeTicks input_start,
+ WasActivatedOption was_activated) {
// A form submission happens either because the navigation is a
// renderer-initiated form submission that took the OpenURL path or a
// back/forward/reload navigation the does a form resubmission.
@@ -322,7 +328,7 @@ std::unique_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated(
CommonNavigationParams common_params = entry.ConstructCommonNavigationParams(
frame_entry, request_body, dest_url, dest_referrer, navigation_type,
- previews_state, navigation_start);
+ previews_state, navigation_start, input_start);
RequestNavigationParams request_params =
entry.ConstructRequestNavigationParams(
@@ -334,19 +340,21 @@ std::unique_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated(
controller->GetLastCommittedEntryIndex(),
controller->GetEntryCount());
request_params.post_content_type = post_content_type;
+ request_params.was_activated = was_activated;
std::unique_ptr<NavigationRequest> navigation_request(new NavigationRequest(
frame_tree_node, common_params,
mojom::BeginNavigationParams::New(
entry.extra_headers(), net::LOAD_NORMAL,
- false /* skip_service_worker */, REQUEST_CONTEXT_TYPE_LOCATION,
+ false /* skip_service_worker */,
+ blink::mojom::RequestContextType::LOCATION,
blink::WebMixedContentContextType::kBlockable, is_form_submission,
GURL() /* searchable_form_url */,
std::string() /* searchable_form_encoding */, initiator,
GURL() /* client_side_redirect_url */,
base::nullopt /* devtools_initiator_info */),
request_params, browser_initiated, false /* from_begin_navigation */,
- &frame_entry, &entry, std::move(navigation_ui_data), nullptr));
+ &frame_entry, &entry, std::move(navigation_ui_data), nullptr, nullptr));
navigation_request->blob_url_loader_factory_ =
frame_entry.blob_url_loader_factory();
return navigation_request;
@@ -362,7 +370,8 @@ std::unique_ptr<NavigationRequest> NavigationRequest::CreateRendererInitiated(
int current_history_list_length,
bool override_user_agent,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- mojom::NavigationClientAssociatedPtrInfo navigation_client) {
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator) {
// Only normal navigations to a different document or reloads are expected.
// - Renderer-initiated fragment-navigations never take place in the browser,
// even with PlzNavigate.
@@ -397,7 +406,7 @@ std::unique_ptr<NavigationRequest> NavigationRequest::CreateRendererInitiated(
true, // from_begin_navigation
nullptr, entry,
nullptr, // navigation_ui_data
- std::move(navigation_client)));
+ std::move(navigation_client), std::move(navigation_initiator)));
navigation_request->blob_url_loader_factory_ =
std::move(blob_url_loader_factory);
return navigation_request;
@@ -413,7 +422,8 @@ NavigationRequest::NavigationRequest(
const FrameNavigationEntry* frame_entry,
const NavigationEntryImpl* entry,
std::unique_ptr<NavigationUIData> navigation_ui_data,
- mojom::NavigationClientAssociatedPtrInfo navigation_client)
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator)
: frame_tree_node_(frame_tree_node),
common_params_(common_params),
begin_params_(std::move(begin_params)),
@@ -534,7 +544,9 @@ NavigationRequest::NavigationRequest(
begin_params_->headers = headers.ToString();
initiator_csp_context_.reset(new InitiatorCSPContext(
- common_params_.initiator_csp, common_params_.initiator_self_source));
+ common_params_.initiator_csp_info.initiator_csp,
+ common_params_.initiator_csp_info.initiator_self_source,
+ std::move(navigation_initiator)));
}
NavigationRequest::~NavigationRequest() {
@@ -592,8 +604,8 @@ void NavigationRequest::BeginNavigation() {
// otherwise block. Similarly, the NavigationHandle is created afterwards, so
// that it gets the request URL after potentially being modified by CSP.
net::Error net_error = CheckContentSecurityPolicy(
- false /* is redirect */, false /* url_upgraded_after_redirect */,
- false /* is_response_check */);
+ false /* has_followed redirect */,
+ false /* url_upgraded_after_redirect */, false /* is_response_check */);
if (net_error != net::OK) {
// Create a navigation handle so that the correct error code can be set on
// it by OnRequestFailedInternal().
@@ -686,7 +698,7 @@ void NavigationRequest::CreateNavigationHandle() {
common_params_.navigation_type),
common_params_.navigation_start, nav_entry_id_,
common_params_.started_from_context_menu,
- common_params_.should_check_main_world_csp,
+ common_params_.initiator_csp_info.should_check_main_world_csp,
begin_params_->is_form_submission, std::move(navigation_ui_data_),
common_params_.method, std::move(headers), common_params_.post_data,
Referrer::SanitizeForRequest(common_params_.url,
@@ -852,9 +864,10 @@ void NavigationRequest::OnRequestRedirected(
// Check Content Security Policy before the NavigationThrottles run. This
// gives CSP a chance to modify requests that NavigationThrottles would
// otherwise block.
- net::Error net_error = CheckContentSecurityPolicy(
- true /* is redirect */, redirect_info.insecure_scheme_was_upgraded,
- false /* is_response_check */);
+ net::Error net_error =
+ CheckContentSecurityPolicy(true /* has_followed_redirect */,
+ redirect_info.insecure_scheme_was_upgraded,
+ false /* is_response_check */);
if (net_error != net::OK) {
OnRequestFailedInternal(
network::URLLoaderCompletionStatus(net_error), false /*skip_throttles*/,
@@ -958,6 +971,16 @@ void NavigationRequest::OnResponseStarted(
? navigation_handle_->appcache_handle()->appcache_host_id()
: kAppCacheNoHostId;
+ // Update fetch start timing. While NavigationRequest updates fetch start
+ // timing for redirects, it's not aware of service worker interception so
+ // fetch start timing could happen earlier than worker start timing. Use
+ // worker ready time if it is greater than the current value to make sure
+ // fetch start timing always comes after worker start timing (if a service
+ // worker intercepted the navigation).
+ request_params_.navigation_timing.fetch_start =
+ std::max(request_params_.navigation_timing.fetch_start,
+ response->head.service_worker_ready_time);
+
// A navigation is user activated if it contains a user gesture or the frame
// received a gesture and the navigation is renderer initiated. If the
// navigation is browser initiated, it has to come from the context menu.
@@ -965,7 +988,7 @@ void NavigationRequest::OnResponseStarted(
// `ShouldPropagateUserActivation` requirements (same eTLD+1).
// There are two different checks:
// 1. if the `frame_tree_node_` has an origin and is following the rules above
- // with the target URL, it is used and the bit is set iif the navigation is
+ // with the target URL, it is used and the bit is set if the navigation is
// renderer initiated and the `frame_tree_node_` had a gesture. This should
// apply to same page navigations and is preferred over using the referrer
// as it can be changed.
@@ -975,23 +998,28 @@ void NavigationRequest::OnResponseStarted(
// context menu. This should apply to pages that open in a new tab and we
// have to follow the referrer. It means that the activation might not be
// transmitted if it should have.
- request_params_.was_activated = false;
- if (navigation_handle_->IsRendererInitiated() &&
- frame_tree_node_->has_received_user_gesture() &&
- ShouldPropagateUserActivation(
- frame_tree_node_->current_origin(),
- url::Origin::Create(navigation_handle_->GetURL()))) {
- request_params_.was_activated = true;
- // TODO(805871): the next check is relying on
- // navigation_handle_->GetReferrer() but should ideally use a more reliable
- // source for the originating URL when the navigation is renderer initiated.
- } else if (((navigation_handle_->HasUserGesture() &&
- navigation_handle_->IsRendererInitiated()) ||
- navigation_handle_->WasStartedFromContextMenu()) &&
- ShouldPropagateUserActivation(
- url::Origin::Create(navigation_handle_->GetReferrer().url),
- url::Origin::Create(navigation_handle_->GetURL()))) {
- request_params_.was_activated = true;
+ if (request_params_.was_activated == WasActivatedOption::kUnknown) {
+ request_params_.was_activated = WasActivatedOption::kNo;
+
+ if (navigation_handle_->IsRendererInitiated() &&
+ (frame_tree_node_->has_received_user_gesture() ||
+ frame_tree_node_->has_received_user_gesture_before_nav()) &&
+ ShouldPropagateUserActivation(
+ frame_tree_node_->current_origin(),
+ url::Origin::Create(navigation_handle_->GetURL()))) {
+ request_params_.was_activated = WasActivatedOption::kYes;
+ // TODO(805871): the next check is relying on
+ // navigation_handle_->GetReferrer() but should ideally use a more
+ // reliable source for the originating URL when the navigation is renderer
+ // initiated.
+ } else if (((navigation_handle_->HasUserGesture() &&
+ navigation_handle_->IsRendererInitiated()) ||
+ navigation_handle_->WasStartedFromContextMenu()) &&
+ ShouldPropagateUserActivation(
+ url::Origin::Create(navigation_handle_->GetReferrer().url),
+ url::Origin::Create(navigation_handle_->GetURL()))) {
+ request_params_.was_activated = WasActivatedOption::kYes;
+ }
}
// Update the previews state of the request.
@@ -1088,7 +1116,7 @@ void NavigationRequest::OnResponseStarted(
// redirect or not in order to perform its checks. This is the reason
// why we need to check the CSP both on request and response.
net::Error net_error = CheckContentSecurityPolicy(
- navigation_handle_->WasServerRedirect(),
+ navigation_handle_->WasServerRedirect() /* has_followed_redirect */,
false /* url_upgraded_after_redirect */, true /* is_response_check */);
if (net_error != net::OK) {
OnRequestFailedInternal(network::URLLoaderCompletionStatus(net_error),
@@ -1106,7 +1134,7 @@ void NavigationRequest::OnResponseStarted(
render_frame_host, response->head.headers.get(),
response->head.connection_info, response->head.socket_address, ssl_info_,
request_id, common_params_.should_replace_current_entry, is_download,
- is_stream,
+ is_stream, response->head.is_signed_exchange_inner_response,
base::Bind(&NavigationRequest::OnWillProcessResponseChecksComplete,
base::Unretained(this)));
}
@@ -1226,12 +1254,6 @@ bool NavigationRequest::ShouldKeepErrorPageInCurrentProcess(int net_error) {
}
void NavigationRequest::OnRequestStarted(base::TimeTicks timestamp) {
- if (frame_tree_node_->IsMainFrame()) {
- TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(
- "navigation", "Navigation timeToNetworkStack", navigation_handle_.get(),
- timestamp);
- }
-
frame_tree_node_->navigator()->LogResourceRequestTime(timestamp,
common_params_.url);
}
@@ -1266,8 +1288,8 @@ void NavigationRequest::OnStartChecksComplete(
// is no onbeforeunload handler or if a NavigationThrottle cancelled it,
// then this could cause reentrancy into NavigationController. So use a
// PostTask to avoid that.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&NavigationRequest::OnRequestFailedInternal,
weak_factory_.GetWeakPtr(),
@@ -1343,7 +1365,7 @@ void NavigationRequest::OnStartChecksComplete(
: frame_tree_node_->frame_tree()->root()->current_url();
// Walk the ancestor chain to determine whether all frames are same-site. If
- // not, the |site_for_cookies| is set to an opaque URL.
+ // not, the |site_for_cookies| is set to an empty URL.
//
// TODO(mkwst): This is incorrect. It ought to use the definition from
// 'Document::SiteForCookies()' in Blink, which special-cases extension
@@ -1363,7 +1385,7 @@ void NavigationRequest::OnStartChecksComplete(
(ancestors_are_same_site || !base_url.is_empty())
? (frame_tree_node_->IsMainFrame() ? common_params_.url
: top_document_url)
- : GURL("data:,");
+ : GURL::EmptyGURL();
bool parent_is_main_frame = !frame_tree_node_->parent()
? false
: frame_tree_node_->parent()->IsMainFrame();
@@ -1493,10 +1515,20 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
// If the NavigationThrottles allowed the navigation to continue, have the
// processing of the response resume in the network stack.
if (result.action() == NavigationThrottle::PROCEED) {
- // If this is a download, intercept the navigation response and pass it to
- // DownloadManager, and cancel the navigation.
- if (is_download_ &&
- base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // NetworkService doesn't use ResourceDispatcherHost.
+ bool served_via_resource_dispatcher_host =
+ !base::FeatureList::IsEnabled(network::features::kNetworkService);
+ // When S13nServiceWorker is on, it doesn't use ResourceDispatcherHost when
+ // a service worker serves the response.
+ served_via_resource_dispatcher_host =
+ served_via_resource_dispatcher_host &&
+ !(blink::ServiceWorkerUtils::IsServicificationEnabled() &&
+ response_->head.was_fetched_via_service_worker);
+
+ // NetworkService or S13nServiceWorker: If this is a download, intercept the
+ // navigation response and pass it to DownloadManager, and cancel the
+ // navigation.
+ if (is_download_ && !served_via_resource_dispatcher_host) {
// TODO(arthursonzogni): Pass the real ResourceRequest. For the moment
// only these 4 parameters will be used, but it may evolve quickly.
auto resource_request = std::make_unique<network::ResourceRequest>();
@@ -1669,7 +1701,7 @@ void NavigationRequest::CommitNavigation() {
bool NavigationRequest::IsAllowedByCSPDirective(
CSPContext* context,
CSPDirective::Name directive,
- bool is_redirect,
+ bool has_followed_redirect,
bool url_upgraded_after_redirect,
bool is_response_check,
CSPContext::CheckCSPDisposition disposition) {
@@ -1686,25 +1718,26 @@ bool NavigationRequest::IsAllowedByCSPDirective(
url = common_params_.url;
}
return context->IsAllowedByCsp(
- directive, url, is_redirect, is_response_check,
+ directive, url, has_followed_redirect, is_response_check,
common_params_.source_location.value_or(SourceLocation()), disposition,
begin_params_->is_form_submission);
}
net::Error NavigationRequest::CheckCSPDirectives(
RenderFrameHostImpl* parent,
- bool is_redirect,
+ bool has_followed_redirect,
bool url_upgraded_after_redirect,
bool is_response_check,
CSPContext::CheckCSPDisposition disposition) {
bool navigate_to_allowed = IsAllowedByCSPDirective(
- initiator_csp_context_.get(), CSPDirective::NavigateTo, is_redirect,
- url_upgraded_after_redirect, is_response_check, disposition);
+ initiator_csp_context_.get(), CSPDirective::NavigateTo,
+ has_followed_redirect, url_upgraded_after_redirect, is_response_check,
+ disposition);
bool frame_src_allowed = true;
if (parent) {
frame_src_allowed = IsAllowedByCSPDirective(
- parent, CSPDirective::FrameSrc, is_redirect,
+ parent, CSPDirective::FrameSrc, has_followed_redirect,
url_upgraded_after_redirect, is_response_check, disposition);
}
@@ -1724,13 +1757,13 @@ net::Error NavigationRequest::CheckCSPDirectives(
}
net::Error NavigationRequest::CheckContentSecurityPolicy(
- bool is_redirect,
+ bool has_followed_redirect,
bool url_upgraded_after_redirect,
bool is_response_check) {
if (common_params_.url.SchemeIs(url::kAboutScheme))
return net::OK;
- if (common_params_.should_check_main_world_csp ==
+ if (common_params_.initiator_csp_info.should_check_main_world_csp ==
CSPDisposition::DO_NOT_CHECK) {
return net::OK;
}
@@ -1756,13 +1789,13 @@ net::Error NavigationRequest::CheckContentSecurityPolicy(
// This sequence of events allows site owners to learn about (via step 1) any
// requests that are upgraded in step 2.
- net::Error report_only_csp_status =
- CheckCSPDirectives(parent, is_redirect, url_upgraded_after_redirect,
- is_response_check, CSPContext::CHECK_REPORT_ONLY_CSP);
+ net::Error report_only_csp_status = CheckCSPDirectives(
+ parent, has_followed_redirect, url_upgraded_after_redirect,
+ is_response_check, CSPContext::CHECK_REPORT_ONLY_CSP);
// upgrade-insecure-requests is handled in the network code for redirects,
// only do the upgrade here if this is not a redirect.
- if (!is_redirect && !frame_tree_node()->IsMainFrame()) {
+ if (!has_followed_redirect && !frame_tree_node()->IsMainFrame()) {
if (parent &&
parent->ShouldModifyRequestUrlForCsp(true /* is subresource */)) {
upgrade_if_insecure_ = true;
@@ -1771,9 +1804,9 @@ net::Error NavigationRequest::CheckContentSecurityPolicy(
}
}
- net::Error enforced_csp_status =
- CheckCSPDirectives(parent, is_redirect, url_upgraded_after_redirect,
- is_response_check, CSPContext::CHECK_ENFORCED_CSP);
+ net::Error enforced_csp_status = CheckCSPDirectives(
+ parent, has_followed_redirect, url_upgraded_after_redirect,
+ is_response_check, CSPContext::CHECK_ENFORCED_CSP);
if (enforced_csp_status != net::OK)
return enforced_csp_status;
return report_only_csp_status;
diff --git a/chromium/content/browser/frame_host/navigation_request.h b/chromium/content/browser/frame_host/navigation_request.h
index 5d4aa5cbeab..7d37652271a 100644
--- a/chromium/content/browser/frame_host/navigation_request.h
+++ b/chromium/content/browser/frame_host/navigation_request.h
@@ -91,9 +91,11 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
bool is_same_document_history_load,
bool is_history_navigation_in_new_child,
const scoped_refptr<network::ResourceRequestBody>& post_body,
- const base::TimeTicks& navigation_start,
+ base::TimeTicks navigation_start,
NavigationControllerImpl* controller,
- std::unique_ptr<NavigationUIData> navigation_ui_data);
+ std::unique_ptr<NavigationUIData> navigation_ui_data,
+ base::TimeTicks input_start,
+ WasActivatedOption was_activated);
// Creates a request for a renderer-intiated navigation.
// Note: |body| is sent to the IO thread when calling BeginNavigation, and
@@ -109,7 +111,8 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
int current_history_list_length,
bool override_user_agent,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- mojom::NavigationClientAssociatedPtrInfo navigation_client);
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator);
~NavigationRequest() override;
@@ -224,7 +227,8 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
const FrameNavigationEntry* frame_navigation_entry,
const NavigationEntryImpl* navitation_entry,
std::unique_ptr<NavigationUIData> navigation_ui_data,
- mojom::NavigationClientAssociatedPtrInfo navigation_client);
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator);
// NavigationURLLoaderDelegate implementation.
void OnRequestRedirected(
@@ -284,7 +288,7 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
// and navigate-to checks.
bool IsAllowedByCSPDirective(CSPContext* context,
CSPDirective::Name directive,
- bool is_redirect,
+ bool has_followed_redirect,
bool url_upgraded_after_redirect,
bool is_response_check,
CSPContext::CheckCSPDisposition disposition);
@@ -294,7 +298,7 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
// Returns net::OK if the checks pass, and net::ERR_ABORTED or
// net::ERR_BLOCKED_BY_CLIENT depending on which checks fail.
net::Error CheckCSPDirectives(RenderFrameHostImpl* parent,
- bool is_redirect,
+ bool has_followed_redirect,
bool url_upgraded_after_redirect,
bool is_response_check,
CSPContext::CheckCSPDisposition disposition);
@@ -305,7 +309,7 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
// a report will be sent.
// - The navigation request may be upgraded from HTTP to HTTPS if a CSP is
// configured to upgrade insecure requests.
- net::Error CheckContentSecurityPolicy(bool is_redirect,
+ net::Error CheckContentSecurityPolicy(bool has_followed_redirect,
bool url_upgraded_after_redirect,
bool is_response_check);
diff --git a/chromium/content/browser/frame_host/navigator.cc b/chromium/content/browser/frame_host/navigator.cc
index 59cea6fbf74..7cce6d26021 100644
--- a/chromium/content/browser/frame_host/navigator.cc
+++ b/chromium/content/browser/frame_host/navigator.cc
@@ -32,6 +32,7 @@ void Navigator::OnBeginNavigation(
const CommonNavigationParams& common_params,
mojom::BeginNavigationParamsPtr begin_params,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- mojom::NavigationClientAssociatedPtrInfo navigation_client) {}
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator) {}
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigator.h b/chromium/content/browser/frame_host/navigator.h
index fe5fe87f06f..a02d2e9fe72 100644
--- a/chromium/content/browser/frame_host/navigator.h
+++ b/chromium/content/browser/frame_host/navigator.h
@@ -52,13 +52,6 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
// Notifications coming from the RenderFrameHosts ----------------------------
- // The RenderFrameHostImpl started a provisional load.
- virtual void DidStartProvisionalLoad(
- RenderFrameHostImpl* render_frame_host,
- const GURL& url,
- const std::vector<GURL>& redirect_chain,
- const base::TimeTicks& navigation_start) {}
-
// The RenderFrameHostImpl has failed a provisional load.
virtual void DidFailProvisionalLoadWithError(
RenderFrameHostImpl* render_frame_host,
@@ -151,7 +144,8 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
const CommonNavigationParams& common_params,
mojom::BeginNavigationParamsPtr begin_params,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- mojom::NavigationClientAssociatedPtrInfo navigation_client);
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator);
// Used to restart a navigation that was thought to be same-document in
// cross-document mode.
diff --git a/chromium/content/browser/frame_host/navigator_impl.cc b/chromium/content/browser/frame_host/navigator_impl.cc
index f53badc0816..7d7544debb3 100644
--- a/chromium/content/browser/frame_host/navigator_impl.cc
+++ b/chromium/content/browser/frame_host/navigator_impl.cc
@@ -105,35 +105,6 @@ NavigationController* NavigatorImpl::GetController() {
return controller_;
}
-// TODO(clamy): See if we can remove this function now that PlzNavigate has
-// shipped.
-void NavigatorImpl::DidStartProvisionalLoad(
- RenderFrameHostImpl* render_frame_host,
- const GURL& url,
- const std::vector<GURL>& redirect_chain,
- const base::TimeTicks& navigation_start) {
- bool is_main_frame = render_frame_host->frame_tree_node()->IsMainFrame();
- bool is_error_page = (url.spec() == kUnreachableWebDataURL);
- GURL validated_url(url);
- RenderProcessHost* render_process_host = render_frame_host->GetProcess();
- render_process_host->FilterURL(false, &validated_url);
-
- // Do not allow browser plugin guests to navigate to non-web URLs, since they
- // cannot swap processes or grant bindings.
- ChildProcessSecurityPolicyImpl* policy =
- ChildProcessSecurityPolicyImpl::GetInstance();
- if (render_process_host->IsForGuestsOnly() &&
- !policy->IsWebSafeScheme(validated_url.scheme())) {
- validated_url = GURL(url::kAboutBlankURL);
- }
-
- if (is_main_frame && !is_error_page) {
- DidStartMainFrameNavigation(validated_url,
- render_frame_host->GetSiteInstance(),
- render_frame_host->GetNavigationHandle());
- }
-}
-
void NavigatorImpl::DidFailProvisionalLoadWithError(
RenderFrameHostImpl* render_frame_host,
const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) {
@@ -398,19 +369,6 @@ void NavigatorImpl::Navigate(std::unique_ptr<NavigationRequest> request,
// after this point without null checking it first.
}
- if (frame_tree_node->IsMainFrame() && frame_tree_node->navigation_request()) {
- // For the trace below we're using the navigation handle as the async
- // trace id, |navigation_start| as the timestamp and reporting the
- // FrameTreeNode id as a parameter. For navigations where no network
- // request is made (data URLs, JavaScript URLs, etc) there is no handle
- // and so no tracing is done.
- TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
- "navigation", "Navigation timeToNetworkStack",
- frame_tree_node->navigation_request()->navigation_handle(),
- frame_tree_node->navigation_request()->common_params().navigation_start,
- "FrameTreeNode id", frame_tree_node->frame_tree_node_id());
- }
-
// Make sure no code called via RFH::Navigate clears the pending entry.
if (is_pending_entry)
CHECK_EQ(nav_entry_id, controller_->GetPendingEntry()->GetUniqueID());
@@ -624,7 +582,8 @@ void NavigatorImpl::OnBeginNavigation(
const CommonNavigationParams& common_params,
mojom::BeginNavigationParamsPtr begin_params,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- mojom::NavigationClientAssociatedPtrInfo navigation_client) {
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator) {
// TODO(clamy): the url sent by the renderer should be validated with
// FilterURL.
// This is a renderer-initiated navigation.
@@ -687,7 +646,8 @@ void NavigatorImpl::OnBeginNavigation(
frame_tree_node, pending_entry, common_params,
std::move(begin_params), controller_->GetLastCommittedEntryIndex(),
controller_->GetEntryCount(), override_user_agent,
- std::move(blob_url_loader_factory), std::move(navigation_client)));
+ std::move(blob_url_loader_factory), std::move(navigation_client),
+ std::move(navigation_initiator)));
NavigationRequest* navigation_request = frame_tree_node->navigation_request();
// This frame has already run beforeunload before it sent this IPC. See if
@@ -807,9 +767,14 @@ void NavigatorImpl::DiscardPendingEntryIfNeeded(int expected_pending_entry_id) {
// allow the view to clear the pending entry and typed URL if the user
// requests (e.g., hitting Escape with focus in the address bar).
//
+ // Do not leave the pending entry visible if it has an invalid URL, since this
+ // might be formatted in an unexpected or unsafe way.
+ // TODO(creis): Block navigations to invalid URLs in https://crbug.com/850824.
+ //
// Note: don't touch the transient entry, since an interstitial may exist.
- bool should_preserve_entry = controller_->IsUnmodifiedBlankTab() ||
- delegate_->ShouldPreserveAbortedURLs();
+ bool should_preserve_entry = pending_entry->GetURL().is_valid() &&
+ (controller_->IsUnmodifiedBlankTab() ||
+ delegate_->ShouldPreserveAbortedURLs());
if (pending_entry != controller_->GetVisibleEntry() ||
!should_preserve_entry) {
controller_->DiscardPendingEntry(true);
diff --git a/chromium/content/browser/frame_host/navigator_impl.h b/chromium/content/browser/frame_host/navigator_impl.h
index b97af7081e4..cfc56346eaa 100644
--- a/chromium/content/browser/frame_host/navigator_impl.h
+++ b/chromium/content/browser/frame_host/navigator_impl.h
@@ -40,11 +40,6 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
// Navigator implementation.
NavigatorDelegate* GetDelegate() override;
NavigationController* GetController() override;
- void DidStartProvisionalLoad(
- RenderFrameHostImpl* render_frame_host,
- const GURL& url,
- const std::vector<GURL>& redirect_chain,
- const base::TimeTicks& navigation_start) override;
void DidFailProvisionalLoadWithError(
RenderFrameHostImpl* render_frame_host,
const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params)
@@ -95,7 +90,8 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
const CommonNavigationParams& common_params,
mojom::BeginNavigationParamsPtr begin_params,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- mojom::NavigationClientAssociatedPtrInfo navigation_client) override;
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator) override;
void RestartNavigationAsCrossDocument(
std::unique_ptr<NavigationRequest> navigation_request) override;
void OnAbortNavigation(FrameTreeNode* frame_tree_node) override;
diff --git a/chromium/content/browser/frame_host/navigator_impl_unittest.cc b/chromium/content/browser/frame_host/navigator_impl_unittest.cc
index 7d748abfede..abda7b16451 100644
--- a/chromium/content/browser/frame_host/navigator_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigator_impl_unittest.cc
@@ -1301,7 +1301,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, FeaturePolicyNewChild) {
blink::FeaturePolicy* subframe_feature_policy =
subframe_rfh->feature_policy();
ASSERT_TRUE(subframe_feature_policy);
- ASSERT_FALSE(subframe_feature_policy->GetOriginForTest().unique());
+ ASSERT_FALSE(subframe_feature_policy->GetOriginForTest().opaque());
}
TEST_F(NavigatorTestWithBrowserSideNavigation, TwoNavigationsRacingCommit) {
diff --git a/chromium/content/browser/frame_host/origin_policy_throttle.cc b/chromium/content/browser/frame_host/origin_policy_throttle.cc
index 5d2904a633b..e315801fd55 100644
--- a/chromium/content/browser/frame_host/origin_policy_throttle.cc
+++ b/chromium/content/browser/frame_host/origin_policy_throttle.cc
@@ -11,6 +11,7 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/origin_policy_error_reason.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
@@ -21,7 +22,7 @@
namespace {
// Constants derived from the spec, https://github.com/WICG/origin-policy
-static const char* kDefaultPolicy = "1";
+static const char* kDefaultPolicy = "0";
static const char* kDeletePolicy = "0";
static const char* kWellKnown = "/.well-known/origin-policy/";
@@ -36,8 +37,12 @@ namespace content {
bool OriginPolicyThrottle::ShouldRequestOriginPolicy(
const GURL& url,
std::string* request_version) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- if (!base::FeatureList::IsEnabled(features::kOriginPolicy))
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ bool origin_policy_enabled =
+ base::FeatureList::IsEnabled(features::kOriginPolicy) ||
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableExperimentalWebPlatformFeatures);
+ if (!origin_policy_enabled)
return false;
if (!url.SchemeIs(url::kHttpsScheme))
@@ -55,7 +60,7 @@ bool OriginPolicyThrottle::ShouldRequestOriginPolicy(
// static
std::unique_ptr<NavigationThrottle>
OriginPolicyThrottle::MaybeCreateThrottleFor(NavigationHandle* handle) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(handle);
// We use presence of the origin policy request header to determine
@@ -64,7 +69,11 @@ OriginPolicyThrottle::MaybeCreateThrottleFor(NavigationHandle* handle) {
net::HttpRequestHeaders::kSecOriginPolicy))
return nullptr;
- DCHECK(base::FeatureList::IsEnabled(features::kOriginPolicy));
+ // TODO(vogelheim): Rewrite & hoist up this DCHECK to ensure that ..HasHeader
+ // and ShouldRequestOriginPolicy are always equal on entry to the method.
+ // This depends on https://crbug.com/881234 being fixed.
+ DCHECK(OriginPolicyThrottle::ShouldRequestOriginPolicy(handle->GetURL(),
+ nullptr));
return base::WrapUnique(new OriginPolicyThrottle(handle));
}
@@ -109,9 +118,9 @@ OriginPolicyThrottle::WillProcessResponse() {
url::Origin origin = GetRequestOrigin();
DCHECK(!origin.Serialize().empty());
- DCHECK(!origin.unique());
+ DCHECK(!origin.opaque());
KnownVersionMap& versions = GetKnownVersions();
- KnownVersionMap::iterator iter = versions.find(origin);
+ auto iter = versions.find(origin);
// Process policy deletion first!
if (header_found && response_version == kDeletePolicy) {
@@ -136,7 +145,9 @@ OriginPolicyThrottle::WillProcessResponse() {
FetchCallback done =
base::BindOnce(&OriginPolicyThrottle::OnTheGloriousPolicyHasArrived,
base::Unretained(this));
- FetchPolicy(policy, std::move(done));
+ RedirectCallback redirect = base::BindRepeating(
+ &OriginPolicyThrottle::OnRedirect, base::Unretained(this));
+ FetchPolicy(policy, std::move(done), std::move(redirect));
return NavigationThrottle::DEFER;
}
@@ -163,7 +174,9 @@ const url::Origin OriginPolicyThrottle::GetRequestOrigin() {
return url::Origin::Create(navigation_handle()->GetURL());
}
-void OriginPolicyThrottle::FetchPolicy(const GURL& url, FetchCallback done) {
+void OriginPolicyThrottle::FetchPolicy(const GURL& url,
+ FetchCallback done,
+ RedirectCallback redirect) {
// Create the traffic annotation
net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("origin_policy_loader", R"(
@@ -187,26 +200,22 @@ void OriginPolicyThrottle::FetchPolicy(const GURL& url, FetchCallback done) {
policy_exception_justification:
"Not implemented, considered not useful."})");
- // Create the SimpleURLLoader for the policy.
+ // Create and configure the SimpleURLLoader for the policy.
std::unique_ptr<network::ResourceRequest> policy_request =
std::make_unique<network::ResourceRequest>();
policy_request->url = url;
policy_request->request_initiator = url::Origin::Create(url);
- policy_request->fetch_credentials_mode =
- network::mojom::FetchCredentialsMode::kOmit;
- policy_request->fetch_redirect_mode =
- network::mojom::FetchRedirectMode::kError;
policy_request->load_flags = net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DO_NOT_SEND_AUTH_DATA;
url_loader_ = network::SimpleURLLoader::Create(std::move(policy_request),
traffic_annotation);
+ url_loader_->SetOnRedirectCallback(std::move(redirect));
// Obtain the URLLoaderFactory from the NavigationHandle.
SiteInstance* site_instance = navigation_handle()->GetStartingSiteInstance();
- content::StoragePartition* storage_partition =
- BrowserContext::GetStoragePartition(site_instance->GetBrowserContext(),
- site_instance);
+ StoragePartition* storage_partition = BrowserContext::GetStoragePartition(
+ site_instance->GetBrowserContext(), site_instance);
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory =
storage_partition->GetURLLoaderFactoryForBrowserProcess();
@@ -227,7 +236,7 @@ void OriginPolicyThrottle::OnTheGloriousPolicyHasArrived(
// Fail hard if the policy could not be loaded.
if (!policy_content) {
- CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
+ CancelNavigation(OriginPolicyErrorReason::kCannotLoadPolicy);
return;
}
@@ -239,4 +248,21 @@ void OriginPolicyThrottle::OnTheGloriousPolicyHasArrived(
Resume();
}
+void OriginPolicyThrottle::OnRedirect(
+ const net::RedirectInfo& redirect_info,
+ const network::ResourceResponseHead& response_head,
+ std::vector<std::string>* to_be_removed_headers) {
+ // Fail hard if the policy response follows a redirect.
+ url_loader_.reset(); // Cancel the request while it's ongoing.
+ CancelNavigation(OriginPolicyErrorReason::kPolicyShouldNotRedirect);
+}
+
+void OriginPolicyThrottle::CancelNavigation(OriginPolicyErrorReason reason) {
+ base::Optional<std::string> error_page =
+ GetContentClient()->browser()->GetOriginPolicyErrorPage(
+ reason, GetRequestOrigin(), navigation_handle()->GetURL());
+ CancelDeferredNavigation(NavigationThrottle::ThrottleCheckResult(
+ NavigationThrottle::CANCEL, net::ERR_BLOCKED_BY_CLIENT, error_page));
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/origin_policy_throttle.h b/chromium/content/browser/frame_host/origin_policy_throttle.h
index 320558cce4e..f142dcfbc5f 100644
--- a/chromium/content/browser/frame_host/origin_policy_throttle.h
+++ b/chromium/content/browser/frame_host/origin_policy_throttle.h
@@ -19,12 +19,17 @@ class GURL;
namespace url {
class Origin;
}
+namespace net {
+struct RedirectInfo;
+} // namespace net
namespace network {
+struct ResourceResponseHead;
class SimpleURLLoader;
} // namespace network
namespace content {
class NavigationHandle;
+enum class OriginPolicyErrorReason;
// The OriginPolicyThrottle is responsible for deciding whether an origin
// policy should be fetched, and doing so when that is positive.
@@ -63,15 +68,25 @@ class CONTENT_EXPORT OriginPolicyThrottle : public NavigationThrottle {
private:
using FetchCallback = base::OnceCallback<void(std::unique_ptr<std::string>)>;
+ using RedirectCallback =
+ base::RepeatingCallback<void(const net::RedirectInfo&,
+ const network::ResourceResponseHead&,
+ std::vector<std::string>*)>;
explicit OriginPolicyThrottle(NavigationHandle* handle);
static KnownVersionMap& GetKnownVersions();
const url::Origin GetRequestOrigin();
- void FetchPolicy(const GURL& url, FetchCallback done);
+ void FetchPolicy(const GURL& url,
+ FetchCallback done,
+ RedirectCallback redirect);
void OnTheGloriousPolicyHasArrived(
std::unique_ptr<std::string> policy_content);
+ void OnRedirect(const net::RedirectInfo& redirect_info,
+ const network::ResourceResponseHead& response_head,
+ std::vector<std::string>* to_be_removed_headers);
+ void CancelNavigation(OriginPolicyErrorReason reason);
// We may need the SimpleURLLoader to download the policy. The loader must
// be kept alive while the load is ongoing.
diff --git a/chromium/content/browser/frame_host/origin_policy_throttle_unittest.cc b/chromium/content/browser/frame_host/origin_policy_throttle_unittest.cc
index 859a318dfc7..8dcc643a765 100644
--- a/chromium/content/browser/frame_host/origin_policy_throttle_unittest.cc
+++ b/chromium/content/browser/frame_host/origin_policy_throttle_unittest.cc
@@ -41,7 +41,7 @@ class OriginPolicyThrottleTest : public RenderViewHostTestHarness,
void CreateHandleFor(const GURL& url) {
net::HttpRequestHeaders headers;
if (OriginPolicyThrottle::ShouldRequestOriginPolicy(url, nullptr))
- headers.SetHeader(net::HttpRequestHeaders::kSecOriginPolicy, "1");
+ headers.SetHeader(net::HttpRequestHeaders::kSecOriginPolicy, "0");
// Except for url and headers (which are determined by the test case)
// all parameters below are cargo-culted from
@@ -101,7 +101,7 @@ TEST_P(OriginPolicyThrottleTest, ShouldRequestLastKnownVersion) {
std::string version;
OriginPolicyThrottle::ShouldRequestOriginPolicy(url, &version);
- EXPECT_EQ(version, "1");
+ EXPECT_EQ(version, "0");
OriginPolicyThrottle::GetKnownVersionsForTesting()[url::Origin::Create(url)] =
"abcd";
diff --git a/chromium/content/browser/frame_host/render_frame_host_delegate.cc b/chromium/content/browser/frame_host/render_frame_host_delegate.cc
index 623cd428e20..b77280ef73f 100644
--- a/chromium/content/browser/frame_host/render_frame_host_delegate.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_delegate.cc
@@ -8,6 +8,7 @@
#include "base/strings/string16.h"
#include "build/build_config.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
+#include "content/public/browser/file_select_listener.h"
#include "ipc/ipc_message.h"
#include "ui/gfx/native_widget_types.h"
#include "url/gurl.h"
@@ -33,6 +34,13 @@ bool RenderFrameHostDelegate::DidAddMessageToConsole(
return false;
}
+void RenderFrameHostDelegate::RunFileChooser(
+ RenderFrameHost* render_frame_host,
+ std::unique_ptr<FileSelectListener> listener,
+ const blink::mojom::FileChooserParams& params) {
+ listener->FileSelectionCanceled();
+}
+
WebContents* RenderFrameHostDelegate::GetAsWebContents() {
return nullptr;
}
diff --git a/chromium/content/browser/frame_host/render_frame_host_delegate.h b/chromium/content/browser/frame_host/render_frame_host_delegate.h
index 9ac81d17f61..61b1c295618 100644
--- a/chromium/content/browser/frame_host/render_frame_host_delegate.h
+++ b/chromium/content/browser/frame_host/render_frame_host_delegate.h
@@ -56,9 +56,13 @@ class Origin;
namespace blink {
struct WebFullscreenOptions;
+namespace mojom {
+class FileChooserParams;
+}
}
namespace content {
+class FileSelectListener;
class FrameTreeNode;
class InterstitialPage;
class PageState;
@@ -69,7 +73,6 @@ class WebContents;
struct AXEventNotificationDetails;
struct AXLocationChangeNotificationDetails;
struct ContextMenuParams;
-struct FileChooserParams;
struct GlobalRequestID;
namespace mojom {
@@ -135,8 +138,12 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
IPC::Message* reply_msg) {}
// Called when a file selection is to be done.
- virtual void RunFileChooser(RenderFrameHost* render_frame_host,
- const FileChooserParams& params) {}
+ // Overrides of this function must call either listener->FileSelected() or
+ // listener->FileSelectionCanceled().
+ virtual void RunFileChooser(
+ RenderFrameHost* render_frame_host,
+ std::unique_ptr<content::FileSelectListener> listener,
+ const blink::mojom::FileChooserParams& params);
// The pending page load was canceled, so the address bar should be updated.
virtual void DidCancelLoading() {}
@@ -238,6 +245,14 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
virtual void FullscreenStateChanged(RenderFrameHost* rfh,
bool is_fullscreen) {}
+#if defined(OS_ANDROID)
+ // Updates information to determine whether a user gesture should carryover to
+ // future navigations. This is needed so navigations within a certain
+ // timeframe of a request initiated by a gesture will be treated as if they
+ // were initiated by a gesture too, otherwise the navigation may be blocked.
+ virtual void UpdateUserGestureCarryoverInfo() {}
+#endif
+
// Let the delegate decide whether postMessage should be delivered to
// |target_rfh| from a source frame in the given SiteInstance. This defaults
// to false and overrides the RenderFrameHost's decision if true.
diff --git a/chromium/content/browser/frame_host/render_frame_host_factory.cc b/chromium/content/browser/frame_host/render_frame_host_factory.cc
index 4276b86c21a..5f8784a5a6d 100644
--- a/chromium/content/browser/frame_host/render_frame_host_factory.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_factory.cc
@@ -19,7 +19,6 @@ std::unique_ptr<RenderFrameHostImpl> RenderFrameHostFactory::Create(
SiteInstance* site_instance,
RenderViewHostImpl* render_view_host,
RenderFrameHostDelegate* delegate,
- RenderWidgetHostDelegate* rwh_delegate,
FrameTree* frame_tree,
FrameTreeNode* frame_tree_node,
int32_t routing_id,
@@ -28,14 +27,12 @@ std::unique_ptr<RenderFrameHostImpl> RenderFrameHostFactory::Create(
bool renderer_initiated_creation) {
if (factory_) {
return factory_->CreateRenderFrameHost(
- site_instance, render_view_host, delegate, rwh_delegate, frame_tree,
- frame_tree_node, routing_id, widget_routing_id, hidden,
- renderer_initiated_creation);
+ site_instance, render_view_host, delegate, frame_tree, frame_tree_node,
+ routing_id, widget_routing_id, hidden, renderer_initiated_creation);
}
return base::WrapUnique(new RenderFrameHostImpl(
- site_instance, render_view_host, delegate, rwh_delegate, frame_tree,
- frame_tree_node, routing_id, widget_routing_id, hidden,
- renderer_initiated_creation));
+ site_instance, render_view_host, delegate, frame_tree, frame_tree_node,
+ routing_id, widget_routing_id, hidden, renderer_initiated_creation));
}
// static
diff --git a/chromium/content/browser/frame_host/render_frame_host_factory.h b/chromium/content/browser/frame_host/render_frame_host_factory.h
index 5fd70cb0d36..9b3c548a925 100644
--- a/chromium/content/browser/frame_host/render_frame_host_factory.h
+++ b/chromium/content/browser/frame_host/render_frame_host_factory.h
@@ -19,7 +19,6 @@ class FrameTreeNode;
class RenderFrameHostDelegate;
class RenderFrameHostImpl;
class RenderViewHostImpl;
-class RenderWidgetHostDelegate;
class SiteInstance;
// A factory for creating RenderFrameHosts. There is a global factory function
@@ -33,7 +32,6 @@ class CONTENT_EXPORT RenderFrameHostFactory {
SiteInstance* site_instance,
RenderViewHostImpl* render_view_host,
RenderFrameHostDelegate* delegate,
- RenderWidgetHostDelegate* rwh_delegate,
FrameTree* frame_tree,
FrameTreeNode* frame_tree_node,
int32_t routing_id,
@@ -54,7 +52,6 @@ class CONTENT_EXPORT RenderFrameHostFactory {
SiteInstance* site_instance,
RenderViewHostImpl* render_view_host,
RenderFrameHostDelegate* delegate,
- RenderWidgetHostDelegate* rwh_delegate,
FrameTree* frame_tree,
FrameTreeNode* frame_tree_node,
int32_t routing_id,
diff --git a/chromium/content/browser/frame_host/render_frame_host_impl.cc b/chromium/content/browser/frame_host/render_frame_host_impl.cc
index e67018e0f80..a17ae7ca0c0 100644
--- a/chromium/content/browser/frame_host/render_frame_host_impl.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_impl.cc
@@ -40,6 +40,7 @@
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/download/mhtml_generation_manager.h"
#include "content/browser/file_url_loader_factory.h"
+#include "content/browser/fileapi/file_system_manager_impl.h"
#include "content/browser/fileapi/file_system_url_loader_factory.h"
#include "content/browser/frame_host/cross_process_frame_connector.h"
#include "content/browser/frame_host/debug_urls.h"
@@ -84,7 +85,6 @@
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_delegate_view.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
-#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_factory.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
@@ -119,7 +119,9 @@
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host_view.h"
@@ -132,8 +134,6 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
-#include "content/public/common/file_chooser_file_info.h"
-#include "content/public/common/file_chooser_params.h"
#include "content/public/common/isolated_world_ids.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
@@ -150,6 +150,7 @@
#include "media/mojo/services/media_metrics_provider.h"
#include "media/mojo/services/video_decode_perf_history.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/data_pipe.h"
@@ -169,6 +170,7 @@
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/frame/frame_policy.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
@@ -183,6 +185,7 @@
#include "url/url_constants.h"
#if defined(OS_ANDROID)
+#include "content/browser/android/content_url_loader_factory.h"
#include "content/browser/android/java_interfaces_impl.h"
#include "content/browser/frame_host/render_frame_host_android.h"
#include "content/public/browser/android/java_interfaces.h"
@@ -354,8 +357,8 @@ void NotifyForEachFrameFromUI(RenderFrameHostImpl* root_frame_host,
if (pending_frame_host)
routing_ids->insert(pending_frame_host->GetGlobalFrameRoutingId());
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&NotifyRouteChangesOnIO, frame_callback,
std::move(routing_ids)));
}
@@ -397,8 +400,8 @@ void NotifyResourceSchedulerOfNavigation(
if (!ui::PageTransitionIsMainFrame(params.transition))
return;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ResourceSchedulerFilter::OnDidCommitMainframeNavigation,
render_process_id, params.render_view_routing_id));
}
@@ -426,6 +429,24 @@ void LogRendererKillCrashKeys(const GURL& site_url) {
base::debug::SetCrashKeyString(site_url_key, site_url.spec());
}
+url::Origin GetOriginForURLLoaderFactory(GURL target_url,
+ SiteInstanceImpl* site_instance) {
+ // Calculate the origin that will be used as a fallback for URLs such as
+ // about:blank and/or data:. If full site isolation is enabled, then
+ // |site_instance|-based origin will be correct. Otherwise, falling back to a
+ // unique/opaque origin should be safe.
+ //
+ // TODO(lukasza, nasko): https://crbug.com/888079: Do not fall back to
+ // |site_instance| - instead the browser process should already know at
+ // ready-to-commit time the origin to be committed.
+ url::Origin fallback_origin =
+ SiteIsolationPolicy::UseDedicatedProcessesForAllSites()
+ ? url::Origin::Create(site_instance->GetSiteURL())
+ : url::Origin();
+
+ return url::Origin::Resolve(target_url, fallback_origin);
+}
+
} // namespace
class RenderFrameHostImpl::DroppedInterfaceRequestLogger
@@ -467,23 +488,120 @@ struct PendingNavigation {
mojom::BeginNavigationParamsPtr begin_navigation_params;
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory;
mojom::NavigationClientAssociatedPtrInfo navigation_client;
+ blink::mojom::NavigationInitiatorPtr navigation_initiator;
PendingNavigation(
CommonNavigationParams common_params,
mojom::BeginNavigationParamsPtr begin_navigation_params,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- mojom::NavigationClientAssociatedPtrInfo navigation_client);
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator);
};
PendingNavigation::PendingNavigation(
CommonNavigationParams common_params,
mojom::BeginNavigationParamsPtr begin_navigation_params,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- mojom::NavigationClientAssociatedPtrInfo navigation_client)
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator)
: common_params(common_params),
begin_navigation_params(std::move(begin_navigation_params)),
blob_url_loader_factory(std::move(blob_url_loader_factory)),
- navigation_client(std::move(navigation_client)) {}
+ navigation_client(std::move(navigation_client)),
+ navigation_initiator(std::move(navigation_initiator)) {}
+
+class FileChooserImpl : public content::FileSelectListener,
+ private content::WebContentsObserver {
+ public:
+ FileChooserImpl(RenderFrameHostImpl* render_frame_host)
+ : render_frame_host_(render_frame_host) {
+ Observe(WebContents::FromRenderFrameHost(render_frame_host));
+ }
+
+ ~FileChooserImpl() override {
+#if DCHECK_IS_ON()
+ DCHECK(was_file_select_listener_function_called_)
+ << "Should call either FileSelectListener::FileSelected() or "
+ "FileSelectListener::FileSelectionCanceled()";
+#endif
+ }
+
+ // FileSelectListener overrides:
+
+ void FileSelected(std::vector<blink::mojom::FileChooserFileInfoPtr> files,
+ blink::mojom::FileChooserParams::Mode mode) override {
+#if DCHECK_IS_ON()
+ DCHECK(!was_file_select_listener_function_called_)
+ << "Should not call both of FileSelectListener::FileSelected() and "
+ "FileSelectListener::FileSelectionCanceled()";
+ was_file_select_listener_function_called_ = true;
+#endif
+ if (!render_frame_host_)
+ return;
+ storage::FileSystemContext* file_system_context = nullptr;
+ const int pid = render_frame_host_->GetProcess()->GetID();
+ auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
+ // Grant the security access requested to the given files.
+ for (const auto& file : files) {
+ if (mode == blink::mojom::FileChooserParams::Mode::kSave) {
+ policy->GrantCreateReadWriteFile(pid,
+ file->get_native_file()->file_path);
+ } else {
+ if (file->is_file_system()) {
+ if (!file_system_context) {
+ file_system_context =
+ BrowserContext::GetStoragePartition(
+ render_frame_host_->GetProcess()->GetBrowserContext(),
+ render_frame_host_->GetSiteInstance())
+ ->GetFileSystemContext();
+ }
+ policy->GrantReadFileSystem(
+ pid, file_system_context->CrackURL(file->get_file_system()->url)
+ .mount_filesystem_id());
+ } else {
+ policy->GrantReadFile(pid, file->get_native_file()->file_path);
+ }
+ }
+ }
+ render_frame_host_->Send(new FrameMsg_RunFileChooserResponse(
+ render_frame_host_->routing_id(), files));
+ }
+
+ void FileSelectionCanceled() override {
+#if DCHECK_IS_ON()
+ DCHECK(!was_file_select_listener_function_called_)
+ << "Should not call both of FileSelectListener::FileSelected() and "
+ "FileSelectListener::FileSelectionCanceled()";
+ was_file_select_listener_function_called_ = true;
+#endif
+ if (!render_frame_host_)
+ return;
+ render_frame_host_->Send(new FrameMsg_RunFileChooserResponse(
+ render_frame_host_->routing_id(),
+ std::vector<blink::mojom::FileChooserFileInfoPtr>()));
+ }
+
+ private:
+ // content::WebContentsObserver overrides:
+
+ void RenderFrameHostChanged(RenderFrameHost* old_host,
+ RenderFrameHost* new_host) override {
+ if (old_host == render_frame_host_)
+ render_frame_host_ = nullptr;
+ }
+
+ void RenderFrameDeleted(RenderFrameHost* render_frame_host) override {
+ if (render_frame_host == render_frame_host_)
+ render_frame_host_ = nullptr;
+ }
+
+ void WebContentsDestroyed() override { render_frame_host_ = nullptr; }
+
+ RenderFrameHostImpl* render_frame_host_;
+#if DCHECK_IS_ON()
+ bool was_file_select_listener_function_called_ = false;
+#endif
+};
// static
RenderFrameHost* RenderFrameHost::FromID(int render_process_id,
@@ -503,20 +621,18 @@ RenderFrameHostImpl* RenderFrameHostImpl::FromID(int process_id,
int routing_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RoutingIDFrameMap* frames = g_routing_id_frame_map.Pointer();
- RoutingIDFrameMap::iterator it = frames->find(
- RenderFrameHostID(process_id, routing_id));
+ auto it = frames->find(RenderFrameHostID(process_id, routing_id));
return it == frames->end() ? NULL : it->second;
}
// static
-RenderFrameHost* RenderFrameHost::FromAXTreeID(
- int ax_tree_id) {
+RenderFrameHost* RenderFrameHost::FromAXTreeID(ui::AXTreeID ax_tree_id) {
return RenderFrameHostImpl::FromAXTreeID(ax_tree_id);
}
// static
RenderFrameHostImpl* RenderFrameHostImpl::FromAXTreeID(
- ui::AXTreeIDRegistry::AXTreeID ax_tree_id) {
+ ui::AXTreeID ax_tree_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
ui::AXTreeIDRegistry::FrameID frame_id =
ui::AXTreeIDRegistry::GetInstance()->GetFrameID(ax_tree_id);
@@ -547,7 +663,6 @@ void RenderFrameHostImpl::SetNetworkFactoryForTesting(
RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
RenderViewHostImpl* render_view_host,
RenderFrameHostDelegate* delegate,
- RenderWidgetHostDelegate* rwh_delegate,
FrameTree* frame_tree,
FrameTreeNode* frame_tree_node,
int32_t routing_id,
@@ -566,6 +681,7 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
is_waiting_for_swapout_ack_(false),
render_frame_created_(false),
is_waiting_for_beforeunload_ack_(false),
+ beforeunload_dialog_request_cancels_unload_(false),
unload_ack_is_for_navigation_(false),
beforeunload_timeout_delay_(base::TimeDelta::FromMilliseconds(
RenderViewHostImpl::kUnloadTimeoutMS)),
@@ -574,7 +690,7 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
nav_entry_id_(0),
accessibility_reset_token_(0),
accessibility_reset_count_(0),
- browser_plugin_embedder_ax_tree_id_(ui::AXTreeIDRegistry::kNoAXTreeID),
+ browser_plugin_embedder_ax_tree_id_(ui::AXTreeIDUnknown()),
no_create_browser_accessibility_manager_for_testing_(false),
web_ui_type_(WebUI::kNoWebUI),
pending_web_ui_type_(WebUI::kNoWebUI),
@@ -643,8 +759,8 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
if (!render_widget_host_) {
DCHECK(frame_tree_node->parent());
render_widget_host_ = RenderWidgetHostFactory::Create(
- rwh_delegate, GetProcess(), widget_routing_id, std::move(widget),
- hidden);
+ frame_tree_->render_widget_delegate(), GetProcess(),
+ widget_routing_id, std::move(widget), hidden);
render_widget_host_->set_owned_by_render_frame_host(true);
} else {
DCHECK(!render_widget_host_->owned_by_render_frame_host());
@@ -768,7 +884,7 @@ int RenderFrameHostImpl::GetRoutingID() {
return routing_id_;
}
-ui::AXTreeIDRegistry::AXTreeID RenderFrameHostImpl::GetAXTreeID() {
+ui::AXTreeID RenderFrameHostImpl::GetAXTreeID() {
return ax_tree_id_;
}
@@ -809,6 +925,18 @@ RenderFrameHostImpl* RenderFrameHostImpl::GetParent() {
return parent_;
}
+bool RenderFrameHostImpl::IsDescendantOf(RenderFrameHost* ancestor) {
+ if (!ancestor || !static_cast<RenderFrameHostImpl*>(ancestor)->child_count())
+ return false;
+
+ for (RenderFrameHostImpl* current = GetParent(); current;
+ current = current->GetParent()) {
+ if (current == ancestor)
+ return true;
+ }
+ return false;
+}
+
int RenderFrameHostImpl::GetFrameTreeNodeId() {
return frame_tree_node_->frame_tree_node_id();
}
@@ -867,7 +995,32 @@ void RenderFrameHostImpl::ExecuteMediaPlayerActionAtLocation(
bool RenderFrameHostImpl::CreateNetworkServiceDefaultFactory(
network::mojom::URLLoaderFactoryRequest default_factory_request) {
return CreateNetworkServiceDefaultFactoryInternal(
- last_committed_url_, std::move(default_factory_request));
+ last_committed_origin_, std::move(default_factory_request));
+}
+
+void RenderFrameHostImpl::MarkInitiatorsAsRequiringSeparateURLLoaderFactory(
+ std::vector<url::Origin> request_initiators,
+ bool push_to_renderer_now) {
+ size_t old_size = initiators_requiring_separate_url_loader_factory_.size();
+ initiators_requiring_separate_url_loader_factory_.insert(
+ request_initiators.begin(), request_initiators.end());
+ size_t new_size = initiators_requiring_separate_url_loader_factory_.size();
+ bool insertion_took_place = (old_size != new_size);
+ if (push_to_renderer_now && insertion_took_place)
+ UpdateSubresourceLoaderFactories();
+}
+
+URLLoaderFactoryBundleInfo::OriginMap
+RenderFrameHostImpl::CreateInitiatorSpecificURLLoaderFactories() {
+ URLLoaderFactoryBundleInfo::OriginMap result;
+ for (const url::Origin& initiator :
+ initiators_requiring_separate_url_loader_factory_) {
+ network::mojom::URLLoaderFactoryPtrInfo factory_info;
+ CreateNetworkServiceDefaultFactoryInternal(
+ initiator, mojo::MakeRequest(&factory_info));
+ result[initiator] = std::move(factory_info);
+ }
+ return result;
}
gfx::NativeView RenderFrameHostImpl::GetNativeView() {
@@ -1065,8 +1218,6 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
OnDidAddMessageToConsole)
IPC_MESSAGE_HANDLER(FrameHostMsg_Detach, OnDetach)
IPC_MESSAGE_HANDLER(FrameHostMsg_FrameFocused, OnFrameFocused)
- IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartProvisionalLoad,
- OnDidStartProvisionalLoad)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidFailProvisionalLoadWithError,
OnDidFailProvisionalLoadWithError)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidFailLoadWithError,
@@ -1117,7 +1268,6 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER(FrameHostMsg_ExitFullscreen, OnExitFullscreen)
IPC_MESSAGE_HANDLER(FrameHostMsg_SuddenTerminationDisablerChanged,
OnSuddenTerminationDisablerChanged)
- IPC_MESSAGE_HANDLER(FrameHostMsg_DidStartLoading, OnDidStartLoading)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidStopLoading, OnDidStopLoading)
IPC_MESSAGE_HANDLER(FrameHostMsg_DidChangeLoadProgress,
OnDidChangeLoadProgress)
@@ -1461,7 +1611,8 @@ void RenderFrameHostImpl::Init() {
frame_tree_node(), pending_navigate_->common_params,
std::move(pending_navigate_->begin_navigation_params),
std::move(pending_navigate_->blob_url_loader_factory),
- std::move(pending_navigate_->navigation_client));
+ std::move(pending_navigate_->navigation_client),
+ std::move(pending_navigate_->navigation_initiator));
pending_navigate_.reset();
}
}
@@ -1581,6 +1732,51 @@ void RenderFrameHostImpl::SetLastCommittedOriginForTesting(
SetLastCommittedOrigin(origin);
}
+FrameTreeNode* RenderFrameHostImpl::AddChild(
+ std::unique_ptr<FrameTreeNode> child,
+ int process_id,
+ int frame_routing_id) {
+ // Child frame must always be created in the same process as the parent.
+ CHECK_EQ(process_id, GetProcess()->GetID());
+
+ // Initialize the RenderFrameHost for the new node. We always create child
+ // frames in the same SiteInstance as the current frame, and they can swap to
+ // a different one if they navigate away.
+ child->render_manager()->Init(GetSiteInstance(),
+ render_view_host()->GetRoutingID(),
+ frame_routing_id, MSG_ROUTING_NONE, false);
+
+ // Other renderer processes in this BrowsingInstance may need to find out
+ // about the new frame. Create a proxy for the child frame in all
+ // SiteInstances that have a proxy for the frame's parent, since all frames
+ // in a frame tree should have the same set of proxies.
+ frame_tree_node_->render_manager()->CreateProxiesForChildFrame(child.get());
+
+ children_.push_back(std::move(child));
+
+ return children_.back().get();
+}
+
+void RenderFrameHostImpl::RemoveChild(FrameTreeNode* child) {
+ for (auto iter = children_.begin(); iter != children_.end(); ++iter) {
+ if (iter->get() == child) {
+ // Subtle: we need to make sure the node is gone from the tree before
+ // observers are notified of its deletion.
+ std::unique_ptr<FrameTreeNode> node_to_delete(std::move(*iter));
+ children_.erase(iter);
+ node_to_delete.reset();
+ return;
+ }
+ }
+}
+
+void RenderFrameHostImpl::ResetChildren() {
+ // Remove child nodes from the tree, then delete them. This destruction
+ // operation will notify observers. See https://crbug.com/612450 for
+ // explanation why we don't just call the std::vector::clear method.
+ std::vector<std::unique_ptr<FrameTreeNode>>().swap(children_);
+}
+
void RenderFrameHostImpl::SetLastCommittedUrl(const GURL& url) {
last_committed_url_ = url;
}
@@ -1653,24 +1849,6 @@ void RenderFrameHostImpl::OnDocumentOnLoadCompleted() {
delegate_->DocumentOnLoadCompleted(this);
}
-void RenderFrameHostImpl::OnDidStartProvisionalLoad(
- const GURL& url,
- const std::vector<GURL>& redirect_chain,
- const base::TimeTicks& navigation_start) {
- // TODO(clamy): Check if other navigation methods (OpenURL,
- // DidFailProvisionalLoad, ...) should also be ignored if the RFH is no longer
- // active.
- if (!is_active())
- return;
-
- TRACE_EVENT2("navigation", "RenderFrameHostImpl::OnDidStartProvisionalLoad",
- "frame_tree_node", frame_tree_node_->frame_tree_node_id(), "url",
- url.possibly_invalid_spec());
-
- frame_tree_node_->navigator()->DidStartProvisionalLoad(
- this, url, redirect_chain, navigation_start);
-}
-
void RenderFrameHostImpl::OnDidFailProvisionalLoadWithError(
const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) {
TRACE_EVENT2("navigation",
@@ -2252,8 +2430,7 @@ void RenderFrameHostImpl::OnJavaScriptExecuteResponse(
return;
}
- std::map<int, JavaScriptResultCallback>::iterator it =
- javascript_callbacks_.find(id);
+ auto it = javascript_callbacks_.find(id);
if (it != javascript_callbacks_.end()) {
it->second.Run(result_value);
javascript_callbacks_.erase(it);
@@ -2325,6 +2502,15 @@ void RenderFrameHostImpl::OnRunBeforeUnloadConfirm(
// Allow at most one attempt to show a beforeunload dialog per navigation.
RenderFrameHostImpl* beforeunload_initiator = GetBeforeUnloadInitiator();
if (beforeunload_initiator) {
+ // If the running beforeunload handler wants to display a dialog and the
+ // before-unload type wants to ignore it, then short-circuit the request and
+ // respond as if the user decided to stay on the page, canceling the unload.
+ if (beforeunload_initiator->beforeunload_dialog_request_cancels_unload_) {
+ SendJavaScriptDialogReply(reply_msg, false /* success */,
+ base::string16());
+ return;
+ }
+
if (beforeunload_initiator->has_shown_beforeunload_dialog_) {
// TODO(alexmos): Pass enough data back to renderer to record histograms
// for Document.BeforeUnloadDialog and add the intervention console
@@ -2361,17 +2547,20 @@ void RenderFrameHostImpl::OnRunBeforeUnloadConfirm(
delegate_->RunBeforeUnloadConfirm(this, is_reload, reply_msg);
}
-void RenderFrameHostImpl::OnRunFileChooser(const FileChooserParams& params) {
+void RenderFrameHostImpl::OnRunFileChooser(
+ const blink::mojom::FileChooserParams& params) {
+ auto listener = std::make_unique<FileChooserImpl>(this);
// Do not allow messages with absolute paths in them as this can permit a
// renderer to coerce the browser to perform I/O on a renderer controlled
// path.
if (params.default_file_name != params.default_file_name.BaseName()) {
bad_message::ReceivedBadMessage(GetProcess(),
bad_message::RFH_FILE_CHOOSER_PATH);
+ listener->FileSelectionCanceled();
return;
}
- delegate_->RunFileChooser(this, params);
+ delegate_->RunFileChooser(this, std::move(listener), params);
}
void RenderFrameHostImpl::RequestTextSurroundingSelection(
@@ -2631,6 +2820,12 @@ void RenderFrameHostImpl::FullscreenStateChanged(bool is_fullscreen) {
delegate_->FullscreenStateChanged(this, is_fullscreen);
}
+#if defined(OS_ANDROID)
+void RenderFrameHostImpl::UpdateUserGestureCarryoverInfo() {
+ delegate_->UpdateUserGestureCarryoverInfo();
+}
+#endif
+
void RenderFrameHostImpl::OnDidBlockFramebust(const GURL& url) {
delegate_->OnDidBlockFramebust(url);
}
@@ -2948,29 +3143,6 @@ void RenderFrameHostImpl::OnExitFullscreen() {
render_view_host_->GetWidget()->SynchronizeVisualProperties();
}
-// TODO(clamy): Remove this IPC now that it is only used for same-document
-// navigations.
-void RenderFrameHostImpl::OnDidStartLoading(bool to_different_document) {
- TRACE_EVENT2("navigation", "RenderFrameHostImpl::OnDidStartLoading",
- "frame_tree_node", frame_tree_node_->frame_tree_node_id(),
- "to different document", to_different_document);
-
- if (to_different_document) {
- bad_message::ReceivedBadMessage(GetProcess(),
- bad_message::RFH_UNEXPECTED_LOAD_START);
- return;
- }
- bool was_previously_loading = frame_tree_node_->frame_tree()->IsLoading();
- is_loading_ = true;
-
- // Only inform the FrameTreeNode of a change in load state if the load state
- // of this RenderFrameHost is being tracked.
- if (is_active()) {
- frame_tree_node_->DidStartLoading(to_different_document,
- was_previously_loading);
- }
-}
-
void RenderFrameHostImpl::OnSuddenTerminationDisablerChanged(
bool present,
blink::WebSuddenTerminationDisablerType disabler_type) {
@@ -3252,8 +3424,8 @@ void RenderFrameHostImpl::CreateNewWindow(
rdh->BlockRequestsForRoute(id);
},
GlobalFrameRoutingId(render_process_id, main_frame_route_id));
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- std::move(block_requests_for_route));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ std::move(block_requests_for_route));
}
}
@@ -3329,7 +3501,8 @@ void RenderFrameHostImpl::BeginNavigation(
const CommonNavigationParams& common_params,
mojom::BeginNavigationParamsPtr begin_params,
blink::mojom::BlobURLTokenPtr blob_url_token,
- mojom::NavigationClientAssociatedPtrInfo navigation_client) {
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator) {
if (!is_active())
return;
@@ -3393,13 +3566,15 @@ void RenderFrameHostImpl::BeginNavigation(
if (waiting_for_init_) {
pending_navigate_ = std::make_unique<PendingNavigation>(
validated_params, std::move(begin_params),
- std::move(blob_url_loader_factory), std::move(navigation_client));
+ std::move(blob_url_loader_factory), std::move(navigation_client),
+ std::move(navigation_initiator));
return;
}
frame_tree_node()->navigator()->OnBeginNavigation(
frame_tree_node(), validated_params, std::move(begin_params),
- std::move(blob_url_loader_factory), std::move(navigation_client));
+ std::move(blob_url_loader_factory), std::move(navigation_client),
+ std::move(navigation_initiator));
}
void RenderFrameHostImpl::SubresourceResponseStarted(
@@ -3509,10 +3684,8 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
base::BindRepeating(&RenderFrameHostImpl::CreateAudioOutputStreamFactory,
base::Unretained(this)));
- if (resource_coordinator::IsResourceCoordinatorEnabled()) {
- registry_->AddInterface(
- base::Bind(&CreateFrameResourceCoordinator, base::Unretained(this)));
- }
+ registry_->AddInterface(
+ base::Bind(&CreateFrameResourceCoordinator, base::Unretained(this)));
// BrowserMainLoop::GetInstance() may be null on unit tests.
if (BrowserMainLoop::GetInstance()) {
@@ -3524,15 +3697,14 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
BrowserMainLoop::GetInstance()->media_stream_manager();
registry_->AddInterface(
base::Bind(&MediaDevicesDispatcherHost::Create, GetProcess()->GetID(),
- GetRoutingID(),
- base::Unretained(media_stream_manager)),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ GetRoutingID(), base::Unretained(media_stream_manager)),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
registry_->AddInterface(
base::BindRepeating(
&RenderFrameHostImpl::CreateMediaStreamDispatcherHost,
base::Unretained(this), base::Unretained(media_stream_manager)),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
}
#if BUILDFLAG(ENABLE_MEDIA_REMOTING)
@@ -3599,7 +3771,16 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
registry_->AddInterface(
base::BindRepeating(SpeechRecognitionDispatcherHost::Create,
GetProcess()->GetID(), routing_id_),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
+
+ file_system_manager_.reset(new FileSystemManagerImpl(
+ GetProcess()->GetID(), routing_id_,
+ GetProcess()->GetStoragePartition()->GetFileSystemContext(),
+ ChromeBlobStorageContext::GetFor(GetProcess()->GetBrowserContext())));
+ registry_->AddInterface(
+ base::BindRepeating(&FileSystemManagerImpl::BindRequest,
+ base::Unretained(file_system_manager_.get())),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
if (Portal::IsEnabled()) {
registry_->AddInterface(base::BindRepeating(IgnoreResult(&Portal::Create),
@@ -3650,7 +3831,7 @@ bool RenderFrameHostImpl::CanCommitOrigin(
// It is safe to commit into a unique origin, regardless of the URL, as it is
// restricted from accessing other origins.
- if (origin.unique())
+ if (origin.opaque())
return true;
// Standard URLs must match the reported origin.
@@ -3673,13 +3854,10 @@ void RenderFrameHostImpl::NavigateToInterstitialURL(const GURL& data_url) {
DCHECK(data_url.SchemeIs(url::kDataScheme));
CommonNavigationParams common_params(
data_url, Referrer(), ui::PAGE_TRANSITION_LINK,
- FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT, false, false,
- GURL(), GURL(), PREVIEWS_OFF, base::TimeTicks::Now(), "GET", nullptr,
- base::Optional<SourceLocation>(),
- CSPDisposition::CHECK /* should_check_main_world_csp */,
- false /* started_from_context_menu */, false /* has_user_gesture */,
- std::vector<ContentSecurityPolicy>() /* initiator_csp */,
- CSPSource() /* initiator_self_source */);
+ FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT, false, false, GURL(), GURL(),
+ PREVIEWS_OFF, base::TimeTicks::Now(), "GET", nullptr,
+ base::Optional<SourceLocation>(), false /* started_from_context_menu */,
+ false /* has_user_gesture */, InitiatorCSPInfo());
CommitNavigation(0, nullptr, network::mojom::URLLoaderClientEndpointsPtr(),
common_params, RequestNavigationParams(), false,
base::nullopt, base::nullopt /* subresource_overrides */,
@@ -3699,8 +3877,9 @@ void RenderFrameHostImpl::DispatchBeforeUnload(BeforeUnloadType type,
type == BeforeUnloadType::RENDERER_INITIATED_NAVIGATION;
DCHECK(for_navigation || !is_reload);
- // Tab close should only dispatch beforeunload on main frames.
- DCHECK(type != BeforeUnloadType::TAB_CLOSE ||
+ // TAB_CLOSE and DISCARD should only dispatch beforeunload on main frames.
+ DCHECK(type == BeforeUnloadType::BROWSER_INITIATED_NAVIGATION ||
+ type == BeforeUnloadType::RENDERER_INITIATED_NAVIGATION ||
frame_tree_node_->IsMainFrame());
if (!for_navigation) {
@@ -3757,13 +3936,16 @@ void RenderFrameHostImpl::DispatchBeforeUnload(BeforeUnloadType type,
// Start the hang monitor in case the renderer hangs in the beforeunload
// handler.
is_waiting_for_beforeunload_ack_ = true;
+ beforeunload_dialog_request_cancels_unload_ = false;
unload_ack_is_for_navigation_ = for_navigation;
send_before_unload_start_time_ = base::TimeTicks::Now();
if (render_view_host_->GetDelegate()->IsJavaScriptDialogShowing()) {
// If there is a JavaScript dialog up, don't bother sending the renderer
// the unload event because it is known unresponsive, waiting for the
- // reply from the dialog.
- SimulateBeforeUnloadAck();
+ // reply from the dialog. If this incoming request is for a DISCARD be
+ // sure to reply with |proceed = false|, because the presence of a dialog
+ // indicates that the page can't be discarded.
+ SimulateBeforeUnloadAck(type != BeforeUnloadType::DISCARD);
} else {
// Start a timer that will be shared by all frames that need to run
// beforeunload in the current frame's subtree.
@@ -3771,6 +3953,8 @@ void RenderFrameHostImpl::DispatchBeforeUnload(BeforeUnloadType type,
beforeunload_timeout_->Start(beforeunload_timeout_delay_);
beforeunload_pending_replies_.clear();
+ beforeunload_dialog_request_cancels_unload_ =
+ (type == BeforeUnloadType::DISCARD);
// Run beforeunload in this frame and its cross-process descendant
// frames, in parallel.
@@ -3843,8 +4027,7 @@ bool RenderFrameHostImpl::CheckOrDispatchBeforeUnloadForSubtree(
// descendants. Detect cases like this and skip them.
bool has_same_site_ancestor = false;
for (auto* added_rfh : beforeunload_pending_replies_) {
- if (rfh->frame_tree_node()->IsDescendantOf(
- added_rfh->frame_tree_node()) &&
+ if (rfh->IsDescendantOf(added_rfh) &&
rfh->GetSiteInstance() == added_rfh->GetSiteInstance()) {
has_same_site_ancestor = true;
break;
@@ -3863,7 +4046,7 @@ bool RenderFrameHostImpl::CheckOrDispatchBeforeUnloadForSubtree(
return found_beforeunload;
}
-void RenderFrameHostImpl::SimulateBeforeUnloadAck() {
+void RenderFrameHostImpl::SimulateBeforeUnloadAck(bool proceed) {
DCHECK(is_waiting_for_beforeunload_ack_);
base::TimeTicks approx_renderer_start_time = send_before_unload_start_time_;
@@ -3871,7 +4054,7 @@ void RenderFrameHostImpl::SimulateBeforeUnloadAck() {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&RenderFrameHostImpl::ProcessBeforeUnloadACK,
- weak_ptr_factory_.GetWeakPtr(), true /* proceed */,
+ weak_ptr_factory_.GetWeakPtr(), proceed,
true /* treat_as_final_ack */, approx_renderer_start_time,
base::TimeTicks::Now()));
}
@@ -4023,7 +4206,7 @@ void RenderFrameHostImpl::CommitNavigation(
} else {
// This is a webui scheme that doesn't have webui bindings. Give it
// access to the network loader as it might require it.
- subresource_loader_factories->factories_info().emplace(
+ subresource_loader_factories->scheme_specific_factory_infos().emplace(
scheme, factory_for_webui.PassInterface());
}
}
@@ -4034,7 +4217,9 @@ void RenderFrameHostImpl::CommitNavigation(
// appropriate NetworkContext.
bool bypass_redirect_checks =
CreateNetworkServiceDefaultFactoryAndObserve(
- common_params.url, mojo::MakeRequest(&default_factory_info));
+ GetOriginForURLLoaderFactory(common_params.url,
+ GetSiteInstance()),
+ mojo::MakeRequest(&default_factory_info));
subresource_loader_factories->set_bypass_redirect_checks(
bypass_redirect_checks);
}
@@ -4056,6 +4241,18 @@ void RenderFrameHostImpl::CommitNavigation(
std::move(file_factory));
}
+#if defined(OS_ANDROID)
+ if (common_params.url.SchemeIs(url::kContentScheme)) {
+ // Only content:// URLs can load content:// subresources
+ auto content_factory = std::make_unique<ContentURLLoaderFactory>(
+ base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}));
+ non_network_url_loader_factories_.emplace(url::kContentScheme,
+ std::move(content_factory));
+ }
+#endif
+
StoragePartition* partition =
BrowserContext::GetStoragePartition(browser_context, GetSiteInstance());
std::string storage_domain;
@@ -4081,16 +4278,20 @@ void RenderFrameHostImpl::CommitNavigation(
network::mojom::URLLoaderFactoryPtrInfo factory_proxy_info;
auto factory_request = mojo::MakeRequest(&factory_proxy_info);
GetContentClient()->browser()->WillCreateURLLoaderFactory(
- browser_context, this, false /* is_navigation */, common_params.url,
- &factory_request);
+ browser_context, this, false /* is_navigation */,
+ GetOriginForURLLoaderFactory(common_params.url, GetSiteInstance()),
+ &factory_request, nullptr /* bypass_redirect_checks */);
// Keep DevTools proxy lasy, i.e. closest to the network.
RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory(
this, false /* is_navigation */, false /* is_download */,
&factory_request);
factory.second->Clone(std::move(factory_request));
- subresource_loader_factories->factories_info().emplace(
+ subresource_loader_factories->scheme_specific_factory_infos().emplace(
factory.first, std::move(factory_proxy_info));
}
+
+ subresource_loader_factories->initiator_specific_factory_infos() =
+ CreateInitiatorSpecificURLLoaderFactories();
}
// It is imperative that cross-document navigations always provide a set of
@@ -4123,25 +4324,42 @@ void RenderFrameHostImpl::CommitNavigation(
}
}
+ std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_for_prefetch;
network::mojom::URLLoaderFactoryPtr prefetch_loader_factory;
if (subresource_loader_factories) {
SaveSubresourceFactories(std::move(subresource_loader_factories));
+ factory_bundle_for_prefetch = CloneSubresourceFactories();
+ } else if (base::FeatureList::IsEnabled(
+ blink::features::kServiceWorkerServicification) &&
+ (!is_same_document || is_first_navigation)) {
+ DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
+ factory_bundle_for_prefetch =
+ std::make_unique<URLLoaderFactoryBundleInfo>();
+ network::mojom::URLLoaderFactoryPtrInfo factory_info;
+ CreateNetworkServiceDefaultFactoryInternal(
+ url::Origin(), mojo::MakeRequest(&factory_info));
+ factory_bundle_for_prefetch->default_factory_info() =
+ std::move(factory_info);
+ }
+ if (factory_bundle_for_prefetch) {
// Also set-up URLLoaderFactory for prefetch using the same loader
// factories. TODO(kinuko): Consider setting this up only when prefetch
// is used. Currently we have this here to make sure we have non-racy
// situation (https://crbug.com/849929).
- DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
+ DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService) ||
+ base::FeatureList::IsEnabled(
+ blink::features::kServiceWorkerServicification));
auto* storage_partition = static_cast<StoragePartitionImpl*>(
BrowserContext::GetStoragePartition(
GetSiteInstance()->GetBrowserContext(), GetSiteInstance()));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PrefetchURLLoaderService::GetFactory,
storage_partition->GetPrefetchURLLoaderService(),
mojo::MakeRequest(&prefetch_loader_factory),
frame_tree_node_->frame_tree_node_id(),
- CloneSubresourceFactories()));
+ std::move(factory_bundle_for_prefetch)));
}
auto find_request = navigation_requests_.find(navigation_id);
@@ -4175,8 +4393,8 @@ void RenderFrameHostImpl::CommitNavigation(
// it until its request endpoint is sent. Now that the request endpoint was
// sent, it can be used, so add it to ServiceWorkerObjectHost.
if (remote_object.is_valid()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ServiceWorkerObjectHost::AddRemoteObjectPtrAndUpdateState,
subresource_loader_params->controller_service_worker_object_host,
@@ -4210,15 +4428,21 @@ void RenderFrameHostImpl::FailedNavigation(
// completing an unload handler.
ResetWaitingState();
+ // Error page will commit in an opaque origin.
+ //
+ // TODO(lukasza): https://crbug.com/888079: Use this origin when committing
+ // later on.
+ url::Origin origin = url::Origin();
+
std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories;
if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
network::mojom::URLLoaderFactoryPtrInfo default_factory_info;
bool bypass_redirect_checks = CreateNetworkServiceDefaultFactoryAndObserve(
- common_params.url, mojo::MakeRequest(&default_factory_info));
+ origin, mojo::MakeRequest(&default_factory_info));
subresource_loader_factories = std::make_unique<URLLoaderFactoryBundleInfo>(
std::move(default_factory_info),
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>(),
- bypass_redirect_checks);
+ URLLoaderFactoryBundleInfo::SchemeMap(),
+ URLLoaderFactoryBundleInfo::OriginMap(), bypass_redirect_checks);
}
SaveSubresourceFactories(std::move(subresource_loader_factories));
@@ -4311,10 +4535,12 @@ void RenderFrameHostImpl::InvalidateMojoConnection() {
}
bool RenderFrameHostImpl::IsFocused() {
- return GetRenderWidgetHost()->is_focused() &&
- frame_tree_->GetFocusedFrame() &&
- (frame_tree_->GetFocusedFrame() == frame_tree_node() ||
- frame_tree_->GetFocusedFrame()->IsDescendantOf(frame_tree_node()));
+ if (!GetRenderWidgetHost()->is_focused() || !frame_tree_->GetFocusedFrame())
+ return false;
+
+ RenderFrameHostImpl* focused_rfh =
+ frame_tree_->GetFocusedFrame()->current_frame_host();
+ return focused_rfh == this || focused_rfh->IsDescendantOf(this);
}
bool RenderFrameHostImpl::UpdatePendingWebUI(const GURL& dest_url,
@@ -4430,22 +4656,15 @@ RenderFrameHostImpl::GetFindInPage() {
resource_coordinator::FrameResourceCoordinator*
RenderFrameHostImpl::GetFrameResourceCoordinator() {
- if (frame_resource_coordinator_)
- return frame_resource_coordinator_.get();
-
- if (!resource_coordinator::IsResourceCoordinatorEnabled()) {
- frame_resource_coordinator_ =
- std::make_unique<resource_coordinator::FrameResourceCoordinator>(
- nullptr);
- } else {
+ if (!frame_resource_coordinator_) {
auto* connection = ServiceManagerConnection::GetForProcess();
frame_resource_coordinator_ =
std::make_unique<resource_coordinator::FrameResourceCoordinator>(
connection ? connection->GetConnector() : nullptr);
- }
- if (parent_) {
- parent_->GetFrameResourceCoordinator()->AddChildFrame(
- *frame_resource_coordinator_);
+ if (parent_) {
+ parent_->GetFrameResourceCoordinator()->AddChildFrame(
+ *frame_resource_coordinator_);
+ }
}
return frame_resource_coordinator_.get();
}
@@ -4529,6 +4748,13 @@ void RenderFrameHostImpl::CancelBlockedRequestsForFrame() {
}
}
+void RenderFrameHostImpl::BindDevToolsAgent(
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host,
+ blink::mojom::DevToolsAgentAssociatedRequest request) {
+ GetNavigationControl()->BindDevToolsAgent(std::move(host),
+ std::move(request));
+}
+
bool RenderFrameHostImpl::IsSameSiteInstance(
RenderFrameHostImpl* other_render_frame_host) {
// As a sanity check, make sure the frame belongs to the same BrowserContext.
@@ -4637,33 +4863,6 @@ int RenderFrameHostImpl::GetProxyCount() {
return frame_tree_node_->render_manager()->GetProxyCount();
}
-void RenderFrameHostImpl::FilesSelectedInChooser(
- const std::vector<content::FileChooserFileInfo>& files,
- FileChooserParams::Mode permissions) {
- storage::FileSystemContext* const file_system_context =
- BrowserContext::GetStoragePartition(GetProcess()->GetBrowserContext(),
- GetSiteInstance())
- ->GetFileSystemContext();
- // Grant the security access requested to the given files.
- for (const auto& file : files) {
- if (permissions == FileChooserParams::Save) {
- ChildProcessSecurityPolicyImpl::GetInstance()->GrantCreateReadWriteFile(
- GetProcess()->GetID(), file.file_path);
- } else {
- ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
- GetProcess()->GetID(), file.file_path);
- }
- if (file.file_system_url.is_valid()) {
- ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFileSystem(
- GetProcess()->GetID(),
- file_system_context->CrackURL(file.file_system_url)
- .mount_filesystem_id());
- }
- }
-
- Send(new FrameMsg_RunFileChooserResponse(routing_id_, files));
-}
-
bool RenderFrameHostImpl::HasSelection() {
return has_selection_;
}
@@ -4755,13 +4954,13 @@ void RenderFrameHostImpl::UpdateSubresourceLoaderFactories() {
network::mojom::URLLoaderFactoryPtrInfo default_factory_info;
bool bypass_redirect_checks = CreateNetworkServiceDefaultFactoryAndObserve(
- last_committed_url_, mojo::MakeRequest(&default_factory_info));
+ last_committed_origin_, mojo::MakeRequest(&default_factory_info));
std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories =
std::make_unique<URLLoaderFactoryBundleInfo>(
std::move(default_factory_info),
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>(),
- bypass_redirect_checks);
+ URLLoaderFactoryBundleInfo::SchemeMap(),
+ CreateInitiatorSpecificURLLoaderFactories(), bypass_redirect_checks);
SaveSubresourceFactories(std::move(subresource_loader_factories));
GetNavigationControl()->UpdateSubresourceLoaderFactories(
CloneSubresourceFactories());
@@ -4777,10 +4976,10 @@ std::set<int> RenderFrameHostImpl::GetNavigationEntryIdsPendingCommit() {
}
bool RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryAndObserve(
- const GURL& url,
+ const url::Origin& origin,
network::mojom::URLLoaderFactoryRequest default_factory_request) {
bool bypass_redirect_checks = CreateNetworkServiceDefaultFactoryInternal(
- url, std::move(default_factory_request));
+ origin, std::move(default_factory_request));
// Add connection error observer when Network Service is running
// out-of-process.
@@ -4804,43 +5003,35 @@ bool RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryAndObserve(
}
bool RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryInternal(
- const GURL& url,
+ const url::Origin& origin,
network::mojom::URLLoaderFactoryRequest default_factory_request) {
- network::mojom::URLLoaderFactoryParamsPtr params =
- network::mojom::URLLoaderFactoryParams::New();
- params->process_id = GetProcess()->GetID();
- params->disable_web_security =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableWebSecurity);
- SiteIsolationPolicy::PopulateURLLoaderFactoryParamsPtrForCORB(params.get());
-
auto* context = GetSiteInstance()->GetBrowserContext();
bool bypass_redirect_checks = false;
if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- bypass_redirect_checks =
- GetContentClient()->browser()->WillCreateURLLoaderFactory(
- context, this, false /* is_navigation */, url,
- &default_factory_request);
+ GetContentClient()->browser()->WillCreateURLLoaderFactory(
+ context, this, false /* is_navigation */, origin,
+ &default_factory_request, &bypass_redirect_checks);
}
- // Keep DevTools proxy lasy, i.e. closest to the network.
+ // Keep DevTools proxy last, i.e. closest to the network.
RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory(
this, false /* is_navigation */, false /* is_download */,
&default_factory_request);
- StoragePartitionImpl* storage_partition = static_cast<StoragePartitionImpl*>(
- BrowserContext::GetStoragePartition(context, GetSiteInstance()));
+
+ // Create the URLLoaderFactory - either via ContentBrowserClient or ourselves.
if (g_create_network_factory_callback_for_test.Get().is_null()) {
- storage_partition->GetNetworkContext()->CreateURLLoaderFactory(
- std::move(default_factory_request), std::move(params));
+ GetProcess()->CreateURLLoaderFactory(origin,
+ std::move(default_factory_request));
} else {
network::mojom::URLLoaderFactoryPtr original_factory;
- storage_partition->GetNetworkContext()->CreateURLLoaderFactory(
- mojo::MakeRequest(&original_factory), std::move(params));
+ GetProcess()->CreateURLLoaderFactory(origin,
+ mojo::MakeRequest(&original_factory));
g_create_network_factory_callback_for_test.Get().Run(
std::move(default_factory_request), GetProcess()->GetID(),
original_factory.PassInterface());
}
+
return bypass_redirect_checks;
}
@@ -4884,8 +5075,7 @@ RenderFrameHost* RenderFrameHost::FromPlaceholderId(
return node ? node->current_frame_host() : nullptr;
}
-ui::AXTreeIDRegistry::AXTreeID RenderFrameHostImpl::RoutingIDToAXTreeID(
- int routing_id) {
+ui::AXTreeID RenderFrameHostImpl::RoutingIDToAXTreeID(int routing_id) {
RenderFrameHostImpl* rfh = nullptr;
RenderFrameProxyHost* rfph = nullptr;
LookupRenderFrameHostOrProxy(GetProcess()->GetID(), routing_id, &rfh, &rfph);
@@ -4894,17 +5084,17 @@ ui::AXTreeIDRegistry::AXTreeID RenderFrameHostImpl::RoutingIDToAXTreeID(
}
if (!rfh)
- return ui::AXTreeIDRegistry::kNoAXTreeID;
+ return ui::AXTreeIDUnknown();
return rfh->GetAXTreeID();
}
-ui::AXTreeIDRegistry::AXTreeID
-RenderFrameHostImpl::BrowserPluginInstanceIDToAXTreeID(int instance_id) {
+ui::AXTreeID RenderFrameHostImpl::BrowserPluginInstanceIDToAXTreeID(
+ int instance_id) {
RenderFrameHostImpl* guest = static_cast<RenderFrameHostImpl*>(
delegate()->GetGuestByInstanceID(this, instance_id));
if (!guest)
- return ui::AXTreeIDRegistry::kNoAXTreeID;
+ return ui::AXTreeIDUnknown();
// Create a mapping from the guest to its embedder's AX Tree ID, and
// explicitly update the guest to propagate that mapping immediately.
@@ -4927,12 +5117,13 @@ void RenderFrameHostImpl::AXContentNodeDataToAXNodeData(
int32_t value = iter.second;
switch (attr) {
case AX_CONTENT_ATTR_CHILD_ROUTING_ID:
- dst->int_attributes.push_back(std::make_pair(
- ax::mojom::IntAttribute::kChildTreeId, RoutingIDToAXTreeID(value)));
+ dst->string_attributes.push_back(
+ std::make_pair(ax::mojom::StringAttribute::kChildTreeId,
+ RoutingIDToAXTreeID(value)));
break;
case AX_CONTENT_ATTR_CHILD_BROWSER_PLUGIN_INSTANCE_ID:
- dst->int_attributes.push_back(
- std::make_pair(ax::mojom::IntAttribute::kChildTreeId,
+ dst->string_attributes.push_back(
+ std::make_pair(ax::mojom::StringAttribute::kChildTreeId,
BrowserPluginInstanceIDToAXTreeID(value)));
break;
case AX_CONTENT_INT_ATTRIBUTE_LAST:
@@ -4955,7 +5146,7 @@ void RenderFrameHostImpl::AXContentTreeDataToAXTreeData(
if (src.parent_routing_id != -1)
dst->parent_tree_id = RoutingIDToAXTreeID(src.parent_routing_id);
- if (browser_plugin_embedder_ax_tree_id_ != ui::AXTreeIDRegistry::kNoAXTreeID)
+ if (browser_plugin_embedder_ax_tree_id_ != ui::AXTreeIDUnknown())
dst->parent_tree_id = browser_plugin_embedder_ax_tree_id_;
// If this is not the root frame tree node, we're done.
@@ -5016,10 +5207,9 @@ void RenderFrameHostImpl::CreateAudioInputStreamFactory(
BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance();
DCHECK(browser_main_loop);
if (base::FeatureList::IsEnabled(features::kAudioServiceAudioStreams)) {
- scoped_refptr<AudioInputDeviceManager> aidm =
- browser_main_loop->media_stream_manager()->audio_input_device_manager();
- audio_service_audio_input_stream_factory_.emplace(std::move(request),
- std::move(aidm), this);
+ MediaStreamManager* msm = browser_main_loop->media_stream_manager();
+ audio_service_audio_input_stream_factory_.emplace(std::move(request), msm,
+ this);
} else {
in_content_audio_input_stream_factory_ =
RenderFrameAudioInputStreamFactoryHandle::CreateFactory(
@@ -5284,7 +5474,7 @@ void RenderFrameHostImpl::BeforeUnloadTimeout() {
if (render_view_host_->GetDelegate()->ShouldIgnoreUnresponsiveRenderer())
return;
- SimulateBeforeUnloadAck();
+ SimulateBeforeUnloadAck(true /* proceed */);
}
void RenderFrameHostImpl::SetLastCommittedSiteUrl(const GURL& url) {
@@ -5434,7 +5624,7 @@ bool RenderFrameHostImpl::ValidateDidCommitParams(
// Error pages must commit in a unique origin. Terminate the renderer
// process if this is violated.
- if (!validated_params->origin.unique()) {
+ if (!validated_params->origin.opaque()) {
DEBUG_ALIAS_FOR_ORIGIN(origin_debug_alias, validated_params->origin);
bad_message::ReceivedBadMessage(
process, bad_message::RFH_ERROR_PROCESS_NON_UNIQUE_ORIGIN_COMMIT);
@@ -5452,7 +5642,7 @@ bool RenderFrameHostImpl::ValidateDidCommitParams(
net::ERR_BLOCKED_BY_CLIENT) {
// Since this is known to be an error page commit, verify it happened in
// a unique origin, terminating the renderer process otherwise.
- if (!validated_params->origin.unique()) {
+ if (!validated_params->origin.opaque()) {
DEBUG_ALIAS_FOR_ORIGIN(origin_debug_alias, validated_params->origin);
bad_message::ReceivedBadMessage(
process, bad_message::RFH_ERROR_PROCESS_NON_UNIQUE_ORIGIN_COMMIT);
@@ -5503,11 +5693,10 @@ bool RenderFrameHostImpl::ValidateDidCommitParams(
// be modified to take |validated_params| by const reference.
process->FilterURL(false, &validated_params->url);
process->FilterURL(true, &validated_params->referrer.url);
- for (std::vector<GURL>::iterator it(validated_params->redirects.begin());
+ for (auto it(validated_params->redirects.begin());
it != validated_params->redirects.end(); ++it) {
process->FilterURL(false, &(*it));
}
- process->FilterURL(true, &validated_params->searchable_form_url);
// Without this check, the renderer can trick the browser into using
// filenames it can't access in a future session restore.
@@ -5539,12 +5728,15 @@ bool RenderFrameHostImpl::DidCommitNavigationInternal(
if (!ValidateDidCommitParams(validated_params))
return false;
- // A racy DidStopLoading IPC might have reset the loading state that was set
- // to true in CommitNavigation. Set it to true now.
+ // Set is loading to true now if it has not been set yet. This happens for
+ // renderer-initiated same-document navigations. It can also happen when a
+ // racy DidStopLoading IPC resets the loading state that was set to true in
+ // CommitNavigation.
if (!is_loading()) {
bool was_loading = frame_tree_node()->frame_tree()->IsLoading();
is_loading_ = true;
- frame_tree_node()->DidStartLoading(true, was_loading);
+ frame_tree_node()->DidStartLoading(!is_same_document_navigation,
+ was_loading);
}
if (navigation_request_)
diff --git a/chromium/content/browser/frame_host/render_frame_host_impl.h b/chromium/content/browser/frame_host/render_frame_host_impl.h
index d71a3c050e6..a5598daa56c 100644
--- a/chromium/content/browser/frame_host/render_frame_host_impl.h
+++ b/chromium/content/browser/frame_host/render_frame_host_impl.h
@@ -18,6 +18,7 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
+#include "base/containers/flat_set.h"
#include "base/containers/id_map.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
@@ -64,7 +65,9 @@
#include "services/viz/public/interfaces/hit_test/input_target_client.mojom.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/common/frame/user_activation_update_type.h"
+#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
+#include "third_party/blink/public/mojom/frame/navigation_initiator.mojom.h"
#include "third_party/blink/public/mojom/presentation/presentation.mojom.h"
#include "third_party/blink/public/platform/dedicated_worker_factory.mojom.h"
#include "third_party/blink/public/platform/modules/bluetooth/web_bluetooth.mojom.h"
@@ -74,9 +77,10 @@
#include "third_party/blink/public/platform/web_scroll_types.h"
#include "third_party/blink/public/platform/web_sudden_termination_disabler_type.h"
#include "third_party/blink/public/web/commit_result.mojom.h"
+#include "third_party/blink/public/web/devtools_agent.mojom.h"
#include "third_party/blink/public/web/web_text_direction.h"
#include "third_party/blink/public/web/web_tree_scope_type.h"
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/mojo/window_open_disposition.mojom.h"
#include "ui/base/page_transition_types.h"
@@ -138,7 +142,6 @@ class RenderFrameHostDelegate;
class RenderFrameProxyHost;
class RenderProcessHost;
class RenderViewHostImpl;
-class RenderWidgetHostDelegate;
class RenderWidgetHostImpl;
class RenderWidgetHostView;
class RenderWidgetHostViewBase;
@@ -147,7 +150,6 @@ class TimeoutMonitor;
class WebBluetoothServiceImpl;
struct CommonNavigationParams;
struct ContextMenuParams;
-struct FileChooserParams;
struct FrameOwnerProperties;
struct PendingNavigation;
struct RequestNavigationParams;
@@ -174,8 +176,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
static const int kMaxAccessibilityResets = 5;
static RenderFrameHostImpl* FromID(int process_id, int routing_id);
- static RenderFrameHostImpl* FromAXTreeID(
- ui::AXTreeIDRegistry::AXTreeID ax_tree_id);
+ static RenderFrameHostImpl* FromAXTreeID(ui::AXTreeID ax_tree_id);
static RenderFrameHostImpl* FromOverlayRoutingToken(
const base::UnguessableToken& token);
@@ -194,11 +195,12 @@ class CONTENT_EXPORT RenderFrameHostImpl
// RenderFrameHost
int GetRoutingID() override;
- ui::AXTreeIDRegistry::AXTreeID GetAXTreeID() override;
+ ui::AXTreeID GetAXTreeID() override;
SiteInstanceImpl* GetSiteInstance() override;
RenderProcessHost* GetProcess() override;
RenderWidgetHostView* GetView() override;
RenderFrameHostImpl* GetParent() override;
+ bool IsDescendantOf(RenderFrameHost*) override;
int GetFrameTreeNodeId() override;
base::UnguessableToken GetDevToolsFrameToken() override;
const std::string& GetFrameName() override;
@@ -232,8 +234,6 @@ class CONTENT_EXPORT RenderFrameHostImpl
bool IsRenderFrameLive() override;
bool IsCurrent() override;
int GetProxyCount() override;
- void FilesSelectedInChooser(const std::vector<FileChooserFileInfo>& files,
- FileChooserParams::Mode permissions) override;
bool HasSelection() override;
void RequestTextSurroundingSelection(
const TextSurroundingSelectionCallback& callback,
@@ -253,6 +253,9 @@ class CONTENT_EXPORT RenderFrameHostImpl
const blink::WebMediaPlayerAction& action) override;
bool CreateNetworkServiceDefaultFactory(
network::mojom::URLLoaderFactoryRequest default_factory_request) override;
+ void MarkInitiatorsAsRequiringSeparateURLLoaderFactory(
+ std::vector<url::Origin> request_initiators,
+ bool push_to_renderer_now) override;
// IPC::Sender
bool Send(IPC::Message* msg) override;
@@ -343,6 +346,17 @@ class CONTENT_EXPORT RenderFrameHostImpl
RenderFrameHostDelegate* delegate() { return delegate_; }
FrameTreeNode* frame_tree_node() { return frame_tree_node_; }
+ // Methods to add/remove/reset/query child FrameTreeNodes of this frame.
+ // See class-level comment for FrameTreeNode for how the frame tree is
+ // represented.
+ size_t child_count() { return children_.size(); }
+ FrameTreeNode* child_at(size_t index) const { return children_[index].get(); }
+ FrameTreeNode* AddChild(std::unique_ptr<FrameTreeNode> child,
+ int process_id,
+ int frame_routing_id);
+ void RemoveChild(FrameTreeNode* child);
+ void ResetChildren();
+
// Allows FrameTreeNode::SetCurrentURL to update this frame's last committed
// URL. Do not call this directly, since we rely on SetCurrentURL to track
// whether a real load has committed or not.
@@ -458,7 +472,12 @@ class CONTENT_EXPORT RenderFrameHostImpl
enum class BeforeUnloadType {
BROWSER_INITIATED_NAVIGATION,
RENDERER_INITIATED_NAVIGATION,
- TAB_CLOSE
+ TAB_CLOSE,
+ // This reason is used before a tab is discarded in order to free up
+ // resources. When this is used and the handler returns a non-empty string,
+ // the confirmation dialog will not be displayed and the discard will
+ // automatically be canceled.
+ DISCARD,
};
// Runs the beforeunload handler for this frame and its subframes. |type|
@@ -469,7 +488,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
void DispatchBeforeUnload(BeforeUnloadType type, bool is_reload);
// Simulate beforeunload ack on behalf of renderer if it's unrenresponsive.
- void SimulateBeforeUnloadAck();
+ void SimulateBeforeUnloadAck(bool proceed);
// Returns true if a call to DispatchBeforeUnload will actually send the
// BeforeUnload IPC. This can be called on a main frame or subframe. If
@@ -543,8 +562,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
void UpdateAXTreeData();
// Set the AX tree ID of the embedder RFHI, if this is a browser plugin guest.
- void set_browser_plugin_embedder_ax_tree_id(
- ui::AXTreeIDRegistry::AXTreeID ax_tree_id) {
+ void set_browser_plugin_embedder_ax_tree_id(ui::AXTreeID ax_tree_id) {
browser_plugin_embedder_ax_tree_id_ = ax_tree_id;
}
@@ -702,6 +720,10 @@ class CONTENT_EXPORT RenderFrameHostImpl
// Cancels any blocked request for the frame and its subframes.
void CancelBlockedRequestsForFrame();
+ // Binds a DevToolsAgent interface for debugging.
+ void BindDevToolsAgent(blink::mojom::DevToolsAgentHostAssociatedPtrInfo host,
+ blink::mojom::DevToolsAgentAssociatedRequest request);
+
#if defined(OS_ANDROID)
base::android::ScopedJavaLocalRef<jobject> GetJavaRenderFrameHost();
service_manager::InterfaceProvider* GetJavaInterfaces() override;
@@ -763,14 +785,6 @@ class CONTENT_EXPORT RenderFrameHostImpl
// for unload handler processing.
void SetSubframeUnloadTimeoutForTesting(const base::TimeDelta& timeout);
- bool received_post_message_from_non_descendant() const {
- return received_post_message_from_non_descendant_;
- }
-
- void did_receive_post_message_from_non_descendant() {
- received_post_message_from_non_descendant_ = true;
- }
-
// Returns the list of NavigationEntry ids corresponding to NavigationRequests
// waiting to commit in this RenderFrameHost.
std::set<int> GetNavigationEntryIdsPendingCommit();
@@ -799,7 +813,6 @@ class CONTENT_EXPORT RenderFrameHostImpl
RenderFrameHostImpl(SiteInstance* site_instance,
RenderViewHostImpl* render_view_host,
RenderFrameHostDelegate* delegate,
- RenderWidgetHostDelegate* rwh_delegate,
FrameTree* frame_tree,
FrameTreeNode* frame_tree_node,
int32_t routing_id,
@@ -869,10 +882,6 @@ class CONTENT_EXPORT RenderFrameHostImpl
void OnFrameFocused();
void OnOpenURL(const FrameHostMsg_OpenURL_Params& params);
void OnDocumentOnLoadCompleted();
- void OnDidStartProvisionalLoad(
- const GURL& url,
- const std::vector<GURL>& redirect_chain,
- const base::TimeTicks& navigation_start);
void OnDidFailProvisionalLoadWithError(
const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params);
void OnDidFailLoadWithError(const GURL& url,
@@ -893,7 +902,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
JavaScriptDialogType dialog_type,
IPC::Message* reply_msg);
void OnRunBeforeUnloadConfirm(bool is_reload, IPC::Message* reply_msg);
- void OnRunFileChooser(const FileChooserParams& params);
+ void OnRunFileChooser(const blink::mojom::FileChooserParams& params);
void OnTextSurroundingSelectionResponse(const base::string16& content,
uint32_t start_offset,
uint32_t end_offset);
@@ -938,7 +947,6 @@ class CONTENT_EXPORT RenderFrameHostImpl
void OnSuddenTerminationDisablerChanged(
bool present,
blink::WebSuddenTerminationDisablerType disabler_type);
- void OnDidStartLoading(bool to_different_document);
void OnDidStopLoading();
void OnDidChangeLoadProgress(double load_progress);
void OnSerializeAsMHTMLResponse(
@@ -995,7 +1003,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
const CommonNavigationParams& common_params,
mojom::BeginNavigationParamsPtr begin_params,
blink::mojom::BlobURLTokenPtr blob_url_token,
- mojom::NavigationClientAssociatedPtrInfo navigation_client) override;
+ mojom::NavigationClientAssociatedPtrInfo navigation_client,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator) override;
void SubresourceResponseStarted(const GURL& url,
net::CertStatus cert_status) override;
void ResourceLoadComplete(
@@ -1012,6 +1021,9 @@ class CONTENT_EXPORT RenderFrameHostImpl
void UpdateEncoding(const std::string& encoding) override;
void FrameSizeChanged(const gfx::Size& frame_size) override;
void FullscreenStateChanged(bool is_fullscreen) override;
+#if defined(OS_ANDROID)
+ void UpdateUserGestureCarryoverInfo() override;
+#endif
// Registers Mojo interfaces that this frame host makes available.
void RegisterMojoInterfaces();
@@ -1058,16 +1070,19 @@ class CONTENT_EXPORT RenderFrameHostImpl
// |OnNetworkServiceConnectionError()| if the factory is out-of-process. If
// this returns true, any redirect safety checks should be bypassed in
// downstream loaders.
- // |url| is the URL that the RenderFrame is either committing (in the case of
- // navigation) or has last committed (when handling network process crashes).
+ //
+ // |origin| is the origin that the RenderFrame is either committing (in the
+ // case of navigation) or has last committed (when handling network process
+ // crashes).
bool CreateNetworkServiceDefaultFactoryAndObserve(
- const GURL& url,
+ const url::Origin& origin,
network::mojom::URLLoaderFactoryRequest default_factory_request);
- // |url| is the URL that the RenderFrame is either committing (in the case of
- // navigation) or has last committed (when handling network process crashes).
+ // |origin| is the origin that the RenderFrame is either committing (in the
+ // case of navigation) or has last committed (when handling network process
+ // crashes).
bool CreateNetworkServiceDefaultFactoryInternal(
- const GURL& url,
+ const url::Origin& origin,
network::mojom::URLLoaderFactoryRequest default_factory_request);
// Returns true if the ExecuteJavaScript() API can be used on this host.
@@ -1075,12 +1090,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
// Map a routing ID from a frame in the same frame tree to a globally
// unique AXTreeID.
- ui::AXTreeIDRegistry::AXTreeID RoutingIDToAXTreeID(int routing_id);
+ ui::AXTreeID RoutingIDToAXTreeID(int routing_id);
// Map a browser plugin instance ID to the AXTreeID of the plugin's
// main frame.
- ui::AXTreeIDRegistry::AXTreeID BrowserPluginInstanceIDToAXTreeID(
- int routing_id);
+ ui::AXTreeID BrowserPluginInstanceIDToAXTreeID(int routing_id);
// Convert the content-layer-specific AXContentNodeData to a general-purpose
// AXNodeData structure.
@@ -1296,6 +1310,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
std::unique_ptr<base::trace_event::TracedValue> CommitAsTracedValue(
FrameHostMsg_DidCommitProvisionalLoad_Params* validated_params) const;
+ // Creates initiator-specific URLLoaderFactory objects for intiator origins
+ // registered via MarkInitiatorAsRequiringSeparateURLLoaderFactory method.
+ URLLoaderFactoryBundleInfo::OriginMap
+ CreateInitiatorSpecificURLLoaderFactories();
+
// For now, RenderFrameHosts indirectly keep RenderViewHosts alive via a
// refcount that calls Shutdown when it reaches zero. This allows each
// RenderFrameHostManager to just care about RenderFrameHosts, while ensuring
@@ -1327,6 +1346,9 @@ class CONTENT_EXPORT RenderFrameHostImpl
// The FrameTreeNode which this RenderFrameHostImpl is hosted in.
FrameTreeNode* const frame_tree_node_;
+ // The immediate children of this specific frame.
+ std::vector<std::unique_ptr<FrameTreeNode>> children_;
+
// The active parent RenderFrameHost for this frame, if it is a subframe.
// Null for the main frame. This is cached because the parent FrameTreeNode
// may change its current RenderFrameHost while this child is pending
@@ -1384,6 +1406,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
// machine.
bool is_waiting_for_beforeunload_ack_;
+ // Valid only when |is_waiting_for_beforeunload_ack_| is true. This indicates
+ // whether a subsequent request to launch a modal dialog should be honored or
+ // whether it should implicitly cause the unload to be canceled.
+ bool beforeunload_dialog_request_cancels_unload_;
+
// Valid only when is_waiting_for_beforeunload_ack_ or
// IsWaitingForUnloadACK is true. This tells us if the unload request
// is for closing the entire tab ( = false), or only this RenderFrameHost in
@@ -1429,12 +1456,6 @@ class CONTENT_EXPORT RenderFrameHostImpl
// relevant NavigationEntry.
int nav_entry_id_;
- // Tracks if a frame has been influenced by post message from
- // non-descendant frames. Useful for determining if silently reloading a
- // crashed frame is safe. Post messages from descendants to not matter for
- // this decision since they will be reloaded as well.
- bool received_post_message_from_non_descendant_ = false;
-
// Used to swap out or shut down this RFH when the unload event is taking too
// long to execute, depending on the number of active frames in the
// SiteInstance. May be null in tests.
@@ -1469,11 +1490,10 @@ class CONTENT_EXPORT RenderFrameHostImpl
AXContentTreeData ax_content_tree_data_;
// The AX tree ID of this frame.
- ui::AXTreeIDRegistry::AXTreeID ax_tree_id_ =
- ui::AXTreeIDRegistry::kNoAXTreeID;
+ ui::AXTreeID ax_tree_id_ = ui::AXTreeIDUnknown();
// The AX tree ID of the embedder, if this is a browser plugin guest.
- ui::AXTreeIDRegistry::AXTreeID browser_plugin_embedder_ax_tree_id_;
+ ui::AXTreeID browser_plugin_embedder_ax_tree_id_;
// The mapping from callback id to corresponding callback for pending
// accessibility tree snapshot calls created by RequestAXTreeSnapshot.
@@ -1614,6 +1634,10 @@ class CONTENT_EXPORT RenderFrameHostImpl
// Hosts blink::mojom::PresentationService for the RenderFrame.
std::unique_ptr<PresentationServiceImpl> presentation_service_;
+ // Hosts blink::mojom::FileSystemManager for the RenderFrame.
+ std::unique_ptr<FileSystemManagerImpl, BrowserThread::DeleteOnIOThread>
+ file_system_manager_;
+
#if !defined(OS_ANDROID)
std::unique_ptr<AuthenticatorImpl> authenticator_impl_;
#endif
@@ -1708,6 +1732,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
network::mojom::URLLoaderFactoryPtr
network_service_connection_error_handler_holder_;
+ // Set of request-initiator-origins that require a separate URLLoaderFactory
+ // (e.g. for handling requests initiated by extension content scripts that
+ // require relaxed CORS/CORB rules).
+ base::flat_set<url::Origin> initiators_requiring_separate_url_loader_factory_;
+
// Holds the renderer generated ID and global request ID for the main frame
// request.
std::pair<int, GlobalRequestID> main_frame_request_ids_;
diff --git a/chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc
index bea486b54d1..9517e95efbb 100644
--- a/chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
@@ -202,14 +203,22 @@ class TestJavaScriptDialogManager : public JavaScriptDialogManager,
: message_loop_runner_(new MessageLoopRunner), url_invalidate_count_(0) {}
~TestJavaScriptDialogManager() override {}
+ // This waits until either WCD::BeforeUnloadFired is called (the unload has
+ // been handled) or JSDM::RunJavaScriptDialog/RunBeforeUnloadDialog is called
+ // (a request to display a dialog has been received).
void Wait() {
message_loop_runner_->Run();
message_loop_runner_ = new MessageLoopRunner;
}
- DialogClosedCallback& callback() { return callback_; }
+ // Runs the dialog callback.
+ void Run(bool success, const base::string16& user_input) {
+ std::move(callback_).Run(success, user_input);
+ }
int num_beforeunload_dialogs_seen() { return num_beforeunload_dialogs_seen_; }
+ int num_beforeunload_fired_seen() { return num_beforeunload_fired_seen_; }
+ bool proceed() { return proceed_; }
// WebContentsDelegate
@@ -218,6 +227,14 @@ class TestJavaScriptDialogManager : public JavaScriptDialogManager,
return this;
}
+ void BeforeUnloadFired(WebContents* tab,
+ bool proceed,
+ bool* proceed_to_fire_unload) override {
+ ++num_beforeunload_fired_seen_;
+ proceed_ = proceed;
+ message_loop_runner_->Quit();
+ }
+
// JavaScriptDialogManager
void RunJavaScriptDialog(WebContents* web_contents,
@@ -226,7 +243,10 @@ class TestJavaScriptDialogManager : public JavaScriptDialogManager,
const base::string16& message_text,
const base::string16& default_prompt_text,
DialogClosedCallback callback,
- bool* did_suppress_message) override {}
+ bool* did_suppress_message) override {
+ callback_ = std::move(callback);
+ message_loop_runner_->Quit();
+ }
void RunBeforeUnloadDialog(WebContents* web_contents,
RenderFrameHost* render_frame_host,
@@ -268,6 +288,13 @@ class TestJavaScriptDialogManager : public JavaScriptDialogManager,
// The total number of beforeunload dialogs seen by this dialog manager.
int num_beforeunload_dialogs_seen_ = 0;
+ // The total number of BeforeUnloadFired events witnessed by the
+ // WebContentsDelegate.
+ int num_beforeunload_fired_seen_ = 0;
+
+ // The |proceed| value returned by the last unload event.
+ bool proceed_ = false;
+
DISALLOW_COPY_AND_ASSIGN(TestJavaScriptDialogManager);
};
@@ -339,7 +366,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
main_frame->GetProcess()->AddFilter(filter.get());
// Answer the dialog.
- std::move(dialog_manager.callback()).Run(true, base::string16());
+ dialog_manager.Run(true, base::string16());
// There will be no beforeunload ACK, so if the beforeunload ACK timer isn't
// functioning then the navigation will hang forever and this test will time
@@ -378,7 +405,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
dialog_manager.Wait();
// Answer the dialog.
- std::move(dialog_manager.callback()).Run(true, base::string16());
+ dialog_manager.Run(true, base::string16());
EXPECT_TRUE(WaitForLoadStop(wc));
// The reload should have cleared the user gesture bit, so upon leaving again
@@ -409,7 +436,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
// Cancel the dialog.
dialog_manager.reset_url_invalidate_count();
- std::move(dialog_manager.callback()).Run(false, base::string16());
+ dialog_manager.Run(false, base::string16());
EXPECT_FALSE(wc->IsLoading());
// Verify there are no pending history items after the dialog is cancelled.
@@ -447,13 +474,13 @@ class RenderFrameHostImplBeforeUnloadBrowserTest
}
void CloseDialogAndProceed() {
- std::move(dialog_manager()->callback())
- .Run(true /* navigation should proceed */, base::string16());
+ dialog_manager_->Run(true /* navigation should proceed */,
+ base::string16());
}
void CloseDialogAndCancel() {
- std::move(dialog_manager()->callback())
- .Run(false /* navigation should proceed */, base::string16());
+ dialog_manager_->Run(false /* navigation should proceed */,
+ base::string16());
}
// Installs a beforeunload handler in the given frame.
@@ -953,7 +980,7 @@ class ExecuteScriptBeforeRenderFrameDeletedHelper
//
// Note that if the second WebContents scheduled a call to window.close() to
// close itself after it calls window.open(), the CreateNewWindow sync IPC could
-// be dispatched *before* ViewHostMsg_Close in the browser process, provided
+// be dispatched *before* WidgetHostMsg_Close in the browser process, provided
// that the browser happened to be in IPC::SyncChannel::WaitForReply on the UI
// thread (most likely after sending GpuCommandBufferMsg_* messages), in which
// case incoming sync IPCs to this thread are dispatched, but the message loop
@@ -1874,6 +1901,77 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
}
IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
+ BeforeUnloadDialogSuppressedForDiscard) {
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
+ TestJavaScriptDialogManager dialog_manager;
+ wc->SetDelegate(&dialog_manager);
+
+ EXPECT_TRUE(NavigateToURL(
+ shell(), GetTestUrl("render_frame_host", "beforeunload.html")));
+ // Disable the hang monitor, otherwise there will be a race between the
+ // beforeunload dialog and the beforeunload hang timer.
+ wc->GetMainFrame()->DisableBeforeUnloadHangMonitorForTesting();
+
+ // Give the page a user gesture so javascript beforeunload works, and then
+ // dispatch a before unload with discard as a reason. This should return
+ // without any dialog being seen.
+ wc->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
+ base::string16());
+ wc->GetMainFrame()->DispatchBeforeUnload(
+ RenderFrameHostImpl::BeforeUnloadType::DISCARD, false);
+ dialog_manager.Wait();
+ EXPECT_EQ(0, dialog_manager.num_beforeunload_dialogs_seen());
+ EXPECT_EQ(1, dialog_manager.num_beforeunload_fired_seen());
+ EXPECT_FALSE(dialog_manager.proceed());
+
+ wc->SetDelegate(nullptr);
+ wc->SetJavaScriptDialogManagerForTesting(nullptr);
+}
+
+IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
+ PendingDialogMakesDiscardUnloadReturnFalse) {
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
+ TestJavaScriptDialogManager dialog_manager;
+ wc->SetDelegate(&dialog_manager);
+
+ EXPECT_TRUE(NavigateToURL(
+ shell(), GetTestUrl("render_frame_host", "beforeunload.html")));
+ // Disable the hang monitor, otherwise there will be a race between the
+ // beforeunload dialog and the beforeunload hang timer.
+ wc->GetMainFrame()->DisableBeforeUnloadHangMonitorForTesting();
+
+ // Give the page a user gesture so javascript beforeunload works, and then
+ // dispatch a before unload with discard as a reason. This should return
+ // without any dialog being seen.
+ wc->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
+ base::string16());
+
+ // Launch an alert javascript dialog. This pending dialog should block a
+ // subsequent discarding before unload request.
+ wc->GetMainFrame()->ExecuteJavaScriptForTests(
+ base::ASCIIToUTF16("setTimeout(function(){alert('hello');}, 10);"));
+ dialog_manager.Wait();
+ EXPECT_EQ(0, dialog_manager.num_beforeunload_dialogs_seen());
+ EXPECT_EQ(0, dialog_manager.num_beforeunload_fired_seen());
+
+ // Dispatch a before unload request while the first is still blocked
+ // on the dialog, and expect it to return false immediately (synchronously).
+ wc->GetMainFrame()->DispatchBeforeUnload(
+ RenderFrameHostImpl::BeforeUnloadType::DISCARD, false);
+ dialog_manager.Wait();
+ EXPECT_EQ(0, dialog_manager.num_beforeunload_dialogs_seen());
+ EXPECT_EQ(1, dialog_manager.num_beforeunload_fired_seen());
+ EXPECT_FALSE(dialog_manager.proceed());
+
+ // Clear the existing javascript dialog so that the associated IPC message
+ // doesn't leak.
+ dialog_manager.Run(true, base::string16());
+
+ wc->SetDelegate(nullptr);
+ wc->SetJavaScriptDialogManagerForTesting(nullptr);
+}
+
+IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest,
NotifiesProcessHostOfAudibleAudio) {
const auto RunPostedTasks = []() {
base::RunLoop run_loop;
diff --git a/chromium/content/browser/frame_host/render_frame_host_manager.cc b/chromium/content/browser/frame_host/render_frame_host_manager.cc
index 49ad391a313..69913022bb1 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_manager.cc
@@ -68,15 +68,10 @@ bool IsDataOrAbout(const GURL& url) {
} // namespace
-RenderFrameHostManager::RenderFrameHostManager(
- FrameTreeNode* frame_tree_node,
- RenderFrameHostDelegate* render_frame_delegate,
- RenderWidgetHostDelegate* render_widget_delegate,
- Delegate* delegate)
+RenderFrameHostManager::RenderFrameHostManager(FrameTreeNode* frame_tree_node,
+ Delegate* delegate)
: frame_tree_node_(frame_tree_node),
delegate_(delegate),
- render_frame_delegate_(render_frame_delegate),
- render_widget_delegate_(render_widget_delegate),
weak_factory_(this) {
DCHECK(frame_tree_node_);
}
@@ -213,7 +208,7 @@ void RenderFrameHostManager::SetIsLoading(bool is_loading) {
void RenderFrameHostManager::OnBeforeUnloadACK(
bool proceed,
const base::TimeTicks& proceed_time) {
- bool proceed_to_fire_unload;
+ bool proceed_to_fire_unload = false;
delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time,
&proceed_to_fire_unload);
@@ -451,9 +446,8 @@ void RenderFrameHostManager::DiscardUnusedFrame(
bool RenderFrameHostManager::DeleteFromPendingList(
RenderFrameHostImpl* render_frame_host) {
- for (RFHPendingDeleteList::iterator iter = pending_delete_hosts_.begin();
- iter != pending_delete_hosts_.end();
- iter++) {
+ for (auto iter = pending_delete_hosts_.begin();
+ iter != pending_delete_hosts_.end(); iter++) {
if (iter->get() == render_frame_host) {
pending_delete_hosts_.erase(iter);
return true;
@@ -654,8 +648,10 @@ RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
// RenderFrameHostManager are completely initialized. This should be
// removed once the process manager moves away from NotificationService.
// See https://crbug.com/462682.
- delegate_->NotifyMainFrameSwappedFromRenderManager(
- nullptr, render_frame_host_.get());
+ if (frame_tree_node_->IsMainFrame()) {
+ delegate_->NotifyMainFrameSwappedFromRenderManager(
+ nullptr, render_frame_host_.get());
+ }
}
}
@@ -1079,8 +1075,16 @@ RenderFrameHostManager::GetSiteInstanceForNavigation(
static_cast<SiteInstanceImpl*>(new_instance.get());
if (!frame_tree_node_->IsMainFrame() && !new_instance_impl->HasProcess() &&
new_instance_impl->RequiresDedicatedProcess()) {
- new_instance_impl->set_process_reuse_policy(
- SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE);
+ // Also give the embedder a chance to override this decision. Certain
+ // frames have different enough workloads so that it's better to avoid
+ // placing a subframe into an existing process for better performance
+ // isolation. See https://crbug.com/899418.
+ if (GetContentClient()->browser()->ShouldSubframesTryToReuseExistingProcess(
+ frame_tree_node_->frame_tree()->GetMainFrame())) {
+ new_instance_impl->set_process_reuse_policy(
+ SiteInstanceImpl::ProcessReusePolicy::
+ REUSE_PENDING_OR_COMMITTED_SITE);
+ }
}
return new_instance;
@@ -1113,8 +1117,10 @@ void RenderFrameHostManager::InitializeRenderFrameIfNecessary(
// RenderFrameHostManager are completely initialized. This should be
// removed once the process manager moves away from NotificationService.
// See https://crbug.com/462682.
- delegate_->NotifyMainFrameSwappedFromRenderManager(nullptr,
- render_frame_host_.get());
+ if (frame_tree_node_->IsMainFrame()) {
+ delegate_->NotifyMainFrameSwappedFromRenderManager(
+ nullptr, render_frame_host_.get());
+ }
}
RenderFrameHostManager::SiteInstanceDescriptor
@@ -1358,29 +1364,10 @@ RenderFrameHostManager::DetermineSiteInstanceForURL(
return SiteInstanceDescriptor(opener_frame->GetSiteInstance());
}
- if (!frame_tree_node_->IsMainFrame() &&
- SiteIsolationPolicy::IsTopDocumentIsolationEnabled() &&
- !SiteInstanceImpl::DoesSiteRequireDedicatedProcess(browser_context,
- dest_url)) {
- if (GetContentClient()
- ->browser()
- ->ShouldFrameShareParentSiteInstanceDespiteTopDocumentIsolation(
- dest_url, current_instance)) {
- return SiteInstanceDescriptor(render_frame_host_->GetSiteInstance());
- }
-
- // This is a cross-site subframe of a non-isolated origin, so place this
- // frame in the default subframe site instance.
- return SiteInstanceDescriptor(
- browser_context, dest_url,
- SiteInstanceRelation::RELATED_DEFAULT_SUBFRAME);
- }
-
// Keep subframes in the parent's SiteInstance unless a dedicated process is
// required for either the parent or the subframe's destination URL. This
// isn't a strict invariant but rather a heuristic to avoid unnecessary
- // OOPIFs; see https://crbug.com/711006. Note that this shouldn't apply to
- // TopDocumentIsolation, so do this after TDI checks above.
+ // OOPIFs; see https://crbug.com/711006.
//
// TODO(alexmos): Remove this check after fixing https://crbug.com/787576.
if (!frame_tree_node_->IsMainFrame()) {
@@ -1441,21 +1428,23 @@ bool RenderFrameHostManager::IsBrowsingInstanceSwapAllowedForPageTransition(
bool RenderFrameHostManager::IsRendererTransferNeededForNavigation(
RenderFrameHostImpl* rfh,
const GURL& dest_url) {
- // A transfer is not needed if the current SiteInstance doesn't yet have a
- // site. This is the case for tests that use NavigateToURL.
- //
- // One exception is that a siteless SiteInstance may still have a process,
- // which might be unsuitable for |dest_url|. For example, another navigation
- // could share that process (e.g., when over process limit) and lock it to a
- // different origin before this SiteInstance sets its site. Hence, we also
- // check for cases like this. See https://crbug.com/773809.
+ // Always attempt a process transfer if the SiteInstance has a process that's
+ // unsuitable for |dest_url|. For example, this might happen when reloading
+ // a URL for which a hosted app was just installed or uninstalled.
//
- // TODO(alexmos): We should always check HasWrongProcessForURL regardless of
- // HasSite, but currently we cannot do that because of hosted app workarounds
- // (see https://crbug.com/92669). Revisit this once hosted apps swap
- // processes for cross-site web iframes and popups.
+ // This might also happen for a siteless SiteInstance which may have a
+ // process that's unsuitable for |dest_url|. For example, another navigation
+ // could share that process when over process limit and lock it to a
+ // different site before this SiteInstance sets its site. See
+ // https://crbug.com/773809.
+ if (rfh->GetSiteInstance()->HasWrongProcessForURL(dest_url))
+ return true;
+
+ // A transfer is not needed if the current SiteInstance doesn't yet have a
+ // site. For example, this happens when tests use NavigateToURL or when
+ // navigating a blank window in some cases.
if (!rfh->GetSiteInstance()->HasSite())
- return rfh->GetSiteInstance()->HasWrongProcessForURL(dest_url);
+ return false;
// We do not currently swap processes for navigations in webview tag guests.
if (rfh->GetSiteInstance()->GetSiteURL().SchemeIs(kGuestScheme))
@@ -1479,13 +1468,6 @@ bool RenderFrameHostManager::IsRendererTransferNeededForNavigation(
return true;
}
- if (SiteIsolationPolicy::IsTopDocumentIsolationEnabled() &&
- (!frame_tree_node_->IsMainFrame() ||
- rfh->GetSiteInstance()->IsDefaultSubframeSiteInstance())) {
- // Always attempt a transfer in these cases.
- return true;
- }
-
// If the destination URL is not same-site with current RenderFrameHost and
// doesn't require a dedicated process (see above), but it is same-site with
// the opener RenderFrameHost, attempt a transfer so that the destination URL
@@ -1518,9 +1500,6 @@ scoped_refptr<SiteInstance> RenderFrameHostManager::ConvertToSiteInstance(
if (descriptor.relation == SiteInstanceRelation::RELATED)
return current_instance->GetRelatedSiteInstance(descriptor.dest_url);
- if (descriptor.relation == SiteInstanceRelation::RELATED_DEFAULT_SUBFRAME)
- return current_instance->GetDefaultSubframeSiteInstance();
-
// At this point we know an unrelated site instance must be returned. First
// check if the candidate matches.
if (candidate_instance &&
@@ -1597,7 +1576,7 @@ bool RenderFrameHostManager::IsCurrentlySameSite(RenderFrameHostImpl* candidate,
// It is possible that last_successful_url() was a nonstandard scheme (for
// example, "about:blank"). If so, examine the replicated origin to determine
// the site.
- if (!candidate->GetLastCommittedOrigin().unique() &&
+ if (!candidate->GetLastCommittedOrigin().opaque() &&
SiteInstanceImpl::IsSameWebSite(
browser_context,
GURL(candidate->GetLastCommittedOrigin().Serialize()), dest_url,
@@ -1612,7 +1591,7 @@ bool RenderFrameHostManager::IsCurrentlySameSite(RenderFrameHostImpl* candidate,
// tests rely on that behavior. To accomplish this, compare |dest_url|
// against the site URL.
if (candidate->last_successful_url().IsAboutBlank() &&
- candidate->GetLastCommittedOrigin().unique() &&
+ candidate->GetLastCommittedOrigin().opaque() &&
SiteInstanceImpl::IsSameWebSite(
browser_context, candidate->GetSiteInstance()->original_url(),
dest_url, should_compare_effective_urls)) {
@@ -1706,9 +1685,9 @@ RenderFrameHostManager::CreateRenderFrameHost(
}
return RenderFrameHostFactory::Create(
- site_instance, render_view_host, render_frame_delegate_,
- render_widget_delegate_, frame_tree, frame_tree_node_, frame_routing_id,
- widget_routing_id, hidden, renderer_initiated_creation);
+ site_instance, render_view_host, frame_tree->render_frame_delegate(),
+ frame_tree, frame_tree_node_, frame_routing_id, widget_routing_id, hidden,
+ renderer_initiated_creation);
}
bool RenderFrameHostManager::CreateSpeculativeRenderFrameHost(
@@ -1958,9 +1937,19 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
// navigation should use the current SiteInstance.
SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance();
bool no_renderer_swap_allowed = false;
+ bool should_swap_for_error_isolation = false;
bool was_server_redirect = request.navigation_handle() &&
request.navigation_handle()->WasServerRedirect();
+ // When error page isolation is enabled, each navigation that crosses
+ // from a success to failure and vice versa needs to do a process swap.
+ if (SiteIsolationPolicy::IsErrorPageIsolationEnabled(
+ frame_tree_node_->IsMainFrame())) {
+ should_swap_for_error_isolation =
+ (request.state() == NavigationRequest::FAILED) !=
+ (current_site_instance->GetSiteURL() == GURL(kUnreachableWebDataURL));
+ }
+
if (frame_tree_node_->IsMainFrame()) {
// Renderer-initiated main frame navigations that may require a
// SiteInstance swap are sent to the browser via the OpenURL IPC and are
@@ -1968,16 +1957,12 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
// marked as renderer-initiated are created by receiving a BeginNavigation
// IPC, and will then proceed in the same renderer. In site-per-process
// mode, it is possible for renderer-intiated navigations to be allowed to
- // go cross-process. Main frame navigations resulting in an error are also
- // expected to change process. Check it first.
+ // go cross-process. Check it first.
bool can_renderer_initiate_transfer =
- (request.state() == NavigationRequest::FAILED &&
- SiteIsolationPolicy::IsErrorPageIsolationEnabled(
- true /* in_main_frame */)) ||
- (render_frame_host_->IsRenderFrameLive() &&
- IsURLHandledByNetworkStack(request.common_params().url) &&
- IsRendererTransferNeededForNavigation(render_frame_host_.get(),
- request.common_params().url));
+ render_frame_host_->IsRenderFrameLive() &&
+ IsURLHandledByNetworkStack(request.common_params().url) &&
+ IsRendererTransferNeededForNavigation(render_frame_host_.get(),
+ request.common_params().url);
no_renderer_swap_allowed |=
request.from_begin_navigation() && !can_renderer_initiate_transfer;
} else {
@@ -1988,7 +1973,7 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
request.dest_site_instance());
}
- if (no_renderer_swap_allowed)
+ if (no_renderer_swap_allowed && !should_swap_for_error_isolation)
return scoped_refptr<SiteInstance>(current_site_instance);
// If the navigation can swap SiteInstances, compute the SiteInstance it
@@ -2169,7 +2154,9 @@ void RenderFrameHostManager::CommitPending() {
// Removing them when they are deleted is too late.
// This needs to be done before updating the frame tree structure, else it
// will have trouble removing the descendants.
- render_frame_delegate_->FullscreenStateChanged(current_frame_host(), false);
+ frame_tree_node_->frame_tree()
+ ->render_frame_delegate()
+ ->FullscreenStateChanged(current_frame_host(), false);
// While the old frame is still current, remove its children from the tree.
frame_tree_node_->ResetForNewProcess();
@@ -2574,7 +2561,7 @@ bool RenderFrameHostManager::CanSubframeSwapProcess(
// If dest_url is a unique origin like about:blank, then the need for a swap
// is determined by the source_instance or dest_instance.
GURL resolved_url = dest_url;
- if (url::Origin::Create(resolved_url).unique()) {
+ if (url::Origin::Create(resolved_url).opaque()) {
if (source_instance) {
resolved_url = source_instance->GetSiteURL();
} else if (dest_instance) {
diff --git a/chromium/content/browser/frame_host/render_frame_host_manager.h b/chromium/content/browser/frame_host/render_frame_host_manager.h
index d8cf377f4e2..0ce014d0f9f 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager.h
+++ b/chromium/content/browser/frame_host/render_frame_host_manager.h
@@ -17,7 +17,6 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
-#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/site_instance_impl.h"
#include "content/common/content_export.h"
#include "content/public/browser/global_request_id.h"
@@ -34,12 +33,10 @@ class NavigationControllerImpl;
class NavigationEntry;
class NavigationRequest;
class NavigatorTestWithBrowserSideNavigation;
-class RenderFrameHostDelegate;
class RenderFrameHostManagerTest;
class RenderFrameProxyHost;
class RenderViewHost;
class RenderViewHostImpl;
-class RenderWidgetHostDelegate;
class RenderWidgetHostView;
class TestWebContents;
class WebUIImpl;
@@ -176,17 +173,11 @@ class CONTENT_EXPORT RenderFrameHostManager
virtual ~Delegate() {}
};
- // All three delegate pointers must be non-NULL and are not owned by this
- // class. They must outlive this class. The RenderViewHostDelegate and
- // RenderWidgetHostDelegate are what will be installed into all
- // RenderViewHosts that are created.
+ // The delegate pointer must be non-NULL and is not owned by this class. It
+ // must outlive this class.
//
// You must call Init() before using this class.
- RenderFrameHostManager(
- FrameTreeNode* frame_tree_node,
- RenderFrameHostDelegate* render_frame_delegate,
- RenderWidgetHostDelegate* render_widget_delegate,
- Delegate* delegate);
+ RenderFrameHostManager(FrameTreeNode* frame_tree_node, Delegate* delegate);
~RenderFrameHostManager();
// For arguments, see WebContentsImpl constructor.
@@ -504,8 +495,6 @@ class CONTENT_EXPORT RenderFrameHostManager
UNRELATED,
// A SiteInstance in the same browsing instance as the current.
RELATED,
- // The default subframe SiteInstance for the current browsing instance.
- RELATED_DEFAULT_SUBFRAME,
};
// Stores information regarding a SiteInstance targeted at a specific URL to
@@ -747,11 +736,6 @@ class CONTENT_EXPORT RenderFrameHostManager
// Our delegate, not owned by us. Guaranteed non-NULL.
Delegate* delegate_;
- // Implemented by the owner of this class. These delegates are installed into
- // all the RenderFrameHosts that we create.
- RenderFrameHostDelegate* render_frame_delegate_;
- RenderWidgetHostDelegate* render_widget_delegate_;
-
// Our RenderFrameHost which is responsible for all communication with a child
// RenderFrame instance.
// For now, RenderFrameHost keeps a RenderViewHost in its SiteInstance alive.
diff --git a/chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc
index a6821503c3e..aa292b7a734 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -37,7 +37,6 @@
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
@@ -2372,6 +2371,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, WebUIGetsBindings) {
EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
shell()->web_contents()->GetMainFrame()->GetProcess()->GetID()));
SiteInstance* site_instance1 = shell()->web_contents()->GetSiteInstance();
+ int process1_id = site_instance1->GetProcess()->GetID();
// Open a new tab. Initially it gets a render view in the original tab's
// current site instance.
@@ -2384,9 +2384,14 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, WebUIGetsBindings) {
WebContentsImpl* new_web_contents = static_cast<WebContentsImpl*>(
new_shell->web_contents());
SiteInstance* site_instance2 = new_web_contents->GetSiteInstance();
+ int process2_id = site_instance2->GetProcess()->GetID();
+ // The 2nd WebUI page should swap to a different process (and SiteInstance),
+ // but should stay in the same BrowsingInstance as the 1st WebUI page.
+ EXPECT_NE(process1_id, process2_id);
EXPECT_NE(site_instance2, site_instance1);
EXPECT_TRUE(site_instance2->IsRelatedSiteInstance(site_instance1));
+
RenderViewHost* initial_rvh = new_web_contents->
GetRenderManagerForTesting()->GetSwappedOutRenderViewHost(site_instance1);
ASSERT_TRUE(initial_rvh);
@@ -3009,16 +3014,15 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Navigate again to the original site, but to a page that will take a while
// to commit.
GURL same_site_url(embedded_test_server()->GetURL("a.com", "/title3.html"));
- NavigationStallDelegate stall_delegate(same_site_url);
- ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
+ TestNavigationManager stalled_navigation(new_shell->web_contents(),
+ same_site_url);
new_shell->LoadURL(same_site_url);
+ EXPECT_TRUE(stalled_navigation.WaitForRequestStart());
// Going back in history should work and the test should not crash.
TestNavigationObserver back_nav_load_observer(new_shell->web_contents());
new_shell->web_contents()->GetController().GoBack();
back_nav_load_observer.Wait();
-
- ResourceDispatcherHost::Get()->SetDelegate(nullptr);
}
// Tests that InputMsg type IPCs are ignored by swapped out RenderViews. It
@@ -3273,9 +3277,10 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Start a cross-site navigation to the same site but don't commit.
GURL cross_site_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
- NavigationStallDelegate stall_delegate(cross_site_url);
- ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
+ TestNavigationManager stalled_navigation(shell()->web_contents(),
+ cross_site_url);
shell()->LoadURL(cross_site_url);
+ EXPECT_TRUE(stalled_navigation.WaitForResponse());
WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
shell()->web_contents());
@@ -3295,8 +3300,6 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
EXPECT_EQ(next_rfh, web_contents->GetMainFrame());
EXPECT_FALSE(
web_contents->GetRenderManagerForTesting()->speculative_frame_host());
-
- ResourceDispatcherHost::Get()->SetDelegate(nullptr);
}
// Check that if a sandboxed subframe opens a cross-process popup such that the
@@ -3353,11 +3356,11 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
EXPECT_NE(new_shell->web_contents()->GetSiteInstance(),
shell()->web_contents()->GetSiteInstance());
- // Check that the popup is sandboxed by checking its document.origin, which
+ // Check that the popup is sandboxed by checking its self.origin, which
// should be unique.
std::string origin;
EXPECT_TRUE(ExecuteScriptAndExtractString(
- new_shell, "domAutomationController.send(document.origin)", &origin));
+ new_shell, "domAutomationController.send(self.origin)", &origin));
EXPECT_EQ("null", origin);
};
diff --git a/chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc b/chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc
index bc5e48e26e0..a5e33ca7eb5 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -450,7 +450,8 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
manager->frame_tree_node_, frame_entry->url(),
frame_entry->referrer(), *frame_entry, entry, navigate_type,
PREVIEWS_UNSPECIFIED, false, false, nullptr, base::TimeTicks::Now(),
- controller, nullptr);
+ controller, nullptr, base::TimeTicks(),
+ WasActivatedOption::kUnknown);
// Simulates request creation that triggers the 1st internal call to
// GetFrameHostForNavigation.
@@ -2823,7 +2824,8 @@ TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation,
frame_entry->referrer(), *frame_entry, entry,
FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT, PREVIEWS_UNSPECIFIED,
false, false, nullptr, base::TimeTicks::Now(),
- static_cast<NavigationControllerImpl*>(&controller()), nullptr);
+ static_cast<NavigationControllerImpl*>(&controller()), nullptr,
+ base::TimeTicks(), WasActivatedOption::kUnknown);
manager->DidCreateNavigationRequest(navigation_request.get());
// As the initial RenderFrame was not live, the new RenderFrameHost should be
@@ -2885,7 +2887,8 @@ TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation,
frame_entry->referrer(), *frame_entry, entry,
FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT, PREVIEWS_UNSPECIFIED,
false, false, nullptr, base::TimeTicks::Now(),
- static_cast<NavigationControllerImpl*>(&controller()), nullptr);
+ static_cast<NavigationControllerImpl*>(&controller()), nullptr,
+ base::TimeTicks(), WasActivatedOption::kUnknown);
manager->DidCreateNavigationRequest(navigation_request.get());
// The current WebUI should still be in place and the pending WebUI should be
@@ -2944,7 +2947,8 @@ TEST_F(RenderFrameHostManagerTestWithBrowserSideNavigation,
frame_entry->referrer(), *frame_entry, entry,
FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT, PREVIEWS_UNSPECIFIED,
false, false, nullptr, base::TimeTicks::Now(),
- static_cast<NavigationControllerImpl*>(&controller()), nullptr);
+ static_cast<NavigationControllerImpl*>(&controller()), nullptr,
+ base::TimeTicks(), WasActivatedOption::kUnknown);
manager->DidCreateNavigationRequest(navigation_request.get());
// The current WebUI should still be in place and there should be a new
diff --git a/chromium/content/browser/frame_host/render_frame_message_filter.cc b/chromium/content/browser/frame_host/render_frame_message_filter.cc
index dfd9bb1aa8c..f1db4db0d67 100644
--- a/chromium/content/browser/frame_host/render_frame_message_filter.cc
+++ b/chromium/content/browser/frame_host/render_frame_message_filter.cc
@@ -14,6 +14,7 @@
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/syslog_logging.h"
+#include "base/task/post_task.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "components/download/public/common/download_url_parameters.h"
@@ -30,6 +31,7 @@
#include "content/common/frame_owner_properties.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/storage_partition.h"
@@ -143,8 +145,8 @@ void DownloadBlobURLFromToken(
blob_handle = context->GetBlobDataFromUUID(uuid);
}
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DownloadUrlOnUIThread, std::move(params),
std::move(blob_handle), nullptr));
}
@@ -280,8 +282,8 @@ RenderFrameMessageFilter::~RenderFrameMessageFilter() {
network::mojom::CookieManagerPtr* RenderFrameMessageFilter::GetCookieManager() {
if (!cookie_manager_ || cookie_manager_.encountered_error()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&RenderFrameMessageFilter::InitializeCookieManager, this,
mojo::MakeRequest(&cookie_manager_)));
}
@@ -373,9 +375,9 @@ void RenderFrameMessageFilter::DownloadUrl(
}
})");
std::unique_ptr<download::DownloadUrlParameters> parameters(
- new download::DownloadUrlParameters(
- url, render_process_id_, render_view_id, render_frame_id,
- request_context_.get(), traffic_annotation));
+ new download::DownloadUrlParameters(url, render_process_id_,
+ render_view_id, render_frame_id,
+ traffic_annotation));
parameters->set_content_initiated(true);
parameters->set_suggested_name(suggested_name);
parameters->set_prompt(use_prompt);
@@ -416,8 +418,8 @@ void RenderFrameMessageFilter::DownloadUrl(
// through and allow it to be interrupted so that the embedder can deal.
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DownloadUrlOnUIThread, std::move(parameters),
std::move(blob_data_handle), std::move(blob_url_token)));
}
@@ -436,8 +438,8 @@ void RenderFrameMessageFilter::OnCreateChildFrame(
*devtools_frame_token = base::UnguessableToken::Create();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&CreateChildFrameOnUI, render_process_id_,
params.parent_routing_id, params.scope, params.frame_name,
params.frame_unique_name, params.is_created_by_script,
@@ -464,12 +466,11 @@ void RenderFrameMessageFilter::CheckPolicyForCookies(
const GURL& site_for_cookies,
GetCookiesCallback callback,
const net::CookieList& cookie_list) {
- net::URLRequestContext* context = GetRequestContextForURL(url);
// Check the policy for get cookies, and pass cookie_list to the
// TabSpecificContentSetting for logging purpose.
- if (context && GetContentClient()->browser()->AllowGetCookie(
- url, site_for_cookies, cookie_list, resource_context_,
- render_process_id_, render_frame_id)) {
+ if (GetContentClient()->browser()->AllowGetCookie(
+ url, site_for_cookies, cookie_list, resource_context_,
+ render_process_id_, render_frame_id)) {
std::move(callback).Run(net::CanonicalCookie::BuildCookieLine(cookie_list));
} else {
std::move(callback).Run(std::string());
@@ -531,7 +532,6 @@ void RenderFrameMessageFilter::SetCookie(int32_t render_frame_id,
const GURL& site_for_cookies,
const std::string& cookie_line,
SetCookieCallback callback) {
- std::move(callback).Run();
ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance();
if (!policy->CanAccessDataForOrigin(render_process_id_, url)) {
@@ -540,37 +540,52 @@ void RenderFrameMessageFilter::SetCookie(int32_t render_frame_id,
SYSLOG(WARNING) << "Killing renderer: illegal cookie write. Reason: "
<< reason;
bad_message::ReceivedBadMessage(this, reason);
+ std::move(callback).Run();
return;
}
net::CookieOptions options;
std::unique_ptr<net::CanonicalCookie> cookie = net::CanonicalCookie::Create(
url, cookie_line, base::Time::Now(), options);
- if (!cookie)
+ if (!cookie) {
+ std::move(callback).Run();
return;
+ }
if (!GetContentClient()->browser()->AllowSetCookie(
url, site_for_cookies, *cookie, resource_context_, render_process_id_,
- render_frame_id))
+ render_frame_id)) {
+ std::move(callback).Run();
return;
+ }
- net::URLRequestContext* context = GetRequestContextForURL(url);
- // If the embedder overrides the URLRequestContext then always use it, even if
+ // If the embedder overrides the cookie store then always use it, even if
// the network service is enabled, instead of the CookieManager associated
// this process' StoragePartition.
- if (base::FeatureList::IsEnabled(network::features::kNetworkService) &&
- context == request_context_->GetURLRequestContext()) {
- (*GetCookieManager())
- ->SetCanonicalCookie(*cookie, url.SchemeIsCryptographic(),
- !options.exclude_httponly(),
- net::CookieStore::SetCookiesCallback());
+ net::CookieStore* cookie_store =
+ GetContentClient()->browser()->OverrideCookieStoreForURL(
+ url, resource_context_);
+ if (cookie_store ||
+ !base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ std::move(callback).Run();
+ if (!cookie_store)
+ cookie_store = request_context_->GetURLRequestContext()->cookie_store();
+
+ // Pass a null callback since we don't care about when the 'set' completes.
+ cookie_store->SetCanonicalCookieAsync(
+ std::move(cookie), url.SchemeIsCryptographic(),
+ !options.exclude_httponly(), net::CookieStore::SetCookiesCallback());
return;
}
- // Pass a null callback since we don't care about when the 'set' completes.
- context->cookie_store()->SetCanonicalCookieAsync(
- std::move(cookie), url.SchemeIsCryptographic(),
- !options.exclude_httponly(), net::CookieStore::SetCookiesCallback());
+ net::CookieStore::SetCookiesCallback net_callback =
+ base::BindOnce([](SetCookieCallback callback,
+ bool success) { std::move(callback).Run(); },
+ std::move(callback));
+ (*GetCookieManager())
+ ->SetCanonicalCookie(*cookie, url.SchemeIsCryptographic(),
+ !options.exclude_httponly(),
+ std::move(net_callback));
}
void RenderFrameMessageFilter::GetCookies(int render_frame_id,
@@ -601,33 +616,35 @@ void RenderFrameMessageFilter::GetCookies(int render_frame_id,
options.set_same_site_cookie_mode(
net::CookieOptions::SameSiteCookieMode::DO_NOT_INCLUDE);
}
-
- net::URLRequestContext* context = GetRequestContextForURL(url);
- // If the embedder overrides the URLRequestContext then always use it, even if
+ // If the embedder overrides the cookie store then always use it, even if
// the network service is enabled, instead of the CookieManager associated
// this process' StoragePartition.
- if (base::FeatureList::IsEnabled(network::features::kNetworkService) &&
- context == request_context_->GetURLRequestContext()) {
- // TODO(jam): modify GetRequestContextForURL to work with network service.
- // Merge this with code path below for non-network service.
- (*GetCookieManager())
- ->GetCookieList(
- url, options,
- base::BindOnce(&RenderFrameMessageFilter::CheckPolicyForCookies,
- this, render_frame_id, url, site_for_cookies,
- std::move(callback)));
+ net::CookieStore* cookie_store =
+ GetContentClient()->browser()->OverrideCookieStoreForURL(
+ url, resource_context_);
+ if (cookie_store ||
+ !base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ if (!cookie_store)
+ cookie_store = request_context_->GetURLRequestContext()->cookie_store();
+
+ // If we crash here, figure out what URL the renderer was requesting.
+ // http://crbug.com/99242
+ DEBUG_ALIAS_FOR_GURL(url_buf, url);
+
+ cookie_store->GetCookieListWithOptionsAsync(
+ url, options,
+ base::BindOnce(&RenderFrameMessageFilter::CheckPolicyForCookies, this,
+ render_frame_id, url, site_for_cookies,
+ std::move(callback)));
return;
}
- // If we crash here, figure out what URL the renderer was requesting.
- // http://crbug.com/99242
- DEBUG_ALIAS_FOR_GURL(url_buf, url);
-
- context->cookie_store()->GetCookieListWithOptionsAsync(
- url, options,
- base::BindOnce(&RenderFrameMessageFilter::CheckPolicyForCookies, this,
- render_frame_id, url, site_for_cookies,
- std::move(callback)));
+ (*GetCookieManager())
+ ->GetCookieList(
+ url, options,
+ base::BindOnce(&RenderFrameMessageFilter::CheckPolicyForCookies, this,
+ render_frame_id, url, site_for_cookies,
+ std::move(callback)));
}
#if BUILDFLAG(ENABLE_PLUGINS)
@@ -718,17 +735,4 @@ void RenderFrameMessageFilter::OnPluginInstanceThrottleStateChange(
#endif // ENABLE_PLUGINS
-net::URLRequestContext* RenderFrameMessageFilter::GetRequestContextForURL(
- const GURL& url) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- net::URLRequestContext* context =
- GetContentClient()->browser()->OverrideRequestContextForURL(
- url, resource_context_);
- if (!context)
- context = request_context_->GetURLRequestContext();
-
- return context;
-}
-
} // namespace content
diff --git a/chromium/content/browser/frame_host/render_frame_message_filter.h b/chromium/content/browser/frame_host/render_frame_message_filter.h
index a661ac52665..91a7d32dbe7 100644
--- a/chromium/content/browser/frame_host/render_frame_message_filter.h
+++ b/chromium/content/browser/frame_host/render_frame_message_filter.h
@@ -35,7 +35,6 @@ class MessagePipeHandle;
}
namespace net {
-class URLRequestContext;
class URLRequestContextGetter;
}
@@ -171,11 +170,6 @@ class CONTENT_EXPORT RenderFrameMessageFilter
bool is_throttled);
#endif // ENABLE_PLUGINS
- // Returns the correct net::URLRequestContext depending on what type of url is
- // given.
- // Only call on the IO thread.
- net::URLRequestContext* GetRequestContextForURL(const GURL& url);
-
#if BUILDFLAG(ENABLE_PLUGINS)
PluginServiceImpl* plugin_service_;
base::FilePath profile_data_directory_;
diff --git a/chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc b/chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc
index 6f1ed61980a..01e6a62ce9c 100644
--- a/chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc
+++ b/chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc
@@ -8,6 +8,7 @@
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
+#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "content/browser/bad_message.h"
#include "content/browser/frame_host/frame_tree.h"
@@ -15,6 +16,7 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
#include "content/common/render_frame_message_filter.mojom.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
@@ -232,7 +234,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest,
{
RenderProcessHostKillWaiter iframe_kill_waiter(iframe->GetProcess());
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})
->PostTask(FROM_HERE,
base::BindOnce(
[](RenderFrameHost* frame) {
@@ -262,7 +264,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest,
RenderProcessHostKillWaiter main_frame_kill_waiter(
tab->GetMainFrame()->GetProcess());
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})
->PostTask(FROM_HERE, base::BindOnce(
[](RenderFrameHost* frame) {
GetFilterForProcess(frame->GetProcess())
diff --git a/chromium/content/browser/frame_host/render_frame_proxy_host.cc b/chromium/content/browser/frame_host/render_frame_proxy_host.cc
index bad4c9fc4eb..80d51c9baf6 100644
--- a/chromium/content/browser/frame_host/render_frame_proxy_host.cc
+++ b/chromium/content/browser/frame_host/render_frame_proxy_host.cc
@@ -45,8 +45,7 @@ RenderFrameProxyHost* RenderFrameProxyHost::FromID(int process_id,
int routing_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RoutingIDFrameProxyMap* frames = g_routing_id_frame_proxy_map.Pointer();
- RoutingIDFrameProxyMap::iterator it = frames->find(
- RenderFrameProxyHostID(process_id, routing_id));
+ auto it = frames->find(RenderFrameProxyHostID(process_id, routing_id));
return it == frames->end() ? NULL : it->second;
}
@@ -381,11 +380,6 @@ void RenderFrameProxyHost::OnRouteMessageEvent(
->SynchronizeVisualPropertiesIgnoringPendingAck();
}
- if (!source_rfh->frame_tree_node()->IsDescendantOf(
- target_rfh->frame_tree_node())) {
- target_rfh->did_receive_post_message_from_non_descendant();
- }
-
// Ensure that we have a swapped-out RVH and proxy for the source frame
// in the target SiteInstance. If it doesn't exist, create it on demand
// and also create its opener chain, since that will also be accessible
diff --git a/chromium/content/browser/frame_host/render_widget_host_view_guest.cc b/chromium/content/browser/frame_host/render_widget_host_view_guest.cc
index 86c4876e2d4..96c9cd10005 100644
--- a/chromium/content/browser/frame_host/render_widget_host_view_guest.cc
+++ b/chromium/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -26,7 +26,8 @@
#include "content/common/browser_plugin/browser_plugin_messages.h"
#include "content/common/frame_messages.h"
#include "content/common/input/web_touch_event_traits.h"
-#include "content/common/view_messages.h"
+#include "content/common/text_input_state.h"
+#include "content/common/widget_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "gpu/ipc/common/gpu_messages.h"
@@ -371,12 +372,6 @@ void RenderWidgetHostViewGuest::SetTooltipText(
root_view->GetCursorManager()->SetTooltipTextForView(this, tooltip_text);
}
-void RenderWidgetHostViewGuest::FirstSurfaceActivation(
- const viz::SurfaceInfo& surface_info) {
- if (guest_ && !guest_->is_in_destruction())
- guest_->FirstSurfaceActivation(surface_info);
-}
-
void RenderWidgetHostViewGuest::OnDidUpdateVisualPropertiesComplete(
const cc::RenderFrameMetadata& metadata) {
if (guest_)
@@ -387,7 +382,7 @@ void RenderWidgetHostViewGuest::OnDidUpdateVisualPropertiesComplete(
void RenderWidgetHostViewGuest::OnAttached() {
RegisterFrameSinkId();
#if defined(USE_AURA)
- if (features::IsUsingWindowService()) {
+ if (features::IsMultiProcessMash()) {
aura::Env::GetInstance()->ScheduleEmbed(
GetWindowTreeClientFromRenderer(),
base::BindOnce(&RenderWidgetHostViewGuest::OnGotEmbedToken,
@@ -451,7 +446,7 @@ gfx::NativeViewAccessible RenderWidgetHostViewGuest::GetNativeViewAccessible() {
void RenderWidgetHostViewGuest::UpdateCursor(const WebCursor& cursor) {
// InterstitialPages are not WebContents so we cannot intercept
- // ViewHostMsg_SetCursor for interstitial pages in BrowserPluginGuest.
+ // WidgetHostMsg_SetCursor for interstitial pages in BrowserPluginGuest.
// All guest RenderViewHosts have RenderWidgetHostViewGuests however,
// and so we will always hit this code path.
if (!guest_)
@@ -529,14 +524,14 @@ void RenderWidgetHostViewGuest::SelectionChanged(const base::string16& text,
}
void RenderWidgetHostViewGuest::SelectionBoundsChanged(
- const ViewHostMsg_SelectionBounds_Params& params) {
+ const WidgetHostMsg_SelectionBounds_Params& params) {
if (!guest_)
return;
RenderWidgetHostViewBase* rwhv = GetOwnerRenderWidgetHostView();
if (!rwhv)
return;
- ViewHostMsg_SelectionBounds_Params guest_params(params);
+ WidgetHostMsg_SelectionBounds_Params guest_params(params);
guest_params.anchor_rect.set_origin(
guest_->GetScreenCoordinates(params.anchor_rect.origin()));
guest_params.focus_rect.set_origin(
diff --git a/chromium/content/browser/frame_host/render_widget_host_view_guest.h b/chromium/content/browser/frame_host/render_widget_host_view_guest.h
index db521ae67fb..dae838fe107 100644
--- a/chromium/content/browser/frame_host/render_widget_host_view_guest.h
+++ b/chromium/content/browser/frame_host/render_widget_host_view_guest.h
@@ -118,7 +118,7 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
size_t offset,
const gfx::Range& range) override;
void SelectionBoundsChanged(
- const ViewHostMsg_SelectionBounds_Params& params) override;
+ const WidgetHostMsg_SelectionBounds_Params& params) override;
void PreProcessMouseEvent(const blink::WebMouseEvent& event) override;
void PreProcessTouchEvent(const blink::WebTouchEvent& event) override;
@@ -166,8 +166,6 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
private:
friend class RenderWidgetHostView;
- void FirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
-
void OnDidUpdateVisualPropertiesComplete(
const cc::RenderFrameMetadata& metadata);
diff --git a/chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc b/chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
index bfa0b5f3cf9..4f12cceb05b 100644
--- a/chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
+++ b/chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
@@ -111,17 +111,9 @@ class TestBrowserPluginGuest : public BrowserPluginGuest {
~TestBrowserPluginGuest() override {}
- void ResetTestData() { last_surface_info_ = viz::SurfaceInfo(); }
-
void set_attached(bool attached) {
BrowserPluginGuest::set_attached_for_test(attached);
}
-
- void FirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override {
- last_surface_info_ = surface_info;
- }
-
- viz::SurfaceInfo last_surface_info_;
};
// TODO(wjmaclean): we should restructure RenderWidgetHostViewChildFrameTest to
@@ -197,47 +189,4 @@ class RenderWidgetHostViewGuestSurfaceTest
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewGuestSurfaceTest);
};
-TEST_F(RenderWidgetHostViewGuestSurfaceTest, TestGuestSurface) {
- // Early out because RenderWidgetHostViewChildFrame::SendSurfaceInfoToEmbedder
- // is no-op on mash and the test expects it call into FirstSurfaceActivation
- // of BrowserPluginGuest.
- if (features::IsUsingWindowService())
- return;
-
- gfx::Size view_size(100, 100);
- gfx::Rect view_rect(view_size);
- float scale_factor = 1.f;
- viz::LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create());
- viz::SurfaceId surface_id(view_->GetFrameSinkId(), local_surface_id);
- viz::SurfaceInfo surface_info(surface_id, scale_factor, view_size);
-
- ASSERT_TRUE(browser_plugin_guest_);
-
- view_->SetSize(view_size);
- view_->Show();
-
- browser_plugin_guest_->set_attached(true);
-
- view_->OnFirstSurfaceActivation(surface_info);
-
- EXPECT_EQ(surface_id, GetSurfaceId());
-
- // Surface ID should have been passed to BrowserPluginGuest to
- // be sent to the embedding renderer.
- EXPECT_EQ(surface_info, browser_plugin_guest_->last_surface_info_);
-
- browser_plugin_guest_->ResetTestData();
-
- // The last received SurfaceInfo must be sent to BrowserPluginGuest on
- // attachment.
- view_->OnAttached();
-
- // Surface ID should have been passed to BrowserPluginGuest to
- // be sent to the embedding renderer.
- EXPECT_EQ(surface_info, browser_plugin_guest_->last_surface_info_);
-
- browser_plugin_guest_->set_attached(false);
- browser_plugin_guest_->ResetTestData();
-}
-
} // namespace content
diff --git a/chromium/content/browser/frame_host/webui_navigation_browsertest.cc b/chromium/content/browser/frame_host/webui_navigation_browsertest.cc
index 7add77190dd..fbf93aa4c4c 100644
--- a/chromium/content/browser/frame_host/webui_navigation_browsertest.cc
+++ b/chromium/content/browser/frame_host/webui_navigation_browsertest.cc
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/command_line.h"
+#include "base/macros.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/browser_side_navigation_policy.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
@@ -16,6 +19,7 @@
#include "content/shell/browser/shell.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "url/url_constants.h"
namespace content {
@@ -219,6 +223,11 @@ IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest, WebUIMainFrameToWebAllowed) {
EXPECT_EQ(chrome_url, webui_rfh->GetLastCommittedURL());
EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
webui_rfh->GetProcess()->GetID()));
+ EXPECT_EQ(
+ ChildProcessSecurityPolicyImpl::CheckOriginLockResult::HAS_EQUAL_LOCK,
+ ChildProcessSecurityPolicyImpl::GetInstance()->CheckOriginLock(
+ root->current_frame_host()->GetProcess()->GetID(),
+ webui_site_instance->GetSiteURL()));
GURL web_url(embedded_test_server()->GetURL("/title2.html"));
std::string script =
@@ -233,6 +242,13 @@ IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest, WebUIMainFrameToWebAllowed) {
EXPECT_NE(webui_site_instance, root->current_frame_host()->GetSiteInstance());
EXPECT_FALSE(webui_site_instance->IsRelatedSiteInstance(
root->current_frame_host()->GetSiteInstance()));
+ EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+ root->current_frame_host()->GetProcess()->GetID()));
+ EXPECT_NE(
+ ChildProcessSecurityPolicyImpl::CheckOriginLockResult::HAS_EQUAL_LOCK,
+ ChildProcessSecurityPolicyImpl::GetInstance()->CheckOriginLock(
+ root->current_frame_host()->GetProcess()->GetID(),
+ webui_site_instance->GetSiteURL()));
}
IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
@@ -267,4 +283,37 @@ IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
BINDINGS_POLICY_WEB_UI);
}
+IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
+ WebUIOriginsRequireDedicatedProcess) {
+ // chrome:// URLs should require a dedicated process.
+ WebContents* web_contents = shell()->web_contents();
+ BrowserContext* browser_context = web_contents->GetBrowserContext();
+ GURL chrome_url = GURL(std::string(kChromeUIScheme) + "://" +
+ std::string(kChromeUIGpuHost));
+ EXPECT_TRUE(SiteInstanceImpl::DoesSiteRequireDedicatedProcess(browser_context,
+ chrome_url));
+
+ // Navigate to a WebUI page.
+ EXPECT_TRUE(NavigateToURL(shell(), chrome_url));
+
+ // Verify that the "hostname" is also part of the site URL.
+ GURL site_url = web_contents->GetMainFrame()->GetSiteInstance()->GetSiteURL();
+ EXPECT_EQ(chrome_url, site_url);
+
+ // Ask the page to create a blob URL and return back the blob URL.
+ const char* kScript = R"(
+ var blob = new Blob(['foo'], {type : 'text/html'});
+ var url = URL.createObjectURL(blob);
+ url;
+ )";
+ GURL blob_url(EvalJs(shell(), kScript).ExtractString());
+ EXPECT_EQ(url::kBlobScheme, blob_url.scheme());
+
+ // Verify that the blob also requires a dedicated process and that it would
+ // use the same site url as the original page.
+ EXPECT_TRUE(SiteInstanceImpl::DoesSiteRequireDedicatedProcess(browser_context,
+ blob_url));
+ EXPECT_EQ(chrome_url, SiteInstance::GetSiteForURL(browser_context, blob_url));
+}
+
} // namespace content
diff --git a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
index f141ce1abbd..50ac5ba170f 100644
--- a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -12,6 +12,7 @@
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/timer/timer.h"
@@ -25,6 +26,7 @@
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/gpu/shader_cache_factory.h"
#include "content/common/child_process_host_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/gpu_data_manager.h"
@@ -101,8 +103,8 @@ BrowserGpuChannelHostFactory::EstablishRequest::Create(
scoped_refptr<EstablishRequest> establish_request =
new EstablishRequest(gpu_client_id, gpu_client_tracing_id);
// PostTask outside the constructor to ensure at least one reference exists.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO,
establish_request));
@@ -164,8 +166,8 @@ void BrowserGpuChannelHostFactory::EstablishRequest::OnEstablishedOnIO(
base::BindOnce(
&BrowserGpuChannelHostFactory::EstablishRequest::RestartTimeout,
this));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&BrowserGpuChannelHostFactory::EstablishRequest::EstablishOnIO,
this));
@@ -265,8 +267,8 @@ BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory()
base::FilePath cache_dir =
GetContentClient()->browser()->GetShaderDiskCacheDirectory();
if (!cache_dir.empty()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&BrowserGpuChannelHostFactory::InitializeShaderDiskCacheOnIO,
gpu_client_id_, cache_dir));
@@ -277,8 +279,8 @@ BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory()
base::FilePath gr_cache_dir =
GetContentClient()->browser()->GetGrShaderDiskCacheDirectory();
if (!gr_cache_dir.empty()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&BrowserGpuChannelHostFactory::InitializeGrShaderDiskCacheOnIO,
gr_cache_dir));
@@ -349,6 +351,21 @@ BrowserGpuChannelHostFactory::GetGpuMemoryBufferManager() {
return gpu_memory_buffer_manager_.get();
}
+// Ensures that any pending timeout is cancelled when we are backgrounded.
+// Restarts the timeout when we return to the foreground.
+void BrowserGpuChannelHostFactory::SetApplicationVisible(bool is_visible) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (is_visible_ == is_visible)
+ return;
+
+ is_visible_ = is_visible;
+ if (is_visible_) {
+ RestartTimeout();
+ } else {
+ timeout_.Stop();
+ }
+}
+
gpu::GpuChannelHost* BrowserGpuChannelHostFactory::GetGpuChannel() {
if (gpu_channel_.get() && !gpu_channel_->IsLost())
return gpu_channel_.get();
@@ -375,7 +392,9 @@ void BrowserGpuChannelHostFactory::RestartTimeout() {
return;
}
- if (!pending_request_)
+ // Don't restart the timeout if we aren't visible. This function will be
+ // re-called when we become visible again.
+ if (!pending_request_ || !is_visible_)
return;
#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
diff --git a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.h b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.h
index 6386420710d..c620a0909f0 100644
--- a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.h
+++ b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -41,6 +41,10 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
// thread stops.
void CloseChannel();
+ // Notify the BrowserGpuChannelHostFactory of visibility, used to prevent
+ // timeouts while backgrounded.
+ void SetApplicationVisible(bool is_visible);
+
// Overridden from gpu::GpuChannelEstablishFactory:
// The factory will return a null GpuChannelHost in the callback during
// shutdown.
@@ -69,6 +73,7 @@ class CONTENT_EXPORT BrowserGpuChannelHostFactory
std::unique_ptr<gpu::GpuMemoryBufferManager, BrowserThread::DeleteOnIOThread>
gpu_memory_buffer_manager_;
scoped_refptr<EstablishRequest> pending_request_;
+ bool is_visible_ = true;
base::OneShotTimer timeout_;
diff --git a/chromium/content/browser/gpu/browser_gpu_client_delegate.cc b/chromium/content/browser/gpu/browser_gpu_client_delegate.cc
index 20da7388187..219ca1fa616 100644
--- a/chromium/content/browser/gpu/browser_gpu_client_delegate.cc
+++ b/chromium/content/browser/gpu/browser_gpu_client_delegate.cc
@@ -4,76 +4,21 @@
#include "content/browser/gpu/browser_gpu_client_delegate.h"
-#include <utility>
-
-#include "components/viz/host/gpu_host_impl.h"
#include "content/browser/gpu/gpu_memory_buffer_manager_singleton.h"
#include "content/browser/gpu/gpu_process_host.h"
-#include "gpu/config/gpu_feature_info.h"
-#include "gpu/config/gpu_info.h"
-#include "mojo/public/cpp/system/message_pipe.h"
namespace content {
-namespace {
-
-void OnEstablishGpuChannel(
- viz::GpuClientDelegate::EstablishGpuChannelCallback callback,
- mojo::ScopedMessagePipeHandle channel_handle,
- const gpu::GPUInfo& gpu_info,
- const gpu::GpuFeatureInfo& gpu_feature_info,
- viz::GpuHostImpl::EstablishChannelStatus status) {
- if (!callback)
- return;
-
- viz::GpuClientDelegate::EstablishGpuChannelStatus delegate_status;
- switch (status) {
- case viz::GpuHostImpl::EstablishChannelStatus::kGpuAccessDenied:
- delegate_status =
- viz::GpuClientDelegate::EstablishGpuChannelStatus::kGpuAccessDenied;
- break;
- case viz::GpuHostImpl::EstablishChannelStatus::kGpuHostInvalid:
- delegate_status =
- viz::GpuClientDelegate::EstablishGpuChannelStatus::kGpuHostInvalid;
- break;
- case viz::GpuHostImpl::EstablishChannelStatus::kSuccess:
- delegate_status =
- viz::GpuClientDelegate::EstablishGpuChannelStatus::kSuccess;
- break;
- }
- std::move(callback).Run(std::move(channel_handle), gpu_info, gpu_feature_info,
- delegate_status);
-}
-
-} // namespace
BrowserGpuClientDelegate::BrowserGpuClientDelegate() = default;
BrowserGpuClientDelegate::~BrowserGpuClientDelegate() = default;
-viz::mojom::GpuService* BrowserGpuClientDelegate::EnsureGpuService() {
+viz::GpuHostImpl* BrowserGpuClientDelegate::EnsureGpuHost() {
if (auto* host = GpuProcessHost::Get())
- return host->gpu_service();
+ return host->gpu_host();
return nullptr;
}
-void BrowserGpuClientDelegate::EstablishGpuChannel(
- int client_id,
- uint64_t client_tracing_id,
- EstablishGpuChannelCallback callback) {
- auto* host = GpuProcessHost::Get();
- if (!host) {
- std::move(callback).Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
- gpu::GpuFeatureInfo(),
- EstablishGpuChannelStatus::kGpuAccessDenied);
- return;
- }
-
- const bool is_gpu_host = false;
- host->gpu_host()->EstablishGpuChannel(
- client_id, client_tracing_id, is_gpu_host,
- base::BindOnce(&OnEstablishGpuChannel, std::move(callback)));
-}
-
viz::HostGpuMemoryBufferManager*
BrowserGpuClientDelegate::GetGpuMemoryBufferManager() {
return GpuMemoryBufferManagerSingleton::GetInstance();
diff --git a/chromium/content/browser/gpu/browser_gpu_client_delegate.h b/chromium/content/browser/gpu/browser_gpu_client_delegate.h
index 18150dc6e19..ac8c634b854 100644
--- a/chromium/content/browser/gpu/browser_gpu_client_delegate.h
+++ b/chromium/content/browser/gpu/browser_gpu_client_delegate.h
@@ -15,10 +15,7 @@ class BrowserGpuClientDelegate : public viz::GpuClientDelegate {
~BrowserGpuClientDelegate() override;
// GpuClientDelegate:
- viz::mojom::GpuService* EnsureGpuService() override;
- void EstablishGpuChannel(int client_id,
- uint64_t client_tracing_id,
- EstablishGpuChannelCallback callback) override;
+ viz::GpuHostImpl* EnsureGpuHost() override;
viz::HostGpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
private:
diff --git a/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc b/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc
index 8f3efa6a705..f68d485dfc5 100644
--- a/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc
+++ b/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc
@@ -5,7 +5,9 @@
#include "content/browser/gpu/ca_transaction_gpu_coordinator.h"
#include "base/cancelable_callback.h"
+#include "base/task/post_task.h"
#include "content/browser/gpu/gpu_process_host.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "services/viz/privileged/interfaces/gl/gpu_service.mojom.h"
#include "ui/accelerated_widget_mac/ca_transaction_observer.h"
@@ -61,8 +63,8 @@ void CATransactionGPUCoordinator::RemovePostCommitObserverOnUIThread() {
void CATransactionGPUCoordinator::OnActivateForTransaction() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CATransactionGPUCoordinator::OnActivateForTransactionOnIO,
this));
}
@@ -75,8 +77,8 @@ void CATransactionGPUCoordinator::OnEnterPostCommit() {
// (and removed from the list of post-commit observers) soon after.
pending_commit_count_++;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CATransactionGPUCoordinator::OnEnterPostCommitOnIO,
this));
}
diff --git a/chromium/content/browser/gpu/compositor_util.cc b/chromium/content/browser/gpu/compositor_util.cc
index 9bcf1916304..c4a41532110 100644
--- a/chromium/content/browser/gpu/compositor_util.cc
+++ b/chromium/content/browser/gpu/compositor_util.cc
@@ -177,6 +177,16 @@ const GpuFeatureData GetGpuFeatureData(
"Native GpuMemoryBuffers have been disabled, either via about:flags or "
"command line.",
true, true},
+ {"surface_control",
+ SafeGetFeatureStatus(gpu_feature_info,
+ gpu::GPU_FEATURE_TYPE_ANDROID_SURFACE_CONTROL),
+#if defined(OS_ANDROID)
+ !base::FeatureList::IsEnabled(features::kAndroidSurfaceControl),
+#else
+ false,
+#endif
+ "Surface Control has been disabled by Finch trial or command line.",
+ false, false},
{"surface_synchronization", gpu::kGpuFeatureStatusEnabled,
!features::IsSurfaceSynchronizationEnabled(),
"Surface synchronization has been disabled by Finch trial or command "
diff --git a/chromium/content/browser/gpu/compositor_util.h b/chromium/content/browser/gpu/compositor_util.h
index e9ed20977ea..c7155e6dec9 100644
--- a/chromium/content/browser/gpu/compositor_util.h
+++ b/chromium/content/browser/gpu/compositor_util.h
@@ -37,9 +37,6 @@ CONTENT_EXPORT int NumberOfRendererRasterThreads();
// Returns true if main thread can be pipelined with activation.
CONTENT_EXPORT bool IsMainFrameBeforeActivationEnabled();
-// Returns true if image animations should run in the compositor.
-CONTENT_EXPORT bool IsCompositorImageAnimationEnabled();
-
CONTENT_EXPORT std::unique_ptr<base::DictionaryValue> GetFeatureStatus();
CONTENT_EXPORT std::unique_ptr<base::ListValue> GetProblems();
CONTENT_EXPORT std::vector<std::string> GetDriverBugWorkarounds();
diff --git a/chromium/content/browser/gpu/delegate_to_browser_gpu_service_accelerator_factory.cc b/chromium/content/browser/gpu/delegate_to_browser_gpu_service_accelerator_factory.cc
new file mode 100644
index 00000000000..1d37054b3ff
--- /dev/null
+++ b/chromium/content/browser/gpu/delegate_to_browser_gpu_service_accelerator_factory.cc
@@ -0,0 +1,16 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/delegate_to_browser_gpu_service_accelerator_factory.h"
+
+#include "content/browser/gpu/video_capture_dependencies.h"
+
+namespace content {
+
+void DelegateToBrowserGpuServiceAcceleratorFactory::CreateJpegDecodeAccelerator(
+ media::mojom::JpegDecodeAcceleratorRequest jda_request) {
+ VideoCaptureDependencies::CreateJpegDecodeAccelerator(std::move(jda_request));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl.cc b/chromium/content/browser/gpu/gpu_data_manager_impl.cc
index f6d3d4c18f1..976bfcd0272 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl.cc
@@ -102,6 +102,20 @@ void GpuDataManagerImpl::UpdateGpuInfo(
private_->UpdateGpuInfo(gpu_info, gpu_info_for_hardware_gpu);
}
+#if defined(OS_WIN)
+void GpuDataManagerImpl::UpdateDxDiagNode(
+ const gpu::DxDiagNode& dx_diagnostics) {
+ base::AutoLock auto_lock(lock_);
+ private_->UpdateDxDiagNode(dx_diagnostics);
+}
+
+void GpuDataManagerImpl::UpdateDx12VulkanInfo(
+ const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info) {
+ base::AutoLock auto_lock(lock_);
+ private_->UpdateDx12VulkanInfo(dx12_vulkan_version_info);
+}
+#endif
+
void GpuDataManagerImpl::UpdateGpuFeatureInfo(
const gpu::GpuFeatureInfo& gpu_feature_info,
const base::Optional<gpu::GpuFeatureInfo>&
@@ -162,8 +176,8 @@ void GpuDataManagerImpl::HandleGpuSwitch() {
private_->HandleGpuSwitch();
}
-void GpuDataManagerImpl::BlockDomainFrom3DAPIs(
- const GURL& url, DomainGuilt guilt) {
+void GpuDataManagerImpl::BlockDomainFrom3DAPIs(const GURL& url,
+ gpu::DomainGuilt guilt) {
base::AutoLock auto_lock(lock_);
private_->BlockDomainFrom3DAPIs(url, guilt);
}
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl.h b/chromium/content/browser/gpu/gpu_data_manager_impl.h
index d91d77659f3..2a18cf5b40e 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl.h
@@ -17,11 +17,14 @@
#include "base/no_destructor.h"
#include "base/process/kill.h"
#include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "base/values.h"
+#include "build/build_config.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/common/three_d_api_types.h"
#include "gpu/config/gpu_control_list.h"
+#include "gpu/config/gpu_domain_guilt.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_info.h"
#include "gpu/config/gpu_mode.h"
@@ -43,24 +46,6 @@ class GpuDataManagerImplPrivate;
class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager {
public:
- // Indicates the guilt level of a domain which caused a GPU reset.
- // If a domain is 100% known to be guilty of resetting the GPU, then
- // it will generally not cause other domains' use of 3D APIs to be
- // blocked, unless system stability would be compromised.
- enum DomainGuilt {
- DOMAIN_GUILT_KNOWN,
- DOMAIN_GUILT_UNKNOWN
- };
-
- // Indicates the reason that access to a given client API (like
- // WebGL or Pepper 3D) was blocked or not. This state is distinct
- // from blacklisting of an entire feature.
- enum DomainBlockStatus {
- DOMAIN_BLOCK_STATUS_BLOCKED,
- DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
- DOMAIN_BLOCK_STATUS_NOT_BLOCKED
- };
-
// Getter for the singleton. This will return NULL on failure.
static GpuDataManagerImpl* GetInstance();
@@ -89,12 +74,14 @@ class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager {
bool IsGpuFeatureInfoAvailable() const;
gpu::GpuFeatureStatus GetFeatureStatus(gpu::GpuFeatureType feature) const;
- // Only update if the current GPUInfo is not finalized. If blacklist is
- // loaded, run through blacklist and update blacklisted features.
void UpdateGpuInfo(
const gpu::GPUInfo& gpu_info,
const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu);
-
+#if defined(OS_WIN)
+ void UpdateDx12VulkanInfo(
+ const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info);
+ void UpdateDxDiagNode(const gpu::DxDiagNode& dx_diagnostics);
+#endif
// Update the GPU feature info. This updates the blacklist and enabled status
// of GPU rasterization. In the future this will be used for more features.
void UpdateGpuFeatureInfo(const gpu::GpuFeatureInfo& gpu_feature_info,
@@ -132,7 +119,7 @@ class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager {
//
// The given URL may be a partial URL (including at least the host)
// or a full URL to a page.
- void BlockDomainFrom3DAPIs(const GURL& url, DomainGuilt guilt);
+ void BlockDomainFrom3DAPIs(const GURL& url, gpu::DomainGuilt guilt);
bool Are3DAPIsBlocked(const GURL& top_origin_url,
int render_process_id,
int render_frame_id,
@@ -176,7 +163,8 @@ class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager {
~GpuDataManagerImpl() override;
mutable base::Lock lock_;
- std::unique_ptr<GpuDataManagerImplPrivate> private_;
+ std::unique_ptr<GpuDataManagerImplPrivate> private_ GUARDED_BY(lock_)
+ PT_GUARDED_BY(lock_);
DISALLOW_COPY_AND_ASSIGN(GpuDataManagerImpl);
};
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc b/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
index 4541da4f15c..03a570f5d8e 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -18,6 +18,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
#include "base/version.h"
#include "build/build_config.h"
@@ -25,6 +26,7 @@
#include "components/viz/common/features.h"
#include "content/browser/gpu/gpu_memory_buffer_manager_singleton.h"
#include "content/browser/gpu/gpu_process_host.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/gpu_data_manager_observer.h"
#include "content/public/browser/gpu_utils.h"
@@ -235,8 +237,8 @@ void OnVideoMemoryUsageStats(
const base::Callback<void(const gpu::VideoMemoryUsageStats& stats)>&
callback,
const gpu::VideoMemoryUsageStats& stats) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(callback, stats));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(callback, stats));
}
void RequestVideoMemoryUsageStats(
@@ -249,21 +251,35 @@ void RequestVideoMemoryUsageStats(
base::BindOnce(&OnVideoMemoryUsageStats, callback));
}
-void UpdateGpuInfoOnIO(const gpu::GPUInfo& gpu_info) {
+#if defined(OS_WIN)
+void UpdateDxDiagNodeOnIO(const gpu::DxDiagNode& dx_diagnostics) {
// This function is called on the IO thread, but GPUInfo on GpuDataManagerImpl
- // should be updated on the UI thread (since it can call into functions that
- // expect to run in the UI thread, e.g. ContentClient::SetGpuInfo()).
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ // should be updated on the UI thread since it can call into functions that
+ // expect to run in the UI thread.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
- [](const gpu::GPUInfo& gpu_info) {
- TRACE_EVENT0("test_gpu", "OnGraphicsInfoCollected");
- GpuDataManagerImpl::GetInstance()->UpdateGpuInfo(gpu_info,
- base::nullopt);
+ [](const gpu::DxDiagNode& dx_diagnostics) {
+ GpuDataManagerImpl::GetInstance()->UpdateDxDiagNode(dx_diagnostics);
},
- gpu_info));
+ dx_diagnostics));
}
+void UpdateDx12VulkanInfoOnIO(
+ const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info) {
+ // This function is called on the IO thread, but GPUInfo on GpuDataManagerImpl
+ // should be updated on the UI thread since it can call into functions that
+ // expect to run in the UI thread.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(
+ [](const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info) {
+ GpuDataManagerImpl::GetInstance()->UpdateDx12VulkanInfo(
+ dx12_vulkan_version_info);
+ },
+ dx12_vulkan_version_info));
+}
+#endif
} // anonymous namespace
GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(GpuDataManagerImpl* owner)
@@ -335,9 +351,6 @@ bool GpuDataManagerImplPrivate::GpuAccessAllowed(std::string* reason) const {
if (swiftshader_available)
return true;
- if (in_process_gpu_)
- return true;
-
if (card_disabled_) {
if (reason) {
*reason = "GPU access is disabled ";
@@ -373,25 +386,26 @@ void GpuDataManagerImplPrivate::RequestCompleteGpuInfoIfNeeded() {
return;
if (!NeedsCompleteGpuInfoCollection())
return;
+
+#if defined(OS_WIN)
if (!GpuAccessAllowed(nullptr))
return;
if (in_process_gpu_)
return;
-
complete_gpu_info_already_requested_ = true;
-
- GpuProcessHost::CallOnIO(
-#if defined(OS_WIN)
- GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED,
+ GpuProcessHost::CallOnIO(GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED_NO_GL,
+ true /* force_create */,
+ base::Bind([](GpuProcessHost* host) {
+ if (!host)
+ return;
+ host->gpu_service()->RequestCompleteGpuInfo(
+ base::BindOnce(&UpdateDxDiagNodeOnIO));
+ }));
#else
- GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
+ // NeedsCompleteGpuInfoCollection() always returns false on platforms other
+ // than Windows.
+ NOTREACHED();
#endif
- true /* force_create */, base::Bind([](GpuProcessHost* host) {
- if (!host)
- return;
- host->gpu_service()->RequestCompleteGpuInfo(
- base::BindOnce(&UpdateGpuInfoOnIO));
- }));
}
void GpuDataManagerImplPrivate::RequestGpuSupportedRuntimeVersion() {
@@ -399,16 +413,20 @@ void GpuDataManagerImplPrivate::RequestGpuSupportedRuntimeVersion() {
if (in_process_gpu_)
return;
base::OnceClosure task = base::BindOnce([]() {
- GpuProcessHost* host = GpuProcessHost::Get(
- GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED, true /* force_create */);
+ GpuProcessHost* host =
+ GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED_NO_GL,
+ true /* force_create */);
if (!host)
return;
host->gpu_service()->GetGpuSupportedRuntimeVersion(
- base::BindOnce(&UpdateGpuInfoOnIO));
+ base::BindOnce(&UpdateDx12VulkanInfoOnIO));
});
- BrowserThread::PostDelayedTask(BrowserThread::IO, FROM_HERE, std::move(task),
- base::TimeDelta::FromMilliseconds(15000));
+ base::PostDelayedTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ std::move(task),
+ base::TimeDelta::FromMilliseconds(15000));
+#else
+ NOTREACHED();
#endif
}
@@ -474,47 +492,54 @@ void GpuDataManagerImplPrivate::UnblockDomainFrom3DAPIs(const GURL& url) {
void GpuDataManagerImplPrivate::UpdateGpuInfo(
const gpu::GPUInfo& gpu_info,
const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu) {
- bool sandboxed = gpu_info_.sandboxed;
#if defined(OS_WIN)
- uint32_t d3d12_feature_level = gpu_info_.d3d12_feature_level;
- uint32_t vulkan_version = gpu_info_.vulkan_version;
+ // If GPU process crashes and launches again, GPUInfo will be sent back from
+ // the new GPU process again, and may overwrite the DX12, Vulkan, DxDiagNode
+ // info we already collected. This is to make sure it doesn't happen.
+ gpu::DxDiagNode dx_diagnostics = gpu_info_.dx_diagnostics;
+ gpu::Dx12VulkanVersionInfo dx12_vulkan_version_info =
+ gpu_info_.dx12_vulkan_version_info;
#endif
gpu_info_ = gpu_info;
+#if defined(OS_WIN)
+ if (!dx_diagnostics.IsEmpty()) {
+ gpu_info_.dx_diagnostics = dx_diagnostics;
+ }
+ if (!dx12_vulkan_version_info.IsEmpty()) {
+ gpu_info_.dx12_vulkan_version_info = dx12_vulkan_version_info;
+ }
+#endif // OS_WIN
+
if (!gpu_info_for_hardware_gpu_.IsInitialized()) {
- if (!!gpu_info_for_hardware_gpu) {
+ if (gpu_info_for_hardware_gpu) {
DCHECK(gpu_info_for_hardware_gpu->IsInitialized());
gpu_info_for_hardware_gpu_ = gpu_info_for_hardware_gpu.value();
} else {
- gpu_info_for_hardware_gpu_ = gpu_info;
+ gpu_info_for_hardware_gpu_ = gpu_info_;
}
}
-#if defined(OS_WIN)
- // On Windows, complete GPUInfo is collected through an unsandboxed
- // GPU process. If the regular GPU process is sandboxed, it should
- // not be overwritten.
- if (sandboxed)
- gpu_info_.sandboxed = true;
-
- if (d3d12_feature_level) {
- gpu_info_.d3d12_feature_level = d3d12_feature_level;
- gpu_info_.supports_dx12 = true;
- }
- if (vulkan_version) {
- gpu_info_.vulkan_version = vulkan_version;
- gpu_info_.supports_vulkan = true;
- }
-#else
- (void)sandboxed;
-#endif // OS_WIN
- if (complete_gpu_info_already_requested_ &&
- !NeedsCompleteGpuInfoCollection()) {
+ GetContentClient()->SetGpuInfo(gpu_info_);
+ NotifyGpuInfoUpdate();
+}
+
+#if defined(OS_WIN)
+void GpuDataManagerImplPrivate::UpdateDxDiagNode(
+ const gpu::DxDiagNode& dx_diagnostics) {
+ gpu_info_.dx_diagnostics = dx_diagnostics;
+ if (complete_gpu_info_already_requested_)
complete_gpu_info_already_requested_ = false;
- }
+ // No need to call GetContentClient()->SetGpuInfo().
+ NotifyGpuInfoUpdate();
+}
- GetContentClient()->SetGpuInfo(gpu_info_);
+void GpuDataManagerImplPrivate::UpdateDx12VulkanInfo(
+ const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info) {
+ gpu_info_.dx12_vulkan_version_info = dx12_vulkan_version_info;
+ // No need to call GetContentClient()->SetGpuInfo().
NotifyGpuInfoUpdate();
}
+#endif
void GpuDataManagerImplPrivate::UpdateGpuFeatureInfo(
const gpu::GpuFeatureInfo& gpu_feature_info,
@@ -708,8 +733,8 @@ bool GpuDataManagerImplPrivate::UpdateActiveGpu(uint32_t vendor_id,
return true;
}
-void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIs(
- const GURL& url, GpuDataManagerImpl::DomainGuilt guilt) {
+void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIs(const GURL& url,
+ gpu::DomainGuilt guilt) {
BlockDomainFrom3DAPIsAtTime(url, guilt, base::Time::Now());
}
@@ -718,7 +743,7 @@ bool GpuDataManagerImplPrivate::Are3DAPIsBlocked(const GURL& top_origin_url,
int render_frame_id,
ThreeDAPIType requester) {
return Are3DAPIsBlockedAtTime(top_origin_url, base::Time::Now()) !=
- GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
+ DomainBlockStatus::kNotBlocked;
}
void GpuDataManagerImplPrivate::DisableDomainBlockingFor3DAPIsForTesting() {
@@ -758,35 +783,33 @@ std::string GpuDataManagerImplPrivate::GetDomainFromURL(const GURL& url) const {
void GpuDataManagerImplPrivate::BlockDomainFrom3DAPIsAtTime(
const GURL& url,
- GpuDataManagerImpl::DomainGuilt guilt,
+ gpu::DomainGuilt guilt,
base::Time at_time) {
if (!domain_blocking_enabled_)
return;
std::string domain = GetDomainFromURL(url);
- DomainBlockEntry& entry = blocked_domains_[domain];
- entry.last_guilt = guilt;
+ blocked_domains_[domain] = guilt;
timestamps_of_gpu_resets_.push_back(at_time);
}
-GpuDataManagerImpl::DomainBlockStatus
-GpuDataManagerImplPrivate::Are3DAPIsBlockedAtTime(
- const GURL& url, base::Time at_time) const {
+GpuDataManagerImplPrivate::DomainBlockStatus
+GpuDataManagerImplPrivate::Are3DAPIsBlockedAtTime(const GURL& url,
+ base::Time at_time) const {
if (!domain_blocking_enabled_)
- return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
+ return DomainBlockStatus::kNotBlocked;
// Note: adjusting the policies in this code will almost certainly
// require adjusting the associated unit tests.
std::string domain = GetDomainFromURL(url);
{
- DomainBlockMap::const_iterator iter = blocked_domains_.find(domain);
- if (iter != blocked_domains_.end()) {
+ if (blocked_domains_.find(domain) != blocked_domains_.end()) {
// Err on the side of caution, and assume that if a particular
// domain shows up in the block map, it's there for a good
// reason and don't let its presence there automatically expire.
- return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED;
+ return DomainBlockStatus::kBlocked;
}
}
@@ -798,7 +821,7 @@ GpuDataManagerImplPrivate::Are3DAPIsBlockedAtTime(
// TODO(kbr): make this pay attention to the TDR thresholds in the
// Windows registry, but make sure it continues to be testable.
{
- std::list<base::Time>::iterator iter = timestamps_of_gpu_resets_.begin();
+ auto iter = timestamps_of_gpu_resets_.begin();
int num_resets_within_timeframe = 0;
while (iter != timestamps_of_gpu_resets_.end()) {
base::Time time = *iter;
@@ -819,7 +842,7 @@ GpuDataManagerImplPrivate::Are3DAPIsBlockedAtTime(
BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
BLOCK_STATUS_MAX);
- return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED;
+ return DomainBlockStatus::kAllDomainsBlocked;
}
}
@@ -827,7 +850,7 @@ GpuDataManagerImplPrivate::Are3DAPIsBlockedAtTime(
BLOCK_STATUS_NOT_BLOCKED,
BLOCK_STATUS_MAX);
- return GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED;
+ return DomainBlockStatus::kNotBlocked;
}
int64_t GpuDataManagerImplPrivate::GetBlockAllDomainsDurationInMs() const {
@@ -835,11 +858,8 @@ int64_t GpuDataManagerImplPrivate::GetBlockAllDomainsDurationInMs() const {
}
bool GpuDataManagerImplPrivate::NeedsCompleteGpuInfoCollection() const {
-#if defined(OS_MACOSX)
- return gpu_info_.gl_vendor.empty();
-#elif defined(OS_WIN)
- return (gpu_info_.dx_diagnostics.values.empty() &&
- gpu_info_.dx_diagnostics.children.empty());
+#if defined(OS_WIN)
+ return gpu_info_.dx_diagnostics.IsEmpty();
#else
return false;
#endif
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl_private.h b/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
index 68fc14b5286..96346d564cc 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -63,6 +63,11 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
void UpdateGpuInfo(
const gpu::GPUInfo& gpu_info,
const base::Optional<gpu::GPUInfo>& optional_gpu_info_for_hardware_gpu);
+#if defined(OS_WIN)
+ void UpdateDxDiagNode(const gpu::DxDiagNode& dx_diagnostics);
+ void UpdateDx12VulkanInfo(
+ const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info);
+#endif
void UpdateGpuFeatureInfo(const gpu::GpuFeatureInfo& gpu_feature_info,
const base::Optional<gpu::GpuFeatureInfo>&
gpu_feature_info_for_hardware_gpu);
@@ -83,8 +88,7 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
void HandleGpuSwitch();
- void BlockDomainFrom3DAPIs(
- const GURL& url, GpuDataManagerImpl::DomainGuilt guilt);
+ void BlockDomainFrom3DAPIs(const GURL& url, gpu::DomainGuilt guilt);
bool Are3DAPIsBlocked(const GURL& top_origin_url,
int render_process_id,
int render_frame_id,
@@ -125,11 +129,16 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
FRIEND_TEST_ALL_PREFIXES(GpuDataManagerImplPrivateTest,
UnblockThisDomainFrom3DAPIs);
- struct DomainBlockEntry {
- GpuDataManagerImpl::DomainGuilt last_guilt;
+ // Indicates the reason that access to a given client API (like
+ // WebGL or Pepper 3D) was blocked or not. This state is distinct
+ // from blacklisting of an entire feature.
+ enum class DomainBlockStatus {
+ kBlocked,
+ kAllDomainsBlocked,
+ kNotBlocked,
};
- using DomainBlockMap = std::map<std::string, DomainBlockEntry>;
+ using DomainGuiltMap = std::map<std::string, gpu::DomainGuilt>;
using GpuDataManagerObserverList =
base::ObserverListThreadSafe<GpuDataManagerObserver>;
@@ -157,16 +166,15 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
// Implementation functions for blocking of 3D graphics APIs, used
// for unit testing.
void BlockDomainFrom3DAPIsAtTime(const GURL& url,
- GpuDataManagerImpl::DomainGuilt guilt,
+ gpu::DomainGuilt guilt,
base::Time at_time);
- GpuDataManagerImpl::DomainBlockStatus Are3DAPIsBlockedAtTime(
- const GURL& url, base::Time at_time) const;
+ DomainBlockStatus Are3DAPIsBlockedAtTime(const GURL& url,
+ base::Time at_time) const;
int64_t GetBlockAllDomainsDurationInMs() const;
// This is platform specific. At the moment:
- // 1) on MacOSX, if GL strings are missing, this returns true;
- // 2) on Windows, if DxDiagnostics are missing, this returns true;
- // 3) all other platforms, this returns false.
+ // 1) on Windows, if DxDiagnostics are missing, this returns true;
+ // 2) all other platforms, this returns false.
bool NeedsCompleteGpuInfoCollection() const;
GpuDataManagerImpl* const owner_;
@@ -197,7 +205,7 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
// they cause random failures.
bool update_histograms_ = true;
- DomainBlockMap blocked_domains_;
+ DomainGuiltMap blocked_domains_;
mutable std::list<base::Time> timestamps_of_gpu_resets_;
bool domain_blocking_enabled_ = true;
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc b/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
index bb1ddc7b334..6dac8e939ee 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc
@@ -6,8 +6,8 @@
#include "base/command_line.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/browser/gpu/gpu_data_manager_impl_private.h"
@@ -84,8 +84,14 @@ class GpuDataManagerImplPrivateTest : public testing::Test {
ScopedGpuDataManagerImplPrivate() { EXPECT_TRUE(impl_.private_.get()); }
~ScopedGpuDataManagerImplPrivate() = default;
- GpuDataManagerImplPrivate* get() { return impl_.private_.get(); }
- GpuDataManagerImplPrivate* operator->() { return impl_.private_.get(); }
+ // NO_THREAD_SAFETY_ANALYSIS should be fine below, because unit tests
+ // pinky-promise to only run single-threaded.
+ GpuDataManagerImplPrivate* get() NO_THREAD_SAFETY_ANALYSIS {
+ return impl_.private_.get();
+ }
+ GpuDataManagerImplPrivate* operator->() NO_THREAD_SAFETY_ANALYSIS {
+ return impl_.private_.get();
+ }
private:
GpuDataManagerImpl impl_;
@@ -94,12 +100,10 @@ class GpuDataManagerImplPrivateTest : public testing::Test {
base::Time JustBeforeExpiration(const GpuDataManagerImplPrivate* manager);
base::Time JustAfterExpiration(const GpuDataManagerImplPrivate* manager);
- void TestBlockingDomainFrom3DAPIs(
- GpuDataManagerImpl::DomainGuilt guilt_level);
- void TestUnblockingDomainFrom3DAPIs(
- GpuDataManagerImpl::DomainGuilt guilt_level);
+ void TestBlockingDomainFrom3DAPIs(gpu::DomainGuilt guilt_level);
+ void TestUnblockingDomainFrom3DAPIs(gpu::DomainGuilt guilt_level);
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
};
// We use new method instead of GetInstance() method because we want
@@ -141,7 +145,7 @@ base::Time GpuDataManagerImplPrivateTest::JustAfterExpiration(
}
void GpuDataManagerImplPrivateTest::TestBlockingDomainFrom3DAPIs(
- GpuDataManagerImpl::DomainGuilt guilt_level) {
+ gpu::DomainGuilt guilt_level) {
ScopedGpuDataManagerImplPrivate manager;
manager->BlockDomainFrom3DAPIsAtTime(GetDomain1ForTesting(),
@@ -149,19 +153,19 @@ void GpuDataManagerImplPrivateTest::TestBlockingDomainFrom3DAPIs(
GetTimeForTesting());
// This domain should be blocked no matter what.
- EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED,
+ EXPECT_EQ(GpuDataManagerImplPrivate::DomainBlockStatus::kBlocked,
manager->Are3DAPIsBlockedAtTime(GetDomain1ForTesting(),
- GetTimeForTesting()));
- EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED,
+ GetTimeForTesting()));
+ EXPECT_EQ(GpuDataManagerImplPrivate::DomainBlockStatus::kBlocked,
manager->Are3DAPIsBlockedAtTime(
GetDomain1ForTesting(), JustBeforeExpiration(manager.get())));
- EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED,
+ EXPECT_EQ(GpuDataManagerImplPrivate::DomainBlockStatus::kBlocked,
manager->Are3DAPIsBlockedAtTime(
GetDomain1ForTesting(), JustAfterExpiration(manager.get())));
}
void GpuDataManagerImplPrivateTest::TestUnblockingDomainFrom3DAPIs(
- GpuDataManagerImpl::DomainGuilt guilt_level) {
+ gpu::DomainGuilt guilt_level) {
ScopedGpuDataManagerImplPrivate manager;
manager->BlockDomainFrom3DAPIsAtTime(GetDomain1ForTesting(),
@@ -170,64 +174,62 @@ void GpuDataManagerImplPrivateTest::TestUnblockingDomainFrom3DAPIs(
// Unblocking the domain should work.
manager->UnblockDomainFrom3DAPIs(GetDomain1ForTesting());
- EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED,
+ EXPECT_EQ(GpuDataManagerImplPrivate::DomainBlockStatus::kNotBlocked,
manager->Are3DAPIsBlockedAtTime(GetDomain1ForTesting(),
GetTimeForTesting()));
- EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED,
+ EXPECT_EQ(GpuDataManagerImplPrivate::DomainBlockStatus::kNotBlocked,
manager->Are3DAPIsBlockedAtTime(
GetDomain1ForTesting(), JustBeforeExpiration(manager.get())));
- EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED,
+ EXPECT_EQ(GpuDataManagerImplPrivate::DomainBlockStatus::kNotBlocked,
manager->Are3DAPIsBlockedAtTime(
GetDomain1ForTesting(), JustAfterExpiration(manager.get())));
}
TEST_F(GpuDataManagerImplPrivateTest, BlockGuiltyDomainFrom3DAPIs) {
- TestBlockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_KNOWN);
+ TestBlockingDomainFrom3DAPIs(gpu::DomainGuilt::kKnown);
}
TEST_F(GpuDataManagerImplPrivateTest, BlockDomainOfUnknownGuiltFrom3DAPIs) {
- TestBlockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN);
+ TestBlockingDomainFrom3DAPIs(gpu::DomainGuilt::kUnknown);
}
TEST_F(GpuDataManagerImplPrivateTest, BlockAllDomainsFrom3DAPIs) {
ScopedGpuDataManagerImplPrivate manager;
- manager->BlockDomainFrom3DAPIsAtTime(GetDomain1ForTesting(),
- GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN,
- GetTimeForTesting());
+ manager->BlockDomainFrom3DAPIsAtTime(
+ GetDomain1ForTesting(), gpu::DomainGuilt::kUnknown, GetTimeForTesting());
// Blocking of other domains should expire.
- EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_ALL_DOMAINS_BLOCKED,
+ EXPECT_EQ(GpuDataManagerImplPrivate::DomainBlockStatus::kAllDomainsBlocked,
manager->Are3DAPIsBlockedAtTime(
GetDomain2ForTesting(), JustBeforeExpiration(manager.get())));
- EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED,
+ EXPECT_EQ(GpuDataManagerImplPrivate::DomainBlockStatus::kNotBlocked,
manager->Are3DAPIsBlockedAtTime(
GetDomain2ForTesting(), JustAfterExpiration(manager.get())));
}
TEST_F(GpuDataManagerImplPrivateTest, UnblockGuiltyDomainFrom3DAPIs) {
- TestUnblockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_KNOWN);
+ TestUnblockingDomainFrom3DAPIs(gpu::DomainGuilt::kKnown);
}
TEST_F(GpuDataManagerImplPrivateTest, UnblockDomainOfUnknownGuiltFrom3DAPIs) {
- TestUnblockingDomainFrom3DAPIs(GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN);
+ TestUnblockingDomainFrom3DAPIs(gpu::DomainGuilt::kUnknown);
}
TEST_F(GpuDataManagerImplPrivateTest, UnblockOtherDomainFrom3DAPIs) {
ScopedGpuDataManagerImplPrivate manager;
- manager->BlockDomainFrom3DAPIsAtTime(GetDomain1ForTesting(),
- GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN,
- GetTimeForTesting());
+ manager->BlockDomainFrom3DAPIsAtTime(
+ GetDomain1ForTesting(), gpu::DomainGuilt::kUnknown, GetTimeForTesting());
manager->UnblockDomainFrom3DAPIs(GetDomain2ForTesting());
- EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED,
+ EXPECT_EQ(GpuDataManagerImplPrivate::DomainBlockStatus::kNotBlocked,
manager->Are3DAPIsBlockedAtTime(
GetDomain2ForTesting(), JustBeforeExpiration(manager.get())));
// The original domain should still be blocked.
- EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_BLOCKED,
+ EXPECT_EQ(GpuDataManagerImplPrivate::DomainBlockStatus::kBlocked,
manager->Are3DAPIsBlockedAtTime(
GetDomain1ForTesting(), JustBeforeExpiration(manager.get())));
}
@@ -235,15 +237,14 @@ TEST_F(GpuDataManagerImplPrivateTest, UnblockOtherDomainFrom3DAPIs) {
TEST_F(GpuDataManagerImplPrivateTest, UnblockThisDomainFrom3DAPIs) {
ScopedGpuDataManagerImplPrivate manager;
- manager->BlockDomainFrom3DAPIsAtTime(GetDomain1ForTesting(),
- GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN,
- GetTimeForTesting());
+ manager->BlockDomainFrom3DAPIsAtTime(
+ GetDomain1ForTesting(), gpu::DomainGuilt::kUnknown, GetTimeForTesting());
manager->UnblockDomainFrom3DAPIs(GetDomain1ForTesting());
// This behavior is debatable. Perhaps the GPU reset caused by
// domain 1 should still cause other domains to be blocked.
- EXPECT_EQ(GpuDataManagerImpl::DOMAIN_BLOCK_STATUS_NOT_BLOCKED,
+ EXPECT_EQ(GpuDataManagerImplPrivate::DomainBlockStatus::kNotBlocked,
manager->Are3DAPIsBlockedAtTime(
GetDomain2ForTesting(), JustBeforeExpiration(manager.get())));
}
diff --git a/chromium/content/browser/gpu/gpu_internals_ui.cc b/chromium/content/browser/gpu/gpu_internals_ui.cc
index 02779864950..abfcc0c3c02 100644
--- a/chromium/content/browser/gpu/gpu_internals_ui.cc
+++ b/chromium/content/browser/gpu/gpu_internals_ui.cc
@@ -213,11 +213,12 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
basic_info->Append(NewDescriptionValuePair(
"Driver D3D12 feature level",
- D3dFeaturelevelToString(gpu_info.d3d12_feature_level)));
+ D3dFeaturelevelToString(
+ gpu_info.dx12_vulkan_version_info.d3d12_feature_level)));
- basic_info->Append(
- NewDescriptionValuePair("Driver Vulkan API version",
- VulkanVersionToString(gpu_info.vulkan_version)));
+ basic_info->Append(NewDescriptionValuePair(
+ "Driver Vulkan API version",
+ VulkanVersionToString(gpu_info.dx12_vulkan_version_info.vulkan_version)));
#endif
basic_info->Append(
diff --git a/chromium/content/browser/gpu/gpu_ipc_browsertests.cc b/chromium/content/browser/gpu/gpu_ipc_browsertests.cc
index 5c930b2e7da..02b5dac7d15 100644
--- a/chromium/content/browser/gpu/gpu_ipc_browsertests.cc
+++ b/chromium/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -4,15 +4,17 @@
#include "base/command_line.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "components/viz/common/gpu/context_provider.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/compositor/image_transport_factory.h"
#include "content/browser/gpu/gpu_process_host.h"
-#include "content/common/gpu_stream_constants.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/gpu_data_manager.h"
#include "content/public/browser/gpu_utils.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_stream_constants.h"
#include "content/public/test/content_browser_test.h"
#include "content/test/gpu_browsertest_helpers.h"
#include "gpu/ipc/client/command_buffer_proxy_impl.h"
@@ -349,7 +351,7 @@ IN_PROC_BROWSER_TEST_F(BrowserGpuChannelHostFactoryTest, CreateTransferBuffer) {
// channel on the IO thread, which then notifies the main thread about the
// error state.
base::RunLoop wait_for_io_run_loop;
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})
->PostTask(FROM_HERE, wait_for_io_run_loop.QuitClosure());
// Waits for the IO thread to run.
wait_for_io_run_loop.Run();
diff --git a/chromium/content/browser/gpu/gpu_memory_buffer_manager_singleton.cc b/chromium/content/browser/gpu/gpu_memory_buffer_manager_singleton.cc
index 780450a72bc..bcbf14e38e4 100644
--- a/chromium/content/browser/gpu/gpu_memory_buffer_manager_singleton.cc
+++ b/chromium/content/browser/gpu/gpu_memory_buffer_manager_singleton.cc
@@ -6,7 +6,10 @@
#include "base/bind.h"
#include "base/logging.h"
+#include "base/task/post_task.h"
+#include "components/viz/host/gpu_host_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
@@ -18,7 +21,8 @@ GpuMemoryBufferManagerSingleton* g_gpu_memory_buffer_manager;
viz::mojom::GpuService* GetGpuService(
base::OnceClosure connection_error_handler) {
if (auto* host = GpuProcessHost::Get()) {
- host->AddConnectionErrorHandler(std::move(connection_error_handler));
+ host->gpu_host()->AddConnectionErrorHandler(
+ std::move(connection_error_handler));
return host->gpu_service();
}
return nullptr;
@@ -31,7 +35,7 @@ GpuMemoryBufferManagerSingleton::GpuMemoryBufferManagerSingleton(int client_id)
base::BindRepeating(&content::GetGpuService),
client_id,
std::make_unique<gpu::GpuMemoryBufferSupport>(),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)) {
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})) {
DCHECK(!g_gpu_memory_buffer_manager);
g_gpu_memory_buffer_manager = this;
}
diff --git a/chromium/content/browser/gpu/gpu_process_host.cc b/chromium/content/browser/gpu/gpu_process_host.cc
index 9511100e607..b184eee1b89 100644
--- a/chromium/content/browser/gpu/gpu_process_host.cc
+++ b/chromium/content/browser/gpu/gpu_process_host.cc
@@ -15,7 +15,6 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
-#include "base/debug/alias.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -26,6 +25,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
@@ -50,6 +50,7 @@
#include "content/common/memory_coordinator.mojom.h"
#include "content/common/service_manager/child_connection.h"
#include "content/common/view_messages.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/gpu_utils.h"
@@ -277,39 +278,6 @@ void RunCallbackOnIO(GpuProcessHost::GpuProcessKind kind,
callback.Run(host);
}
-#if defined(USE_OZONE)
-// The ozone platform use this callback to send IPC messages to the gpu process.
-void SendGpuProcessMessage(base::WeakPtr<GpuProcessHost> host,
- IPC::Message* message) {
- if (host)
- host->Send(message);
- else
- delete message;
-}
-
-// Helper to register Mus/conventional thread bouncers for ozone startup.
-void OzoneRegisterStartupCallbackHelper(
- base::OnceCallback<void(ui::OzonePlatform*)> io_callback) {
- // The callback registered in ozone can be called in any thread. So use an
- // intermediary callback that bounces to the IO thread if needed, before
- // running the callback.
- auto bounce_callback = base::BindOnce(
- [](base::TaskRunner* task_runner,
- base::OnceCallback<void(ui::OzonePlatform*)> callback,
- ui::OzonePlatform* platform) {
- if (task_runner->RunsTasksInCurrentSequence()) {
- std::move(callback).Run(platform);
- } else {
- task_runner->PostTask(FROM_HERE,
- base::BindOnce(std::move(callback), platform));
- }
- },
- base::RetainedRef(base::ThreadTaskRunnerHandle::Get()),
- std::move(io_callback));
- ui::OzonePlatform::RegisterStartupCallback(std::move(bounce_callback));
-}
-#endif // defined(USE_OZONE)
-
void OnGpuProcessHostDestroyedOnUI(int host_id, const std::string& message) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
GpuDataManagerImpl::GetInstance()->AddLogMessage(
@@ -477,8 +445,8 @@ void BindDiscardableMemoryRequestOnUI(
return;
}
#endif
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&BindDiscardableMemoryRequestOnIO, std::move(request),
BrowserMainLoop::GetInstance()->discardable_shared_memory_manager()));
@@ -496,7 +464,8 @@ void CreateMemoryCoordinatorHandleForGpuProcess(
class GpuProcessHost::ConnectionFilterImpl : public ConnectionFilter {
public:
explicit ConnectionFilterImpl(int gpu_process_id) {
- auto task_runner = BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
+ auto task_runner =
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
registry_.AddInterface(base::Bind(&FieldTrialRecorder::Create),
task_runner);
#if defined(OS_ANDROID)
@@ -588,8 +557,8 @@ GpuProcessHost* GpuProcessHost::Get(GpuProcessKind kind, bool force_create) {
// static
void GpuProcessHost::GetHasGpuProcess(base::OnceCallback<void(bool)> callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&GpuProcessHost::GetHasGpuProcess, std::move(callback)));
return;
}
@@ -610,10 +579,10 @@ void GpuProcessHost::CallOnIO(
bool force_create,
const base::Callback<void(GpuProcessHost*)>& callback) {
#if !defined(OS_WIN)
- DCHECK_NE(kind, GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED);
+ DCHECK_NE(kind, GpuProcessHost::GPU_PROCESS_KIND_UNSANDBOXED_NO_GL);
#endif
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&RunCallbackOnIO, kind, force_create, callback));
}
@@ -622,18 +591,16 @@ void GpuProcessHost::BindInterface(
mojo::ScopedMessagePipeHandle interface_pipe) {
if (interface_name ==
discardable_memory::mojom::DiscardableSharedMemoryManager::Name_) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(
- &BindDiscardableMemoryRequestOnUI,
- discardable_memory::mojom::DiscardableSharedMemoryManagerRequest(
- std::move(interface_pipe))));
+ BindDiscardableMemoryRequest(
+ discardable_memory::mojom::DiscardableSharedMemoryManagerRequest(
+ std::move(interface_pipe)));
return;
}
process_->child_connection()->BindInterface(interface_name,
std::move(interface_pipe));
}
+#if defined(USE_OZONE)
void GpuProcessHost::TerminateGpuProcess(const std::string& message) {
// At the moment, this path is only used by Ozone/Wayland. Once others start
// to use this, start to distinguish the origin of termination. By default,
@@ -642,6 +609,11 @@ void GpuProcessHost::TerminateGpuProcess(const std::string& message) {
process_->TerminateOnBadMessageReceived(message);
}
+void GpuProcessHost::SendGpuProcessMessage(IPC::Message* message) {
+ Send(message);
+}
+#endif // defined(USE_OZONE)
+
// static
GpuProcessHost* GpuProcessHost::FromID(int host_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -799,65 +771,11 @@ GpuProcessHost::~GpuProcessHost() {
if (block_offscreen_contexts && gpu_host_)
gpu_host_->BlockLiveOffscreenContexts();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&OnGpuProcessHostDestroyedOnUI, host_id_, message));
}
-#if defined(USE_OZONE)
-void GpuProcessHost::InitOzone() {
- // Ozone needs to send the primary DRM device to GPU process as early as
- // possible to ensure the latter always has a valid device. crbug.com/608839
- // When running with mus, the OzonePlatform may not have been created yet. So
- // defer the callback until OzonePlatform instance is created.
- bool using_mojo = true;
-#if defined(OS_CHROMEOS)
- using_mojo = features::IsOzoneDrmMojo();
-#endif
- if (using_mojo) {
- // TODO(rjkroege): Remove the legacy IPC code paths when no longer
- // necessary. https://crbug.com/806092
- auto interface_binder = base::BindRepeating(&GpuProcessHost::BindInterface,
- weak_ptr_factory_.GetWeakPtr());
- auto terminate_cb = base::BindOnce(&GpuProcessHost::TerminateGpuProcess,
- weak_ptr_factory_.GetWeakPtr());
-
- auto io_callback = base::BindOnce(
- [](const base::RepeatingCallback<void(const std::string&,
- mojo::ScopedMessagePipeHandle)>&
- interface_binder,
- base::OnceCallback<void(const std::string&)> terminate_cb,
- ui::OzonePlatform* platform) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- platform->GetGpuPlatformSupportHost()->OnGpuServiceLaunched(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
- interface_binder, std::move(terminate_cb));
- },
- interface_binder, std::move(terminate_cb));
-
- OzoneRegisterStartupCallbackHelper(std::move(io_callback));
- } else {
- auto send_callback = base::BindRepeating(&SendGpuProcessMessage,
- weak_ptr_factory_.GetWeakPtr());
- // Create the callback that should run on the current thread (i.e. IO
- // thread).
- auto io_callback = base::BindOnce(
- [](int host_id,
- const base::RepeatingCallback<void(IPC::Message*)>& send_callback,
- ui::OzonePlatform* platform) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- platform->GetGpuPlatformSupportHost()->OnGpuProcessLaunched(
- host_id, BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
- send_callback);
- },
- host_id_, send_callback);
- OzoneRegisterStartupCallbackHelper(std::move(io_callback));
- }
-}
-#endif // defined(USE_OZONE)
-
bool GpuProcessHost::Init() {
init_start_time_ = base::TimeTicks::Now();
@@ -900,6 +818,10 @@ bool GpuProcessHost::Init() {
return false;
}
+ viz::mojom::VizMainAssociatedPtr viz_main_ptr;
+ process_->child_channel()
+ ->GetAssociatedInterfaceSupport()
+ ->GetRemoteAssociatedInterface(&viz_main_ptr);
viz::GpuHostImpl::InitParams params;
params.restart_id = host_id_;
params.in_process = in_process_;
@@ -909,12 +831,11 @@ bool GpuProcessHost::Init() {
params.product = GetContentClient()->GetProduct();
params.deadline_to_synchronize_surfaces =
switches::GetDeadlineToSynchronizeSurfaces();
+ params.main_thread_task_runner =
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
gpu_host_ = std::make_unique<viz::GpuHostImpl>(
- this, process_->child_channel(), std::move(params));
-
-#if defined(USE_OZONE)
- InitOzone();
-#endif // defined(USE_OZONE)
+ this, std::make_unique<viz::VizMainWrapper>(std::move(viz_main_ptr)),
+ std::move(params));
#if defined(OS_MACOSX)
ca_transaction_gpu_coordinator_ = CATransactionGPUCoordinator::Create(this);
@@ -959,17 +880,6 @@ void GpuProcessHost::OnChannelConnected(int32_t peer_pid) {
}
}
-void GpuProcessHost::AddConnectionErrorHandler(base::OnceClosure handler) {
- connection_error_handlers_.push_back(std::move(handler));
-}
-
-#if defined(OS_ANDROID)
-void GpuProcessHost::OnDestroyingVideoSurfaceAck() {
- TRACE_EVENT0("gpu", "GpuProcessHost::OnDestroyingVideoSurfaceAck");
- if (!send_destroying_video_surface_done_cb_.is_null())
- base::ResetAndReturn(&send_destroying_video_surface_done_cb_).Run();
-}
-#endif
void GpuProcessHost::OnProcessLaunched() {
UMA_HISTOGRAM_TIMES("GPU.GPUProcessLaunchTime",
@@ -987,11 +897,6 @@ void GpuProcessHost::OnProcessLaunched() {
}
void GpuProcessHost::OnProcessLaunchFailed(int error_code) {
- // TODO(crbug.com/849639): Ensure |error_code| is included in crash minidumps.
- // This is for debugging and should be removed when bug is closed.
- int process_launch_error_code = error_code;
- base::debug::Alias(&process_launch_error_code);
-
#if defined(OS_WIN)
if (kind_ == GPU_PROCESS_KIND_SANDBOXED)
RecordAppContainerStatus(error_code, crashed_before_);
@@ -1000,11 +905,6 @@ void GpuProcessHost::OnProcessLaunchFailed(int error_code) {
}
void GpuProcessHost::OnProcessCrashed(int exit_code) {
- // TODO(crbug.com/849639): Ensure |exit_code| is included in crash minidumps.
- // This is for debugging and should be removed when bug is closed.
- int process_crash_exit_code = exit_code;
- base::debug::Alias(&process_crash_exit_code);
-
// Record crash before doing anything that could start a new GPU process.
RecordProcessCrash();
@@ -1025,21 +925,24 @@ gpu::GpuFeatureInfo GpuProcessHost::GetGpuFeatureInfo() const {
return GpuDataManagerImpl::GetInstance()->GetGpuFeatureInfo();
}
-void GpuProcessHost::UpdateGpuInfo(
+void GpuProcessHost::DidInitialize(
const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info,
const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
const base::Optional<gpu::GpuFeatureInfo>&
gpu_feature_info_for_hardware_gpu) {
- auto* gpu_data_manager = GpuDataManagerImpl::GetInstance();
- // Update GpuFeatureInfo first, because UpdateGpuInfo() will notify all
- // listeners.
- gpu_data_manager->UpdateGpuFeatureInfo(gpu_feature_info,
- gpu_feature_info_for_hardware_gpu);
- gpu_data_manager->UpdateGpuInfo(gpu_info, gpu_info_for_hardware_gpu);
+ if (kind_ != GPU_PROCESS_KIND_UNSANDBOXED_NO_GL) {
+ auto* gpu_data_manager = GpuDataManagerImpl::GetInstance();
+ // Update GpuFeatureInfo first, because UpdateGpuInfo() will notify all
+ // listeners.
+ gpu_data_manager->UpdateGpuFeatureInfo(gpu_feature_info,
+ gpu_feature_info_for_hardware_gpu);
+ gpu_data_manager->UpdateGpuInfo(gpu_info, gpu_info_for_hardware_gpu);
+ }
}
void GpuProcessHost::DidFailInitialize() {
+ did_fail_initialize_ = true;
if (kind_ == GPU_PROCESS_KIND_SANDBOXED)
GpuDataManagerImpl::GetInstance()->FallBackToNextGpuMode();
}
@@ -1054,17 +957,8 @@ void GpuProcessHost::DidCreateContextSuccessfully() {
}
void GpuProcessHost::BlockDomainFrom3DAPIs(const GURL& url,
- Delegate::DomainGuilt guilt) {
- GpuDataManagerImpl::DomainGuilt gpu_data_manager_guilt;
- switch (guilt) {
- case Delegate::DomainGuilt::kKnown:
- gpu_data_manager_guilt = GpuDataManagerImpl::DOMAIN_GUILT_KNOWN;
- break;
- case Delegate::DomainGuilt::kUnknown:
- gpu_data_manager_guilt = GpuDataManagerImpl::DOMAIN_GUILT_UNKNOWN;
- }
- GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs(
- url, gpu_data_manager_guilt);
+ gpu::DomainGuilt guilt) {
+ GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs(url, guilt);
}
bool GpuProcessHost::GpuAccessAllowed() const {
@@ -1075,8 +969,8 @@ void GpuProcessHost::DisableGpuCompositing() {
#if !defined(OS_ANDROID)
// TODO(crbug.com/819474): The switch from GPU to software compositing should
// be handled here instead of by ImageTransportFactory.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, base::BindOnce([]() {
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI}, base::BindOnce([]() {
if (auto* factory = ImageTransportFactory::GetInstance())
factory->DisableGpuCompositing();
}));
@@ -1095,8 +989,8 @@ void GpuProcessHost::RecordLogMessage(int32_t severity,
void GpuProcessHost::BindDiscardableMemoryRequest(
discardable_memory::mojom::DiscardableSharedMemoryManagerRequest request) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&BindDiscardableMemoryRequestOnUI, std::move(request)));
}
@@ -1151,8 +1045,11 @@ bool GpuProcessHost::LaunchGpuProcess() {
cmd_line->AppendArg(switches::kPrefetchArgumentGpu);
#endif // defined(OS_WIN)
- if (kind_ == GPU_PROCESS_KIND_UNSANDBOXED)
+ if (kind_ == GPU_PROCESS_KIND_UNSANDBOXED_NO_GL) {
cmd_line->AppendSwitch(service_manager::switches::kDisableGpuSandbox);
+ cmd_line->AppendSwitchASCII(switches::kUseGL,
+ gl::kGLImplementationDisabledName);
+ }
// TODO(penghuang): Replace all GPU related switches with GpuPreferences.
// https://crbug.com/590825
@@ -1217,15 +1114,8 @@ bool GpuProcessHost::LaunchGpuProcess() {
void GpuProcessHost::SendOutstandingReplies() {
valid_ = false;
- for (auto& handler : connection_error_handlers_)
- std::move(handler).Run();
- connection_error_handlers_.clear();
-
if (gpu_host_)
gpu_host_->SendOutstandingReplies();
-
- if (!send_destroying_video_surface_done_cb_.is_null())
- base::ResetAndReturn(&send_destroying_video_surface_done_cb_).Run();
}
void GpuProcessHost::RecordProcessCrash() {
@@ -1276,18 +1166,8 @@ void GpuProcessHost::RecordProcessCrash() {
recent_crash_count = display_compositor_recent_crash_count_;
}
- // TODO(crbug.com/849639): Ensure crash counts are included in crash
- // minidumps. This is for debugging and should be removed when bug is closed.
- int hardware_accelerated_crash_count =
- hardware_accelerated_recent_crash_count_;
- base::debug::Alias(&hardware_accelerated_crash_count);
- int swiftshader_crash_count = swiftshader_recent_crash_count_;
- base::debug::Alias(&swiftshader_crash_count);
- int display_compositor_crash_count = display_compositor_recent_crash_count_;
- base::debug::Alias(&display_compositor_crash_count);
-
// GPU process initialization failed and fallback already happened.
- if (!gpu_host_ || !gpu_host_->initialized())
+ if (did_fail_initialize_)
return;
bool disable_crash_limit = base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/chromium/content/browser/gpu/gpu_process_host.h b/chromium/content/browser/gpu/gpu_process_host.h
index d79907844e1..fdc79781b4d 100644
--- a/chromium/content/browser/gpu/gpu_process_host.h
+++ b/chromium/content/browser/gpu/gpu_process_host.h
@@ -11,7 +11,6 @@
#include <memory>
#include <set>
#include <string>
-#include <vector>
#include "base/atomicops.h"
#include "base/callback.h"
@@ -56,7 +55,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
public viz::GpuHostImpl::Delegate {
public:
enum GpuProcessKind {
- GPU_PROCESS_KIND_UNSANDBOXED,
+ GPU_PROCESS_KIND_UNSANDBOXED_NO_GL, // Unsandboxed, no init GL bindings.
GPU_PROCESS_KIND_SANDBOXED,
GPU_PROCESS_KIND_COUNT
};
@@ -85,10 +84,6 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
bool force_create,
const base::Callback<void(GpuProcessHost*)>& callback);
- void BindInterface(const std::string& interface_name,
- mojo::ScopedMessagePipeHandle interface_pipe);
- void TerminateGpuProcess(const std::string& message);
-
// Get the GPU process host for the GPU process with the given ID. Returns
// null if the process no longer exists.
static GpuProcessHost* FromID(int host_id);
@@ -98,9 +93,6 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
// IPC::Sender implementation.
bool Send(IPC::Message* msg) override;
- // Adds a connection error handler for the GpuService.
- void AddConnectionErrorHandler(base::OnceClosure handler);
-
// What kind of GPU process, e.g. sandboxed or unsandboxed.
GpuProcessKind kind();
@@ -134,10 +126,6 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
bool Init();
-#if defined(USE_OZONE)
- void InitOzone();
-#endif // defined(USE_OZONE)
-
// BrowserChildProcessHostDelegate implementation.
bool OnMessageReceived(const IPC::Message& message) override;
void OnChannelConnected(int32_t peer_pid) override;
@@ -148,7 +136,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
// viz::GpuHostImpl::Delegate:
gpu::GPUInfo GetGPUInfo() const override;
gpu::GpuFeatureInfo GetGpuFeatureInfo() const override;
- void UpdateGpuInfo(
+ void DidInitialize(
const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info,
const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu,
@@ -156,8 +144,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
gpu_feature_info_for_hardware_gpu) override;
void DidFailInitialize() override;
void DidCreateContextSuccessfully() override;
- void BlockDomainFrom3DAPIs(const GURL& url,
- Delegate::DomainGuilt guilt) override;
+ void BlockDomainFrom3DAPIs(const GURL& url, gpu::DomainGuilt guilt) override;
void DisableGpuCompositing() override;
bool GpuAccessAllowed() const override;
gpu::ShaderCacheFactory* GetShaderCacheFactory() override;
@@ -167,11 +154,14 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
void BindDiscardableMemoryRequest(
discardable_memory::mojom::DiscardableSharedMemoryManagerRequest request)
override;
+ void BindInterface(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe) override;
+#if defined(USE_OZONE)
+ void TerminateGpuProcess(const std::string& message) override;
+ void SendGpuProcessMessage(IPC::Message* message) override;
+#endif
// Message handlers.
-#if defined(OS_ANDROID)
- void OnDestroyingVideoSurfaceAck();
-#endif
void OnFieldTrialActivated(const std::string& trial_name);
bool LaunchGpuProcess();
@@ -189,12 +179,6 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
// GPU process id in case GPU is not in-process.
base::ProcessId process_id_ = base::kNullProcessId;
- // List of connection error handlers for the GpuService.
- std::vector<base::OnceClosure> connection_error_handlers_;
-
- // A callback to signal the completion of a SendDestroyingVideoSurface call.
- base::Closure send_destroying_video_surface_done_cb_;
-
// Qeueud messages to send when the process launches.
base::queue<IPC::Message*> queued_messages_;
@@ -218,6 +202,9 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
// Time Init started. Used to log total GPU process startup time to UMA.
base::TimeTicks init_start_time_;
+ // The GPU process reported failure to initialize.
+ bool did_fail_initialize_ = false;
+
// The total number of GPU process crashes.
static base::subtle::Atomic32 gpu_crash_count_;
static bool crashed_before_;
diff --git a/chromium/content/browser/gpu/in_process_gpu_thread_browsertests.cc b/chromium/content/browser/gpu/in_process_gpu_thread_browsertests.cc
index 22cc546f4c4..f3b231e7faf 100644
--- a/chromium/content/browser/gpu/in_process_gpu_thread_browsertests.cc
+++ b/chromium/content/browser/gpu/in_process_gpu_thread_browsertests.cc
@@ -4,9 +4,11 @@
#include "base/command_line.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/gpu/in_process_gpu_thread.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/content_browser_test.h"
@@ -30,9 +32,9 @@ void CreateGpuProcessHost() {
void WaitUntilGpuProcessHostIsCreated() {
base::RunLoop run_loop;
- content::BrowserThread::PostTaskAndReply(
- content::BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CreateGpuProcessHost), run_loop.QuitClosure());
+ base::PostTaskWithTraitsAndReply(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(&CreateGpuProcessHost),
+ run_loop.QuitClosure());
run_loop.Run();
}
diff --git a/chromium/content/browser/renderer_host/media/video_capture_dependencies.cc b/chromium/content/browser/gpu/video_capture_dependencies.cc
index 26567c6579b..c84be26c82a 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_dependencies.cc
+++ b/chromium/content/browser/gpu/video_capture_dependencies.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/renderer_host/media/video_capture_dependencies.h"
+#include "content/browser/gpu/video_capture_dependencies.h"
+#include "base/task/post_task.h"
#include "content/browser/gpu/gpu_process_host.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
namespace content {
@@ -14,8 +15,8 @@ namespace content {
void VideoCaptureDependencies::CreateJpegDecodeAccelerator(
media::mojom::JpegDecodeAcceleratorRequest accelerator) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&VideoCaptureDependencies::CreateJpegDecodeAccelerator,
std::move(accelerator)));
return;
@@ -34,8 +35,8 @@ void VideoCaptureDependencies::CreateJpegDecodeAccelerator(
void VideoCaptureDependencies::CreateJpegEncodeAccelerator(
media::mojom::JpegEncodeAcceleratorRequest accelerator) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&VideoCaptureDependencies::CreateJpegEncodeAccelerator,
std::move(accelerator)));
return;
diff --git a/chromium/content/browser/renderer_host/media/video_capture_dependencies.h b/chromium/content/browser/gpu/video_capture_dependencies.h
index 5804eef9f03..ab169bb1051 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_dependencies.h
+++ b/chromium/content/browser/gpu/video_capture_dependencies.h
@@ -2,16 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_DEPENDENCIES_H_
-#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_DEPENDENCIES_H_
+#ifndef CONTENT_BROWSER_GPU_VIDEO_CAPTURE_DEPENDENCIES_H_
+#define CONTENT_BROWSER_GPU_VIDEO_CAPTURE_DEPENDENCIES_H_
#include "content/common/content_export.h"
-#include "services/video_capture/public/mojom/device_factory.mojom.h"
#include "services/viz/privileged/interfaces/gl/gpu_service.mojom.h"
namespace content {
-// Browser-provided GPU dependencies for video capture.
+// Browser-process-provided GPU dependencies for video capture.
class CONTENT_EXPORT VideoCaptureDependencies {
public:
static void CreateJpegDecodeAccelerator(
@@ -22,4 +21,4 @@ class CONTENT_EXPORT VideoCaptureDependencies {
} // namespace content
-#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_DEPENDENCIES_H_
+#endif // CONTENT_BROWSER_GPU_VIDEO_CAPTURE_DEPENDENCIES_H_
diff --git a/chromium/content/browser/gpu_interface_provider.cc b/chromium/content/browser/gpu_interface_provider.cc
new file mode 100644
index 00000000000..f4153c7f5f5
--- /dev/null
+++ b/chromium/content/browser/gpu_interface_provider.cc
@@ -0,0 +1,96 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/gpu_interface_provider.h"
+
+#include "base/containers/unique_ptr_adapters.h"
+#include "base/memory/ref_counted.h"
+#include "base/task/post_task.h"
+#include "components/discardable_memory/public/interfaces/discardable_shared_memory_manager.mojom.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/gpu_client.h"
+#include "content/public/browser/gpu_interface_provider_factory.h"
+#include "content/public/browser/gpu_service_registry.h"
+#include "services/ws/public/mojom/gpu.mojom.h"
+
+namespace content {
+
+// InterfaceBinderImpl handles the actual binding. The binding has to happen on
+// the IO thread.
+class GpuInterfaceProvider::InterfaceBinderImpl
+ : public base::RefCountedThreadSafe<InterfaceBinderImpl> {
+ public:
+ InterfaceBinderImpl() = default;
+
+ void BindGpuRequestOnGpuTaskRunner(ws::mojom::GpuRequest request) {
+ // The GPU task runner is bound to the IO thread.
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ auto gpu_client = content::CreateGpuClient(
+ std::move(request),
+ base::BindOnce(&InterfaceBinderImpl::OnGpuClientConnectionError, this),
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {content::BrowserThread::IO}));
+ gpu_clients_.push_back(std::move(gpu_client));
+ }
+
+ void BindDiscardableSharedMemoryManagerOnGpuTaskRunner(
+ discardable_memory::mojom::DiscardableSharedMemoryManagerRequest
+ request) {
+ content::BindInterfaceInGpuProcess(std::move(request));
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<InterfaceBinderImpl>;
+ ~InterfaceBinderImpl() = default;
+
+ void OnGpuClientConnectionError(viz::GpuClient* client) {
+ base::EraseIf(
+ gpu_clients_,
+ base::UniquePtrMatcher<viz::GpuClient, base::OnTaskRunnerDeleter>(
+ client));
+ }
+
+ std::vector<std::unique_ptr<viz::GpuClient, base::OnTaskRunnerDeleter>>
+ gpu_clients_;
+
+ DISALLOW_COPY_AND_ASSIGN(InterfaceBinderImpl);
+};
+
+GpuInterfaceProvider::GpuInterfaceProvider()
+ : interface_binder_impl_(base::MakeRefCounted<InterfaceBinderImpl>()) {}
+
+GpuInterfaceProvider::~GpuInterfaceProvider() = default;
+
+void GpuInterfaceProvider::RegisterGpuInterfaces(
+ service_manager::BinderRegistry* registry) {
+ scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner =
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {content::BrowserThread::IO});
+ registry->AddInterface(
+ base::BindRepeating(&InterfaceBinderImpl::
+ BindDiscardableSharedMemoryManagerOnGpuTaskRunner,
+ interface_binder_impl_),
+ gpu_task_runner);
+ registry->AddInterface(
+ base::BindRepeating(&InterfaceBinderImpl::BindGpuRequestOnGpuTaskRunner,
+ interface_binder_impl_),
+ gpu_task_runner);
+}
+
+#if defined(USE_OZONE)
+void GpuInterfaceProvider::RegisterOzoneGpuInterfaces(
+ service_manager::BinderRegistry* registry) {
+ // Registers the gpu-related interfaces needed by Ozone.
+ // TODO(rjkroege): Adjust when Ozone/DRM/Mojo is complete.
+ NOTIMPLEMENTED();
+}
+#endif
+
+// Factory.
+std::unique_ptr<ws::GpuInterfaceProvider> CreateGpuInterfaceProvider() {
+ return std::make_unique<GpuInterfaceProvider>();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/gpu_interface_provider.h b/chromium/content/browser/gpu_interface_provider.h
new file mode 100644
index 00000000000..e256aa05cf3
--- /dev/null
+++ b/chromium/content/browser/gpu_interface_provider.h
@@ -0,0 +1,40 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_GPU_INTERFACE_PROVIDER_H_
+#define CONTENT_BROWSER_GPU_INTERFACE_PROVIDER_H_
+
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "content/common/content_export.h"
+#include "services/ws/public/cpp/host/gpu_interface_provider.h"
+
+namespace content {
+
+// An implementation of GpuInterfaceProvider that forwards to the Gpu
+// implementation in content.
+class CONTENT_EXPORT GpuInterfaceProvider : public ws::GpuInterfaceProvider {
+ public:
+ GpuInterfaceProvider();
+ ~GpuInterfaceProvider() override;
+
+ // ws::GpuInterfaceProvider:
+ void RegisterGpuInterfaces(
+ service_manager::BinderRegistry* registry) override;
+#if defined(USE_OZONE)
+ void RegisterOzoneGpuInterfaces(
+ service_manager::BinderRegistry* registry) override;
+#endif
+
+ private:
+ class InterfaceBinderImpl;
+
+ scoped_refptr<InterfaceBinderImpl> interface_binder_impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(GpuInterfaceProvider);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_GPU_INTERFACE_PROVIDER_H_
diff --git a/chromium/content/browser/histogram_controller.cc b/chromium/content/browser/histogram_controller.cc
index 7d1c1108bb7..1c52b9e3ec1 100644
--- a/chromium/content/browser/histogram_controller.cc
+++ b/chromium/content/browser/histogram_controller.cc
@@ -7,9 +7,11 @@
#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/process_handle.h"
+#include "base/task/post_task.h"
#include "content/browser/histogram_subscriber.h"
#include "content/common/histogram_fetcher.mojom.h"
#include "content/public/browser/browser_child_process_host_iterator.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/render_process_host.h"
@@ -42,8 +44,8 @@ void HistogramController::OnHistogramDataCollected(
int sequence_number,
const std::vector<std::string>& pickled_histograms) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&HistogramController::OnHistogramDataCollected,
base::Unretained(this), sequence_number,
pickled_histograms));
@@ -166,8 +168,8 @@ void HistogramController::GetHistogramDataFromChildProcesses(
++pending_processes;
}
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&HistogramController::OnPendingProcesses,
base::Unretained(this), sequence_number, pending_processes,
true));
@@ -191,8 +193,8 @@ void HistogramController::GetHistogramData(int sequence_number) {
}
OnPendingProcesses(sequence_number, pending_processes, false);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&HistogramController::GetHistogramDataFromChildProcesses,
base::Unretained(this), sequence_number));
}
diff --git a/chromium/content/browser/histogram_synchronizer.cc b/chromium/content/browser/histogram_synchronizer.cc
index 796c34fbe21..9dc2eedef0c 100644
--- a/chromium/content/browser/histogram_synchronizer.cc
+++ b/chromium/content/browser/histogram_synchronizer.cc
@@ -14,9 +14,11 @@
#include "base/metrics/histogram_macros.h"
#include "base/pickle.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "content/browser/histogram_controller.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/histogram_fetcher.h"
#include "content/public/common/content_constants.h"
@@ -94,8 +96,7 @@ class HistogramSynchronizer::RequestContext {
static RequestContext* GetRequestContext(int sequence_number) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RequestContextMap::iterator it =
- outstanding_requests_.Get().find(sequence_number);
+ auto it = outstanding_requests_.Get().find(sequence_number);
if (it == outstanding_requests_.Get().end())
return nullptr;
@@ -110,8 +111,7 @@ class HistogramSynchronizer::RequestContext {
static void Unregister(int sequence_number) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RequestContextMap::iterator it =
- outstanding_requests_.Get().find(sequence_number);
+ auto it = outstanding_requests_.Get().find(sequence_number);
if (it == outstanding_requests_.Get().end())
return;
@@ -127,15 +127,15 @@ class HistogramSynchronizer::RequestContext {
UMA_HISTOGRAM_BOOLEAN("Histogram.ReceivedProcessGroupCount",
received_process_group_count);
- UMA_HISTOGRAM_COUNTS("Histogram.PendingProcessNotResponding",
- unresponsive_processes);
+ UMA_HISTOGRAM_COUNTS_1M("Histogram.PendingProcessNotResponding",
+ unresponsive_processes);
}
// Delete all the entries in |outstanding_requests_| map.
static void OnShutdown() {
// Just in case we have any pending tasks, clear them out.
while (!outstanding_requests_.Get().empty()) {
- RequestContextMap::iterator it = outstanding_requests_.Get().begin();
+ auto it = outstanding_requests_.Get().begin();
delete it->second;
outstanding_requests_.Get().erase(it);
}
@@ -189,8 +189,8 @@ HistogramSynchronizer* HistogramSynchronizer::GetInstance() {
// static
void HistogramSynchronizer::FetchHistograms() {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&HistogramSynchronizer::FetchHistograms));
return;
}
@@ -249,8 +249,8 @@ void HistogramSynchronizer::RegisterAndNotifyAllProcesses(
// Post a task that would be called after waiting for wait_time. This acts
// as a watchdog, to cancel the requests for non-responsive processes.
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&RequestContext::Unregister, sequence_number), wait_time);
}
diff --git a/chromium/content/browser/histogram_synchronizer.h b/chromium/content/browser/histogram_synchronizer.h
index 2e9b79539dc..c037a502c4a 100644
--- a/chromium/content/browser/histogram_synchronizer.h
+++ b/chromium/content/browser/histogram_synchronizer.h
@@ -127,8 +127,8 @@ class HistogramSynchronizer : public HistogramSubscriber {
// When a request is made to asynchronously update the histograms, we store
// the task and TaskRunner we use to post a completion notification in
// |callback_| and |callback_task_runner_|.
- base::Closure callback_;
- scoped_refptr<base::TaskRunner> callback_task_runner_;
+ base::Closure callback_ GUARDED_BY(lock_);
+ scoped_refptr<base::TaskRunner> callback_task_runner_ GUARDED_BY(lock_);
// We don't track the actual processes that are contacted for an update, only
// the count of the number of processes, and we can sometimes time-out and
@@ -138,11 +138,11 @@ class HistogramSynchronizer : public HistogramSubscriber {
// All sequence numbers used are non-negative.
// last_used_sequence_number_ is the most recently used number (used to avoid
// reuse for a long time).
- int last_used_sequence_number_;
+ int last_used_sequence_number_ GUARDED_BY(lock_);
// The sequence number used by the most recent asynchronous update request to
// contact all processes.
- int async_sequence_number_;
+ int async_sequence_number_ GUARDED_BY(lock_);
DISALLOW_COPY_AND_ASSIGN(HistogramSynchronizer);
};
diff --git a/chromium/content/browser/host_zoom_map_impl.cc b/chromium/content/browser/host_zoom_map_impl.cc
index 34775d0204d..b97855ddd80 100644
--- a/chromium/content/browser/host_zoom_map_impl.cc
+++ b/chromium/content/browser/host_zoom_map_impl.cc
@@ -153,8 +153,7 @@ double HostZoomMapImpl::GetZoomLevelForHost(const std::string& host) const {
bool HostZoomMapImpl::HasZoomLevel(const std::string& scheme,
const std::string& host) const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SchemeHostZoomLevels::const_iterator scheme_iterator(
- scheme_host_zoom_levels_.find(scheme));
+ auto scheme_iterator(scheme_host_zoom_levels_.find(scheme));
const HostZoomLevels& zoom_levels =
(scheme_iterator != scheme_host_zoom_levels_.end())
@@ -168,10 +167,9 @@ double HostZoomMapImpl::GetZoomLevelForHostAndScheme(
const std::string& scheme,
const std::string& host) const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- SchemeHostZoomLevels::const_iterator scheme_iterator(
- scheme_host_zoom_levels_.find(scheme));
+ auto scheme_iterator(scheme_host_zoom_levels_.find(scheme));
if (scheme_iterator != scheme_host_zoom_levels_.end()) {
- HostZoomLevels::const_iterator i(scheme_iterator->second.find(host));
+ auto i(scheme_iterator->second.find(host));
if (i != scheme_iterator->second.end())
return i->second.level;
}
@@ -499,7 +497,7 @@ void HostZoomMapImpl::ClearTemporaryZoomLevel(int render_process_id,
int render_view_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderViewKey key(render_process_id, render_view_id);
- TemporaryZoomLevels::iterator it = temporary_zoom_levels_.find(key);
+ auto it = temporary_zoom_levels_.find(key);
if (it == temporary_zoom_levels_.end())
return;
diff --git a/chromium/content/browser/host_zoom_map_impl_unittest.cc b/chromium/content/browser/host_zoom_map_impl_unittest.cc
index c6676920158..0e0d2fc630a 100644
--- a/chromium/content/browser/host_zoom_map_impl_unittest.cc
+++ b/chromium/content/browser/host_zoom_map_impl_unittest.cc
@@ -8,7 +8,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_clock.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread.h"
@@ -18,11 +18,12 @@ namespace content {
class HostZoomMapTest : public testing::Test {
public:
- HostZoomMapTest() : ui_thread_(BrowserThread::UI, &message_loop_) {
- }
+ HostZoomMapTest()
+ : ui_thread_(BrowserThread::UI,
+ task_environment_.GetMainThreadTaskRunner()) {}
protected:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
TestBrowserThread ui_thread_;
};
diff --git a/chromium/content/browser/hyphenation/hyphenation_impl.cc b/chromium/content/browser/hyphenation/hyphenation_impl.cc
index 8d2cb168722..aa05d6baae9 100644
--- a/chromium/content/browser/hyphenation/hyphenation_impl.cc
+++ b/chromium/content/browser/hyphenation/hyphenation_impl.cc
@@ -11,6 +11,7 @@
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
@@ -29,12 +30,12 @@ bool IsValidLocale(const std::string& locale) {
base::File GetDictionaryFile(const std::string& locale) {
// Keep Files open in the cache for subsequent calls.
- CR_DEFINE_STATIC_LOCAL(DictionaryFileMap, cache, ());
+ static base::NoDestructor<DictionaryFileMap> cache;
- const auto& it = cache.find(locale);
- if (it != cache.end())
+ const auto& it = cache->find(locale);
+ if (it != cache->end())
return it->second.Duplicate();
- const auto& inserted = cache.insert(std::make_pair(locale, base::File()));
+ const auto& inserted = cache->insert(std::make_pair(locale, base::File()));
base::File& file = inserted.first->second;
DCHECK(!file.IsValid());
@@ -67,12 +68,11 @@ void HyphenationImpl::Create(blink::mojom::HyphenationRequest request) {
// static
scoped_refptr<base::SequencedTaskRunner> HyphenationImpl::GetTaskRunner() {
- CR_DEFINE_STATIC_LOCAL(
- scoped_refptr<base::SequencedTaskRunner>, runner,
- (base::CreateSequencedTaskRunnerWithTraits(
+ static base::NoDestructor<scoped_refptr<base::SequencedTaskRunner>> runner(
+ base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
- base::TaskPriority::USER_BLOCKING})));
- return runner;
+ base::TaskPriority::USER_BLOCKING}));
+ return *runner;
}
void HyphenationImpl::OpenDictionary(const std::string& locale,
diff --git a/chromium/content/browser/image_capture/image_capture_impl.cc b/chromium/content/browser/image_capture/image_capture_impl.cc
index 5198e94e456..27ad33e0b6b 100644
--- a/chromium/content/browser/image_capture/image_capture_impl.cc
+++ b/chromium/content/browser/image_capture/image_capture_impl.cc
@@ -7,9 +7,11 @@
#include <utility>
#include "base/bind_helpers.h"
+#include "base/task/post_task.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
#include "content/public/common/media_stream_request.h"
@@ -90,8 +92,8 @@ void ImageCaptureImpl::GetPhotoState(const std::string& source_id,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
media::BindToCurrentLoop(std::move(callback)),
mojo::CreateEmptyPhotoState());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&GetPhotoStateOnIOThread, source_id,
BrowserMainLoop::GetInstance()->media_stream_manager(),
std::move(scoped_callback)));
@@ -105,8 +107,8 @@ void ImageCaptureImpl::SetOptions(const std::string& source_id,
SetOptionsCallback scoped_callback =
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
media::BindToCurrentLoop(std::move(callback)), false);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SetOptionsOnIOThread, source_id,
BrowserMainLoop::GetInstance()->media_stream_manager(),
std::move(settings), std::move(scoped_callback)));
@@ -120,8 +122,8 @@ void ImageCaptureImpl::TakePhoto(const std::string& source_id,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
media::BindToCurrentLoop(std::move(callback)),
media::mojom::Blob::New());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&TakePhotoOnIOThread, source_id,
BrowserMainLoop::GetInstance()->media_stream_manager(),
std::move(scoped_callback)));
diff --git a/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.cc b/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.cc
index a3edf627425..370906e2f8a 100644
--- a/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_active_blob_registry.cc
@@ -29,7 +29,7 @@ void IndexedDBActiveBlobRegistry::AddBlobRef(int64_t database_id,
DCHECK(!base::ContainsKey(deleted_dbs_, database_id));
bool need_ref = use_tracker_.empty();
SingleDBMap& single_db_map = use_tracker_[database_id];
- SingleDBMap::iterator iter = single_db_map.find(blob_key);
+ auto iter = single_db_map.find(blob_key);
if (iter == single_db_map.end()) {
single_db_map[blob_key] = false;
if (need_ref) {
@@ -54,7 +54,7 @@ void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64_t database_id,
return;
}
SingleDBMap& single_db = db_pair->second;
- SingleDBMap::iterator blob_pair = single_db.find(blob_key);
+ auto blob_pair = single_db.find(blob_key);
if (blob_pair == single_db.end()) {
NOTREACHED();
return;
@@ -97,7 +97,7 @@ bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64_t database_id,
}
SingleDBMap& single_db = db_pair->second;
- SingleDBMap::iterator iter = single_db.find(blob_key);
+ auto iter = single_db.find(blob_key);
if (iter == single_db.end())
return false;
diff --git a/chromium/content/browser/indexed_db/indexed_db_backing_store.cc b/chromium/content/browser/indexed_db/indexed_db_backing_store.cc
index 01c03fae5ce..413adf0d0ce 100644
--- a/chromium/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -19,6 +19,7 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/trace_event/memory_dump_manager.h"
#include "build/build_config.h"
#include "content/browser/child_process_security_policy_impl.h"
@@ -38,6 +39,7 @@
#include "content/browser/indexed_db/leveldb/leveldb_factory.h"
#include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
#include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
#include "net/base/load_flags.h"
@@ -569,7 +571,6 @@ IndexedDBBackingStore::IndexedDBBackingStore(
IndexedDBFactory* indexed_db_factory,
const Origin& origin,
const FilePath& blob_path,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
std::unique_ptr<LevelDBDatabase> db,
std::unique_ptr<LevelDBComparator> comparator,
base::SequencedTaskRunner* task_runner)
@@ -577,7 +578,6 @@ IndexedDBBackingStore::IndexedDBBackingStore(
origin_(origin),
blob_path_(blob_path),
origin_identifier_(ComputeOriginIdentifier(origin)),
- request_context_getter_(request_context_getter),
task_runner_(task_runner),
db_(std::move(db)),
comparator_(std::move(comparator)),
@@ -620,7 +620,6 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
IndexedDBFactory* indexed_db_factory,
const Origin& origin,
const FilePath& path_base,
- scoped_refptr<net::URLRequestContextGetter> request_context,
IndexedDBDataLossInfo* data_loss_info,
bool* disk_full,
base::SequencedTaskRunner* task_runner,
@@ -628,8 +627,8 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
Status* status) {
DefaultLevelDBFactory leveldb_factory;
return IndexedDBBackingStore::Open(
- indexed_db_factory, origin, path_base, request_context, data_loss_info,
- disk_full, &leveldb_factory, task_runner, clean_journal, status);
+ indexed_db_factory, origin, path_base, data_loss_info, disk_full,
+ &leveldb_factory, task_runner, clean_journal, status);
}
Status IndexedDBBackingStore::DestroyBackingStore(const FilePath& path_base,
@@ -702,6 +701,34 @@ Status IndexedDBBackingStore::RevertSchemaToV2() {
return s;
}
+V2SchemaCorruptionStatus IndexedDBBackingStore::HasV2SchemaCorruption() {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ const std::string schema_version_key = SchemaVersionKey::Encode();
+ scoped_refptr<LevelDBTransaction> transaction =
+ IndexedDBClassFactory::Get()->CreateLevelDBTransaction(db_.get());
+
+ int64_t db_schema_version = 0;
+ bool found = false;
+ Status s =
+ GetInt(transaction.get(), schema_version_key, &db_schema_version, &found);
+ if (!s.ok())
+ return V2SchemaCorruptionStatus::kUnknown;
+ if (db_schema_version != 2)
+ return V2SchemaCorruptionStatus::kNo;
+
+ bool has_blobs = false;
+ s = AnyDatabaseContainsBlobs(transaction.get(), &has_blobs);
+ if (!s.ok())
+ return V2SchemaCorruptionStatus::kUnknown;
+ if (!has_blobs)
+ return V2SchemaCorruptionStatus::kNo;
+
+ s = transaction->Commit();
+ if (!s.ok())
+ return V2SchemaCorruptionStatus::kUnknown;
+ return V2SchemaCorruptionStatus::kYes;
+}
+
WARN_UNUSED_RESULT Status IndexedDBBackingStore::SetUpMetadata() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
@@ -939,7 +966,6 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
IndexedDBFactory* indexed_db_factory,
const Origin& origin,
const FilePath& path_base,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
IndexedDBDataLossInfo* data_loss_info,
bool* is_disk_full,
LevelDBFactory* leveldb_factory,
@@ -1075,8 +1101,8 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
base::trace_event::MemoryDumpProvider::Options());
scoped_refptr<IndexedDBBackingStore> backing_store =
- Create(indexed_db_factory, origin, blob_path, request_context_getter,
- std::move(db), std::move(comparator), task_runner, status);
+ Create(indexed_db_factory, origin, blob_path, std::move(db),
+ std::move(comparator), task_runner, status);
if (clean_journal && backing_store.get()) {
*status = backing_store->CleanUpBlobJournal(LiveBlobJournalKey::Encode());
@@ -1126,8 +1152,7 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory(
base::trace_event::MemoryDumpProvider::Options());
return Create(nullptr /* indexed_db_factory */, origin, FilePath(),
- nullptr /* request_context */, std::move(db),
- std::move(comparator), task_runner, status);
+ std::move(db), std::move(comparator), task_runner, status);
}
// static
@@ -1135,14 +1160,13 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create(
IndexedDBFactory* indexed_db_factory,
const Origin& origin,
const FilePath& blob_path,
- scoped_refptr<net::URLRequestContextGetter> request_context,
std::unique_ptr<LevelDBDatabase> db,
std::unique_ptr<LevelDBComparator> comparator,
base::SequencedTaskRunner* task_runner,
Status* status) {
// TODO(jsbell): Handle comparator name changes.
scoped_refptr<IndexedDBBackingStore> backing_store(new IndexedDBBackingStore(
- indexed_db_factory, origin, blob_path, request_context, std::move(db),
+ indexed_db_factory, origin, blob_path, std::move(db),
std::move(comparator), task_runner));
*status = backing_store->SetUpMetadata();
if (!status->ok())
@@ -1822,8 +1846,8 @@ bool IndexedDBBackingStore::WriteBlobFile(
DCHECK(descriptor.blob());
scoped_refptr<LocalWriteClosure> write_closure(
new LocalWriteClosure(chained_blob_writer, task_runner_.get()));
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(
&LocalWriteClosure::WriteBlobToFileOnIOThread, write_closure, path,
std::make_unique<storage::BlobDataHandle>(*descriptor.blob()),
@@ -1856,9 +1880,8 @@ void IndexedDBBackingStore::ReportBlobUnused(int64_t database_id,
// matching (database_id, blob_key) tuple, we should move it to the primary
// journal.
BlobJournalType new_live_blob_journal;
- for (BlobJournalType::iterator journal_iter = live_blob_journal.begin();
- journal_iter != live_blob_journal.end();
- ++journal_iter) {
+ for (auto journal_iter = live_blob_journal.begin();
+ journal_iter != live_blob_journal.end(); ++journal_iter) {
int64_t current_database_id = journal_iter->first;
int64_t current_blob_key = journal_iter->second;
bool current_all_blobs =
diff --git a/chromium/content/browser/indexed_db/indexed_db_backing_store.h b/chromium/content/browser/indexed_db/indexed_db_backing_store.h
index e5540a77658..5da4da7dc57 100644
--- a/chromium/content/browser/indexed_db/indexed_db_backing_store.h
+++ b/chromium/content/browser/indexed_db/indexed_db_backing_store.h
@@ -50,10 +50,6 @@ namespace storage {
class FileWriterDelegate;
}
-namespace net {
-class URLRequestContextGetter;
-}
-
namespace content {
class IndexedDBFactory;
@@ -68,6 +64,12 @@ class IndexedDBBackingStoreTest;
FORWARD_DECLARE_TEST(IndexedDBBackingStoreTest, ReadCorruptionInfo);
} // namespace indexed_db_backing_store_unittest
+enum class V2SchemaCorruptionStatus {
+ kUnknown = 0, // Due to other unknown/critical errors.
+ kNo = 1,
+ kYes = 2,
+};
+
class CONTENT_EXPORT IndexedDBBackingStore
: public base::RefCounted<IndexedDBBackingStore> {
public:
@@ -400,7 +402,6 @@ class CONTENT_EXPORT IndexedDBBackingStore
IndexedDBFactory* indexed_db_factory,
const url::Origin& origin,
const base::FilePath& path_base,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
IndexedDBDataLossInfo* data_loss_info,
bool* disk_full,
base::SequencedTaskRunner* task_runner,
@@ -410,7 +411,6 @@ class CONTENT_EXPORT IndexedDBBackingStore
IndexedDBFactory* indexed_db_factory,
const url::Origin& origin,
const base::FilePath& path_base,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
IndexedDBDataLossInfo* data_loss_info,
bool* disk_full,
LevelDBFactory* leveldb_factory,
@@ -580,6 +580,10 @@ class CONTENT_EXPORT IndexedDBBackingStore
// Stops the journal_cleaning_timer_ and runs its pending task.
void ForceRunBlobCleanup();
+ // HasV2SchemaCorruption() returns whether the backing store is v2 and
+ // has blob references.
+ V2SchemaCorruptionStatus HasV2SchemaCorruption();
+
// RevertSchemaToV2() updates a backing store state on disk to override its
// metadata version to 2. This allows triggering https://crbug.com/829141 on
// an otherwise healthy backing store.
@@ -592,7 +596,6 @@ class CONTENT_EXPORT IndexedDBBackingStore
IndexedDBFactory* indexed_db_factory,
const url::Origin& origin,
const base::FilePath& blob_path,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
std::unique_ptr<LevelDBDatabase> db,
std::unique_ptr<LevelDBComparator> comparator,
base::SequencedTaskRunner* task_runner);
@@ -637,7 +640,6 @@ class CONTENT_EXPORT IndexedDBBackingStore
IndexedDBFactory* indexed_db_factory,
const url::Origin& origin,
const base::FilePath& blob_path,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
std::unique_ptr<LevelDBDatabase> db,
std::unique_ptr<LevelDBComparator> comparator,
base::SequencedTaskRunner* task_runner,
@@ -687,7 +689,6 @@ class CONTENT_EXPORT IndexedDBBackingStore
// provides for future flexibility.
const std::string origin_identifier_;
- scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
std::set<int> child_process_ids_granted_;
std::map<std::string, std::unique_ptr<BlobChangeRecord>> incognito_blob_map_;
diff --git a/chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
index 6eb906e0216..c9d70844af2 100644
--- a/chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc
@@ -17,6 +17,7 @@
#include "base/sequenced_task_runner.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/time/default_clock.h"
#include "content/browser/indexed_db/indexed_db_class_factory.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
@@ -26,9 +27,9 @@
#include "content/browser/indexed_db/indexed_db_metadata_coding.h"
#include "content/browser/indexed_db/indexed_db_value.h"
#include "content/browser/indexed_db/leveldb/leveldb_factory.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
-#include "net/url_request/url_request_test_util.h"
#include "storage/browser/blob/blob_data_builder.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_storage_context.h"
@@ -93,7 +94,6 @@ class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
IndexedDBFactory* indexed_db_factory,
const Origin& origin,
const base::FilePath& path_base,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
LevelDBFactory* leveldb_factory,
base::SequencedTaskRunner* task_runner,
leveldb::Status* status) {
@@ -120,8 +120,8 @@ class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
scoped_refptr<TestableIndexedDBBackingStore> backing_store(
new TestableIndexedDBBackingStore(indexed_db_factory, origin, blob_path,
- request_context_getter, std::move(db),
- std::move(comparator), task_runner));
+ std::move(db), std::move(comparator),
+ task_runner));
*status = backing_store->SetUpMetadata();
if (!status->ok())
@@ -178,14 +178,12 @@ class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
IndexedDBFactory* indexed_db_factory,
const Origin& origin,
const base::FilePath& blob_path,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
std::unique_ptr<LevelDBDatabase> db,
std::unique_ptr<LevelDBComparator> comparator,
base::SequencedTaskRunner* task_runner)
: IndexedDBBackingStore(indexed_db_factory,
origin,
blob_path,
- request_context_getter,
std::move(db),
std::move(comparator),
task_runner),
@@ -207,14 +205,12 @@ class TestIDBFactory : public IndexedDBFactoryImpl {
: IndexedDBFactoryImpl(idb_context, base::DefaultClock::GetInstance()) {}
scoped_refptr<TestableIndexedDBBackingStore> OpenBackingStoreForTest(
- const Origin& origin,
- scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
+ const Origin& origin) {
IndexedDBDataLossInfo data_loss_info;
bool disk_full;
leveldb::Status status;
scoped_refptr<IndexedDBBackingStore> backing_store = OpenBackingStore(
- origin, context()->data_path(), url_request_context_getter,
- &data_loss_info, &disk_full, &status);
+ origin, context()->data_path(), &data_loss_info, &disk_full, &status);
scoped_refptr<TestableIndexedDBBackingStore> testable_store =
static_cast<TestableIndexedDBBackingStore*>(backing_store.get());
return testable_store;
@@ -226,15 +222,14 @@ class TestIDBFactory : public IndexedDBFactoryImpl {
scoped_refptr<IndexedDBBackingStore> OpenBackingStoreHelper(
const Origin& origin,
const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
IndexedDBDataLossInfo* data_loss_info,
bool* disk_full,
bool first_time,
leveldb::Status* status) override {
DefaultLevelDBFactory leveldb_factory;
- return TestableIndexedDBBackingStore::Open(
- this, origin, data_directory, request_context_getter, &leveldb_factory,
- context()->TaskRunner(), status);
+ return TestableIndexedDBBackingStore::Open(this, origin, data_directory,
+ &leveldb_factory,
+ context()->TaskRunner(), status);
}
private:
@@ -244,10 +239,7 @@ class TestIDBFactory : public IndexedDBFactoryImpl {
class IndexedDBBackingStoreTest : public testing::Test {
public:
IndexedDBBackingStoreTest()
- : url_request_context_getter_(
- base::MakeRefCounted<net::TestURLRequestContextGetter>(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))),
- special_storage_policy_(
+ : special_storage_policy_(
base::MakeRefCounted<MockSpecialStoragePolicy>()),
quota_manager_proxy_(
base::MakeRefCounted<MockQuotaManagerProxy>(nullptr, nullptr)) {}
@@ -262,8 +254,7 @@ class IndexedDBBackingStoreTest : public testing::Test {
test->idb_factory_ = base::MakeRefCounted<TestIDBFactory>(
test->idb_context_.get());
test->backing_store_ =
- test->idb_factory_->OpenBackingStoreForTest(
- origin, test->url_request_context_getter_);
+ test->idb_factory_->OpenBackingStoreForTest(origin);
},
base::Unretained(this)));
RunAllTasksUntilIdle();
@@ -316,11 +307,9 @@ class IndexedDBBackingStoreTest : public testing::Test {
IndexedDBValue value2_;
protected:
- // Must be initialized before url_request_context_getter_
TestBrowserThreadBundle thread_bundle_;
base::ScopedTempDir temp_dir_;
- scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_;
scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
scoped_refptr<IndexedDBContextImpl> idb_context_;
diff --git a/chromium/content/browser/indexed_db/indexed_db_browsertest.cc b/chromium/content/browser/indexed_db/indexed_db_browsertest.cc
index e4f3274ff39..1ae750ded15 100644
--- a/chromium/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -19,6 +19,8 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
+#include "base/test/bind_test_util.h"
#include "base/test/thread_test_helper.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
@@ -28,6 +30,7 @@
#include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@@ -57,12 +60,16 @@ using url::Origin;
namespace content {
+namespace {
+const Origin kFileOrigin = Origin::Create(GURL("file:///"));
+};
+
// This browser test is aimed towards exercising the IndexedDB bindings and
// the actual implementation that lives in the browser side.
class IndexedDBBrowserTest : public ContentBrowserTest,
public ::testing::WithParamInterface<const char*> {
public:
- IndexedDBBrowserTest() : disk_usage_(-1) {}
+ IndexedDBBrowserTest() = default;
void SetUp() override {
GetTestClassFactory()->Reset();
@@ -116,10 +123,11 @@ class IndexedDBBrowserTest : public ContentBrowserTest,
EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
}
- IndexedDBContextImpl* GetContext() {
- StoragePartition* partition =
- BrowserContext::GetDefaultStoragePartition(
- shell()->web_contents()->GetBrowserContext());
+ IndexedDBContextImpl* GetContext(Shell* browser = nullptr) {
+ if (!browser)
+ browser = shell();
+ StoragePartition* partition = BrowserContext::GetDefaultStoragePartition(
+ browser->web_contents()->GetBrowserContext());
return static_cast<IndexedDBContextImpl*>(partition->GetIndexedDBContext());
}
@@ -133,8 +141,8 @@ class IndexedDBBrowserTest : public ContentBrowserTest,
static void SetTempQuota(int per_host_quota_kilobytes,
scoped_refptr<QuotaManager> qm) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IndexedDBBrowserTest::SetTempQuota,
per_host_quota_kilobytes, qm));
return;
@@ -145,37 +153,70 @@ class IndexedDBBrowserTest : public ContentBrowserTest,
storage::GetHardCodedSettings(per_host_quota_kilobytes * KB));
}
- virtual int64_t RequestDiskUsage() {
- PostTaskAndReplyWithResult(
- GetContext()->TaskRunner(), FROM_HERE,
- base::BindOnce(&IndexedDBContextImpl::GetOriginDiskUsage, GetContext(),
- Origin::Create(GURL("file:///"))),
- base::BindOnce(&IndexedDBBrowserTest::DidGetDiskUsage,
- base::Unretained(this)));
- scoped_refptr<base::ThreadTestHelper> helper(
- new base::ThreadTestHelper(GetContext()->TaskRunner()));
- EXPECT_TRUE(helper->Run());
- // Wait for DidGetDiskUsage to be called.
- base::RunLoop().RunUntilIdle();
- return disk_usage_;
+ void DeleteForOrigin(const Origin& origin, Shell* browser = nullptr) {
+ base::RunLoop loop;
+ IndexedDBContextImpl* context = GetContext();
+ context->TaskRunner()->PostTask(FROM_HERE,
+ base::BindLambdaForTesting([&]() {
+ context->DeleteForOrigin(kFileOrigin);
+ loop.Quit();
+ }));
+ loop.Run();
}
- virtual int RequestBlobFileCount() {
- PostTaskAndReplyWithResult(
- GetContext()->TaskRunner(), FROM_HERE,
- base::BindOnce(&IndexedDBContextImpl::GetOriginBlobFileCount,
- GetContext(), Origin::Create(GURL("file:///"))),
- base::BindOnce(&IndexedDBBrowserTest::DidGetBlobFileCount,
- base::Unretained(this)));
- scoped_refptr<base::ThreadTestHelper> helper(
- new base::ThreadTestHelper(GetContext()->TaskRunner()));
- EXPECT_TRUE(helper->Run());
- // Wait for DidGetBlobFileCount to be called.
- base::RunLoop().RunUntilIdle();
- return blob_file_count_;
+ int64_t RequestUsage(const Origin& origin, Shell* browser = nullptr) {
+ base::RunLoop loop;
+ int64_t size;
+ IndexedDBContextImpl* context = GetContext(browser);
+ context->TaskRunner()->PostTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ size = context->GetOriginDiskUsage(origin);
+ loop.Quit();
+ }));
+ loop.Run();
+ return size;
}
- private:
+ int RequestBlobFileCount(const Origin& origin) {
+ base::RunLoop loop;
+ int count;
+ IndexedDBContextImpl* context = GetContext();
+ context->TaskRunner()->PostTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ count = context->GetOriginBlobFileCount(origin);
+ loop.Quit();
+ }));
+ loop.Run();
+ return count;
+ }
+
+ bool RequestSchemaDowngrade(const Origin& origin) {
+ base::RunLoop loop;
+ bool downgraded;
+ IndexedDBContextImpl* context = GetContext();
+ context->TaskRunner()->PostTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ downgraded = context->ForceSchemaDowngrade(origin);
+ loop.Quit();
+ }));
+ loop.Run();
+ return downgraded;
+ }
+
+ V2SchemaCorruptionStatus RequestHasV2SchemaCorruption(Origin origin) {
+ base::RunLoop loop;
+ V2SchemaCorruptionStatus status;
+ IndexedDBContextImpl* context = GetContext();
+ context->TaskRunner()->PostTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ status = context->HasV2SchemaCorruption(origin);
+ loop.Quit();
+ }));
+ loop.Run();
+ return status;
+ }
+
+ protected:
static MockBrowserTestIndexedDBClassFactory* GetTestClassFactory() {
static ::base::LazyInstance<MockBrowserTestIndexedDBClassFactory>::Leaky
s_factory = LAZY_INSTANCE_INITIALIZER;
@@ -186,13 +227,7 @@ class IndexedDBBrowserTest : public ContentBrowserTest,
return GetTestClassFactory();
}
- virtual void DidGetDiskUsage(int64_t bytes) { disk_usage_ = bytes; }
-
- virtual void DidGetBlobFileCount(int count) { blob_file_count_ = count; }
-
- int64_t disk_usage_;
- int blob_file_count_ = 0;
-
+ private:
DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTest);
};
@@ -359,10 +394,10 @@ class IndexedDBBrowserTestWithVersion123456Schema : public
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithVersion123456Schema,
DestroyTest) {
- int64_t original_size = RequestDiskUsage();
+ int64_t original_size = RequestUsage(kFileOrigin);
EXPECT_GT(original_size, 0);
SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
- int64_t new_size = RequestDiskUsage();
+ int64_t new_size = RequestUsage(kFileOrigin);
EXPECT_GT(new_size, 0);
EXPECT_NE(original_size, new_size);
}
@@ -374,10 +409,10 @@ class IndexedDBBrowserTestWithVersion987654SSVData : public
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithVersion987654SSVData,
DestroyTest) {
- int64_t original_size = RequestDiskUsage();
+ int64_t original_size = RequestUsage(kFileOrigin);
EXPECT_GT(original_size, 0);
SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
- int64_t new_size = RequestDiskUsage();
+ int64_t new_size = RequestUsage(kFileOrigin);
EXPECT_GT(new_size, 0);
EXPECT_NE(original_size, new_size);
}
@@ -389,10 +424,10 @@ class IndexedDBBrowserTestWithCorruptLevelDB : public
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithCorruptLevelDB,
DestroyTest) {
- int64_t original_size = RequestDiskUsage();
+ int64_t original_size = RequestUsage(kFileOrigin);
EXPECT_GT(original_size, 0);
SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
- int64_t new_size = RequestDiskUsage();
+ int64_t new_size = RequestUsage(kFileOrigin);
EXPECT_GT(new_size, 0);
EXPECT_NE(original_size, new_size);
}
@@ -404,10 +439,10 @@ class IndexedDBBrowserTestWithMissingSSTFile : public
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithMissingSSTFile,
DestroyTest) {
- int64_t original_size = RequestDiskUsage();
+ int64_t original_size = RequestUsage(kFileOrigin);
EXPECT_GT(original_size, 0);
SimpleTest(GetTestUrl("indexeddb", "open_missing_table.html"));
- int64_t new_size = RequestDiskUsage();
+ int64_t new_size = RequestUsage(kFileOrigin);
EXPECT_GT(new_size, 0);
EXPECT_NE(original_size, new_size);
}
@@ -429,7 +464,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, LevelDBLogFileTest) {
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CanDeleteWhenOverQuotaTest) {
SimpleTest(GetTestUrl("indexeddb", "fill_up_5k.html"));
- int64_t size = RequestDiskUsage();
+ int64_t size = RequestUsage(kFileOrigin);
const int kQuotaKilobytes = 2;
EXPECT_GT(size, kQuotaKilobytes * 1024);
SetQuota(kQuotaKilobytes);
@@ -438,13 +473,8 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CanDeleteWhenOverQuotaTest) {
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, EmptyBlob) {
// First delete all IDB's for the test origin
- // TODO(jsbell): Remove static_cast<> when overloads are eliminated.
- GetContext()->TaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(static_cast<void (IndexedDBContextImpl::*)(const GURL&)>(
- &IndexedDBContextImpl::DeleteForOrigin),
- GetContext(), GURL("file:///")));
- EXPECT_EQ(0, RequestBlobFileCount()); // Start with no blob files.
+ DeleteForOrigin(kFileOrigin);
+ EXPECT_EQ(0, RequestBlobFileCount(kFileOrigin)); // Start with no blob files.
const GURL test_url = GetTestUrl("indexeddb", "empty_blob.html");
// For some reason Android's futimes fails (EPERM) in this test. Do not assert
// file times on Android, but do so on other platforms. crbug.com/467247
@@ -455,7 +485,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, EmptyBlob) {
SimpleTest(GURL(test_url.spec()));
#endif
// Test stores one blob and one file to disk, so expect two files.
- EXPECT_EQ(2, RequestBlobFileCount());
+ EXPECT_EQ(2, RequestBlobFileCount(kFileOrigin));
}
// Very flaky on many bots. See crbug.com/459835
@@ -493,19 +523,31 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, BlobsCountAgainstQuota) {
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteForOriginDeletesBlobs) {
SimpleTest(GetTestUrl("indexeddb", "write_4mb_blob.html"));
- int64_t size = RequestDiskUsage();
+ int64_t size = RequestUsage(kFileOrigin);
// This assertion assumes that we do not compress blobs.
EXPECT_GT(size, 4 << 20 /* 4 MB */);
- // TODO(jsbell): Remove static_cast<> when overloads are eliminated.
- GetContext()->TaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(static_cast<void (IndexedDBContextImpl::*)(const GURL&)>(
- &IndexedDBContextImpl::DeleteForOrigin),
- GetContext(), GURL("file:///")));
- scoped_refptr<base::ThreadTestHelper> helper(
- new base::ThreadTestHelper(GetContext()->TaskRunner()));
- ASSERT_TRUE(helper->Run());
- EXPECT_EQ(0, RequestDiskUsage());
+ DeleteForOrigin(kFileOrigin);
+ EXPECT_EQ(0, RequestUsage(kFileOrigin));
+}
+
+IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteForOriginIncognito) {
+ const GURL test_url = GetTestUrl("indexeddb", "fill_up_5k.html");
+ const Origin origin = Origin::Create(test_url);
+
+ Shell* browser = CreateOffTheRecordBrowser();
+ NavigateToURLBlockUntilNavigationsComplete(browser, test_url, 2);
+
+ EXPECT_GT(RequestUsage(origin, browser), 5 * 1024);
+
+ IndexedDBContextImpl* context = GetContext(browser);
+ base::RunLoop loop;
+ context->TaskRunner()->PostTask(FROM_HERE, base::BindLambdaForTesting([&]() {
+ context->DeleteForOrigin(origin);
+ loop.Quit();
+ }));
+ loop.Run();
+
+ EXPECT_EQ(0, RequestUsage(origin, browser));
}
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DiskFullOnCommit) {
@@ -531,9 +573,23 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DiskFullOnCommit) {
namespace {
-static void CompactIndexedDBBackingStore(
- scoped_refptr<IndexedDBContextImpl> context,
- const Origin& origin) {
+std::unique_ptr<net::test_server::HttpResponse> ServePath(
+ std::string request_path) {
+ base::FilePath resource_path =
+ content::GetTestFilePath("indexeddb", request_path.c_str());
+ std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
+ new net::test_server::BasicHttpResponse);
+ http_response->set_code(net::HTTP_OK);
+
+ std::string file_contents;
+ if (!base::ReadFileToString(resource_path, &file_contents))
+ NOTREACHED() << "could not read file " << resource_path;
+ http_response->set_content(file_contents);
+ return std::move(http_response);
+}
+
+void CompactIndexedDBBackingStore(scoped_refptr<IndexedDBContextImpl> context,
+ const Origin& origin) {
IndexedDBFactory* factory = context->GetIDBFactory();
std::pair<IndexedDBFactory::OriginDBMapIterator,
@@ -550,10 +606,9 @@ static void CompactIndexedDBBackingStore(
backing_store->Compact();
}
-static void CorruptIndexedDBDatabase(
- IndexedDBContextImpl* context,
- const Origin& origin,
- base::WaitableEvent* signal_when_finished) {
+void CorruptIndexedDBDatabase(IndexedDBContextImpl* context,
+ const Origin& origin,
+ base::WaitableEvent* signal_when_finished) {
CompactIndexedDBBackingStore(context, origin);
int num_files = 0;
@@ -587,9 +642,9 @@ static void CorruptIndexedDBDatabase(
signal_when_finished->Signal();
}
-static const char s_corrupt_db_test_prefix[] = "/corrupt/test/";
+const char s_corrupt_db_test_prefix[] = "/corrupt/test/";
-static std::unique_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
+std::unique_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
IndexedDBContextImpl* context,
const Origin& origin,
const std::string& path,
@@ -693,17 +748,20 @@ static std::unique_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
return std::move(http_response);
}
- // A request for a test resource
- base::FilePath resource_path =
- content::GetTestFilePath("indexeddb", request_path.c_str());
- std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
- new net::test_server::BasicHttpResponse);
- http_response->set_code(net::HTTP_OK);
- std::string file_contents;
- if (!base::ReadFileToString(resource_path, &file_contents))
+ return ServePath(request_path);
+}
+
+const char s_indexeddb_test_prefix[] = "/indexeddb/test/";
+
+std::unique_ptr<net::test_server::HttpResponse> StaticFileRequestHandler(
+ const std::string& path,
+ IndexedDBBrowserTest* test,
+ const net::test_server::HttpRequest& request) {
+ if (path.find(s_indexeddb_test_prefix) == std::string::npos)
return std::unique_ptr<net::test_server::HttpResponse>();
- http_response->set_content(file_contents);
- return std::move(http_response);
+ std::string request_path =
+ request.relative_url.substr(std::string(s_indexeddb_test_prefix).size());
+ return ServePath(request_path);
}
} // namespace
@@ -738,11 +796,11 @@ INSTANTIATE_TEST_CASE_P(IndexedDBBrowserTestInstantiation,
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteCompactsBackingStore) {
const GURL test_url = GetTestUrl("indexeddb", "delete_compact.html");
SimpleTest(GURL(test_url.spec() + "#fill"));
- int64_t after_filling = RequestDiskUsage();
+ int64_t after_filling = RequestUsage(kFileOrigin);
EXPECT_GT(after_filling, 0);
SimpleTest(GURL(test_url.spec() + "#purge"));
- int64_t after_deleting = RequestDiskUsage();
+ int64_t after_deleting = RequestUsage(kFileOrigin);
EXPECT_LT(after_deleting, after_filling);
// The above tests verify basic assertions - that filling writes data and
@@ -839,19 +897,67 @@ IN_PROC_BROWSER_TEST_F(
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ForceCloseEventTest) {
NavigateAndWaitForTitle(shell(), "force_close_event.html", nullptr,
"connection ready");
- // TODO(jsbell): Remove static_cast<> when overloads are eliminated.
- GetContext()->TaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(static_cast<void (IndexedDBContextImpl::*)(const GURL&)>(
- &IndexedDBContextImpl::DeleteForOrigin),
- GetContext(), GURL("file:///")));
-
+ DeleteForOrigin(kFileOrigin);
base::string16 expected_title16(ASCIIToUTF16("connection closed"));
TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
title_watcher.AlsoWaitForTitle(ASCIIToUTF16("connection closed with error"));
EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
}
+// The V2 schema corruption test runs in a separate class to avoid corrupting
+// an IDB store that other tests use.
+class IndexedDBBrowserTestV2SchemaCorruption : public IndexedDBBrowserTest {
+ public:
+ void SetUp() override {
+ GetTestClassFactory()->Reset();
+ IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(GetIDBClassFactory);
+ ContentBrowserTest::SetUp();
+ }
+};
+
+// Verify the V2 schema corruption lifecycle:
+// - create a current version backing store (v3 or later)
+// - add an object store, some data, and an object that contains a blob
+// - verify the object+blob are stored in the object store
+// - verify the backing store doesn't have v2 schema corruption
+// - force the schema to downgrade to v2
+// - verify the backing store has v2 schema corruption
+// - verify the object+blob can be fetched
+IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestV2SchemaCorruption, LifecycleTest) {
+ ASSERT_TRUE(embedded_test_server()->Started() ||
+ embedded_test_server()->InitializeAndListen());
+ const Origin origin = Origin::Create(embedded_test_server()->base_url());
+ embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
+ &StaticFileRequestHandler, s_indexeddb_test_prefix, this));
+ embedded_test_server()->StartAcceptingConnections();
+
+ // Set up the IndexedDB instance so it contains our reference data.
+ std::string test_file =
+ std::string(s_indexeddb_test_prefix) + "v2schemacorrupt_setup.html";
+ SimpleTest(embedded_test_server()->GetURL(test_file));
+
+ // Verify the backing store does not have corruption.
+ V2SchemaCorruptionStatus has_corruption =
+ RequestHasV2SchemaCorruption(origin);
+ ASSERT_EQ(has_corruption, V2SchemaCorruptionStatus::kNo);
+
+ // Revert schema to v2. This closes the targeted backing store.
+ bool schema_downgrade = RequestSchemaDowngrade(origin);
+ ASSERT_EQ(schema_downgrade, true);
+
+ // Re-open the backing store and verify it has corruption.
+ test_file =
+ std::string(s_indexeddb_test_prefix) + "v2schemacorrupt_reopen.html";
+ SimpleTest(embedded_test_server()->GetURL(test_file));
+ has_corruption = RequestHasV2SchemaCorruption(origin);
+ ASSERT_EQ(has_corruption, V2SchemaCorruptionStatus::kYes);
+
+ // Verify that the saved blob is get-able with a v2 backing store.
+ test_file =
+ std::string(s_indexeddb_test_prefix) + "v2schemacorrupt_verify.html";
+ SimpleTest(embedded_test_server()->GetURL(test_file));
+}
+
class IndexedDBBrowserTestSingleProcess : public IndexedDBBrowserTest {
public:
void SetUpCommandLine(base::CommandLine* command_line) override {
diff --git a/chromium/content/browser/indexed_db/indexed_db_callbacks.cc b/chromium/content/browser/indexed_db/indexed_db_callbacks.cc
index 55fbe83dc93..d5369e55609 100644
--- a/chromium/content/browser/indexed_db/indexed_db_callbacks.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_callbacks.cc
@@ -14,6 +14,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
#include "content/browser/child_process_security_policy_impl.h"
@@ -27,6 +28,7 @@
#include "content/browser/indexed_db/indexed_db_tracing.h"
#include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/browser/indexed_db/indexed_db_value.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/common/content_features.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "storage/browser/blob/blob_data_builder.h"
@@ -220,8 +222,8 @@ void IndexedDBCallbacks::OnError(const IndexedDBDatabaseError& error) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!complete_);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendError,
base::Unretained(io_helper_.get()), error));
complete_ = true;
@@ -239,8 +241,8 @@ void IndexedDBCallbacks::OnSuccess(const std::vector<base::string16>& value) {
DCHECK(!complete_);
DCHECK(io_helper_);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendSuccessStringList,
base::Unretained(io_helper_.get()), value));
complete_ = true;
@@ -256,8 +258,8 @@ void IndexedDBCallbacks::OnBlocked(int64_t existing_version) {
sent_blocked_ = true;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendBlocked,
base::Unretained(io_helper_.get()), existing_version));
@@ -284,8 +286,8 @@ void IndexedDBCallbacks::OnUpgradeNeeded(
connection_created_ = true;
SafeIOThreadConnectionWrapper wrapper(std::move(connection));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendUpgradeNeeded,
base::Unretained(io_helper_.get()), std::move(wrapper),
old_version, data_loss_info.status, data_loss_info.message,
@@ -317,10 +319,10 @@ void IndexedDBCallbacks::OnSuccess(
database_connection = std::move(connection);
SafeIOThreadConnectionWrapper wrapper(std::move(database_connection));
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&IOThreadHelper::SendSuccessDatabase,
- base::Unretained(io_helper_.get()),
- std::move(wrapper), metadata));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&IOThreadHelper::SendSuccessDatabase,
+ base::Unretained(io_helper_.get()),
+ std::move(wrapper), metadata));
complete_ = true;
if (!connection_open_start_time_.is_null()) {
@@ -350,8 +352,8 @@ void IndexedDBCallbacks::OnSuccess(std::unique_ptr<IndexedDBCursor> cursor,
SafeIOThreadCursorWrapper cursor_wrapper(std::move(cursor));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendSuccessCursor,
base::Unretained(io_helper_.get()),
std::move(cursor_wrapper), key, primary_key,
@@ -375,8 +377,8 @@ void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& key,
blob_info.swap(value->blob_info);
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendSuccessCursorContinue,
base::Unretained(io_helper_.get()), key, primary_key,
std::move(mojo_value), std::move(blob_info)));
@@ -400,8 +402,8 @@ void IndexedDBCallbacks::OnSuccessWithPrefetch(
for (size_t i = 0; i < values->size(); ++i)
mojo_values.push_back(ConvertAndEraseValue(&(*values)[i]));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendSuccessCursorPrefetch,
base::Unretained(io_helper_.get()), keys, primary_keys,
std::move(mojo_values), *values));
@@ -421,8 +423,8 @@ void IndexedDBCallbacks::OnSuccess(IndexedDBReturnValue* value) {
blob_info = value->blob_info;
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendSuccessValue,
base::Unretained(io_helper_.get()), std::move(mojo_value),
std::move(blob_info)));
@@ -442,10 +444,10 @@ void IndexedDBCallbacks::OnSuccessArray(
for (size_t i = 0; i < values->size(); ++i)
mojo_values.push_back(ConvertReturnValue(&(*values)[i]));
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&IOThreadHelper::SendSuccessArray,
- base::Unretained(io_helper_.get()),
- std::move(mojo_values), *values));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&IOThreadHelper::SendSuccessArray,
+ base::Unretained(io_helper_.get()),
+ std::move(mojo_values), *values));
complete_ = true;
}
@@ -456,8 +458,8 @@ void IndexedDBCallbacks::OnSuccess(const IndexedDBKey& value) {
DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendSuccessKey,
base::Unretained(io_helper_.get()), value));
complete_ = true;
@@ -467,8 +469,8 @@ void IndexedDBCallbacks::OnSuccess(int64_t value) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!complete_);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendSuccessInteger,
base::Unretained(io_helper_.get()), value));
complete_ = true;
@@ -481,9 +483,9 @@ void IndexedDBCallbacks::OnSuccess() {
DCHECK_EQ(blink::kWebIDBDataLossNone, data_loss_);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&IOThreadHelper::SendSuccess,
- base::Unretained(io_helper_.get())));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&IOThreadHelper::SendSuccess,
+ base::Unretained(io_helper_.get())));
complete_ = true;
}
diff --git a/chromium/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc
index 0c702bf0f8f..5f73076637c 100644
--- a/chromium/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_cleanup_on_io_error_unittest.cc
@@ -14,7 +14,6 @@
#include "content/browser/indexed_db/indexed_db_data_loss_info.h"
#include "content/browser/indexed_db/leveldb/leveldb_database.h"
#include "content/browser/indexed_db/leveldb/mock_leveldb_factory.h"
-#include "net/url_request/url_request_context_getter.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/env_chromium.h"
@@ -86,7 +85,6 @@ TEST(IndexedDBIOErrorTest, CleanUpTest) {
base::ScopedTempDir temp_directory;
ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
const base::FilePath path = temp_directory.GetPath();
- scoped_refptr<net::URLRequestContextGetter> request_context_getter;
BustedLevelDBFactory busted_factory;
content::MockLevelDBFactory mock_leveldb_factory;
@@ -103,15 +101,14 @@ TEST(IndexedDBIOErrorTest, CleanUpTest) {
bool clean_journal = false;
leveldb::Status s;
scoped_refptr<IndexedDBBackingStore> backing_store =
- IndexedDBBackingStore::Open(
- factory, origin, path, request_context_getter, &data_loss_info,
- &disk_full, &mock_leveldb_factory, task_runner, clean_journal, &s);
+ IndexedDBBackingStore::Open(factory, origin, path, &data_loss_info,
+ &disk_full, &mock_leveldb_factory,
+ task_runner, clean_journal, &s);
}
TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
content::IndexedDBFactory* factory = nullptr;
const url::Origin origin = url::Origin::Create(GURL("http://localhost:81"));
- scoped_refptr<net::URLRequestContextGetter> request_context_getter;
base::ScopedTempDir temp_directory;
ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
const base::FilePath path = temp_directory.GetPath();
@@ -135,9 +132,9 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
leveldb_env::kNewLogger,
base::File::FILE_ERROR_NO_SPACE));
scoped_refptr<IndexedDBBackingStore> backing_store =
- IndexedDBBackingStore::Open(
- factory, origin, path, request_context_getter, &data_loss_info,
- &disk_full, &mock_leveldb_factory, task_runner, clean_journal, &s);
+ IndexedDBBackingStore::Open(factory, origin, path, &data_loss_info,
+ &disk_full, &mock_leveldb_factory,
+ task_runner, clean_journal, &s);
ASSERT_TRUE(s.IsIOError());
busted_factory.SetOpenError(MakeIOError("some filename",
@@ -145,18 +142,18 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
leveldb_env::kNewLogger,
base::File::FILE_ERROR_NO_MEMORY));
scoped_refptr<IndexedDBBackingStore> backing_store2 =
- IndexedDBBackingStore::Open(
- factory, origin, path, request_context_getter, &data_loss_info,
- &disk_full, &mock_leveldb_factory, task_runner, clean_journal, &s);
+ IndexedDBBackingStore::Open(factory, origin, path, &data_loss_info,
+ &disk_full, &mock_leveldb_factory,
+ task_runner, clean_journal, &s);
ASSERT_TRUE(s.IsIOError());
busted_factory.SetOpenError(MakeIOError("some filename", "some message",
leveldb_env::kNewLogger,
base::File::FILE_ERROR_IO));
scoped_refptr<IndexedDBBackingStore> backing_store3 =
- IndexedDBBackingStore::Open(
- factory, origin, path, request_context_getter, &data_loss_info,
- &disk_full, &mock_leveldb_factory, task_runner, clean_journal, &s);
+ IndexedDBBackingStore::Open(factory, origin, path, &data_loss_info,
+ &disk_full, &mock_leveldb_factory,
+ task_runner, clean_journal, &s);
ASSERT_TRUE(s.IsIOError());
busted_factory.SetOpenError(MakeIOError("some filename",
@@ -164,9 +161,9 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
leveldb_env::kNewLogger,
base::File::FILE_ERROR_FAILED));
scoped_refptr<IndexedDBBackingStore> backing_store4 =
- IndexedDBBackingStore::Open(
- factory, origin, path, request_context_getter, &data_loss_info,
- &disk_full, &mock_leveldb_factory, task_runner, clean_journal, &s);
+ IndexedDBBackingStore::Open(factory, origin, path, &data_loss_info,
+ &disk_full, &mock_leveldb_factory,
+ task_runner, clean_journal, &s);
ASSERT_TRUE(s.IsIOError());
}
diff --git a/chromium/content/browser/indexed_db/indexed_db_context_impl.cc b/chromium/content/browser/indexed_db/indexed_db_context_impl.cc
index 2bd6e7fc36e..6aa1736eba6 100644
--- a/chromium/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -200,9 +200,7 @@ base::ListValue* IndexedDBContextImpl::GetAllOriginsDetails() {
std::unique_ptr<base::ListValue> database_list(
std::make_unique<base::ListValue>());
- for (IndexedDBFactory::OriginDBMapIterator it = range.first;
- it != range.second;
- ++it) {
+ for (auto it = range.first; it != range.second; ++it) {
const IndexedDBDatabase* db = it->second;
std::unique_ptr<base::DictionaryValue> db_info(
std::make_unique<base::DictionaryValue>());
@@ -312,8 +310,6 @@ base::Time IndexedDBContextImpl::GetOriginLastModified(const Origin& origin) {
return factory_->GetLastModified(origin);
}
- if (data_path_.empty())
- return base::Time();
base::FilePath idb_directory = GetLevelDBPath(origin);
base::File::Info file_info;
if (!base::GetFileInfo(idb_directory, &file_info))
@@ -329,8 +325,14 @@ void IndexedDBContextImpl::DeleteForOrigin(const GURL& origin_url) {
void IndexedDBContextImpl::DeleteForOrigin(const Origin& origin) {
DCHECK(TaskRunner()->RunsTasksInCurrentSequence());
ForceClose(origin, FORCE_CLOSE_DELETE_ORIGIN);
- if (data_path_.empty() || !HasOrigin(origin))
+ if (!HasOrigin(origin))
+ return;
+
+ if (is_incognito()) {
+ GetOriginSet()->erase(origin);
+ origin_size_map_.erase(origin);
return;
+ }
base::FilePath idb_directory = GetLevelDBPath(origin);
EnsureDiskUsageCacheInitialized(origin);
@@ -348,7 +350,7 @@ void IndexedDBContextImpl::DeleteForOrigin(const Origin& origin) {
base::DeleteFile(GetBlobStorePath(origin), true /* recursive */);
QueryDiskAndUpdateQuotaUsage(origin);
if (s.ok()) {
- RemoveFromOriginSet(origin);
+ GetOriginSet()->erase(origin);
origin_size_map_.erase(origin);
}
}
@@ -362,7 +364,7 @@ void IndexedDBContextImpl::CopyOriginData(const GURL& origin_url,
void IndexedDBContextImpl::CopyOriginData(const Origin& origin,
IndexedDBContext* dest_context) {
DCHECK(TaskRunner()->RunsTasksInCurrentSequence());
- if (data_path_.empty() || !HasOrigin(origin))
+ if (is_incognito() || !HasOrigin(origin))
return;
IndexedDBContextImpl* dest_context_impl =
@@ -397,23 +399,38 @@ void IndexedDBContextImpl::ForceClose(const Origin origin,
reason,
FORCE_CLOSE_REASON_MAX);
- if (data_path_.empty() || !HasOrigin(origin))
+ if (!HasOrigin(origin))
return;
if (factory_.get())
- factory_->ForceClose(origin);
+ factory_->ForceClose(origin, reason == FORCE_CLOSE_DELETE_ORIGIN);
DCHECK_EQ(0UL, GetConnectionCount(origin));
}
-void IndexedDBContextImpl::ForceSchemaDowngrade(const Origin& origin) {
+bool IndexedDBContextImpl::ForceSchemaDowngrade(const Origin& origin) {
DCHECK(TaskRunner()->RunsTasksInCurrentSequence());
- if (data_path_.empty() || !HasOrigin(origin))
- return;
+ if (is_incognito() || !HasOrigin(origin))
+ return false;
- if (factory_.get())
+ if (factory_.get()) {
factory_->ForceSchemaDowngrade(origin);
- DCHECK_EQ(0UL, GetConnectionCount(origin));
+ return true;
+ }
+ this->ForceClose(origin, FORCE_SCHEMA_DOWNGRADE_INTERNALS_PAGE);
+ return false;
+}
+
+V2SchemaCorruptionStatus IndexedDBContextImpl::HasV2SchemaCorruption(
+ const Origin& origin) {
+ DCHECK(TaskRunner()->RunsTasksInCurrentSequence());
+
+ if (is_incognito() || !HasOrigin(origin))
+ return V2SchemaCorruptionStatus::kUnknown;
+
+ if (factory_.get())
+ return factory_->HasV2SchemaCorruption(origin);
+ return V2SchemaCorruptionStatus::kUnknown;
}
size_t IndexedDBContextImpl::GetConnectionCount(const Origin& origin) {
@@ -462,7 +479,7 @@ void IndexedDBContextImpl::ConnectionOpened(const Origin& origin,
quota_manager_proxy()->NotifyStorageAccessed(
storage::QuotaClient::kIndexedDatabase, origin,
blink::mojom::StorageType::kTemporary);
- if (AddToOriginSet(origin)) {
+ if (GetOriginSet()->insert(origin).second) {
// A newly created db, notify the quota system.
QueryDiskAndUpdateQuotaUsage(origin);
} else {
@@ -486,7 +503,7 @@ void IndexedDBContextImpl::TransactionComplete(const Origin& origin) {
}
void IndexedDBContextImpl::DatabaseDeleted(const Origin& origin) {
- AddToOriginSet(origin);
+ GetOriginSet()->insert(origin);
QueryDiskAndUpdateQuotaUsage(origin);
}
@@ -527,7 +544,7 @@ IndexedDBContextImpl::~IndexedDBContextImpl() {
std::move(factory_)));
}
- if (data_path_.empty())
+ if (is_incognito())
return;
if (force_keep_session_state_)
@@ -567,13 +584,13 @@ base::FilePath IndexedDBContextImpl::GetLevelDBFileName(const Origin& origin) {
base::FilePath IndexedDBContextImpl::GetBlobStorePath(
const Origin& origin) const {
- DCHECK(!data_path_.empty());
+ DCHECK(!is_incognito());
return data_path_.Append(GetBlobStoreFileName(origin));
}
base::FilePath IndexedDBContextImpl::GetLevelDBPath(
const Origin& origin) const {
- DCHECK(!data_path_.empty());
+ DCHECK(!is_incognito());
return data_path_.Append(GetLevelDBFileName(origin));
}
diff --git a/chromium/content/browser/indexed_db/indexed_db_context_impl.h b/chromium/content/browser/indexed_db/indexed_db_context_impl.h
index 856f9e3e482..ed60ffcb0f0 100644
--- a/chromium/content/browser/indexed_db/indexed_db_context_impl.h
+++ b/chromium/content/browser/indexed_db/indexed_db_context_impl.h
@@ -123,7 +123,8 @@ class CONTENT_EXPORT IndexedDBContextImpl : public IndexedDBContext {
// ForceClose takes a value rather than a reference since it may release the
// owning object.
void ForceClose(const url::Origin origin, ForceCloseReason reason);
- void ForceSchemaDowngrade(const url::Origin& origin);
+ bool ForceSchemaDowngrade(const url::Origin& origin);
+ V2SchemaCorruptionStatus HasV2SchemaCorruption(const url::Origin& origin);
// GetStoragePaths returns all paths owned by this database, in arbitrary
// order.
std::vector<base::FilePath> GetStoragePaths(const url::Origin& origin) const;
@@ -176,16 +177,16 @@ class CONTENT_EXPORT IndexedDBContextImpl : public IndexedDBContext {
void QueryDiskAndUpdateQuotaUsage(const url::Origin& origin);
base::Time GetOriginLastModified(const url::Origin& origin);
+ // Returns |origin_set_| (this context's in-memory cache of origins with
+ // backing stores); the cache will be primed as needed by checking disk.
std::set<url::Origin>* GetOriginSet();
- bool AddToOriginSet(const url::Origin& origin) {
- return GetOriginSet()->insert(origin).second;
- }
- void RemoveFromOriginSet(const url::Origin& origin) {
- GetOriginSet()->erase(origin);
- }
scoped_refptr<IndexedDBFactory> factory_;
+
+ // If |data_path_| is empty then this is an incognito session and the backing
+ // store will be held in-memory rather than on-disk.
base::FilePath data_path_;
+
// If true, nothing (not even session-only data) should be deleted on exit.
bool force_keep_session_state_;
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
diff --git a/chromium/content/browser/indexed_db/indexed_db_database_callbacks.cc b/chromium/content/browser/indexed_db/indexed_db_database_callbacks.cc
index 2da4f50e3b4..329a7acf999 100644
--- a/chromium/content/browser/indexed_db/indexed_db_database_callbacks.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_database_callbacks.cc
@@ -4,10 +4,12 @@
#include "content/browser/indexed_db/indexed_db_database_callbacks.h"
+#include "base/task/post_task.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/indexed_db/indexed_db_database_error.h"
#include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
#include "content/browser/indexed_db/indexed_db_transaction.h"
+#include "content/public/browser/browser_task_traits.h"
using blink::mojom::IDBDatabaseCallbacksAssociatedPtrInfo;
@@ -50,9 +52,9 @@ void IndexedDBDatabaseCallbacks::OnForcedClose() {
return;
DCHECK(io_helper_);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&IOThreadHelper::SendForcedClose,
- base::Unretained(io_helper_.get())));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&IOThreadHelper::SendForcedClose,
+ base::Unretained(io_helper_.get())));
complete_ = true;
}
@@ -63,10 +65,10 @@ void IndexedDBDatabaseCallbacks::OnVersionChange(int64_t old_version,
return;
DCHECK(io_helper_);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&IOThreadHelper::SendVersionChange,
- base::Unretained(io_helper_.get()),
- old_version, new_version));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&IOThreadHelper::SendVersionChange,
+ base::Unretained(io_helper_.get()),
+ old_version, new_version));
}
void IndexedDBDatabaseCallbacks::OnAbort(
@@ -77,10 +79,10 @@ void IndexedDBDatabaseCallbacks::OnAbort(
return;
DCHECK(io_helper_);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&IOThreadHelper::SendAbort,
- base::Unretained(io_helper_.get()),
- transaction.id(), error));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&IOThreadHelper::SendAbort,
+ base::Unretained(io_helper_.get()),
+ transaction.id(), error));
}
void IndexedDBDatabaseCallbacks::OnComplete(
@@ -91,8 +93,8 @@ void IndexedDBDatabaseCallbacks::OnComplete(
indexed_db_context_->TransactionComplete(transaction.database()->origin());
DCHECK(io_helper_);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendComplete,
base::Unretained(io_helper_.get()), transaction.id()));
}
@@ -101,8 +103,8 @@ void IndexedDBDatabaseCallbacks::OnDatabaseChange(
blink::mojom::IDBObserverChangesPtr changes) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(io_helper_);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&IOThreadHelper::SendChanges,
base::Unretained(io_helper_.get()), std::move(changes)));
}
diff --git a/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc
index e876744e8dc..f7c98abe58c 100644
--- a/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.cc
@@ -12,11 +12,13 @@
#include "base/sequenced_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h"
#include "content/browser/indexed_db/indexed_db_connection.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/indexed_db/indexed_db_database_callbacks.h"
#include "content/browser/indexed_db/indexed_db_pending_connection.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/database/database_util.h"
@@ -29,7 +31,7 @@ namespace {
const char kInvalidOrigin[] = "Origin is invalid";
bool IsValidOrigin(const url::Origin& origin) {
- return !origin.unique();
+ return !origin.opaque();
}
blink::mojom::IDBStatus GetIndexedDBStatus(leveldb::Status status) {
@@ -87,10 +89,8 @@ class IndexedDBDispatcherHost::IDBSequenceHelper {
public:
IDBSequenceHelper(
int ipc_process_id,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
scoped_refptr<IndexedDBContextImpl> indexed_db_context)
: ipc_process_id_(ipc_process_id),
- request_context_getter_(std::move(request_context_getter)),
indexed_db_context_(std::move(indexed_db_context)) {}
~IDBSequenceHelper() {}
@@ -116,7 +116,6 @@ class IndexedDBDispatcherHost::IDBSequenceHelper {
private:
const int ipc_process_id_;
- scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
scoped_refptr<IndexedDBContextImpl> indexed_db_context_;
DISALLOW_COPY_AND_ASSIGN(IDBSequenceHelper);
@@ -124,14 +123,12 @@ class IndexedDBDispatcherHost::IDBSequenceHelper {
IndexedDBDispatcherHost::IndexedDBDispatcherHost(
int ipc_process_id,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
scoped_refptr<IndexedDBContextImpl> indexed_db_context,
scoped_refptr<ChromeBlobStorageContext> blob_storage_context)
: indexed_db_context_(std::move(indexed_db_context)),
blob_storage_context_(std::move(blob_storage_context)),
ipc_process_id_(ipc_process_id),
idb_helper_(new IDBSequenceHelper(ipc_process_id_,
- std::move(request_context_getter),
indexed_db_context_)),
weak_factory_(this) {
DCHECK(indexed_db_context_.get());
@@ -161,8 +158,8 @@ void IndexedDBDispatcherHost::AddCursorBinding(
void IndexedDBDispatcherHost::RenderProcessExited(
RenderProcessHost* host,
const ChildProcessTerminationInfo& info) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&IndexedDBDispatcherHost::InvalidateWeakPtrsAndClearBindings,
base::Unretained(this)));
@@ -290,8 +287,8 @@ void IndexedDBDispatcherHost::IDBSequenceHelper::GetDatabaseNamesOnIDBThread(
DCHECK(indexed_db_context_->TaskRunner()->RunsTasksInCurrentSequence());
base::FilePath indexed_db_path = indexed_db_context_->data_path();
- indexed_db_context_->GetIDBFactory()->GetDatabaseNames(
- callbacks, origin, indexed_db_path, request_context_getter_);
+ indexed_db_context_->GetIDBFactory()->GetDatabaseNames(callbacks, origin,
+ indexed_db_path);
}
void IndexedDBDispatcherHost::IDBSequenceHelper::OpenOnIDBThread(
@@ -313,10 +310,8 @@ void IndexedDBDispatcherHost::IDBSequenceHelper::OpenOnIDBThread(
std::make_unique<IndexedDBPendingConnection>(
callbacks, database_callbacks, ipc_process_id_, transaction_id,
version);
- DCHECK(request_context_getter_);
indexed_db_context_->GetIDBFactory()->Open(name, std::move(connection),
- request_context_getter_, origin,
- indexed_db_path);
+ origin, indexed_db_path);
}
void IndexedDBDispatcherHost::IDBSequenceHelper::DeleteDatabaseOnIDBThread(
@@ -327,10 +322,8 @@ void IndexedDBDispatcherHost::IDBSequenceHelper::DeleteDatabaseOnIDBThread(
DCHECK(indexed_db_context_->TaskRunner()->RunsTasksInCurrentSequence());
base::FilePath indexed_db_path = indexed_db_context_->data_path();
- DCHECK(request_context_getter_);
indexed_db_context_->GetIDBFactory()->DeleteDatabase(
- name, request_context_getter_, callbacks, origin, indexed_db_path,
- force_close);
+ name, callbacks, origin, indexed_db_path, force_close);
}
void IndexedDBDispatcherHost::IDBSequenceHelper::
diff --git a/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.h b/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.h
index 099b0315498..a4babe252bc 100644
--- a/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.h
+++ b/chromium/content/browser/indexed_db/indexed_db_dispatcher_host.h
@@ -21,7 +21,6 @@
#include "content/public/browser/render_process_host_observer.h"
#include "mojo/public/cpp/bindings/associated_binding_set.h"
#include "mojo/public/cpp/bindings/strong_associated_binding_set.h"
-#include "net/url_request/url_request_context_getter.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"
namespace base {
@@ -45,7 +44,6 @@ class CONTENT_EXPORT IndexedDBDispatcherHost
// Only call the constructor from the UI thread.
IndexedDBDispatcherHost(
int ipc_process_id,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
scoped_refptr<IndexedDBContextImpl> indexed_db_context,
scoped_refptr<ChromeBlobStorageContext> blob_storage_context);
diff --git a/chromium/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
index 960febdf847..64bae16348b 100644
--- a/chromium/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_dispatcher_host_unittest.cc
@@ -11,6 +11,7 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_offset_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread.h"
#include "content/browser/indexed_db/indexed_db_callbacks.h"
@@ -20,12 +21,12 @@
#include "content/browser/indexed_db/indexed_db_pending_connection.h"
#include "content/browser/indexed_db/mock_mojo_indexed_db_callbacks.h"
#include "content/browser/indexed_db/mock_mojo_indexed_db_database_callbacks.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
-#include "net/url_request/url_request_test_util.h"
#include "storage/browser/test/mock_quota_manager.h"
#include "storage/browser/test/mock_quota_manager_proxy.h"
#include "storage/browser/test/mock_special_storage_policy.h"
@@ -56,6 +57,11 @@ using testing::StrictMock;
namespace content {
namespace {
+// TODO(crbug.com/889590): Replace with common converter.
+url::Origin ToOrigin(const std::string& url) {
+ return url::Origin::Create(GURL(url));
+}
+
ACTION_TEMPLATE(MoveArg,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(out)) {
@@ -159,7 +165,7 @@ class IndexedDBDispatcherHostTest : public testing::Test {
quota_manager_(base::MakeRefCounted<MockQuotaManager>(
false /*is_incognito*/,
browser_context_.GetPath(),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
special_storage_policy_)),
context_impl_(base::MakeRefCounted<IndexedDBContextImpl>(
CreateAndReturnTempDir(&temp_dir_),
@@ -167,12 +173,11 @@ class IndexedDBDispatcherHostTest : public testing::Test {
quota_manager_->proxy())),
host_(new IndexedDBDispatcherHost(
kFakeProcessId,
- base::MakeRefCounted<net::TestURLRequestContextGetter>(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)),
context_impl_,
ChromeBlobStorageContext::GetFor(&browser_context_))) {
- quota_manager_->SetQuota(
- GURL(kOrigin), blink::mojom::StorageType::kTemporary, kTemporaryQuota);
+ quota_manager_->SetQuota(ToOrigin(kOrigin),
+ blink::mojom::StorageType::kTemporary,
+ kTemporaryQuota);
}
void TearDown() override {
@@ -237,7 +242,7 @@ TEST_F(IndexedDBDispatcherHostTest, CloseAfterUpgrade) {
const char kObjectStoreName[] = "os";
// Open connection.
- TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
+ TestDatabaseConnection connection(ToOrigin(kOrigin),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
@@ -319,9 +324,8 @@ TEST_F(IndexedDBDispatcherHostTest, OpenNewConnectionWhileUpgrading) {
// Open connection 2, but expect that we won't be called back.
IDBDatabaseAssociatedPtrInfo database_info2;
IndexedDBDatabaseMetadata metadata2;
- TestDatabaseConnection connection2(url::Origin::Create(GURL(kOrigin)),
- base::UTF8ToUTF16(kDatabaseName),
- kDBVersion, 0);
+ TestDatabaseConnection connection2(
+ ToOrigin(kOrigin), base::UTF8ToUTF16(kDatabaseName), kDBVersion, 0);
connection2.Open(idb_mojo_factory_.get());
// Check that we're called in order and the second connection gets it's
@@ -445,7 +449,7 @@ TEST_F(IndexedDBDispatcherHostTest, CompactDatabaseWithConnection) {
const int64_t kTransactionId = 1;
// Open connection.
- TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
+ TestDatabaseConnection connection(ToOrigin(kOrigin),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -505,7 +509,7 @@ TEST_F(IndexedDBDispatcherHostTest, CompactDatabaseWhileDoingTransaction) {
const char kObjectStoreName[] = "os";
// Open connection.
- TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
+ TestDatabaseConnection connection(ToOrigin(kOrigin),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -570,7 +574,7 @@ TEST_F(IndexedDBDispatcherHostTest, CompactDatabaseWhileUpgrading) {
const int64_t kTransactionId = 1;
// Open connection.
- TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
+ TestDatabaseConnection connection(ToOrigin(kOrigin),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -633,7 +637,7 @@ TEST_F(IndexedDBDispatcherHostTest,
const int64_t kTransactionId = 1;
// Open connection.
- TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
+ TestDatabaseConnection connection(ToOrigin(kOrigin),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -696,7 +700,7 @@ TEST_F(IndexedDBDispatcherHostTest, AbortTransactionsWhileDoingTransaction) {
const char kObjectStoreName[] = "os";
// Open connection.
- TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
+ TestDatabaseConnection connection(ToOrigin(kOrigin),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -761,7 +765,7 @@ TEST_F(IndexedDBDispatcherHostTest, AbortTransactionsWhileUpgrading) {
const int64_t kTransactionId = 1;
// Open connection.
- TestDatabaseConnection connection(url::Origin::Create(GURL(kOrigin)),
+ TestDatabaseConnection connection(ToOrigin(kOrigin),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion, kTransactionId);
IndexedDBDatabaseMetadata metadata;
@@ -835,7 +839,7 @@ TEST_F(IndexedDBDispatcherHostTest, DISABLED_NotifyIndexedDBListChanged) {
context_impl_->AddObserver(&observer);
// Open connection 1.
- TestDatabaseConnection connection1(url::Origin::Create(GURL(kOrigin)),
+ TestDatabaseConnection connection1(ToOrigin(kOrigin),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion1, kTransactionId1);
IndexedDBDatabaseMetadata metadata1;
@@ -940,7 +944,7 @@ TEST_F(IndexedDBDispatcherHostTest, DISABLED_NotifyIndexedDBListChanged) {
connection2.database->Close();
// Open connection 3.
- TestDatabaseConnection connection3(url::Origin::Create(GURL(kOrigin)),
+ TestDatabaseConnection connection3(ToOrigin(kOrigin),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion3, kTransactionId3);
IndexedDBDatabaseMetadata metadata3;
@@ -1069,7 +1073,7 @@ TEST_F(IndexedDBDispatcherHostTest, NotifyIndexedDBContentChanged) {
connection1.database->Close();
// Open connection 2.
- TestDatabaseConnection connection2(url::Origin::Create(GURL(kOrigin)),
+ TestDatabaseConnection connection2(ToOrigin(kOrigin),
base::UTF8ToUTF16(kDatabaseName),
kDBVersion2, kTransactionId2);
IndexedDBDatabaseMetadata metadata2;
diff --git a/chromium/content/browser/indexed_db/indexed_db_factory.h b/chromium/content/browser/indexed_db/indexed_db_factory.h
index d4e62a6a9f7..9edf2b3e39e 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory.h
+++ b/chromium/content/browser/indexed_db/indexed_db_factory.h
@@ -23,10 +23,6 @@
#include "url/gurl.h"
#include "url/origin.h"
-namespace net {
-class URLRequestContextGetter;
-}
-
namespace content {
class IndexedDBBackingStore;
@@ -43,21 +39,17 @@ class CONTENT_EXPORT IndexedDBFactory
virtual void ReleaseDatabase(const IndexedDBDatabase::Identifier& identifier,
bool forced_close) = 0;
- virtual void GetDatabaseNames(
- scoped_refptr<IndexedDBCallbacks> callbacks,
- const url::Origin& origin,
- const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter) = 0;
+ virtual void GetDatabaseNames(scoped_refptr<IndexedDBCallbacks> callbacks,
+ const url::Origin& origin,
+ const base::FilePath& data_directory) = 0;
virtual void Open(
const base::string16& name,
std::unique_ptr<IndexedDBPendingConnection> connection,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
const url::Origin& origin,
const base::FilePath& data_directory) = 0;
virtual void DeleteDatabase(
const base::string16& name,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin,
const base::FilePath& data_directory,
@@ -78,8 +70,15 @@ class CONTENT_EXPORT IndexedDBFactory
virtual OriginDBs GetOpenDatabasesForOrigin(
const url::Origin& origin) const = 0;
- virtual void ForceClose(const url::Origin& origin) = 0;
+ // Close all connections to all databases within the origin. If
+ // |delete_in_memory_store| is true, references to in-memory databases will be
+ // dropped thereby allowing their deletion (otherwise they are retained for
+ // the lifetime of the factory).
+ virtual void ForceClose(const url::Origin& origin,
+ bool delete_in_memory_store = false) = 0;
virtual void ForceSchemaDowngrade(const url::Origin& origin) = 0;
+ virtual V2SchemaCorruptionStatus HasV2SchemaCorruption(
+ const url::Origin& origin) = 0;
// Called by the IndexedDBContext destructor so the factory can do cleanup.
virtual void ContextDestroyed() = 0;
@@ -115,7 +114,6 @@ class CONTENT_EXPORT IndexedDBFactory
virtual scoped_refptr<IndexedDBBackingStore> OpenBackingStore(
const url::Origin& origin,
const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
IndexedDBDataLossInfo* data_loss_info,
bool* disk_full,
leveldb::Status* status) = 0;
@@ -123,7 +121,6 @@ class CONTENT_EXPORT IndexedDBFactory
virtual scoped_refptr<IndexedDBBackingStore> OpenBackingStoreHelper(
const url::Origin& origin,
const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
IndexedDBDataLossInfo* data_loss_info,
bool* disk_full,
bool first_time,
diff --git a/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc b/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc
index 404b2556081..e625f0e6a2e 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -15,6 +15,7 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
+#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
@@ -137,7 +138,7 @@ void IndexedDBFactoryImpl::RemoveDatabaseFromMaps(
std::pair<OriginDBMap::iterator, OriginDBMap::iterator> range =
origin_dbs_.equal_range(database->identifier().first);
DCHECK(range.first != range.second);
- for (OriginDBMap::iterator it2 = range.first; it2 != range.second; ++it2) {
+ for (auto it2 = range.first; it2 != range.second; ++it2) {
if (it2->second == database) {
origin_dbs_.erase(it2);
break;
@@ -325,7 +326,8 @@ leveldb::Status IndexedDBFactoryImpl::AbortTransactions(const Origin& origin) {
return leveldb::Status::OK();
}
-void IndexedDBFactoryImpl::ForceClose(const Origin& origin) {
+void IndexedDBFactoryImpl::ForceClose(const Origin& origin,
+ bool delete_in_memory_store) {
OriginDBs range = GetOpenDatabasesForOrigin(origin);
while (range.first != range.second) {
@@ -334,19 +336,33 @@ void IndexedDBFactoryImpl::ForceClose(const Origin& origin) {
db->ForceClose();
}
- if (backing_store_map_.find(origin) != backing_store_map_.end())
+ auto it = backing_store_map_.find(origin);
+ if (it != backing_store_map_.end()) {
+ if (delete_in_memory_store)
+ in_memory_backing_stores_.erase(it->second);
+
ReleaseBackingStore(origin, true /* immediate */);
+ }
}
void IndexedDBFactoryImpl::ForceSchemaDowngrade(const Origin& origin) {
- OriginDBs range = GetOpenDatabasesForOrigin(origin);
+ auto it = backing_store_map_.find(origin);
+ if (it == backing_store_map_.end())
+ return;
- while (range.first != range.second) {
- IndexedDBDatabase* db = range.first->second;
- ++range.first;
- leveldb::Status s = db->backing_store()->RevertSchemaToV2();
- DLOG_IF(ERROR, !s.ok()) << "Unable to force downgrade: " << s.ToString();
- }
+ IndexedDBBackingStore* backing_store = it->second.get();
+ leveldb::Status s = backing_store->RevertSchemaToV2();
+ DLOG_IF(ERROR, !s.ok()) << "Unable to force downgrade: " << s.ToString();
+}
+
+V2SchemaCorruptionStatus IndexedDBFactoryImpl::HasV2SchemaCorruption(
+ const Origin& origin) {
+ auto it = backing_store_map_.find(origin);
+ if (it == backing_store_map_.end())
+ return V2SchemaCorruptionStatus::kUnknown;
+
+ IndexedDBBackingStore* backing_store = it->second.get();
+ return backing_store->HasV2SchemaCorruption();
}
void IndexedDBFactoryImpl::ContextDestroyed() {
@@ -386,8 +402,7 @@ void IndexedDBFactoryImpl::ReportOutstandingBlobs(const Origin& origin,
void IndexedDBFactoryImpl::GetDatabaseNames(
scoped_refptr<IndexedDBCallbacks> callbacks,
const Origin& origin,
- const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter) {
+ const base::FilePath& data_directory) {
IDB_TRACE("IndexedDBFactoryImpl::GetDatabaseNames");
// TODO(dgrogan): Plumb data_loss back to script eventually?
IndexedDBDataLossInfo data_loss_info;
@@ -395,8 +410,7 @@ void IndexedDBFactoryImpl::GetDatabaseNames(
leveldb::Status s;
// TODO(cmumford): Handle this error
scoped_refptr<IndexedDBBackingStore> backing_store =
- OpenBackingStore(origin, data_directory, request_context_getter,
- &data_loss_info, &disk_full, &s);
+ OpenBackingStore(origin, data_directory, &data_loss_info, &disk_full, &s);
if (!backing_store.get()) {
IndexedDBDatabaseError error(
blink::kWebIDBDatabaseExceptionUnknownError,
@@ -430,7 +444,6 @@ void IndexedDBFactoryImpl::GetDatabaseNames(
void IndexedDBFactoryImpl::DeleteDatabase(
const base::string16& name,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
scoped_refptr<IndexedDBCallbacks> callbacks,
const Origin& origin,
const base::FilePath& data_directory,
@@ -450,8 +463,7 @@ void IndexedDBFactoryImpl::DeleteDatabase(
bool disk_full = false;
leveldb::Status s;
scoped_refptr<IndexedDBBackingStore> backing_store =
- OpenBackingStore(origin, data_directory, request_context_getter,
- &data_loss_info, &disk_full, &s);
+ OpenBackingStore(origin, data_directory, &data_loss_info, &disk_full, &s);
if (!backing_store.get()) {
IndexedDBDatabaseError error(
blink::kWebIDBDatabaseExceptionUnknownError,
@@ -596,11 +608,12 @@ void IndexedDBFactoryImpl::HandleBackingStoreCorruption(
bool IndexedDBFactoryImpl::IsDatabaseOpen(const Origin& origin,
const base::string16& name) const {
- return !!database_map_.count(IndexedDBDatabase::Identifier(origin, name));
+ return base::ContainsKey(database_map_,
+ IndexedDBDatabase::Identifier(origin, name));
}
bool IndexedDBFactoryImpl::IsBackingStoreOpen(const Origin& origin) const {
- return backing_store_map_.find(origin) != backing_store_map_.end();
+ return base::ContainsKey(backing_store_map_, origin);
}
bool IndexedDBFactoryImpl::IsBackingStorePendingClose(
@@ -616,20 +629,18 @@ scoped_refptr<IndexedDBBackingStore>
IndexedDBFactoryImpl::OpenBackingStoreHelper(
const Origin& origin,
const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
IndexedDBDataLossInfo* data_loss_info,
bool* disk_full,
bool first_time,
leveldb::Status* status) {
return IndexedDBBackingStore::Open(
- this, origin, data_directory, request_context_getter, data_loss_info,
- disk_full, context_->TaskRunner(), first_time, status);
+ this, origin, data_directory, data_loss_info, disk_full,
+ context_->TaskRunner(), first_time, status);
}
scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore(
const Origin& origin,
const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
IndexedDBDataLossInfo* data_loss_info,
bool* disk_full,
leveldb::Status* status) {
@@ -656,22 +667,22 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore(
} else {
first_time = !backends_opened_since_boot_.count(origin);
- backing_store =
- OpenBackingStoreHelper(origin, data_directory, request_context_getter,
- data_loss_info, disk_full, first_time, status);
+ backing_store = OpenBackingStoreHelper(
+ origin, data_directory, data_loss_info, disk_full, first_time, status);
}
if (backing_store.get()) {
if (first_time)
backends_opened_since_boot_.insert(origin);
backing_store_map_[origin] = backing_store;
+
// If an in-memory database, bind lifetime to this factory instance.
if (open_in_memory)
- session_only_backing_stores_.insert(backing_store);
+ in_memory_backing_stores_.insert(backing_store);
// All backing stores associated with this factory should be of the same
// type.
- DCHECK_NE(session_only_backing_stores_.empty(), open_in_memory);
+ DCHECK_NE(in_memory_backing_stores_.empty(), open_in_memory);
return backing_store;
}
@@ -682,7 +693,6 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore(
void IndexedDBFactoryImpl::Open(
const base::string16& name,
std::unique_ptr<IndexedDBPendingConnection> connection,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
const Origin& origin,
const base::FilePath& data_directory) {
IDB_TRACE("IndexedDBFactoryImpl::Open");
@@ -694,9 +704,8 @@ void IndexedDBFactoryImpl::Open(
bool was_open = (it != database_map_.end());
if (!was_open) {
leveldb::Status s;
- scoped_refptr<IndexedDBBackingStore> backing_store =
- OpenBackingStore(origin, data_directory, request_context_getter,
- &data_loss_info, &disk_full, &s);
+ scoped_refptr<IndexedDBBackingStore> backing_store = OpenBackingStore(
+ origin, data_directory, &data_loss_info, &disk_full, &s);
if (!backing_store.get()) {
if (disk_full) {
connection->callbacks->OnError(IndexedDBDatabaseError(
@@ -757,7 +766,7 @@ size_t IndexedDBFactoryImpl::GetConnectionCount(const Origin& origin) const {
size_t count(0);
OriginDBs range = GetOpenDatabasesForOrigin(origin);
- for (OriginDBMapIterator it = range.first; it != range.second; ++it)
+ for (auto it = range.first; it != range.second; ++it)
count += it->second->ConnectionCount();
return count;
@@ -765,7 +774,9 @@ size_t IndexedDBFactoryImpl::GetConnectionCount(const Origin& origin) const {
int64_t IndexedDBFactoryImpl::GetInMemoryDBSize(const Origin& origin) const {
const auto& it = backing_store_map_.find(origin);
- DCHECK(it != backing_store_map_.end());
+ // Origin won't be present in map if it has been deleted.
+ if (it == backing_store_map_.end())
+ return 0;
const scoped_refptr<IndexedDBBackingStore>& backing_store = it->second;
int64_t level_db_size = 0;
diff --git a/chromium/content/browser/indexed_db/indexed_db_factory_impl.h b/chromium/content/browser/indexed_db/indexed_db_factory_impl.h
index b78429e2e2c..669ba668615 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_impl.h
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_impl.h
@@ -55,18 +55,14 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
void GetDatabaseNames(scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin,
- const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter>
- request_context_getter) override;
+ const base::FilePath& data_directory) override;
void Open(const base::string16& name,
std::unique_ptr<IndexedDBPendingConnection> connection,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
const url::Origin& origin,
const base::FilePath& data_directory) override;
void DeleteDatabase(
const base::string16& name,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
scoped_refptr<IndexedDBCallbacks> callbacks,
const url::Origin& origin,
const base::FilePath& data_directory,
@@ -86,8 +82,11 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
OriginDBs GetOpenDatabasesForOrigin(const url::Origin& origin) const override;
- void ForceClose(const url::Origin& origin) override;
+ void ForceClose(const url::Origin& origin,
+ bool delete_in_memory_store) override;
void ForceSchemaDowngrade(const url::Origin& origin) override;
+ V2SchemaCorruptionStatus HasV2SchemaCorruption(
+ const url::Origin& origin) override;
// Called by the IndexedDBContext destructor so the factory can do cleanup.
void ContextDestroyed() override;
@@ -120,7 +119,6 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
scoped_refptr<IndexedDBBackingStore> OpenBackingStore(
const url::Origin& origin,
const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
IndexedDBDataLossInfo* data_loss_info,
bool* disk_full,
leveldb::Status* s) override;
@@ -128,7 +126,6 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
scoped_refptr<IndexedDBBackingStore> OpenBackingStoreHelper(
const url::Origin& origin,
const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
IndexedDBDataLossInfo* data_loss_info,
bool* disk_full,
bool first_time,
@@ -181,7 +178,10 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
std::map<url::Origin, scoped_refptr<IndexedDBBackingStore>>
backing_store_map_;
- std::set<scoped_refptr<IndexedDBBackingStore> > session_only_backing_stores_;
+ // In-memory (incognito) backing stores should live as long as the
+ // StoragePartition which owns the IndexedDBContext which owns this
+ // IndexedDBFactory.
+ std::set<scoped_refptr<IndexedDBBackingStore>> in_memory_backing_stores_;
std::map<url::Origin, scoped_refptr<IndexedDBBackingStore>>
backing_stores_with_active_blobs_;
std::set<url::Origin> backends_opened_since_boot_;
diff --git a/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc
index 849666e7be5..8951a04e3b6 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -52,9 +52,8 @@ class MockIDBFactory : public IndexedDBFactoryImpl {
IndexedDBDataLossInfo data_loss_info;
bool disk_full;
leveldb::Status s;
- scoped_refptr<IndexedDBBackingStore> backing_store =
- OpenBackingStore(origin, data_directory, nullptr /* request_context */,
- &data_loss_info, &disk_full, &s);
+ scoped_refptr<IndexedDBBackingStore> backing_store = OpenBackingStore(
+ origin, data_directory, &data_loss_info, &disk_full, &s);
EXPECT_EQ(blink::kWebIDBDataLossNone, data_loss_info.status);
return backing_store;
}
@@ -447,7 +446,6 @@ class DiskFullFactory : public IndexedDBFactoryImpl {
scoped_refptr<IndexedDBBackingStore> OpenBackingStore(
const Origin& origin,
const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
IndexedDBDataLossInfo* data_loss_info,
bool* disk_full,
leveldb::Status* s) override {
@@ -503,8 +501,7 @@ TEST_F(IndexedDBFactoryTest, QuotaErrorOnDiskFull) {
callbacks, dummy_database_callbacks,
0 /* child_process_id */, 2 /* transaction_id */,
1 /* version */));
- factory->Open(name, std::move(connection),
- nullptr /* request_context */, origin,
+ factory->Open(name, std::move(connection), origin,
context->data_path());
EXPECT_TRUE(callbacks->error_called());
},
@@ -531,8 +528,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleasedOnForcedClose) {
callbacks, db_callbacks, 0 /* child_process_id */,
transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
- factory->Open(ASCIIToUTF16("db"), std::move(connection),
- nullptr /* request_context */, origin,
+ factory->Open(ASCIIToUTF16("db"), std::move(connection), origin,
context->data_path());
EXPECT_TRUE(callbacks->connection());
@@ -569,8 +565,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) {
callbacks, db_callbacks, 0 /* child_process_id */,
transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
- factory->Open(ASCIIToUTF16("db"), std::move(connection),
- nullptr /* request_context */, origin,
+ factory->Open(ASCIIToUTF16("db"), std::move(connection), origin,
context->data_path());
EXPECT_TRUE(callbacks->connection());
@@ -613,9 +608,9 @@ TEST_F(IndexedDBFactoryTest, DeleteDatabaseClosesBackingStore) {
const Origin origin = Origin::Create(GURL("http://localhost:81"));
EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
- factory->DeleteDatabase(
- ASCIIToUTF16("db"), nullptr /* request_context */, callbacks,
- origin, context->data_path(), false /* force_close */);
+ factory->DeleteDatabase(ASCIIToUTF16("db"), callbacks, origin,
+ context->data_path(),
+ false /* force_close */);
EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
EXPECT_TRUE(factory->IsBackingStorePendingClose(origin));
@@ -645,8 +640,7 @@ TEST_F(IndexedDBFactoryTest, GetDatabaseNamesClosesBackingStore) {
const Origin origin = Origin::Create(GURL("http://localhost:81"));
EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
- factory->GetDatabaseNames(callbacks, origin, context->data_path(),
- nullptr /* request_context */);
+ factory->GetDatabaseNames(callbacks, origin, context->data_path());
EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
EXPECT_TRUE(factory->IsBackingStorePendingClose(origin));
@@ -681,8 +675,7 @@ TEST_F(IndexedDBFactoryTest, ForceCloseReleasesBackingStore) {
callbacks, db_callbacks, 0 /* child_process_id */,
transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
- factory->Open(ASCIIToUTF16("db"), std::move(connection),
- nullptr /* request_context */, origin,
+ factory->Open(ASCIIToUTF16("db"), std::move(connection), origin,
context->data_path());
EXPECT_TRUE(callbacks->connection());
@@ -694,13 +687,13 @@ TEST_F(IndexedDBFactoryTest, ForceCloseReleasesBackingStore) {
EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
EXPECT_TRUE(factory->IsBackingStorePendingClose(origin));
- factory->ForceClose(origin);
+ factory->ForceClose(origin, /*delete_in_memory_store=*/false);
EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));
// Ensure it is safe if the store is not open.
- factory->ForceClose(origin);
+ factory->ForceClose(origin, /*delete_in_memory_store=*/false);
},
base::Unretained(context()),
@@ -782,7 +775,7 @@ TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) {
std::make_unique<IndexedDBPendingConnection>(
*upgrade_callbacks, db_callbacks, 0 /* child_process_id */,
transaction_id, db_version),
- nullptr /* request_context */, origin, context->data_path());
+ origin, context->data_path());
EXPECT_TRUE((*factory)->IsDatabaseOpen(origin, db_name));
},
@@ -822,15 +815,14 @@ TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) {
std::make_unique<IndexedDBPendingConnection>(
failed_open_callbacks, db_callbacks,
0 /* child_process_id */, transaction_id, db_version));
- factory->Open(db_name, std::move(connection),
- nullptr /* request_context */, origin,
+ factory->Open(db_name, std::move(connection), origin,
context->data_path());
EXPECT_TRUE(failed_open_callbacks->saw_error());
EXPECT_FALSE(factory->IsDatabaseOpen(origin, db_name));
}
// Terminate all pending-close timers.
- factory->ForceClose(origin);
+ factory->ForceClose(origin, /*delete_in_memory_store=*/false);
},
base::Unretained(context()), std::move(factory),
std::move(upgrade_callbacks), base::MakeRefCounted<ErrorCallbacks>(),
@@ -898,7 +890,7 @@ TEST_F(IndexedDBFactoryTest, DataFormatVersion) {
std::make_unique<IndexedDBPendingConnection>(
*callbacks, db_callbacks, 0 /* child_process_id */,
transaction_id, 1 /* version */),
- nullptr /* request_context */, origin, context->data_path());
+ origin, context->data_path());
},
base::Unretained(context()), base::Unretained(&factory),
base::Unretained(&callbacks),
@@ -916,7 +908,7 @@ TEST_F(IndexedDBFactoryTest, DataFormatVersion) {
connection->database()->Commit(
connection->GetTransaction(transaction_id));
connection->Close();
- factory->ForceClose(origin);
+ factory->ForceClose(origin, /*delete_in_memory_store=*/false);
*result = callbacks->data_loss();
},
std::move(factory), std::move(callbacks), origin, transaction_id,
diff --git a/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.cc b/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.cc
index 7477de76328..7444756a65e 100644
--- a/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_fake_backing_store.cc
@@ -6,7 +6,6 @@
#include "base/files/file_path.h"
#include "base/threading/sequenced_task_runner_handle.h"
-#include "net/url_request/url_request_context_getter.h"
namespace content {
namespace {
@@ -20,7 +19,6 @@ IndexedDBFakeBackingStore::IndexedDBFakeBackingStore()
: IndexedDBBackingStore(nullptr /* indexed_db_factory */,
url::Origin::Create(GURL("http://localhost:81")),
base::FilePath(),
- scoped_refptr<net::URLRequestContextGetter>(),
std::unique_ptr<LevelDBDatabase>(),
std::unique_ptr<LevelDBComparator>(),
base::SequencedTaskRunnerHandle::Get().get()) {}
@@ -30,7 +28,6 @@ IndexedDBFakeBackingStore::IndexedDBFakeBackingStore(
: IndexedDBBackingStore(factory,
url::Origin::Create(GURL("http://localhost:81")),
base::FilePath(),
- nullptr /* request_context */,
std::unique_ptr<LevelDBDatabase>(),
std::unique_ptr<LevelDBComparator>(),
task_runner) {}
diff --git a/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc b/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc
index cd8bc3bdb43..909b8e86fd7 100644
--- a/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc
@@ -18,6 +18,7 @@
#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/grit/content_resources.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/download_request_utils.h"
@@ -119,8 +120,8 @@ void IndexedDBInternalsUI::GetAllOriginsOnIndexedDBThread(
context_impl->GetAllOriginsDetails());
bool is_incognito = context_impl->is_incognito();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&IndexedDBInternalsUI::OnOriginsReady,
base::Unretained(this), std::move(info_list),
is_incognito ? base::FilePath() : context_path));
@@ -261,8 +262,8 @@ void IndexedDBInternalsUI::DownloadOriginDataOnIndexedDBThread(
zip::ZipWithFilterCallback(context->data_path(), zip_path,
base::Bind(AllowWhitelistedPaths, paths));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&IndexedDBInternalsUI::OnDownloadDataReady,
base::Unretained(this), partition_path, origin, temp_path,
zip_path, connection_count));
@@ -281,8 +282,8 @@ void IndexedDBInternalsUI::ForceCloseOriginOnIndexedDBThread(
context->ForceClose(origin, IndexedDBContextImpl::FORCE_CLOSE_INTERNALS_PAGE);
size_t connection_count = context->GetConnectionCount(origin);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&IndexedDBInternalsUI::OnForcedSchemaDowngrade,
base::Unretained(this), partition_path, origin,
connection_count));
@@ -303,8 +304,8 @@ void IndexedDBInternalsUI::ForceSchemaDowngradeOriginOnIndexedDBThread(
origin, IndexedDBContextImpl::FORCE_SCHEMA_DOWNGRADE_INTERNALS_PAGE);
size_t connection_count = context->GetConnectionCount(origin);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&IndexedDBInternalsUI::OnForcedSchemaDowngrade,
base::Unretained(this), partition_path, origin,
connection_count));
diff --git a/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.cc b/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
index 91dd95712ad..f8e127b6fbe 100644
--- a/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_transaction_coordinator.cc
@@ -147,8 +147,8 @@ void IndexedDBTransactionCoordinator::ProcessQueuedTransactions() {
template<typename T>
static bool DoSetsIntersect(const std::set<T>& set1,
const std::set<T>& set2) {
- typename std::set<T>::const_iterator it1 = set1.begin();
- typename std::set<T>::const_iterator it2 = set2.begin();
+ auto it1 = set1.begin();
+ auto it2 = set2.begin();
while (it1 != set1.end() && it2 != set2.end()) {
if (*it1 < *it2)
++it1;
diff --git a/chromium/content/browser/indexed_db/indexed_db_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_unittest.cc
index 4763c2f5eaf..e651a8edf6f 100644
--- a/chromium/content/browser/indexed_db/indexed_db_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_unittest.cc
@@ -173,7 +173,6 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) {
const int child_process_id = 0;
const int64_t host_transaction_id = 0;
const int64_t version = 0;
- const scoped_refptr<net::URLRequestContextGetter> request_context;
IndexedDBFactory* factory = idb_context->GetIDBFactory();
@@ -184,14 +183,14 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnDelete) {
std::make_unique<IndexedDBPendingConnection>(
open_callbacks, open_db_callbacks,
child_process_id, host_transaction_id, version),
- request_context, origin, idb_context->data_path());
+ origin, idb_context->data_path());
EXPECT_TRUE(base::DirectoryExists(test_path));
factory->Open(base::ASCIIToUTF16("closeddb"),
std::make_unique<IndexedDBPendingConnection>(
closed_callbacks, closed_db_callbacks,
child_process_id, host_transaction_id, version),
- request_context, origin, idb_context->data_path());
+ origin, idb_context->data_path());
closed_callbacks->connection()->Close();
@@ -260,14 +259,13 @@ TEST_F(IndexedDBTest, ForceCloseOpenDatabasesOnCommitFailure) {
const int child_process_id = 0;
const int64_t transaction_id = 1;
- const scoped_refptr<net::URLRequestContextGetter> request_context;
std::unique_ptr<IndexedDBPendingConnection> connection(
std::make_unique<IndexedDBPendingConnection>(
callbacks, db_callbacks, child_process_id, transaction_id,
IndexedDBDatabaseMetadata::DEFAULT_VERSION));
factory->Open(base::ASCIIToUTF16("db"), std::move(connection),
- request_context, Origin(kTestOrigin), temp_path);
+ Origin(kTestOrigin), temp_path);
EXPECT_TRUE(callbacks->connection());
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc b/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc
index 761cc63bb32..5b758222da1 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_database.cc
@@ -387,7 +387,7 @@ leveldb::Status LevelDBDatabase::Remove(const StringPiece& key) {
const leveldb::Status s =
db_->Delete(write_options, leveldb_env::MakeSlice(key));
- if (!s.IsNotFound())
+ if (!s.ok() && !s.IsNotFound())
LOG(ERROR) << "LevelDB remove failed: " << s.ToString();
last_modified_ = clock_->Now();
return s;
diff --git a/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc b/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc
index 89035f6fb43..97690b6f879 100644
--- a/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc
+++ b/chromium/content/browser/indexed_db/leveldb/leveldb_transaction.cc
@@ -46,7 +46,7 @@ void LevelDBTransaction::Set(const StringPiece& key,
std::string* value,
bool deleted) {
DCHECK(!finished_);
- DataType::iterator it = data_.find(key);
+ auto it = data_.find(key);
if (it == data_.end()) {
std::unique_ptr<Record> record = std::make_unique<Record>();
diff --git a/chromium/content/browser/indexed_db/mock_indexed_db_factory.h b/chromium/content/browser/indexed_db/mock_indexed_db_factory.h
index b2747857a84..2d92895000d 100644
--- a/chromium/content/browser/indexed_db/mock_indexed_db_factory.h
+++ b/chromium/content/browser/indexed_db/mock_indexed_db_factory.h
@@ -21,36 +21,29 @@ class MockIndexedDBFactory : public IndexedDBFactory {
MOCK_METHOD2(ReleaseDatabase,
void(const IndexedDBDatabase::Identifier& identifier,
bool forced_close));
+ MOCK_METHOD3(GetDatabaseNames,
+ void(scoped_refptr<IndexedDBCallbacks> callbacks,
+ const url::Origin& origin,
+ const base::FilePath& data_directory));
MOCK_METHOD4(
- GetDatabaseNames,
- void(scoped_refptr<IndexedDBCallbacks> callbacks,
- const url::Origin& origin,
- const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter));
- MOCK_METHOD5(
OpenProxy,
void(const base::string16& name,
IndexedDBPendingConnection* connection,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
const url::Origin& origin,
const base::FilePath& data_directory));
// Googlemock can't deal with move-only types, so *Proxy() is a workaround.
void Open(const base::string16& name,
std::unique_ptr<IndexedDBPendingConnection> connection,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
const url::Origin& origin,
const base::FilePath& data_directory) override {
- OpenProxy(name, connection.get(), request_context_getter, origin,
- data_directory);
+ OpenProxy(name, connection.get(), origin, data_directory);
}
- MOCK_METHOD6(
- DeleteDatabase,
- void(const base::string16& name,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
- scoped_refptr<IndexedDBCallbacks> callbacks,
- const url::Origin& origin,
- const base::FilePath& data_directory,
- bool force_close));
+ MOCK_METHOD5(DeleteDatabase,
+ void(const base::string16& name,
+ scoped_refptr<IndexedDBCallbacks> callbacks,
+ const url::Origin& origin,
+ const base::FilePath& data_directory,
+ bool force_close));
MOCK_METHOD2(AbortTransactionsAndCompactDatabaseProxy,
void(base::OnceCallback<void(leveldb::Status)>* callback,
const url::Origin& origin));
@@ -77,8 +70,11 @@ class MockIndexedDBFactory : public IndexedDBFactory {
// The Android NDK implements a subset of STL, and the gtest templates can't
// deal with std::pair's. This means we can't use GoogleMock for this method
OriginDBs GetOpenDatabasesForOrigin(const url::Origin& origin) const override;
- MOCK_METHOD1(ForceClose, void(const url::Origin& origin));
+ MOCK_METHOD2(ForceClose,
+ void(const url::Origin& origin, bool delete_in_memory_store));
MOCK_METHOD1(ForceSchemaDowngrade, void(const url::Origin& origin));
+ MOCK_METHOD1(HasV2SchemaCorruption,
+ V2SchemaCorruptionStatus(const url::Origin& origin));
MOCK_METHOD0(ContextDestroyed, void());
MOCK_METHOD1(DatabaseDeleted,
void(const IndexedDBDatabase::Identifier& identifier));
@@ -103,26 +99,22 @@ class MockIndexedDBFactory : public IndexedDBFactory {
protected:
~MockIndexedDBFactory() override;
- MOCK_METHOD6(
- OpenBackingStore,
- scoped_refptr<IndexedDBBackingStore>(
- const url::Origin& origin,
- const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
- IndexedDBDataLossInfo* data_loss_info,
- bool* disk_full,
- leveldb::Status* s));
-
- MOCK_METHOD7(
- OpenBackingStoreHelper,
- scoped_refptr<IndexedDBBackingStore>(
- const url::Origin& origin,
- const base::FilePath& data_directory,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter,
- IndexedDBDataLossInfo* data_loss_info,
- bool* disk_full,
- bool first_time,
- leveldb::Status* s));
+ MOCK_METHOD5(OpenBackingStore,
+ scoped_refptr<IndexedDBBackingStore>(
+ const url::Origin& origin,
+ const base::FilePath& data_directory,
+ IndexedDBDataLossInfo* data_loss_info,
+ bool* disk_full,
+ leveldb::Status* s));
+
+ MOCK_METHOD6(OpenBackingStoreHelper,
+ scoped_refptr<IndexedDBBackingStore>(
+ const url::Origin& origin,
+ const base::FilePath& data_directory,
+ IndexedDBDataLossInfo* data_loss_info,
+ bool* disk_full,
+ bool first_time,
+ leveldb::Status* s));
private:
DISALLOW_COPY_AND_ASSIGN(MockIndexedDBFactory);
diff --git a/chromium/content/browser/initiator_csp_context.cc b/chromium/content/browser/initiator_csp_context.cc
index a29e02d4e97..2529f9eefbd 100644
--- a/chromium/content/browser/initiator_csp_context.cc
+++ b/chromium/content/browser/initiator_csp_context.cc
@@ -8,8 +8,10 @@ namespace content {
InitiatorCSPContext::InitiatorCSPContext(
const std::vector<ContentSecurityPolicy>& policies,
- base::Optional<CSPSource>& self_source)
- : reporting_render_frame_host_impl_(nullptr) {
+ base::Optional<CSPSource>& self_source,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator)
+ : reporting_render_frame_host_impl_(nullptr),
+ initiator_ptr(std::move(navigation_initiator)) {
for (const auto& policy : policies)
AddContentSecurityPolicy(policy);
@@ -17,6 +19,8 @@ InitiatorCSPContext::InitiatorCSPContext(
SetSelf(self_source.value());
}
+InitiatorCSPContext::~InitiatorCSPContext() {}
+
void InitiatorCSPContext::SetReportingRenderFrameHost(
RenderFrameHostImpl* rfh) {
reporting_render_frame_host_impl_ = rfh;
@@ -24,9 +28,19 @@ void InitiatorCSPContext::SetReportingRenderFrameHost(
void InitiatorCSPContext::ReportContentSecurityPolicyViolation(
const CSPViolationParams& violation_params) {
- if (reporting_render_frame_host_impl_) {
- reporting_render_frame_host_impl_->ReportContentSecurityPolicyViolation(
- violation_params);
+ if (initiator_ptr.is_bound()) {
+ initiator_ptr->SendViolationReport(blink::mojom::CSPViolationParams::New(
+ violation_params.directive, violation_params.effective_directive,
+ violation_params.console_message, violation_params.blocked_url.spec(),
+ violation_params.report_endpoints, violation_params.use_reporting_api,
+ violation_params.header,
+ (blink::mojom::WebContentSecurityPolicyType)
+ violation_params.disposition,
+ violation_params.after_redirect,
+ blink::mojom::SourceLocation::New(
+ violation_params.source_location.url,
+ violation_params.source_location.column_number,
+ violation_params.source_location.line_number)));
}
}
diff --git a/chromium/content/browser/initiator_csp_context.h b/chromium/content/browser/initiator_csp_context.h
index e370eee3b60..097e228b9aa 100644
--- a/chromium/content/browser/initiator_csp_context.h
+++ b/chromium/content/browser/initiator_csp_context.h
@@ -20,8 +20,11 @@ namespace content {
// `navigate-to` and `form-action` (in the case of form submissions).
class InitiatorCSPContext : public CSPContext {
public:
- InitiatorCSPContext(const std::vector<ContentSecurityPolicy>& policies,
- base::Optional<CSPSource>& self_source);
+ InitiatorCSPContext(
+ const std::vector<ContentSecurityPolicy>& policies,
+ base::Optional<CSPSource>& self_source,
+ blink::mojom::NavigationInitiatorPtr navigation_initiator);
+ ~InitiatorCSPContext() override;
void ReportContentSecurityPolicyViolation(
const CSPViolationParams& violation_params) override;
@@ -35,6 +38,9 @@ class InitiatorCSPContext : public CSPContext {
private:
RenderFrameHostImpl* reporting_render_frame_host_impl_;
+ blink::mojom::NavigationInitiatorPtr initiator_ptr;
+
+ DISALLOW_COPY_AND_ASSIGN(InitiatorCSPContext);
};
} // namespace content
diff --git a/chromium/content/browser/interface_provider_filtering.cc b/chromium/content/browser/interface_provider_filtering.cc
index 239566b6f1f..2642276f488 100644
--- a/chromium/content/browser/interface_provider_filtering.cc
+++ b/chromium/content/browser/interface_provider_filtering.cc
@@ -6,7 +6,9 @@
#include <utility>
+#include "base/task/post_task.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "services/service_manager/public/cpp/connector.h"
@@ -48,8 +50,8 @@ FilterRendererExposedInterfaces(
service_manager::mojom::InterfaceProviderPtr provider;
auto filtered_request = mojo::MakeRequest(&provider);
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&FilterInterfacesImpl, spec, process_id,
std::move(request), std::move(provider)));
} else {
diff --git a/chromium/content/browser/isolated_origin_browsertest.cc b/chromium/content/browser/isolated_origin_browsertest.cc
index 7c0f014d404..20c7c4f3455 100644
--- a/chromium/content/browser/isolated_origin_browsertest.cc
+++ b/chromium/content/browser/isolated_origin_browsertest.cc
@@ -1115,6 +1115,42 @@ IN_PROC_BROWSER_TEST_F(IsolatedOriginFieldTrialTest, Test) {
policy->IsIsolatedOrigin(url::Origin::Create(GURL("https://bar.com/"))));
}
+class IsolatedOriginCommandLineAndFieldTrialTest
+ : public IsolatedOriginFieldTrialTest {
+ public:
+ IsolatedOriginCommandLineAndFieldTrialTest() = default;
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitchASCII(
+ switches::kIsolateOrigins,
+ "https://cmd.line.com/,https://cmdline.com/");
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(IsolatedOriginCommandLineAndFieldTrialTest);
+};
+
+// Verify that the lists of isolated origins specified via --isolate-origins
+// and via field trials are merged. See https://crbug.com/894535.
+IN_PROC_BROWSER_TEST_F(IsolatedOriginCommandLineAndFieldTrialTest, Test) {
+ auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
+ // --isolate-origins should take effect regardless of the
+ // kDisableSiteIsolationTrials opt-out flag.
+ EXPECT_TRUE(policy->IsIsolatedOrigin(
+ url::Origin::Create(GURL("https://cmd.line.com/"))));
+ EXPECT_TRUE(policy->IsIsolatedOrigin(
+ url::Origin::Create(GURL("https://cmdline.com/"))));
+
+ // Field trial origins should also take effect, but only if the opt-out flag
+ // is not present.
+ bool expected_to_isolate = !base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableSiteIsolationTrials);
+ EXPECT_EQ(expected_to_isolate, policy->IsIsolatedOrigin(url::Origin::Create(
+ GURL("https://field.trial.com/"))));
+ EXPECT_EQ(
+ expected_to_isolate,
+ policy->IsIsolatedOrigin(url::Origin::Create(GURL("https://bar.com/"))));
+}
+
// This is a regresion test for https://crbug.com/793350 - the long list of
// origins to isolate used to be unnecessarily propagated to the renderer
// process, trigerring a crash due to exceeding kZygoteMaxMessageLength.
diff --git a/chromium/content/browser/isolated_origin_util.cc b/chromium/content/browser/isolated_origin_util.cc
index fe25348a652..9086edb778a 100644
--- a/chromium/content/browser/isolated_origin_util.cc
+++ b/chromium/content/browser/isolated_origin_util.cc
@@ -31,7 +31,7 @@ bool IsolatedOriginUtil::DoesOriginMatchIsolatedOrigin(
// static
bool IsolatedOriginUtil::IsValidIsolatedOrigin(const url::Origin& origin) {
- if (origin.unique())
+ if (origin.opaque())
return false;
// Isolated origins should have HTTP or HTTPS schemes. Hosts in other
diff --git a/chromium/content/browser/loader/cors_file_origin_browsertest.cc b/chromium/content/browser/loader/cors_file_origin_browsertest.cc
index 2b0e7a609ba..9790099a59d 100644
--- a/chromium/content/browser/loader/cors_file_origin_browsertest.cc
+++ b/chromium/content/browser/loader/cors_file_origin_browsertest.cc
@@ -29,6 +29,7 @@
#include "services/network/public/cpp/cors/cors.h"
#include "services/network/public/cpp/features.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
#include "url/gurl.h"
namespace content {
@@ -39,20 +40,42 @@ using net::test_server::BasicHttpResponse;
using net::test_server::HttpRequest;
using net::test_server::HttpResponse;
+enum class CorsTestMode {
+ kInBlink,
+ kInBrowserProcess,
+ kInNetworkService,
+};
+
// Tests end to end Origin header and CORS check behaviors without
// --allow-file-access-from-files flag.
-class CORSFileOriginBrowserTest : public ContentBrowserTest,
- public testing::WithParamInterface<bool> {
+class CORSFileOriginBrowserTest
+ : public ContentBrowserTest,
+ public testing::WithParamInterface<CorsTestMode> {
public:
CORSFileOriginBrowserTest()
: pass_string_(base::ASCIIToUTF16("PASS")),
fail_string_(base::ASCIIToUTF16("FAIL")) {
- if (GetParam()) {
- scoped_feature_list_.InitAndEnableFeature(
- network::features::kOutOfBlinkCORS);
- } else {
- scoped_feature_list_.InitAndDisableFeature(
- network::features::kOutOfBlinkCORS);
+ switch (GetParam()) {
+ case CorsTestMode::kInBlink:
+ scoped_feature_list_.InitWithFeatures(
+ {} /* enabled */,
+ {network::features::kOutOfBlinkCORS,
+ blink::features::kServiceWorkerServicification,
+ network::features::kNetworkService} /* disabled */);
+ break;
+ case CorsTestMode::kInBrowserProcess:
+ scoped_feature_list_.InitWithFeatures(
+ {network::features::kOutOfBlinkCORS,
+ blink::features::kServiceWorkerServicification} /* enabled */,
+ {network::features::kNetworkService} /* disabled */);
+ break;
+ case CorsTestMode::kInNetworkService:
+ scoped_feature_list_.InitWithFeatures(
+ {network::features::kOutOfBlinkCORS,
+ blink::features::kServiceWorkerServicification,
+ network::features::kNetworkService} /* enabled */,
+ {} /*disabled */);
+ break;
}
}
~CORSFileOriginBrowserTest() override = default;
@@ -77,11 +100,19 @@ class CORSFileOriginBrowserTest : public ContentBrowserTest,
// Does not appear in the expectations, but the title can be on unexpected
// failures.
base::string16 wrong_origin_string =
- base::ASCIIToUTF16("FAIL: request origin does not match");
+ base::ASCIIToUTF16("FAIL: response text does not match");
watcher->AlsoWaitForTitle(wrong_origin_string);
return watcher;
}
+ std::string target_http_url() {
+ return base::StringPrintf("http://127.0.0.1:%d/test", port());
+ }
+ std::string target_file_url() const { return "get.txt"; }
+ std::string target_self_file_url() const {
+ return "cors_file_origin_test.html";
+ }
+
const base::string16& pass_string() const { return pass_string_; }
const base::string16& fail_string() const { return fail_string_; }
@@ -195,9 +226,10 @@ IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTest,
AccessControlAllowOriginIsNull) {
std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL(
- shell(), CreateTestDataURL(base::StringPrintf(
- "cors_file_origin_test.html?port=%d&allow=%s&origin=%s",
- port(), "null", "null"))));
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_http_url().c_str(), "null", "null"))));
EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle());
EXPECT_TRUE(is_preflight_requested());
@@ -207,21 +239,45 @@ IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTest,
AccessControlAllowOriginIsFile) {
std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL(
- shell(), CreateTestDataURL(base::StringPrintf(
- "cors_file_origin_test.html?port=%d&allow=%s&origin=%s",
- port(), "file://", "null"))));
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_http_url().c_str(), "file://", "null"))));
EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle());
EXPECT_TRUE(is_preflight_requested());
}
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTest, AccessToSelfFileUrl) {
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_self_file_url().c_str(), "unused", "unused"))));
+
+ EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle());
+}
+
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTest, AccessToAnotherFileUrl) {
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_file_url().c_str(), "unused", "unused"))));
+
+ EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle());
+}
+
IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
AccessControlAllowOriginIsNull) {
std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL(
- shell(), CreateTestDataURL(base::StringPrintf(
- "cors_file_origin_test.html?port=%d&allow=%s&origin=%s",
- port(), "null", "file://"))));
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_http_url().c_str(), "null", "file://"))));
EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle());
EXPECT_TRUE(is_preflight_requested());
@@ -231,21 +287,47 @@ IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
AccessControlAllowOriginIsFile) {
std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL(
- shell(), CreateTestDataURL(base::StringPrintf(
- "cors_file_origin_test.html?port=%d&allow=%s&origin=%s",
- port(), "file://", "file://"))));
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_http_url().c_str(), "file://", "file://"))));
EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle());
EXPECT_TRUE(is_preflight_requested());
}
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
+ AccessToSelfFileUrl) {
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_self_file_url().c_str(), "unused", "unused"))));
+
+ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle());
+}
+
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
+ AccessToAnotherFileUrl) {
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_file_url().c_str(), "unused", "unused"))));
+
+ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle());
+}
+
IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithDisableWebSecurity,
AccessControlAllowOriginIsNull) {
std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL(
- shell(), CreateTestDataURL(base::StringPrintf(
- "cors_file_origin_test.html?port=%d&allow=%s&origin=%s",
- port(), "unused", ""))));
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_http_url().c_str(), "unused", ""))));
EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle());
EXPECT_FALSE(is_preflight_requested());
@@ -255,30 +337,59 @@ IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithDisableWebSecurity,
AccessControlAllowOriginIsFile) {
std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL(
- shell(), CreateTestDataURL(base::StringPrintf(
- "cors_file_origin_test.html?port=%d&allow=%s&origin=%s",
- port(), "unused", ""))));
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_http_url().c_str(), "unused", ""))));
EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle());
EXPECT_FALSE(is_preflight_requested());
}
-// --allow-file-access-from-files is currently not supported by OOR-CORS.
-// We may remove the feature.
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithDisableWebSecurity,
+ AccessToSelfFileUrl) {
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_self_file_url().c_str(), "unused", "unused"))));
+
+ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle());
+}
+
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithDisableWebSecurity,
+ AccessToAnotherFileUrl) {
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(),
+ CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?url=%s&allow=%s&response_text=%s",
+ target_file_url().c_str(), "unused", "unused"))));
+
+ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle());
+}
+
INSTANTIATE_TEST_CASE_P(
/* No test prefix */,
CORSFileOriginBrowserTest,
- ::testing::Values(false));
+ ::testing::Values(CorsTestMode::kInBlink,
+ CorsTestMode::kInBrowserProcess,
+ CorsTestMode::kInNetworkService));
INSTANTIATE_TEST_CASE_P(
/* No test prefix */,
CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
- ::testing::Values(false));
+ ::testing::Values(CorsTestMode::kInBlink,
+ CorsTestMode::kInBrowserProcess,
+ CorsTestMode::kInNetworkService));
INSTANTIATE_TEST_CASE_P(
/* No test prefix */,
CORSFileOriginBrowserTestWithDisableWebSecurity,
- ::testing::Values(false, true));
+ ::testing::Values(CorsTestMode::kInBlink,
+ CorsTestMode::kInBrowserProcess,
+ CorsTestMode::kInNetworkService));
} // namespace
diff --git a/chromium/content/browser/loader/cors_origin_access_list_browsertest.cc b/chromium/content/browser/loader/cors_origin_access_list_browsertest.cc
new file mode 100644
index 00000000000..8f32876deb5
--- /dev/null
+++ b/chromium/content/browser/loader/cors_origin_access_list_browsertest.cc
@@ -0,0 +1,285 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/path_service.h"
+#include "base/run_loop.h"
+#include "base/strings/string16.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "net/base/host_port_pair.h"
+#include "net/dns/mock_host_resolver.h"
+#include "services/network/public/cpp/features.h"
+#include "services/network/public/mojom/cors.mojom.h"
+#include "services/network/public/mojom/cors_origin_pattern.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace content {
+
+namespace {
+
+const char kTestPath[] = "/loader/cors_origin_access_list_test.html";
+
+const char kTestHost[] = "crossorigin.example.com";
+const char kTestHostInDifferentCase[] = "CrossOrigin.example.com";
+const char kTestSubdomainHost[] = "subdomain.crossorigin.example.com";
+
+enum class TestMode {
+ kOutOfBlinkCorsWithServicification,
+ kOutOfBlinkCorsWithoutServicification,
+};
+
+// Tests end to end functionality of CORS access origin allow lists.
+class CorsOriginAccessListBrowserTest
+ : public ContentBrowserTest,
+ public testing::WithParamInterface<TestMode> {
+ public:
+ CorsOriginAccessListBrowserTest() {
+ switch (GetParam()) {
+ case TestMode::kOutOfBlinkCorsWithServicification:
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled features
+ {network::features::kOutOfBlinkCORS,
+ network::features::kNetworkService,
+ blink::features::kServiceWorkerServicification},
+ // Disabled features
+ {});
+ break;
+ case TestMode::kOutOfBlinkCorsWithoutServicification:
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled features
+ {network::features::kOutOfBlinkCORS},
+ // Disabled features
+ {network::features::kNetworkService,
+ blink::features::kServiceWorkerServicification});
+ break;
+ }
+ }
+
+ protected:
+ std::unique_ptr<TitleWatcher> CreateWatcher() {
+ // Register all possible result strings here.
+ std::unique_ptr<TitleWatcher> watcher =
+ std::make_unique<TitleWatcher>(shell()->web_contents(), pass_string());
+ watcher->AlsoWaitForTitle(fail_string());
+ return watcher;
+ }
+
+ std::string GetReason() {
+ bool executing = true;
+ std::string reason;
+ shell()->web_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
+ script_,
+ base::BindRepeating(
+ [](bool* flag, std::string* reason, const base::Value* value) {
+ *flag = false;
+ DCHECK(value);
+ DCHECK(value->is_string());
+ *reason = value->GetString();
+ },
+ base::Unretained(&executing), base::Unretained(&reason)));
+ while (executing) {
+ base::RunLoop loop;
+ loop.RunUntilIdle();
+ }
+ return reason;
+ }
+
+ void SetAllowList(const std::string& scheme,
+ const std::string& host,
+ bool allow_subdomains) {
+ std::vector<network::mojom::CorsOriginPatternPtr> list1;
+ list1.push_back(network::mojom::CorsOriginPattern::New(
+ scheme, host, allow_subdomains,
+ network::mojom::CORSOriginAccessMatchPriority::kDefaultPriority));
+ bool first_list_done = false;
+ BrowserContext::SetCorsOriginAccessListsForOrigin(
+ shell()->web_contents()->GetBrowserContext(),
+ url::Origin::Create(embedded_test_server()->base_url().GetOrigin()),
+ std::move(list1), std::vector<network::mojom::CorsOriginPatternPtr>(),
+ base::BindOnce([](bool* flag) { *flag = true; },
+ base::Unretained(&first_list_done)));
+
+ std::vector<network::mojom::CorsOriginPatternPtr> list2;
+ list2.push_back(network::mojom::CorsOriginPattern::New(
+ scheme, host, allow_subdomains,
+ network::mojom::CORSOriginAccessMatchPriority::kDefaultPriority));
+ bool second_list_done = false;
+ BrowserContext::SetCorsOriginAccessListsForOrigin(
+ shell()->web_contents()->GetBrowserContext(),
+ url::Origin::Create(
+ embedded_test_server()->GetURL(kTestHost, "/").GetOrigin()),
+ std::move(list2), std::vector<network::mojom::CorsOriginPatternPtr>(),
+ base::BindOnce([](bool* flag) { *flag = true; },
+ base::Unretained(&second_list_done)));
+ while (!first_list_done || !second_list_done) {
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+ }
+ }
+
+ std::string host_ip() { return embedded_test_server()->base_url().host(); }
+
+ const base::string16& pass_string() const { return pass_string_; }
+ const base::string16& fail_string() const { return fail_string_; }
+
+ private:
+ void SetUpOnMainThread() override {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ // Setup to resolve kTestHost, kTestHostInDifferentCase and
+ // kTestSubdomainHost to the 127.0.0.1 that the test server serves.
+ host_resolver()->AddRule(kTestHost,
+ embedded_test_server()->host_port_pair().host());
+ host_resolver()->AddRule(kTestHostInDifferentCase,
+ embedded_test_server()->host_port_pair().host());
+ host_resolver()->AddRule(kTestSubdomainHost,
+ embedded_test_server()->host_port_pair().host());
+ }
+
+ const base::string16 pass_string_ = base::ASCIIToUTF16("PASS");
+ const base::string16 fail_string_ = base::ASCIIToUTF16("FAIL");
+ const base::string16 script_ = base::ASCIIToUTF16("reason");
+
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(CorsOriginAccessListBrowserTest);
+};
+
+// Tests if specifying only protocol allows all hosts to pass.
+IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAll) {
+ SetAllowList("http", "", true);
+
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(
+ NavigateToURL(shell(), embedded_test_server()->GetURL(base::StringPrintf(
+ "%s?target=%s", kTestPath, kTestHost))));
+ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle()) << GetReason();
+}
+
+// Tests if specifying only protocol allows all IP address based hosts to pass.
+IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAllForIp) {
+ SetAllowList("http", "", true);
+
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL(
+ kTestHost, base::StringPrintf("%s?target=%s", kTestPath,
+ host_ip().c_str()))));
+ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle()) << GetReason();
+}
+
+// Tests if complete allow list set allows only exactly matched host to pass.
+IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowExactHost) {
+ SetAllowList("http", kTestHost, false);
+
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(
+ NavigateToURL(shell(), embedded_test_server()->GetURL(base::StringPrintf(
+ "%s?target=%s", kTestPath, kTestHost))));
+ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle()) << GetReason();
+}
+
+// Tests if complete allow list set allows host that matches exactly, but in
+// case insensitive way to pass.
+IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+ AllowExactHostInCaseInsensitive) {
+ SetAllowList("http", kTestHost, false);
+
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL(base::StringPrintf(
+ "%s?target=%s", kTestPath, kTestHostInDifferentCase))));
+ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle()) << GetReason();
+}
+
+// Tests if complete allow list set does not allow a host with a different port
+// to pass.
+IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockDifferentPort) {
+ SetAllowList("http", kTestHost, false);
+
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL(base::StringPrintf(
+ "%s?target=%s&port_diff=1", kTestPath, kTestHost))));
+ EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle()) << GetReason();
+}
+
+// Tests if complete allow list set allows a subdomain to pass if it is allowed.
+IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowSubdomain) {
+ SetAllowList("http", kTestHost, true);
+
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL(base::StringPrintf(
+ "%s?target=%s", kTestPath, kTestSubdomainHost))));
+ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle()) << GetReason();
+}
+
+// Tests if complete allow list set does not allow a subdomain to pass.
+IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockSubdomain) {
+ SetAllowList("http", kTestHost, false);
+
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL(base::StringPrintf(
+ "%s?target=%s", kTestPath, kTestSubdomainHost))));
+ EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle()) << GetReason();
+}
+
+// Tests if complete allow list set does not allow a host with a different
+// protocol to pass.
+IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+ BlockDifferentProtocol) {
+ SetAllowList("https", kTestHost, false);
+
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(
+ NavigateToURL(shell(), embedded_test_server()->GetURL(base::StringPrintf(
+ "%s?target=%s", kTestPath, kTestHost))));
+ EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle()) << GetReason();
+}
+
+// Tests if IP address based hosts should not follow subdomain match rules.
+IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+ SubdomainMatchShouldNotBeAppliedForIPAddress) {
+ SetAllowList("http", "*.0.0.1", true);
+
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL(
+ kTestHost, base::StringPrintf("%s?target=%s", kTestPath,
+ host_ip().c_str()))));
+ EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle()) << GetReason();
+}
+
+INSTANTIATE_TEST_CASE_P(
+ OutOfBlinkCorsWithServicification,
+ CorsOriginAccessListBrowserTest,
+ ::testing::Values(TestMode::kOutOfBlinkCorsWithServicification));
+
+INSTANTIATE_TEST_CASE_P(
+ OutOfBlinkCorsWithoutServicification,
+ CorsOriginAccessListBrowserTest,
+ ::testing::Values(TestMode::kOutOfBlinkCorsWithoutServicification));
+
+// TODO(toyoshim): Instantiates tests for the case kOutOfBlinkCORS is disabled
+// and remove relevant LayoutTests if it's possible.
+
+} // namespace
+
+} // namespace content
diff --git a/chromium/content/browser/loader/cross_site_document_blocking_browsertest.cc b/chromium/content/browser/loader/cross_site_document_blocking_browsertest.cc
index fa11009de25..b811e6d9f86 100644
--- a/chromium/content/browser/loader/cross_site_document_blocking_browsertest.cc
+++ b/chromium/content/browser/loader/cross_site_document_blocking_browsertest.cc
@@ -12,10 +12,12 @@
#include "base/strings/pattern.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/loader/cross_site_document_resource_handler.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_view_host.h"
@@ -217,8 +219,8 @@ class RequestInterceptor {
// Wait until IO cleanup completes.
base::RunLoop run_loop;
- BrowserThread::PostTaskAndReply(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&RequestInterceptor::CleanUpOnIOThread,
base::Unretained(this)),
run_loop.QuitClosure());
@@ -330,10 +332,10 @@ class DisableWebSecurityContentBrowserClient : public TestContentBrowserClient {
// Note that this BaseTest class does not specify an isolation mode via
// command-line flags. Most of the tests are in the --site-per-process subclass
// below.
-class CrossSiteDocumentBlockingTest : public ContentBrowserTest {
+class CrossSiteDocumentBlockingTestBase : public ContentBrowserTest {
public:
- CrossSiteDocumentBlockingTest() {}
- ~CrossSiteDocumentBlockingTest() override {}
+ CrossSiteDocumentBlockingTestBase() = default;
+ ~CrossSiteDocumentBlockingTestBase() override = default;
void SetUpCommandLine(base::CommandLine* command_line) override {
// EmbeddedTestServer::InitializeAndListen() initializes its |base_url_|
@@ -367,10 +369,38 @@ class CrossSiteDocumentBlockingTest : public ContentBrowserTest {
DisableWebSecurityContentBrowserClient new_client;
ContentBrowserClient* old_client = nullptr;
+ DISALLOW_COPY_AND_ASSIGN(CrossSiteDocumentBlockingTestBase);
+};
+
+enum class TestMode {
+ kWithoutOutOfBlinkCors,
+ kWithOutOfBlinkCors,
+};
+class CrossSiteDocumentBlockingTest
+ : public CrossSiteDocumentBlockingTestBase,
+ public testing::WithParamInterface<TestMode> {
+ public:
+ CrossSiteDocumentBlockingTest() {
+ switch (GetParam()) {
+ case TestMode::kWithoutOutOfBlinkCors:
+ scoped_feature_list_.InitAndDisableFeature(
+ network::features::kOutOfBlinkCORS);
+ break;
+ case TestMode::kWithOutOfBlinkCors:
+ scoped_feature_list_.InitAndEnableFeature(
+ network::features::kOutOfBlinkCORS);
+ break;
+ }
+ }
+ ~CrossSiteDocumentBlockingTest() override = default;
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
DISALLOW_COPY_AND_ASSIGN(CrossSiteDocumentBlockingTest);
};
-IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockDocuments) {
+IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest, BlockDocuments) {
// Load a page that issues illegal cross-site document requests to bar.com.
// The page uses XHR to request HTML/XML/JSON documents from bar.com, and
// inspects if any of them were successfully received. This test is only
@@ -378,6 +408,15 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockDocuments) {
// it to see the response body if it makes it to the renderer (even if the
// renderer would normally block access to it).
embedded_test_server()->StartAcceptingConnections();
+
+ // This test does not work and won't make much sense if kOutOfBlinkCORS is
+ // enabled. We need to rewrite this test once the feature is shipped. We would
+ // like to add other tests for verifying behavior for fetch mode "no-cors".
+ // See crbug.com/736308, and discussion at http://crrev.com/c/1253623.
+ // The test server should be started before to shutdown tests safely.
+ if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCORS))
+ return;
+
GURL foo_url("http://foo.com/cross_site_document_blocking/request.html");
EXPECT_TRUE(NavigateToURL(shell(), foo_url));
@@ -492,8 +531,14 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockDocuments) {
// can't cause sniffing to fail to force a response to be allowed. This won't
// be a problem for script files mislabeled as HTML/XML/JSON/text (i.e., the
// reason for sniffing), since script tags won't send Range headers.
-IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, RangeRequest) {
+IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest, RangeRequest) {
embedded_test_server()->StartAcceptingConnections();
+
+ // This test does not work and won't make much sense if kOutOfBlinkCORS is
+ // enabled. See detailed comments on BlockDocuments above.
+ if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCORS))
+ return;
+
GURL foo_url("http://foo.com/cross_site_document_blocking/request.html");
EXPECT_TRUE(NavigateToURL(shell(), foo_url));
@@ -534,7 +579,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, RangeRequest) {
}
}
-IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockForVariousTargets) {
+IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest, BlockForVariousTargets) {
// This webpage loads a cross-site HTML page in different targets such as
// <img>,<link>,<embed>, etc. Since the requested document is blocked, and one
// character string (' ') is returned instead, this tests that the renderer
@@ -554,7 +599,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockForVariousTargets) {
// Checks to see that CORB blocking applies to processes hosting error pages.
// Regression test for https://crbug.com/814913.
-IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest,
+IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest,
BlockRequestFromErrorPage) {
embedded_test_server()->StartAcceptingConnections();
GURL error_url = embedded_test_server()->GetURL("bar.com", "/close-socket");
@@ -586,9 +631,14 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest,
EXPECT_EQ("CORB WORKED", result);
}
-IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockHeaders) {
+IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest, BlockHeaders) {
embedded_test_server()->StartAcceptingConnections();
+ // This test does not work and won't make much sense if kOutOfBlinkCORS is
+ // enabled. See detailed comments on BlockDocuments above.
+ if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCORS))
+ return;
+
// Prepare to intercept the network request at the IPC layer.
// This has to be done before the RenderFrameHostImpl is created.
//
@@ -637,7 +687,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockHeaders) {
EXPECT_EQ(0u, interceptor.response_head().content_length);
}
-IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, PrefetchIsNotImpacted) {
+IN_PROC_BROWSER_TEST_P(CrossSiteDocumentBlockingTest, PrefetchIsNotImpacted) {
// Prepare for intercepting the resource request for testing prefetching.
const char* kPrefetchResourcePath = "/prefetch-test";
net::test_server::ControllableHttpResponse response(embedded_test_server(),
@@ -744,6 +794,14 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, PrefetchIsNotImpacted) {
EXPECT_EQ("<p>contents of the response</p>", response_body);
}
+INSTANTIATE_TEST_CASE_P(WithoutOutOfBlinkCors,
+ CrossSiteDocumentBlockingTest,
+ ::testing::Values(TestMode::kWithoutOutOfBlinkCors));
+
+INSTANTIATE_TEST_CASE_P(WithOutOfBlinkCors,
+ CrossSiteDocumentBlockingTest,
+ ::testing::Values(TestMode::kWithOutOfBlinkCors));
+
// This test class sets up a service worker that can be used to try to respond
// to same-origin requests with cross-origin responses.
class CrossSiteDocumentBlockingServiceWorkerTest : public ContentBrowserTest {
@@ -934,51 +992,17 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingServiceWorkerTest,
EXPECT_EQ("error: TypeError: Failed to fetch", response);
}
-class CrossSiteDocumentBlockingKillSwitchTest
- : public CrossSiteDocumentBlockingTest {
- public:
- CrossSiteDocumentBlockingKillSwitchTest() {
- // Simulate flipping both of the kill switches.
- std::vector<base::Feature> disabled_features = {
- features::kCrossSiteDocumentBlockingAlways,
- features::kCrossSiteDocumentBlockingIfIsolating,
- };
- scoped_feature_list_.InitWithFeatures({}, disabled_features);
- }
-
- ~CrossSiteDocumentBlockingKillSwitchTest() override {}
-
- private:
- base::test::ScopedFeatureList scoped_feature_list_;
-
- DISALLOW_COPY_AND_ASSIGN(CrossSiteDocumentBlockingKillSwitchTest);
-};
-
-// After the kill switch is flipped, there should be no document blocking.
-IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingKillSwitchTest,
- NoBlockingWithKillSwitch) {
- // Load a page that issues illegal cross-site document requests to bar.com.
- embedded_test_server()->StartAcceptingConnections();
- GURL foo_url("http://foo.com/cross_site_document_blocking/request.html");
- EXPECT_TRUE(NavigateToURL(shell(), foo_url));
-
- bool was_blocked;
- ASSERT_TRUE(ExecuteScriptAndExtractBool(
- shell(), "sendRequest(\"valid.html\");", &was_blocked));
- EXPECT_FALSE(was_blocked);
-}
-
// Test class to verify that --disable-web-security turns off CORB. This
// inherits from CrossSiteDocumentBlockingTest, so it runs in SitePerProcess.
class CrossSiteDocumentBlockingDisableWebSecurityTest
- : public CrossSiteDocumentBlockingTest {
+ : public CrossSiteDocumentBlockingTestBase {
public:
CrossSiteDocumentBlockingDisableWebSecurityTest() {}
~CrossSiteDocumentBlockingDisableWebSecurityTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(switches::kDisableWebSecurity);
- CrossSiteDocumentBlockingTest::SetUpCommandLine(command_line);
+ CrossSiteDocumentBlockingTestBase::SetUpCommandLine(command_line);
}
private:
@@ -998,40 +1022,9 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingDisableWebSecurityTest,
EXPECT_FALSE(was_blocked);
}
-// Test class to verify that kCrossSiteDocumentBlockingAlways does not take
-// precedence over --disable-web-security. This inherits from
-// CrossSiteDocumentBlockingTest, so it runs in SitePerProcess.
-class CrossSiteDocumentBlockingDisableVsFeatureTest
- : public CrossSiteDocumentBlockingDisableWebSecurityTest {
- public:
- CrossSiteDocumentBlockingDisableVsFeatureTest() {
- scoped_feature_list_.InitAndEnableFeature(
- features::kCrossSiteDocumentBlockingAlways);
- }
- ~CrossSiteDocumentBlockingDisableVsFeatureTest() override {}
-
- private:
- base::test::ScopedFeatureList scoped_feature_list_;
-
- DISALLOW_COPY_AND_ASSIGN(CrossSiteDocumentBlockingDisableVsFeatureTest);
-};
-
-IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingDisableVsFeatureTest,
- DisableBlocking) {
- // Load a page that issues illegal cross-site document requests.
- embedded_test_server()->StartAcceptingConnections();
- GURL foo_url("http://foo.com/cross_site_document_blocking/request.html");
- EXPECT_TRUE(NavigateToURL(shell(), foo_url));
-
- bool was_blocked;
- ASSERT_TRUE(ExecuteScriptAndExtractBool(
- shell(), "sendRequest(\"valid.html\");", &was_blocked));
- EXPECT_FALSE(was_blocked);
-}
-
// Test class to verify that documents are blocked for isolated origins as well.
class CrossSiteDocumentBlockingIsolatedOriginTest
- : public CrossSiteDocumentBlockingTest {
+ : public CrossSiteDocumentBlockingTestBase {
public:
CrossSiteDocumentBlockingIsolatedOriginTest() {}
~CrossSiteDocumentBlockingIsolatedOriginTest() override {}
@@ -1039,7 +1032,7 @@ class CrossSiteDocumentBlockingIsolatedOriginTest
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(switches::kIsolateOrigins,
"http://bar.com");
- CrossSiteDocumentBlockingTest::SetUpCommandLine(command_line);
+ CrossSiteDocumentBlockingTestBase::SetUpCommandLine(command_line);
}
private:
diff --git a/chromium/content/browser/loader/cross_site_document_resource_handler.cc b/chromium/content/browser/loader/cross_site_document_resource_handler.cc
index 585868689f6..be1724e19ee 100644
--- a/chromium/content/browser/loader/cross_site_document_resource_handler.cc
+++ b/chromium/content/browser/loader/cross_site_document_resource_handler.cc
@@ -15,18 +15,20 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
+#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/loader/detachable_resource_handler.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/resource_context.h"
-#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/content_switches.h"
#include "net/base/io_buffer.h"
#include "net/base/mime_sniffer.h"
#include "net/url_request/url_request.h"
@@ -131,8 +133,8 @@ void CrossSiteDocumentResourceHandler::LogBlockedResponse(
// time the posted task runs, the WebContents could have been closed and/or
// navigated to another URL. This is understood and acceptable - this should
// be rare enough to not matter for the collected UKM data.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&CrossSiteDocumentResourceHandler::LogBlockedResponseOnUIThread,
resource_request_info->GetWebContentsGetterForRequest(),
@@ -562,8 +564,8 @@ void CrossSiteDocumentResourceHandler::OnResponseCompleted(
analyzer_->LogAllowedResponse();
if (initiator_scheme_prevented_blocking_ &&
analyzer_->ShouldReportBlockedResponse() && GetRequestInfo()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ContentBrowserClient::
LogInitiatorSchemeBypassingDocumentBlocking,
base::Unretained(GetContentClient()->browser()),
@@ -588,26 +590,10 @@ bool CrossSiteDocumentResourceHandler::ShouldBlockBasedOnHeaders(
if (analyzer_->ShouldAllow())
return false;
- // Check if the response's site needs to have its documents protected. By
- // default, this will usually return false.
- // TODO(creis): This check can go away once the logic here is made fully
- // backward compatible and we can enforce it always, regardless of Site
- // Isolation policy.
- switch (SiteIsolationPolicy::IsCrossSiteDocumentBlockingEnabled()) {
- case SiteIsolationPolicy::XSDB_ENABLED_UNCONDITIONALLY:
- break;
- case SiteIsolationPolicy::XSDB_ENABLED_IF_ISOLATED: {
- url::Origin target_origin = url::Origin::Create(request()->url());
- if (!SiteIsolationPolicy::UseDedicatedProcessesForAllSites() &&
- !ChildProcessSecurityPolicyImpl::GetInstance()->IsIsolatedOrigin(
- target_origin)) {
- return false;
- }
- break;
- }
- case SiteIsolationPolicy::XSDB_DISABLED:
- return false;
- }
+ // --disable-web-security also disables Cross-Origin Read Blocking (CORB).
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableWebSecurity))
+ return false;
// Only block if this is a request made from a renderer process.
const ResourceRequestInfoImpl* info = GetRequestInfo();
diff --git a/chromium/content/browser/loader/cross_site_document_resource_handler_unittest.cc b/chromium/content/browser/loader/cross_site_document_resource_handler_unittest.cc
index e09e9a1b602..78a959f048f 100644
--- a/chromium/content/browser/loader/cross_site_document_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/cross_site_document_resource_handler_unittest.cc
@@ -81,7 +81,7 @@ struct TestScenario {
OriginHeader cors_request;
// Attributes of the HTTP response.
- const char* response_mime_type;
+ const char* response_content_type;
MimeType canonical_mime_type;
bool include_no_sniff_header;
bool simulate_range_response;
@@ -153,24 +153,24 @@ struct TestScenario {
}
packets += "}";
- return os << "\n description = " << scenario.description
- << "\n target_url = " << scenario.target_url
- << "\n resource_type = " << scenario.resource_type
- << "\n initiator_origin = " << scenario.initiator_origin
- << "\n cors_request = "
+ return os << "\n description = " << scenario.description
+ << "\n target_url = " << scenario.target_url
+ << "\n resource_type = " << scenario.resource_type
+ << "\n initiator_origin = " << scenario.initiator_origin
+ << "\n cors_request = "
<< (scenario.cors_request == OriginHeader::kOmit
? "OriginHeader::kOmit"
: "OriginHeader::kInclude")
- << "\n response_mime_type = " << scenario.response_mime_type
- << "\n canonical_mime_type = " << scenario.canonical_mime_type
- << "\n include_no_sniff = "
+ << "\n response_content_type = " << scenario.response_content_type
+ << "\n canonical_mime_type = " << scenario.canonical_mime_type
+ << "\n include_no_sniff = "
<< (scenario.include_no_sniff_header ? "true" : "false")
- << "\n range_response = "
+ << "\n range_response = "
<< (scenario.simulate_range_response ? "true" : "false")
- << "\n cors_response = " << cors_response
- << "\n packets = " << packets
- << "\n verdict = " << verdict
- << "\n verdict_packet = " << scenario.verdict_packet;
+ << "\n cors_response = " << cors_response
+ << "\n packets = " << packets
+ << "\n verdict = " << verdict
+ << "\n verdict_packet = " << scenario.verdict_packet;
}
// An HTML response with an HTML comment that's longer than the sniffing
@@ -207,7 +207,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -223,7 +223,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -239,7 +239,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/json", // response_mime_type
+ "text/json", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -255,7 +255,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_SCRIPT, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "application/javascript", // response_mime_type
+ "application/javascript", // response_content_type
MimeType::kOthers, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -271,7 +271,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kInclude, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -287,7 +287,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kInclude, // cors_request
- "application/rss+xml", // response_mime_type
+ "application/rss+xml", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -303,7 +303,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kInclude, // cors_request
- "text/json", // response_mime_type
+ "text/json", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -319,7 +319,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -335,7 +335,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -357,7 +357,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_PLUGIN_RESOURCE, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -373,7 +373,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_PLUGIN_RESOURCE, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kInclude, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -389,7 +389,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_SCRIPT, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kInclude, // cors_request
- "application/javascript", // response_mime_type
+ "application/javascript", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -405,7 +405,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_SCRIPT, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "application/javascript", // response_mime_type
+ "application/javascript", // response_content_type
MimeType::kOthers, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -421,7 +421,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "image/png", // response_mime_type
+ "image/png", // response_content_type
MimeType::kOthers, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -437,7 +437,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "image/png", // response_mime_type
+ "image/png", // response_content_type
MimeType::kOthers, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -455,7 +455,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_SCRIPT, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -471,7 +471,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_SCRIPT, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/plain", // response_mime_type
+ "text/plain", // response_content_type
MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -487,7 +487,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_SCRIPT, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/plain", // response_mime_type
+ "text/plain", // response_content_type
MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -504,7 +504,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_SCRIPT, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/json", // response_mime_type
+ "text/json", // response_content_type
MimeType::kJson, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -520,7 +520,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_SCRIPT, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/plain", // response_mime_type
+ "text/plain", // response_content_type
MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -536,7 +536,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_SCRIPT, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/plain", // response_mime_type
+ "text/plain", // response_content_type
MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -553,7 +553,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "application/xml", // response_mime_type
+ "application/xml", // response_content_type
MimeType::kXml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -569,7 +569,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/json", // response_mime_type
+ "text/json", // response_content_type
MimeType::kJson, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -585,7 +585,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -601,7 +601,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -617,7 +617,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -633,7 +633,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -649,7 +649,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kInvalidMimeType, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -667,7 +667,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -683,7 +683,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html; charset=utf-8", // response_mime_type
+ "text/html; charset=utf-8", // response_content_type
MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -699,7 +699,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -715,7 +715,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"https://bar.site.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -733,7 +733,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://foo.example.com/", // initiator_origin
OriginHeader::kInclude, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -753,7 +753,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kInclude, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -771,7 +771,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -787,7 +787,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "application/xml", // response_mime_type
+ "application/xml", // response_content_type
MimeType::kXml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -803,7 +803,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "application/json", // response_mime_type
+ "application/json", // response_content_type
MimeType::kJson, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -819,7 +819,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/plain", // response_mime_type
+ "text/plain", // response_content_type
MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -835,7 +835,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/plain", // response_mime_type
+ "text/plain", // response_content_type
MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -851,7 +851,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/plain", // response_mime_type
+ "text/plain", // response_content_type
MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -868,7 +868,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/plain", // response_mime_type
+ "text/plain", // response_content_type
MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -884,7 +884,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/plain", // response_mime_type
+ "text/plain", // response_content_type
MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -900,7 +900,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_SCRIPT, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -918,7 +918,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kInclude, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -934,7 +934,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_PLUGIN_RESOURCE, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kInclude, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -950,7 +950,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://c.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/json", // response_mime_type
+ "text/json", // response_content_type
MimeType::kJson, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -966,7 +966,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://c.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "audio/x-wav", // response_mime_type
+ "audio/x-wav", // response_content_type
MimeType::kOthers, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -982,7 +982,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://c.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "application/javascript", // response_mime_type
+ "application/javascript", // response_content_type
MimeType::kOthers, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -998,7 +998,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://c.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -1015,7 +1015,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_SCRIPT, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kInclude, // cors_request
- "application/javascript", // response_mime_type
+ "application/javascript", // response_content_type
MimeType::kOthers, // canonical_mime_type
true, // include_no_sniff_header
false, // simulate_range_response
@@ -1031,7 +1031,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -1047,7 +1047,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_XHR, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
false, // simulate_range_response
@@ -1063,7 +1063,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_MEDIA, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/plain", // response_mime_type
+ "text/plain", // response_content_type
MimeType::kPlain, // canonical_mime_type
false, // include_no_sniff_header
true, // simulate_range_response
@@ -1079,7 +1079,7 @@ const TestScenario kScenarios[] = {
RESOURCE_TYPE_MEDIA, // resource_type
"http://www.a.com/", // initiator_origin
OriginHeader::kOmit, // cors_request
- "text/html", // response_mime_type
+ "text/html", // response_content_type
MimeType::kHtml, // canonical_mime_type
false, // include_no_sniff_header
true, // simulate_range_response
@@ -1186,7 +1186,7 @@ class CrossSiteDocumentResourceHandlerTest
first_handler_ = std::make_unique<MimeSniffingResourceHandler>(
std::move(first_handler_), &dispatcher_host_, &plugin_service_,
intercepting_handler_.get(), request_.get(),
- REQUEST_CONTEXT_TYPE_SCRIPT);
+ blink::mojom::RequestContextType::SCRIPT);
}
// Create a mock loader to drive our chain of resource loaders.
@@ -1195,7 +1195,7 @@ class CrossSiteDocumentResourceHandlerTest
// Returns a ResourceResponse that matches the TestScenario's parameters.
scoped_refptr<network::ResourceResponse> CreateResponse(
- const char* response_mime_type,
+ const char* response_content_type,
bool include_no_sniff_header,
bool simulate_range_response,
AccessControlAllowOriginHeader cors_response,
@@ -1208,14 +1208,14 @@ class CrossSiteDocumentResourceHandlerTest
// Content-Type header.
std::string charset;
- bool had_charset;
- std::string boundary;
+ bool had_charset = false;
response_headers->AddHeader(std::string("Content-Type: ") +
- response_mime_type);
- response->head.mime_type = response_mime_type;
- net::HttpUtil::ParseContentType(response_mime_type,
+ response_content_type);
+ net::HttpUtil::ParseContentType(response_content_type,
&response->head.mime_type, &charset,
- &had_charset, &boundary);
+ &had_charset, nullptr);
+ EXPECT_FALSE(response->head.mime_type.empty())
+ << "Invalid MIME type defined in kScenarios.";
// No sniff header.
if (include_no_sniff_header)
@@ -1330,7 +1330,7 @@ TEST_P(CrossSiteDocumentResourceHandlerTest, ResponseBlocking) {
// Set up response based on scenario.
scoped_refptr<network::ResourceResponse> response = CreateResponse(
- scenario.response_mime_type, scenario.include_no_sniff_header,
+ scenario.response_content_type, scenario.include_no_sniff_header,
scenario.simulate_range_response, scenario.cors_response,
scenario.initiator_origin);
@@ -1621,7 +1621,7 @@ TEST_P(CrossSiteDocumentResourceHandlerTest, OnWillReadDefer) {
// Set up response based on scenario.
scoped_refptr<network::ResourceResponse> response = CreateResponse(
- scenario.response_mime_type, scenario.include_no_sniff_header,
+ scenario.response_content_type, scenario.include_no_sniff_header,
scenario.simulate_range_response, scenario.cors_response,
scenario.initiator_origin);
@@ -1763,7 +1763,7 @@ TEST_P(CrossSiteDocumentResourceHandlerTest, MimeSnifferInterop) {
// Set up response based on scenario.
scoped_refptr<network::ResourceResponse> response = CreateResponse(
- scenario.response_mime_type, scenario.include_no_sniff_header,
+ scenario.response_content_type, scenario.include_no_sniff_header,
scenario.simulate_range_response, scenario.cors_response,
scenario.initiator_origin);
diff --git a/chromium/content/browser/loader/data_pipe_to_source_stream.cc b/chromium/content/browser/loader/data_pipe_to_source_stream.cc
index 4a3694f5b01..87f422f33ff 100644
--- a/chromium/content/browser/loader/data_pipe_to_source_stream.cc
+++ b/chromium/content/browser/loader/data_pipe_to_source_stream.cc
@@ -33,7 +33,7 @@ std::string DataPipeToSourceStream::Description() const {
int DataPipeToSourceStream::Read(net::IOBuffer* buf,
int buf_size,
net::CompletionOnceCallback callback) {
- base::AutoReset<bool>(&inside_read_, true);
+ base::AutoReset<bool> inside_read_checker(&inside_read_, true);
if (!body_.get()) {
// We have finished reading the pipe.
diff --git a/chromium/content/browser/loader/data_pipe_to_source_stream_unittest.cc b/chromium/content/browser/loader/data_pipe_to_source_stream_unittest.cc
index 17439b760f7..dc8c30c52d6 100644
--- a/chromium/content/browser/loader/data_pipe_to_source_stream_unittest.cc
+++ b/chromium/content/browser/loader/data_pipe_to_source_stream_unittest.cc
@@ -44,7 +44,8 @@ class DataPipeToSourceStreamTest
: public ::testing::TestWithParam<DataPipeToSourceStreamTestParam> {
protected:
DataPipeToSourceStreamTest()
- : output_buffer_(new net::IOBufferWithSize(GetParam().buffer_size)) {}
+ : output_buffer_(base::MakeRefCounted<net::IOBufferWithSize>(
+ GetParam().buffer_size)) {}
void Init(base::StringPiece message) {
message_ = message;
diff --git a/chromium/content/browser/loader/detachable_resource_handler.cc b/chromium/content/browser/loader/detachable_resource_handler.cc
index 26593e97ec0..fb8c1c16113 100644
--- a/chromium/content/browser/loader/detachable_resource_handler.cc
+++ b/chromium/content/browser/loader/detachable_resource_handler.cc
@@ -40,10 +40,8 @@ class DetachableResourceHandler::Controller : public ResourceController {
void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override {
- DCHECK(!modified_request_headers.has_value())
- << "Redirect with modified headers was not supported yet. "
- "crbug.com/845683";
- Resume();
+ MarkAsUsed();
+ detachable_handler_->ResumeForRedirect(modified_request_headers);
}
void Cancel() override {
@@ -210,7 +208,7 @@ void DetachableResourceHandler::OnWillRead(
std::unique_ptr<ResourceController> controller) {
if (!next_handler_) {
if (!read_buffer_.get())
- read_buffer_ = new net::IOBuffer(kReadBufSize);
+ read_buffer_ = base::MakeRefCounted<net::IOBuffer>(kReadBufSize);
*buf = read_buffer_;
*buf_size = kReadBufSize;
controller->Resume();
diff --git a/chromium/content/browser/loader/intercepting_resource_handler.cc b/chromium/content/browser/loader/intercepting_resource_handler.cc
index a7c3a1010ea..2037c700112 100644
--- a/chromium/content/browser/loader/intercepting_resource_handler.cc
+++ b/chromium/content/browser/loader/intercepting_resource_handler.cc
@@ -285,8 +285,8 @@ void InterceptingResourceHandler::OnBufferReceived() {
// already handles that case, anyways, so could share that code with the
// no-swap path as well. Or better, just have MimeSniffingResourceHandler
// create and manage the buffer itself.
- first_read_buffer_double_ =
- new net::IOBuffer(static_cast<size_t>(first_read_buffer_size_));
+ first_read_buffer_double_ = base::MakeRefCounted<net::IOBuffer>(
+ static_cast<size_t>(first_read_buffer_size_));
*parent_read_buffer_ = first_read_buffer_double_;
*parent_read_buffer_size_ = first_read_buffer_size_;
diff --git a/chromium/content/browser/loader/intercepting_resource_handler.h b/chromium/content/browser/loader/intercepting_resource_handler.h
index 0e7840e7120..2b71045cac0 100644
--- a/chromium/content/browser/loader/intercepting_resource_handler.h
+++ b/chromium/content/browser/loader/intercepting_resource_handler.h
@@ -148,7 +148,7 @@ class CONTENT_EXPORT InterceptingResourceHandler
// Result of the first read, that may have to be passed to an alternate
// ResourceHandler instead of the original ResourceHandler.
scoped_refptr<net::IOBuffer> first_read_buffer_;
- // Instead of |first_read_buffer_|, this handler creates a new IOBuffer with
+ // Instead of |first_read_buffer_|, this handler creates an IOBuffer with
// the same size and return it to the client.
scoped_refptr<net::IOBuffer> first_read_buffer_double_;
int first_read_buffer_size_ = 0;
diff --git a/chromium/content/browser/loader/loader_browsertest.cc b/chromium/content/browser/loader/loader_browsertest.cc
index 927f2af62d3..4982a6699e9 100644
--- a/chromium/content/browser/loader/loader_browsertest.cc
+++ b/chromium/content/browser/loader/loader_browsertest.cc
@@ -16,11 +16,13 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/resource_dispatcher_host_delegate.h"
@@ -67,11 +69,11 @@ class LoaderBrowserTest : public ContentBrowserTest,
protected:
void SetUpOnMainThread() override {
base::FilePath path = GetTestFilePath("", "");
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&net::URLRequestMockHTTPJob::AddUrlHandlers, path));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&net::URLRequestFailedJob::AddUrlHandler));
host_resolver()->AddRule("*", "127.0.0.1");
}
@@ -286,11 +288,11 @@ std::unique_ptr<net::test_server::HttpResponse> CancelOnRequest(
return nullptr;
if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- crash_network_service_callback);
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ crash_network_service_callback);
} else {
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&ResourceDispatcherHostImpl::CancelRequestsForProcess,
base::Unretained(ResourceDispatcherHostImpl::Get()),
child_id));
@@ -835,23 +837,23 @@ class PreviewsStateBrowserTest : public ContentBrowserTest {
embedded_test_server()->GetURL("/image.jpg"),
embedded_test_server()->GetURL("/title1.html")));
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(
&PreviewsStateResourceDispatcherHostDelegate::SetDelegate,
base::Unretained(delegate_.get())));
}
void Reset(PreviewsState previews_state) {
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&PreviewsStateResourceDispatcherHostDelegate::Reset,
base::Unretained(delegate_.get()), previews_state));
}
void CheckResourcesRequested(bool should_get_previews_state_called) {
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&PreviewsStateResourceDispatcherHostDelegate::
CheckResourcesRequested,
base::Unretained(delegate_.get()),
@@ -934,8 +936,6 @@ struct RequestData {
referrer(referrer) {}
};
-const GURL kURLWithUniqueOrigin("data:,");
-
} // namespace
class RequestDataBrowserTest : public ContentBrowserTest {
@@ -1092,7 +1092,7 @@ IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, BasicCrossSite) {
// document in which they're embedded.
for (size_t i = 2; i < requests.size(); i++) {
SCOPED_TRACE(requests[i].url);
- EXPECT_EQ(kURLWithUniqueOrigin, requests[i].first_party);
+ EXPECT_EQ(GURL::EmptyGURL(), requests[i].first_party);
EXPECT_EQ(nested_origin, requests[i].initiator);
}
}
@@ -1259,7 +1259,7 @@ IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, CrossOriginNested) {
// Cross-origin subresource requests have a unique first-party, and an
// initiator that matches the document in which they're embedded.
EXPECT_EQ(nested_js_url, requests[3].url);
- EXPECT_EQ(kURLWithUniqueOrigin, requests[3].first_party);
+ EXPECT_EQ(GURL::EmptyGURL(), requests[3].first_party);
EXPECT_EQ(nested_origin, requests[3].initiator);
}
diff --git a/chromium/content/browser/loader/loader_io_thread_notifier.cc b/chromium/content/browser/loader/loader_io_thread_notifier.cc
index 215e2f95fac..44f53d52975 100644
--- a/chromium/content/browser/loader/loader_io_thread_notifier.cc
+++ b/chromium/content/browser/loader/loader_io_thread_notifier.cc
@@ -4,8 +4,10 @@
#include "content/browser/loader/loader_io_thread_notifier.h"
+#include "base/task/post_task.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_routing_id.h"
@@ -28,8 +30,8 @@ LoaderIOThreadNotifier::~LoaderIOThreadNotifier() {}
void LoaderIOThreadNotifier::RenderFrameDeleted(
RenderFrameHost* render_frame_host) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&NotifyRenderFrameDeletedOnIO,
static_cast<RenderFrameHostImpl*>(render_frame_host)
->GetGlobalFrameRoutingId()));
diff --git a/chromium/content/browser/loader/merkle_integrity_source_stream_unittest.cc b/chromium/content/browser/loader/merkle_integrity_source_stream_unittest.cc
index 8765b844ae8..1362d4e18b5 100644
--- a/chromium/content/browser/loader/merkle_integrity_source_stream_unittest.cc
+++ b/chromium/content/browser/loader/merkle_integrity_source_stream_unittest.cc
@@ -56,7 +56,7 @@ class MerkleIntegritySourceStreamTest
: output_buffer_size_(GetParam().buffer_size) {}
void Init(const std::string& mi_header_value) {
- output_buffer_ = new net::IOBuffer(output_buffer_size_);
+ output_buffer_ = base::MakeRefCounted<net::IOBuffer>(output_buffer_size_);
std::unique_ptr<net::MockSourceStream> source(new net::MockSourceStream());
if (GetParam().read_result_type == ReadResultType::ONE_BYTE_AT_A_TIME)
source->set_read_one_byte_at_a_time(true);
diff --git a/chromium/content/browser/loader/mime_sniffing_resource_handler.cc b/chromium/content/browser/loader/mime_sniffing_resource_handler.cc
index 74707ef3128..b228a7dd382 100644
--- a/chromium/content/browser/loader/mime_sniffing_resource_handler.cc
+++ b/chromium/content/browser/loader/mime_sniffing_resource_handler.cc
@@ -115,7 +115,7 @@ MimeSniffingResourceHandler::MimeSniffingResourceHandler(
PluginService* plugin_service,
InterceptingResourceHandler* intercepting_handler,
net::URLRequest* request,
- RequestContextType request_context_type)
+ blink::mojom::RequestContextType request_context_type)
: LayeredResourceHandler(request, std::move(next_handler)),
state_(STATE_STARTING),
host_(host),
@@ -161,7 +161,7 @@ void MimeSniffingResourceHandler::OnResponseStarted(
if (!(response_->head.headers.get() &&
response_->head.headers->response_code() == 304)) {
// MIME sniffing should be disabled for a request initiated by fetch().
- if (request_context_type_ != REQUEST_CONTEXT_TYPE_FETCH &&
+ if (request_context_type_ != blink::mojom::RequestContextType::FETCH &&
network::ShouldSniffContent(request(), response_.get())) {
controller->Resume();
return;
diff --git a/chromium/content/browser/loader/mime_sniffing_resource_handler.h b/chromium/content/browser/loader/mime_sniffing_resource_handler.h
index b1223d34f3d..8e85dba33ff 100644
--- a/chromium/content/browser/loader/mime_sniffing_resource_handler.h
+++ b/chromium/content/browser/loader/mime_sniffing_resource_handler.h
@@ -14,8 +14,8 @@
#include "content/browser/loader/layered_resource_handler.h"
#include "content/browser/loader/resource_controller.h"
#include "content/common/content_export.h"
-#include "content/public/common/request_context_type.h"
#include "ppapi/buildflags/buildflags.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
namespace net {
class URLRequest;
@@ -43,12 +43,13 @@ struct WebPluginInfo;
class CONTENT_EXPORT MimeSniffingResourceHandler
: public LayeredResourceHandler {
public:
- MimeSniffingResourceHandler(std::unique_ptr<ResourceHandler> next_handler,
- ResourceDispatcherHostImpl* host,
- PluginService* plugin_service,
- InterceptingResourceHandler* intercepting_handler,
- net::URLRequest* request,
- RequestContextType request_context_type);
+ MimeSniffingResourceHandler(
+ std::unique_ptr<ResourceHandler> next_handler,
+ ResourceDispatcherHostImpl* host,
+ PluginService* plugin_service,
+ InterceptingResourceHandler* intercepting_handler,
+ net::URLRequest* request,
+ blink::mojom::RequestContextType request_context_type);
~MimeSniffingResourceHandler() override;
private:
@@ -198,7 +199,7 @@ class CONTENT_EXPORT MimeSniffingResourceHandler
// needed.
InterceptingResourceHandler* intercepting_handler_;
- RequestContextType request_context_type_;
+ blink::mojom::RequestContextType request_context_type_;
// True if current in an AdvanceState loop. Used to prevent re-entrancy and
// avoid an extra PostTask.
diff --git a/chromium/content/browser/loader/mime_sniffing_resource_handler_unittest.cc b/chromium/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
index 6d23266622c..4a77bb1af41 100644
--- a/chromium/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
@@ -244,7 +244,7 @@ MimeSniffingResourceHandlerTest::TestAcceptHeaderSettingWithURLRequest(
MimeSniffingResourceHandler mime_sniffing_handler(
std::move(scoped_test_handler), nullptr, nullptr, nullptr, request,
- REQUEST_CONTEXT_TYPE_UNSPECIFIED);
+ blink::mojom::RequestContextType::UNSPECIFIED);
MockResourceLoader mock_loader(&mime_sniffing_handler);
EXPECT_EQ(MockResourceLoader::Status::IDLE,
@@ -290,7 +290,7 @@ bool MimeSniffingResourceHandlerTest::TestStreamIsIntercepted(
MimeSniffingResourceHandler mime_sniffing_handler(
std::unique_ptr<ResourceHandler>(std::move(scoped_test_handler)), &host,
&plugin_service, intercepting_handler.get(), request.get(),
- REQUEST_CONTEXT_TYPE_UNSPECIFIED);
+ blink::mojom::RequestContextType::UNSPECIFIED);
MockResourceLoader mock_loader(&mime_sniffing_handler);
@@ -357,7 +357,7 @@ void MimeSniffingResourceHandlerTest::TestHandlerSniffing(
MimeSniffingResourceHandler mime_sniffing_handler(
std::move(scoped_test_handler), &host, &plugin_service,
intercepting_handler.get(), request.get(),
- REQUEST_CONTEXT_TYPE_UNSPECIFIED);
+ blink::mojom::RequestContextType::UNSPECIFIED);
MockResourceLoader mock_loader(&mime_sniffing_handler);
@@ -521,7 +521,7 @@ void MimeSniffingResourceHandlerTest::TestHandlerNoSniffing(
MimeSniffingResourceHandler mime_sniffing_handler(
std::move(scoped_test_handler), &host, &plugin_service,
intercepting_handler.get(), request.get(),
- REQUEST_CONTEXT_TYPE_UNSPECIFIED);
+ blink::mojom::RequestContextType::UNSPECIFIED);
MockResourceLoader mock_loader(&mime_sniffing_handler);
@@ -854,7 +854,7 @@ TEST_F(MimeSniffingResourceHandlerTest, 304Handling) {
std::unique_ptr<ResourceHandler>(new TestResourceHandler()), &host,
&plugin_service,
static_cast<InterceptingResourceHandler*>(intercepting_handler.get()),
- request.get(), REQUEST_CONTEXT_TYPE_UNSPECIFIED);
+ request.get(), blink::mojom::RequestContextType::UNSPECIFIED);
MockResourceLoader mock_loader(&mime_sniffing_handler);
@@ -907,7 +907,8 @@ TEST_F(MimeSniffingResourceHandlerTest, FetchShouldDisableMimeSniffing) {
scoped_test_handler->set_on_response_started_result(false);
MimeSniffingResourceHandler mime_sniffing_handler(
std::move(scoped_test_handler), &host, &plugin_service,
- intercepting_handler.get(), request.get(), REQUEST_CONTEXT_TYPE_FETCH);
+ intercepting_handler.get(), request.get(),
+ blink::mojom::RequestContextType::FETCH);
MockResourceLoader mock_loader(&mime_sniffing_handler);
@@ -967,7 +968,7 @@ TEST_F(MimeSniffingResourceHandlerTest, NonEmptyPayloadEndsBeforeDecision) {
MimeSniffingResourceHandler mime_sniffing_handler(
std::move(scoped_test_handler), &host, &plugin_service,
intercepting_handler.get(), request.get(),
- REQUEST_CONTEXT_TYPE_UNSPECIFIED);
+ blink::mojom::RequestContextType::UNSPECIFIED);
MockResourceLoader mock_loader(&mime_sniffing_handler);
@@ -1045,7 +1046,7 @@ TEST_F(MimeSniffingResourceHandlerTest, EmptyPayload) {
MimeSniffingResourceHandler mime_sniffing_handler(
std::move(scoped_test_handler), &host, &plugin_service,
intercepting_handler.get(), request.get(),
- REQUEST_CONTEXT_TYPE_UNSPECIFIED);
+ blink::mojom::RequestContextType::UNSPECIFIED);
MockResourceLoader mock_loader(&mime_sniffing_handler);
diff --git a/chromium/content/browser/loader/mojo_async_resource_handler.cc b/chromium/content/browser/loader/mojo_async_resource_handler.cc
index de7d58c0a73..014399c7f58 100644
--- a/chromium/content/browser/loader/mojo_async_resource_handler.cc
+++ b/chromium/content/browser/loader/mojo_async_resource_handler.cc
@@ -186,6 +186,7 @@ void MojoAsyncResourceHandler::OnResponseStarted(
response->head.request_start = request()->creation_time();
response->head.response_start = base::TimeTicks::Now();
sent_received_response_message_ = true;
+ response->head.was_fetched_via_cache = request()->was_cached();
if ((url_loader_options_ &
network::mojom::kURLLoadOptionSendSSLInfoWithResponse) &&
@@ -298,7 +299,7 @@ void MojoAsyncResourceHandler::OnWillRead(
}
DCHECK(!is_using_io_buffer_not_from_writer_);
is_using_io_buffer_not_from_writer_ = true;
- buffer_ = new net::IOBufferWithSize(kMinAllocationSize);
+ buffer_ = base::MakeRefCounted<net::IOBufferWithSize>(kMinAllocationSize);
}
*buf = buffer_;
diff --git a/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc b/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc
index 68e6a784850..5f8fd5bf390 100644
--- a/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc
@@ -492,7 +492,8 @@ TEST_F(MojoAsyncResourceHandlerTest, OnWillStart) {
}
TEST_F(MojoAsyncResourceHandlerTest, OnResponseStarted) {
- scoped_refptr<net::IOBufferWithSize> metadata = new net::IOBufferWithSize(5);
+ scoped_refptr<net::IOBufferWithSize> metadata =
+ base::MakeRefCounted<net::IOBufferWithSize>(5);
memcpy(metadata->data(), "hello", 5);
handler_->SetMetadata(metadata);
diff --git a/chromium/content/browser/loader/navigation_loader_interceptor.cc b/chromium/content/browser/loader/navigation_loader_interceptor.cc
index 957753b1a9a..630456cb714 100644
--- a/chromium/content/browser/loader/navigation_loader_interceptor.cc
+++ b/chromium/content/browser/loader/navigation_loader_interceptor.cc
@@ -17,7 +17,8 @@ bool NavigationLoaderInterceptor::MaybeCreateLoaderForResponse(
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr* loader,
network::mojom::URLLoaderClientRequest* client_request,
- ThrottlingURLLoader* url_loader) {
+ ThrottlingURLLoader* url_loader,
+ bool* skip_other_interceptors) {
return false;
}
diff --git a/chromium/content/browser/loader/navigation_loader_interceptor.h b/chromium/content/browser/loader/navigation_loader_interceptor.h
index ca2f3ad6d5f..1ec858cfaf8 100644
--- a/chromium/content/browser/loader/navigation_loader_interceptor.h
+++ b/chromium/content/browser/loader/navigation_loader_interceptor.h
@@ -93,11 +93,17 @@ class CONTENT_EXPORT NavigationLoaderInterceptor {
// intercept the inflight loading if necessary. Note that the |url_loader|
// will be reset after this method is called, which will also drop the
// URLLoader held by |url_loader_| if it is not unbound yet.
+ // |skip_other_interceptors| is set to true when this interceptor will
+ // exclusively handle the navigation even after redirections. TODO(horo): This
+ // flag was introduced to skip service worker after signed exchange redirect.
+ // Remove this flag when we support service worker and signed exchange
+ // integration. See crbug.com/894755#c1. Nullptr is not allowed.
virtual bool MaybeCreateLoaderForResponse(
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr* loader,
network::mojom::URLLoaderClientRequest* client_request,
- ThrottlingURLLoader* url_loader);
+ ThrottlingURLLoader* url_loader,
+ bool* skip_other_interceptors);
};
} // namespace content
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl.cc b/chromium/content/browser/loader/navigation_url_loader_impl.cc
index f14b46b86a8..257cbf5c165 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_impl.cc
@@ -8,12 +8,15 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/debug/alias.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
+#include "base/rand_util.h"
#include "base/stl_util.h"
#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "components/download/public/common/download_stats.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
#include "content/browser/appcache/appcache_navigation_handle_core.h"
@@ -26,6 +29,7 @@
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/loader/navigation_loader_interceptor.h"
#include "content/browser/loader/navigation_url_loader_delegate.h"
+#include "content/browser/loader/prefetch_url_loader_service.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/resource_context_impl.h"
@@ -46,6 +50,7 @@
#include "content/common/net/record_load_histograms.h"
#include "content/common/throttling_url_loader.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/download_utils.h"
@@ -66,6 +71,7 @@
#include "net/cert/signed_certificate_timestamp_and_status.h"
#include "net/http/http_content_disposition.h"
#include "net/http/http_request_headers.h"
+#include "net/http/http_status_code.h"
#include "net/ssl/ssl_info.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_util.h"
@@ -82,6 +88,11 @@
#include "services/service_manager/public/cpp/connector.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
+#include "url/gurl.h"
+
+#if defined(OS_ANDROID)
+#include "content/browser/android/content_url_loader_factory.h"
+#endif
namespace content {
@@ -217,10 +228,8 @@ std::unique_ptr<network::ResourceRequest> CreateResourceRequest(
request_info->begin_params->headers);
std::string accept_value = network::kFrameAcceptHeader;
- // TODO(https://crbug.com/840704): Decide whether the Accept header should
- // advertise the state of kSignedHTTPExchangeOriginTrial before starting the
- // Origin-Trial.
- if (signed_exchange_utils::IsSignedExchangeHandlingEnabled()) {
+ if (signed_exchange_utils::ShouldAdvertiseAcceptHeader(
+ url::Origin::Create(request_info->common_params.url))) {
DCHECK(!accept_value.empty());
accept_value.append(kAcceptHeaderSignedExchangeSuffix);
}
@@ -253,9 +262,10 @@ std::unique_ptr<network::ResourceRequest> CreateResourceRequest(
network::mojom::FetchCredentialsMode::kInclude;
new_request->fetch_redirect_mode = network::mojom::FetchRedirectMode::kManual;
new_request->fetch_request_context_type =
- request_info->begin_params->request_context_type;
+ static_cast<int>(request_info->begin_params->request_context_type);
new_request->upgrade_if_insecure = request_info->upgrade_if_insecure;
new_request->throttling_profile_id = request_info->devtools_frame_token;
+ new_request->transition_type = request_info->common_params.transition;
return new_request;
}
@@ -436,6 +446,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
storage::FileSystemContext* upload_file_system_context,
ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
AppCacheNavigationHandleCore* appcache_handle_core,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder>
+ signed_exchange_prefetch_metric_recorder,
bool was_request_intercepted) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
@@ -446,7 +458,6 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
weak_factory_.GetWeakPtr(),
base::Unretained(url_request_context_getter),
base::Unretained(upload_file_system_context),
- std::make_unique<NavigationRequestInfo>(*request_info_),
// If the request has already been intercepted, the request should not
// be intercepted again.
// S13nServiceWorker: Requests are intercepted by S13nServiceWorker
@@ -458,23 +469,23 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
? nullptr
: service_worker_navigation_handle_core),
base::Unretained(was_request_intercepted ? nullptr
- : appcache_handle_core));
+ : appcache_handle_core),
+ std::move(signed_exchange_prefetch_metric_recorder));
}
void CreateNonNetworkServiceURLLoader(
net::URLRequestContextGetter* url_request_context_getter,
storage::FileSystemContext* upload_file_system_context,
- std::unique_ptr<NavigationRequestInfo> request_info,
ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
AppCacheNavigationHandleCore* appcache_handle_core,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder>
+ signed_exchange_prefetch_metric_recorder,
const network::ResourceRequest& /* resource_request */,
network::mojom::URLLoaderRequest url_loader,
network::mojom::URLLoaderClientPtr url_loader_client) {
- // |resource_request| is unused here. Its info may not be the same as
- // |request_info|, because URLLoaderThrottles may have rewritten it. We
- // don't propagate the fields to |request_info| here because the request
- // will usually go to ResourceDispatcherHost which does its own request
- // modification independent of URLLoaderThrottles.
+ // |resource_request| is unused here. We don't propagate the fields to
+ // |request_info_| here because the request will usually go to
+ // ResourceDispatcherHost which does its own request modifications.
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
DCHECK(started_);
@@ -489,46 +500,71 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// SignedExchangeHandler which is indirectly owned by |this| until its
// header is verified and parsed, that's where the getter is used.
interceptors_.push_back(std::make_unique<SignedExchangeRequestHandler>(
- url::Origin::Create(request_info->common_params.url),
- request_info->common_params.url,
- GetURLLoaderOptions(request_info->is_main_frame),
- request_info->frame_tree_node_id,
- request_info->devtools_navigation_token,
- request_info->devtools_frame_token, request_info->report_raw_headers,
- request_info->begin_params->load_flags,
+ url::Origin::Create(request_info_->common_params.url),
+ request_info_->common_params.url,
+ GetURLLoaderOptions(request_info_->is_main_frame),
+ request_info_->frame_tree_node_id,
+ request_info_->devtools_navigation_token,
+ request_info_->devtools_frame_token, request_info_->report_raw_headers,
+ request_info_->begin_params->load_flags,
base::MakeRefCounted<
SignedExchangeURLLoaderFactoryForNonNetworkService>(
resource_context_, url_request_context_getter),
base::BindRepeating(
&URLLoaderRequestController::CreateURLLoaderThrottles,
- base::Unretained(this))));
+ base::Unretained(this)),
+ std::move(signed_exchange_prefetch_metric_recorder)));
}
- uint32_t options = GetURLLoaderOptions(request_info->is_main_frame);
+ uint32_t options = GetURLLoaderOptions(request_info_->is_main_frame);
bool intercepted = false;
if (g_interceptor.Get()) {
+ // Recreate the ResourceRequest for the interceptor, in case a
+ // URLLoaderThrottle had changed request_info_.
+ auto latest_resource_request =
+ CreateResourceRequest(request_info_.get(), frame_tree_node_id_,
+ resource_request_->allow_download);
+ latest_resource_request->headers = resource_request_->headers;
intercepted = g_interceptor.Get().Run(
&url_loader, frame_tree_node_id_, 0 /* request_id */, options,
- *resource_request_.get(), &url_loader_client,
+ *latest_resource_request, &url_loader_client,
net::MutableNetworkTrafficAnnotationTag(
kNavigationUrlLoaderTrafficAnnotation));
}
+ // A URLLoaderThrottle may have changed the headers.
+ request_info_->begin_params->headers =
+ resource_request_->headers.ToString();
+
// The ResourceDispatcherHostImpl can be null in unit tests.
- if (!intercepted && ResourceDispatcherHostImpl::Get()) {
- ResourceDispatcherHostImpl::Get()->BeginNavigationRequest(
+ ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
+ if (!intercepted && rdh) {
+ rdh->BeginNavigationRequest(
resource_context_, url_request_context_getter->GetURLRequestContext(),
- upload_file_system_context, *request_info,
+ upload_file_system_context, *request_info_,
std::move(navigation_ui_data_), std::move(url_loader_client),
std::move(url_loader), service_worker_navigation_handle_core,
appcache_handle_core, options, global_request_id_);
+
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ // Get the SWProviderHost for non-S13nSW path. For S13nSW path,
+ // |service_worker_provider_host_| must be set in
+ // CreateServiceWorkerInterceptor().
+ net::URLRequest* url_request = rdh->GetURLRequest(global_request_id_);
+ ServiceWorkerProviderHost* service_worker_provider_host =
+ ServiceWorkerRequestHandler::GetProviderHost(url_request);
+ if (service_worker_provider_host) {
+ service_worker_provider_host_ =
+ service_worker_provider_host->AsWeakPtr();
+ }
+ }
}
// TODO(arthursonzogni): Detect when the ResourceDispatcherHost didn't
// create a URLLoader. When it doesn't, do not send OnRequestStarted().
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NavigationURLLoaderImpl::OnRequestStarted, owner_,
base::TimeTicks::Now()));
}
@@ -539,6 +575,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
storage::FileSystemContext* upload_file_system_context,
ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
AppCacheNavigationHandleCore* appcache_handle_core,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder>
+ signed_exchange_prefetch_metric_recorder,
std::unique_ptr<NavigationRequestInfo> request_info,
std::unique_ptr<NavigationUIData> navigation_ui_data) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -563,7 +601,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
base::Unretained(this), base::Unretained(url_request_context_getter),
base::Unretained(upload_file_system_context),
base::Unretained(service_worker_navigation_handle_core),
- base::Unretained(appcache_handle_core));
+ base::Unretained(appcache_handle_core),
+ base::RetainedRef(signed_exchange_prefetch_metric_recorder));
// Requests to Blob scheme won't get redirected to/from other schemes
// or be intercepted, so we just let it go here.
@@ -627,6 +666,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
network_loader_factory_info,
ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
AppCacheNavigationHandleCore* appcache_handle_core,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder>
+ signed_exchange_prefetch_metric_recorder,
std::unique_ptr<NavigationRequestInfo> request_info,
std::unique_ptr<NavigationUIData> navigation_ui_data,
network::mojom::URLLoaderFactoryPtrInfo factory_for_webui,
@@ -642,6 +683,11 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
base::Bind(&GetWebContentsFromFrameTreeNodeID, frame_tree_node_id);
navigation_ui_data_ = std::move(navigation_ui_data);
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&NavigationURLLoaderImpl::OnRequestStarted, owner_,
+ base::TimeTicks::Now()));
+
DCHECK(network_loader_factory_info);
network_loader_factory_ = network::SharedURLLoaderFactory::Create(
std::move(network_loader_factory_info));
@@ -696,11 +742,6 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
}
if (signed_exchange_utils::IsSignedExchangeHandlingEnabled()) {
- // Signed Exchange is currently disabled when Network Service is enabled
- // (https://crbug.com/849935), but still create
- // SignedExchangeRequestHandler in order to show error message (and
- // devtools warning) to users.
-
// It is safe to pass the callback of CreateURLLoaderThrottles with the
// unretained |this|, because the passed callback will be used by a
// SignedExchangeHandler which is indirectly owned by |this| until its
@@ -715,7 +756,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
request_info->begin_params->load_flags, network_loader_factory_,
base::BindRepeating(
&URLLoaderRequestController::CreateURLLoaderThrottles,
- base::Unretained(this))));
+ base::Unretained(this)),
+ signed_exchange_prefetch_metric_recorder));
}
std::vector<std::unique_ptr<URLLoaderRequestInterceptor>>
@@ -850,7 +892,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// This is the |fallback_callback| passed to
// NavigationLoaderInterceptor::MaybeCreateLoader. It allows an interceptor
// to initially elect to handle a request, and later decide to fallback to
- // the default behavior. This is needed for service worker network fallback.
+ // the default behavior. This is needed for service worker network fallback
+ // and signed exchange (SXG) fallback redirect.
void FallbackToNonInterceptedRequest(bool reset_subresource_loader_params) {
if (reset_subresource_loader_params)
subresource_loader_params_.reset();
@@ -859,21 +902,35 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// Cancel state on ResourceDispatcherHostImpl so it doesn't complain about
// reusing the request_id after redirects. Otherwise the following sequence
// can happen:
- // RDHI Start(request_id) -> Redirect -> SW interception -> SW fallback to
- // network -> RDHI Start(request_id).
+ // case 1. RDHI Start(request_id) -> Redirect -> SW interception -> SW
+ // fallback to network -> RDHI Start(request_id).
+ // case 2. RDHI Start(request_id) -> SXG interception -> SXG fallback to
+ // network -> RDHI Start(request_id).
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
DCHECK(ResourceDispatcherHostImpl::Get());
ResourceDispatcherHostImpl::Get()->CancelRequest(
global_request_id_.child_id, global_request_id_.request_id);
}
- // |url_loader_| is using the factory for the interceptor that decided to
- // fallback, so restart it with the non-interceptor factory.
- DCHECK(url_loader_);
uint32_t options = network::mojom::kURLLoadOptionNone;
scoped_refptr<network::SharedURLLoaderFactory> factory =
PrepareForNonInterceptedRequest(&options);
- url_loader_->RestartWithFactory(std::move(factory), options);
+ if (url_loader_) {
+ // |url_loader_| is using the factory for the interceptor that decided to
+ // fallback, so restart it with the non-interceptor factory.
+ url_loader_->RestartWithFactory(std::move(factory), options);
+ } else {
+ // In SXG cases we don't have |url_loader_| because it was reset when the
+ // SXG interceptor intercepted the response in
+ // MaybeCreateLoaderForResponse.
+ DCHECK(response_loader_binding_);
+ response_loader_binding_.Close();
+ url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
+ std::move(factory), CreateURLLoaderThrottles(), frame_tree_node_id_,
+ global_request_id_.request_id, options, resource_request_.get(),
+ this /* client */, kNavigationUrlLoaderTrafficAnnotation,
+ base::ThreadTaskRunnerHandle::Get());
+ }
}
scoped_refptr<network::SharedURLLoaderFactory>
@@ -931,8 +988,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
network::mojom::URLLoaderFactoryPtr& non_network_factory =
non_network_url_loader_factories_[resource_request_->url.scheme()];
if (!non_network_factory.is_bound()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NavigationURLLoaderImpl ::
BindNonNetworkURLLoaderFactoryRequest,
owner_, frame_tree_node_id_,
@@ -974,6 +1031,14 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!redirect_info_.new_url.is_empty());
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ auto* common_params =
+ const_cast<CommonNavigationParams*>(&request_info_->common_params);
+ common_params->url = redirect_info_.new_url;
+ common_params->referrer.url = GURL(redirect_info_.new_referrer);
+ common_params->method = redirect_info_.new_method;
+ }
+
if (!IsLoaderInterceptionEnabled()) {
url_loader_->FollowRedirect(modified_request_headers);
return;
@@ -987,7 +1052,6 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// there likely remains more to be done.
// a. For subframe navigations, the Origin header may need to be modified
// differently?
- // b. How should redirect_info_.referred_token_binding_host be handled?
bool should_clear_upload = false;
net::RedirectUtil::UpdateHttpRequest(
@@ -1011,6 +1075,27 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// |resource_request_| during redirect.
url_loader_modified_request_headers_ = modified_request_headers;
+ if (signed_exchange_utils::NeedToCheckRedirectedURLForAcceptHeader()) {
+ // Currently we send the SignedExchange accept header only for the limited
+ // origins when SignedHTTPExchangeOriginTrial feature is enabled without
+ // SignedHTTPExchange feature. We need to put the SignedExchange accept
+ // header on when redirecting to the origins in the OriginList of
+ // SignedHTTPExchangeAcceptHeader field trial, and need to remove it when
+ // redirecting to out of the OriginList.
+ if (!url_loader_modified_request_headers_)
+ url_loader_modified_request_headers_ = net::HttpRequestHeaders();
+ std::string accept_value = network::kFrameAcceptHeader;
+ if (signed_exchange_utils::ShouldAdvertiseAcceptHeader(
+ url::Origin::Create(resource_request_->url))) {
+ DCHECK(!accept_value.empty());
+ accept_value.append(kAcceptHeaderSignedExchangeSuffix);
+ }
+ url_loader_modified_request_headers_->SetHeader(network::kAcceptHeader,
+ accept_value);
+ resource_request_->headers.SetHeader(network::kAcceptHeader,
+ accept_value);
+ }
+
Restart();
}
@@ -1036,12 +1121,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints;
- // Currently only plugin handlers may intercept the response. Don't treat
- // the response as download if it has been handled by plugins.
- bool response_intercepted = false;
if (url_loader_) {
url_loader_client_endpoints = url_loader_->Unbind();
- response_intercepted = url_loader_->response_intercepted();
} else {
url_loader_client_endpoints =
network::mojom::URLLoaderClientEndpoints::New(
@@ -1049,6 +1130,16 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
response_loader_binding_.Unbind());
}
+ // 304 responses should abort the navigation, rather than display the page.
+ // This needs to be after the URLLoader has been moved to
+ // |url_loader_client_endpoints| in order to abort the request, to avoid
+ // receiving unexpected call.
+ if (head.headers &&
+ head.headers->response_code() == net::HTTP_NOT_MODIFIED) {
+ OnComplete(network::URLLoaderCompletionStatus(net::ERR_ABORTED));
+ return;
+ }
+
bool is_download;
bool is_stream;
// If there is not an explicit PreviewsState set on the request, turn
@@ -1061,19 +1152,21 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
url_, head.headers.get(), head.mime_type);
bool known_mime_type = blink::IsSupportedMimeType(head.mime_type);
- bool is_download_if_not_handled_by_plugin =
- !response_intercepted && (must_download || !known_mime_type);
-
#if BUILDFLAG(ENABLE_PLUGINS)
- if (!response_intercepted && !must_download && !known_mime_type) {
+ if (!head.intercepted_by_plugin && !must_download && !known_mime_type) {
+ // No plugin throttles intercepted the response. Ask if the plugin
+ // registered to PluginService wants to handle the request.
CheckPluginAndContinueOnReceiveResponse(
head, std::move(url_loader_client_endpoints),
- is_download_if_not_handled_by_plugin, std::vector<WebPluginInfo>());
+ true /* is_download_if_not_handled_by_plugin */,
+ std::vector<WebPluginInfo>());
return;
}
#endif
- is_download = is_download_if_not_handled_by_plugin;
+ // When a plugin intercepted the response, we don't want to download it.
+ is_download =
+ !head.intercepted_by_plugin && (must_download || !known_mime_type);
is_stream = false;
// If NetworkService is on, or an interceptor handled the request, the
@@ -1098,7 +1191,7 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
if (url_request) {
ResourceRequestInfoImpl* info =
ResourceRequestInfoImpl::ForRequest(url_request);
- is_download = !response_intercepted && info->IsDownload();
+ is_download = !head.intercepted_by_plugin && info->IsDownload();
is_stream = info->is_stream();
previews_state = info->GetPreviewsState();
if (rdh->delegate()) {
@@ -1198,8 +1291,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// TODO(davidben): This copy could be avoided if ResourceResponse weren't
// reference counted and the loader stack passed unique ownership of the
// response. https://crbug.com/416050
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NavigationURLLoaderImpl::OnReceiveResponse, owner_,
response->DeepCopy(),
std::move(url_loader_client_endpoints),
@@ -1237,8 +1330,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// TODO(davidben): This copy could be avoided if ResourceResponse weren't
// reference counted and the loader stack passed unique ownership of the
// response. https://crbug.com/416050
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NavigationURLLoaderImpl::OnReceiveRedirect, owner_,
redirect_info, response->DeepCopy()));
}
@@ -1252,6 +1345,40 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
void OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle) override {
// Not reached. At this point, the loader and client endpoints must have
// been unbound and forwarded to the renderer.
+
+ // TODO(crbug.com/882661): Remove these aliases when the linked bug is
+ // fixed.
+ bool received_response = received_response_;
+ base::debug::Alias(&received_response);
+ bool default_loader_used = default_loader_used_;
+ base::debug::Alias(&default_loader_used);
+ DEBUG_ALIAS_FOR_GURL(url, url_);
+ size_t chain_size = url_chain_.size();
+ base::debug::Alias(&chain_size);
+ GURL url0;
+ GURL url1;
+ GURL url2;
+ GURL url3;
+ GURL url4;
+ GURL url5;
+ if (url_chain_.size() > 0)
+ url0 = url_chain_[0];
+ if (url_chain_.size() > 1)
+ url1 = url_chain_[1];
+ if (url_chain_.size() > 2)
+ url2 = url_chain_[2];
+ if (url_chain_.size() > 3)
+ url3 = url_chain_[3];
+ if (url_chain_.size() > 4)
+ url4 = url_chain_[4];
+ if (url_chain_.size() > 5)
+ url5 = url_chain_[5];
+ DEBUG_ALIAS_FOR_GURL(url0_buf, url0);
+ DEBUG_ALIAS_FOR_GURL(url1_buf, url1);
+ DEBUG_ALIAS_FOR_GURL(url2_buf, url2);
+ DEBUG_ALIAS_FOR_GURL(url3_buf, url3);
+ DEBUG_ALIAS_FOR_GURL(url4_buf, url4);
+ DEBUG_ALIAS_FOR_GURL(url5_buf, url5);
CHECK(false);
}
@@ -1276,8 +1403,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
}
status_ = status;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NavigationURLLoaderImpl::OnComplete, owner_, status));
}
@@ -1291,16 +1418,36 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
if (!default_loader_used_)
return false;
- for (auto& interceptor : interceptors_) {
+ for (size_t i = 0u; i < interceptors_.size(); ++i) {
+ NavigationLoaderInterceptor* interceptor = interceptors_[i].get();
network::mojom::URLLoaderClientRequest response_client_request;
+ bool skip_other_interceptors = false;
if (interceptor->MaybeCreateLoaderForResponse(
response, &response_url_loader_, &response_client_request,
- url_loader_.get())) {
+ url_loader_.get(), &skip_other_interceptors)) {
if (response_loader_binding_.is_bound())
response_loader_binding_.Close();
response_loader_binding_.Bind(std::move(response_client_request));
default_loader_used_ = false;
url_loader_.reset();
+ if (skip_other_interceptors) {
+ std::vector<std::unique_ptr<NavigationLoaderInterceptor>>
+ new_interceptors;
+ new_interceptors.push_back(std::move(interceptors_[i]));
+ new_interceptors.swap(interceptors_);
+ if (service_worker_provider_host_) {
+ // Reset the state of ServiceWorkerProviderHost.
+ // Currently we don't support Service Worker in Signed Exchange
+ // pages. The page will not be controlled by service workers. And
+ // Service Worker related APIs will fail with NoDocumentURL error.
+ // TODO(crbug/898733): Support SignedExchange loading and Service
+ // Worker integration.
+ service_worker_provider_host_->SetControllerRegistration(
+ nullptr, false /* notify_controllerchange */);
+ service_worker_provider_host_->SetDocumentUrl(GURL());
+ service_worker_provider_host_->SetTopmostFrameUrl(GURL());
+ }
+ }
return true;
}
}
@@ -1315,8 +1462,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
std::unique_ptr<NavigationLoaderInterceptor> CreateServiceWorkerInterceptor(
const NavigationRequestInfo& request_info,
- ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core)
- const {
+ ServiceWorkerNavigationHandleCore*
+ service_worker_navigation_handle_core) {
const ResourceType resource_type = request_info.is_main_frame
? RESOURCE_TYPE_MAIN_FRAME
: RESOURCE_TYPE_SUB_FRAME;
@@ -1332,7 +1479,7 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
request_info.begin_params->skip_service_worker, resource_type,
request_info.begin_params->request_context_type, frame_type,
request_info.are_ancestors_secure, request_info.common_params.post_data,
- web_contents_getter_);
+ web_contents_getter_, &service_worker_provider_host_);
}
void RecordSCTHistogramIfNeeded(
@@ -1445,6 +1592,10 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// If true, redirect checks will be handled in a proxy, and not here.
bool bypass_redirect_checks_;
+ // Used to reset the state of ServiceWorkerProviderHost when
+ // SignedExchangeRequestHandler will handle the response.
+ base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host_;
+
mutable base::WeakPtrFactory<URLLoaderRequestController> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController);
@@ -1483,7 +1634,12 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
std::unique_ptr<network::ResourceRequest> new_request = CreateResourceRequest(
request_info.get(), frame_tree_node_id, allow_download_);
- new_request->transition_type = request_info->common_params.transition;
+
+ auto* partition = static_cast<StoragePartitionImpl*>(storage_partition);
+ scoped_refptr<SignedExchangePrefetchMetricRecorder>
+ signed_exchange_prefetch_metric_recorder =
+ partition->GetPrefetchURLLoaderService()
+ ->signed_exchange_prefetch_metric_recorder();
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
DCHECK(!request_controller_);
@@ -1496,16 +1652,17 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
/* proxied_url_loader_factory_info */ nullptr, std::set<std::string>(),
/* bypass_redirect_checks */ false, weak_factory_.GetWeakPtr());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&URLLoaderRequestController::StartWithoutNetworkService,
base::Unretained(request_controller_.get()),
base::RetainedRef(storage_partition->GetURLRequestContext()),
base::Unretained(storage_partition->GetFileSystemContext()),
base::Unretained(service_worker_navigation_handle_core),
- base::Unretained(appcache_handle_core), std::move(request_info),
- std::move(navigation_ui_data)));
+ base::Unretained(appcache_handle_core),
+ base::RetainedRef(signed_exchange_prefetch_metric_recorder),
+ std::move(request_info), std::move(navigation_ui_data)));
return;
}
@@ -1524,7 +1681,6 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
network::mojom::URLLoaderFactoryPtrInfo proxied_factory_info;
network::mojom::URLLoaderFactoryRequest proxied_factory_request;
bool bypass_redirect_checks = false;
- auto* partition = static_cast<StoragePartitionImpl*>(storage_partition);
if (frame_tree_node) {
// |frame_tree_node| may be null in some unit test environments.
GetContentClient()
@@ -1532,6 +1688,10 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
->RegisterNonNetworkNavigationURLLoaderFactories(
frame_tree_node_id, &non_network_url_loader_factories_);
+ // Navigation requests are not associated with any particular
+ // |network::ResourceRequest::request_initiator| origin - using an opaque
+ // origin instead.
+ url::Origin navigation_request_initiator = url::Origin();
// The embedder may want to proxy all network-bound URLLoaderFactory
// requests that it can. If it elects to do so, we'll pass its proxy
// endpoints off to the URLLoaderRequestController where wthey will be
@@ -1540,8 +1700,8 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
auto factory_request = mojo::MakeRequest(&factory_info);
bool use_proxy = GetContentClient()->browser()->WillCreateURLLoaderFactory(
partition->browser_context(), frame_tree_node->current_frame_host(),
- true /* is_navigation */, new_request->url, &factory_request);
- bypass_redirect_checks = use_proxy;
+ true /* is_navigation */, navigation_request_initiator,
+ &factory_request, &bypass_redirect_checks);
if (RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory(
frame_tree_node->current_frame_host(), true, false,
&factory_request)) {
@@ -1569,6 +1729,15 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}));
+
+#if defined(OS_ANDROID)
+ non_network_url_loader_factories_[url::kContentScheme] =
+ std::make_unique<ContentURLLoaderFactory>(
+ base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}));
+#endif
+
std::set<std::string> known_schemes;
for (auto& iter : non_network_url_loader_factories_)
known_schemes.insert(iter.first);
@@ -1580,13 +1749,14 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
std::move(proxied_factory_request), std::move(proxied_factory_info),
std::move(known_schemes), bypass_redirect_checks,
weak_factory_.GetWeakPtr());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&URLLoaderRequestController::Start,
base::Unretained(request_controller_.get()),
partition->url_loader_factory_getter()->GetNetworkFactoryInfo(),
service_worker_navigation_handle_core, appcache_handle_core,
+ std::move(signed_exchange_prefetch_metric_recorder),
std::move(request_info), std::move(navigation_ui_data),
std::move(factory_for_webui), frame_tree_node_id,
ServiceManagerConnection::GetForProcess()->GetConnector()->Clone()));
@@ -1601,8 +1771,8 @@ void NavigationURLLoaderImpl::FollowRedirect(
const base::Optional<std::vector<std::string>>&
to_be_removed_request_headers,
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&URLLoaderRequestController::FollowRedirect,
base::Unretained(request_controller_.get()),
modified_request_headers));
@@ -1671,12 +1841,19 @@ void NavigationURLLoaderImpl::BindNonNetworkURLLoaderFactoryRequest(
DVLOG(1) << "Ignoring request with unknown scheme: " << url.spec();
return;
}
+
+ // Navigation requests are not associated with any particular
+ // |network::ResourceRequest::request_initiator| origin - using an opaque
+ // origin instead.
+ url::Origin navigation_request_initiator = url::Origin();
+
FrameTreeNode* frame_tree_node =
FrameTreeNode::GloballyFindByID(frame_tree_node_id);
auto* frame = frame_tree_node->current_frame_host();
GetContentClient()->browser()->WillCreateURLLoaderFactory(
frame->GetSiteInstance()->GetBrowserContext(), frame,
- true /* is_navigation */, url, &factory);
+ true /* is_navigation */, navigation_request_initiator, &factory,
+ nullptr /* bypass_redirect_checks */);
it->second->Clone(std::move(factory));
}
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl_unittest.cc b/chromium/content/browser/loader/navigation_url_loader_impl_unittest.cc
index 37cf04dda21..1972331fefb 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl_unittest.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_impl_unittest.cc
@@ -10,6 +10,7 @@
#include <vector>
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "base/unguessable_token.h"
#include "content/browser/frame_host/navigation_request_info.h"
@@ -19,6 +20,7 @@
#include "content/common/navigation_params.mojom.h"
#include "content/common/service_manager/service_manager_connection_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_ui_data.h"
#include "content/public/browser/plugin_service.h"
@@ -99,7 +101,8 @@ class TestNavigationLoaderInterceptor : public NavigationLoaderInterceptor {
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr* loader,
network::mojom::URLLoaderClientRequest* client_request,
- ThrottlingURLLoader* url_loader) override {
+ ThrottlingURLLoader* url_loader,
+ bool* skip_other_interceptors) override {
return false;
}
@@ -133,7 +136,7 @@ class NavigationURLLoaderImplTest : public testing::Test {
ServiceManagerConnection::SetForProcess(
std::make_unique<ServiceManagerConnectionImpl>(
mojo::MakeRequest(&service),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})));
browser_context_.reset(new TestBrowserContext);
http_test_server_.AddDefaultHandlers(
@@ -163,7 +166,7 @@ class NavigationURLLoaderImplTest : public testing::Test {
mojom::BeginNavigationParamsPtr begin_params =
mojom::BeginNavigationParams::New(
headers, net::LOAD_NORMAL, false /* skip_service_worker */,
- REQUEST_CONTEXT_TYPE_LOCATION,
+ blink::mojom::RequestContextType::LOCATION,
blink::WebMixedContentContextType::kBlockable,
false /* is_form_submission */, GURL() /* searchable_form_url */,
std::string() /* searchable_form_encoding */,
diff --git a/chromium/content/browser/loader/navigation_url_loader_unittest.cc b/chromium/content/browser/loader/navigation_url_loader_unittest.cc
index 75f70ba50a4..7a7eb768fcf 100644
--- a/chromium/content/browser/loader/navigation_url_loader_unittest.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_unittest.cc
@@ -83,7 +83,8 @@ class NavigationURLLoaderTest : public testing::Test {
mojom::BeginNavigationParamsPtr begin_params =
mojom::BeginNavigationParams::New(
std::string() /* headers */, net::LOAD_NORMAL,
- false /* skip_service_worker */, REQUEST_CONTEXT_TYPE_LOCATION,
+ false /* skip_service_worker */,
+ blink::mojom::RequestContextType::LOCATION,
blink::WebMixedContentContextType::kBlockable,
false /* is_form_submission */, GURL() /* searchable_form_url */,
std::string() /* searchable_form_encoding */,
diff --git a/chromium/content/browser/loader/prefetch_browsertest.cc b/chromium/content/browser/loader/prefetch_browsertest.cc
index b3776b2bac6..011142e91ae 100644
--- a/chromium/content/browser/loader/prefetch_browsertest.cc
+++ b/chromium/content/browser/loader/prefetch_browsertest.cc
@@ -10,11 +10,13 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "content/browser/loader/prefetch_url_loader_service.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/web_package/mock_signed_exchange_handler.h"
#include "content/browser/web_package/signed_exchange_loader.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
@@ -77,8 +79,8 @@ class PrefetchBrowserTest
StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
BrowserContext::GetDefaultStoragePartition(
shell()->web_contents()->GetBrowserContext()));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
BindOnce(
&PrefetchURLLoaderService::RegisterPrefetchLoaderCallbackForTest,
base::RetainedRef(partition->GetPrefetchURLLoaderService()),
@@ -108,13 +110,10 @@ class PrefetchBrowserTest
void WatchURLAndRunClosure(
const std::string& relative_url,
int* visit_count,
- net::test_server::HttpRequest::HeaderMap* out_headers,
base::OnceClosure closure,
const net::test_server::HttpRequest& request) {
if (request.relative_url == relative_url) {
(*visit_count)++;
- if (out_headers)
- *out_headers = request.headers;
if (closure)
std::move(closure).Run();
}
@@ -151,7 +150,7 @@ IN_PROC_BROWSER_TEST_P(PrefetchBrowserTest, Simple) {
base::RunLoop prefetch_waiter;
embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
&PrefetchBrowserTest::WatchURLAndRunClosure, base::Unretained(this),
- target_url, &target_fetch_count, nullptr, prefetch_waiter.QuitClosure()));
+ target_url, &target_fetch_count, prefetch_waiter.QuitClosure()));
embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
&PrefetchBrowserTest::ServeResponses, base::Unretained(this)));
ASSERT_TRUE(embedded_test_server()->Start());
@@ -189,7 +188,7 @@ IN_PROC_BROWSER_TEST_P(PrefetchBrowserTest, DoublePrefetch) {
base::RunLoop prefetch_waiter;
embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
&PrefetchBrowserTest::WatchURLAndRunClosure, base::Unretained(this),
- target_url, &target_fetch_count, nullptr, prefetch_waiter.QuitClosure()));
+ target_url, &target_fetch_count, prefetch_waiter.QuitClosure()));
embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
&PrefetchBrowserTest::ServeResponses, base::Unretained(this)));
ASSERT_TRUE(embedded_test_server()->Start());
@@ -236,12 +235,10 @@ IN_PROC_BROWSER_TEST_P(PrefetchBrowserTest, NoCacheAndNoStore) {
base::RunLoop nostore_waiter;
embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
&PrefetchBrowserTest::WatchURLAndRunClosure, base::Unretained(this),
- nocache_url, &nocache_fetch_count, nullptr,
- nocache_waiter.QuitClosure()));
+ nocache_url, &nocache_fetch_count, nocache_waiter.QuitClosure()));
embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
&PrefetchBrowserTest::WatchURLAndRunClosure, base::Unretained(this),
- nostore_url, &nostore_fetch_count, nullptr,
- nostore_waiter.QuitClosure()));
+ nostore_url, &nostore_fetch_count, nostore_waiter.QuitClosure()));
embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
&PrefetchBrowserTest::ServeResponses, base::Unretained(this)));
ASSERT_TRUE(embedded_test_server()->Start());
@@ -298,11 +295,10 @@ IN_PROC_BROWSER_TEST_P(PrefetchBrowserTest, WithPreload) {
base::RunLoop preload_waiter;
embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
&PrefetchBrowserTest::WatchURLAndRunClosure, base::Unretained(this),
- target_url, &target_fetch_count, nullptr, base::RepeatingClosure()));
+ target_url, &target_fetch_count, base::RepeatingClosure()));
embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
&PrefetchBrowserTest::WatchURLAndRunClosure, base::Unretained(this),
- preload_url, &preload_fetch_count, nullptr,
- preload_waiter.QuitClosure()));
+ preload_url, &preload_fetch_count, preload_waiter.QuitClosure()));
embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
&PrefetchBrowserTest::ServeResponses, base::Unretained(this)));
ASSERT_TRUE(embedded_test_server()->Start());
@@ -353,22 +349,20 @@ IN_PROC_BROWSER_TEST_P(PrefetchBrowserTest, WebPackageWithPreload) {
base::RunLoop preload_waiter;
base::RunLoop prefetch_waiter;
- net::test_server::HttpRequest::HeaderMap prefetch_headers;
embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
&PrefetchBrowserTest::WatchURLAndRunClosure, base::Unretained(this),
- target_sxg, &target_fetch_count, &prefetch_headers,
- prefetch_waiter.QuitClosure()));
+ target_sxg, &target_fetch_count, prefetch_waiter.QuitClosure()));
embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
&PrefetchBrowserTest::WatchURLAndRunClosure, base::Unretained(this),
- preload_url_in_sxg, &preload_fetch_count, nullptr,
- preload_waiter.QuitClosure()));
+ preload_url_in_sxg, &preload_fetch_count, preload_waiter.QuitClosure()));
embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
&PrefetchBrowserTest::ServeResponses, base::Unretained(this)));
ASSERT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(CheckPrefetchURLLoaderCountIfSupported(0));
MockSignedExchangeHandlerFactory factory(
- net::OK, GURL(embedded_test_server()->GetURL(target_url)), "text/html",
+ SignedExchangeLoadResult::kSuccess, net::OK,
+ GURL(embedded_test_server()->GetURL(target_url)), "text/html",
{base::StringPrintf(
"Link: <%s>;rel=\"preload\";as=\"script\"",
embedded_test_server()->GetURL(preload_url_in_sxg).spec().c_str())});
@@ -380,11 +374,6 @@ IN_PROC_BROWSER_TEST_P(PrefetchBrowserTest, WebPackageWithPreload) {
prefetch_waiter.Run();
EXPECT_EQ(1, target_fetch_count);
EXPECT_TRUE(CheckPrefetchURLLoaderCountIfSupported(1));
- if (base::FeatureList::IsEnabled(features::kSignedHTTPExchange))
- EXPECT_EQ(prefetch_headers["Accept"],
- "application/signed-exchange;v=b2;q=0.9,*/*;q=0.8");
- else
- EXPECT_EQ(prefetch_headers["Accept"], "*/*");
// Test after this point requires SignedHTTPExchange support
if (!base::FeatureList::IsEnabled(features::kSignedHTTPExchange))
diff --git a/chromium/content/browser/loader/prefetch_url_loader.cc b/chromium/content/browser/loader/prefetch_url_loader.cc
index bbfd85fcc3c..63f58daf2ca 100644
--- a/chromium/content/browser/loader/prefetch_url_loader.cc
+++ b/chromium/content/browser/loader/prefetch_url_loader.cc
@@ -6,14 +6,23 @@
#include "base/feature_list.h"
#include "content/browser/web_package/signed_exchange_prefetch_handler.h"
+#include "content/browser/web_package/signed_exchange_prefetch_metric_recorder.h"
#include "content/browser/web_package/signed_exchange_utils.h"
#include "content/public/common/content_features.h"
#include "net/url_request/url_request_context_getter.h"
+#include "services/network/loader_util.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace content {
+namespace {
+
+constexpr char kSignedExchangeEnabledAcceptHeaderForPrefetch[] =
+ "application/signed-exchange;v=b2;q=0.9,*/*;q=0.8";
+
+} // namespace
+
PrefetchURLLoader::PrefetchURLLoader(
int32_t routing_id,
int32_t request_id,
@@ -25,7 +34,9 @@ PrefetchURLLoader::PrefetchURLLoader(
scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory,
URLLoaderThrottlesGetter url_loader_throttles_getter,
ResourceContext* resource_context,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter)
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder>
+ signed_exchange_prefetch_metric_recorder)
: frame_tree_node_id_getter_(frame_tree_node_id_getter),
url_(resource_request.url),
report_raw_headers_(resource_request.report_raw_headers),
@@ -36,19 +47,32 @@ PrefetchURLLoader::PrefetchURLLoader(
forwarding_client_(std::move(client)),
url_loader_throttles_getter_(url_loader_throttles_getter),
resource_context_(resource_context),
- request_context_getter_(std::move(request_context_getter)) {
+ request_context_getter_(std::move(request_context_getter)),
+ signed_exchange_prefetch_metric_recorder_(
+ std::move(signed_exchange_prefetch_metric_recorder)) {
DCHECK(network_loader_factory_);
if (resource_request.request_initiator)
request_initiator_ = *resource_request.request_initiator;
+ base::Optional<network::ResourceRequest> modified_resource_request;
+ if (signed_exchange_utils::ShouldAdvertiseAcceptHeader(
+ url::Origin::Create(resource_request.url))) {
+ // Set the SignedExchange accept header only for the limited origins.
+ // (https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#internet-media-type-applicationsigned-exchange).
+ modified_resource_request = resource_request;
+ modified_resource_request->headers.SetHeader(
+ network::kAcceptHeader, kSignedExchangeEnabledAcceptHeaderForPrefetch);
+ }
+
network::mojom::URLLoaderClientPtr network_client;
client_binding_.Bind(mojo::MakeRequest(&network_client));
client_binding_.set_connection_error_handler(base::BindOnce(
&PrefetchURLLoader::OnNetworkConnectionError, base::Unretained(this)));
network_loader_factory_->CreateLoaderAndStart(
mojo::MakeRequest(&loader_), routing_id, request_id, options,
- resource_request, std::move(network_client), traffic_annotation);
+ modified_resource_request ? *modified_resource_request : resource_request,
+ std::move(network_client), traffic_annotation);
}
PrefetchURLLoader::~PrefetchURLLoader() = default;
@@ -60,6 +84,7 @@ void PrefetchURLLoader::FollowRedirect(
DCHECK(!modified_request_headers.has_value()) << "Redirect with modified "
"headers was not supported "
"yet. crbug.com/845683";
+ DCHECK(new_url_for_redirect_.is_valid());
if (signed_exchange_prefetch_handler_) {
// Rebind |client_binding_| and |loader_|.
client_binding_.Bind(signed_exchange_prefetch_handler_->FollowRedirect(
@@ -67,6 +92,25 @@ void PrefetchURLLoader::FollowRedirect(
return;
}
+ if (signed_exchange_utils::NeedToCheckRedirectedURLForAcceptHeader()) {
+ // Currently we send the SignedExchange accept header only for the limited
+ // origins when SignedHTTPExchangeOriginTrial feature is enabled without
+ // SignedHTTPExchange feature. So need to update the accept header by
+ // checking the new URL when redirected.
+ net::HttpRequestHeaders modified_request_headers_for_accept;
+ if (signed_exchange_utils::ShouldAdvertiseAcceptHeader(
+ url::Origin::Create(new_url_for_redirect_))) {
+ modified_request_headers_for_accept.SetHeader(
+ network::kAcceptHeader,
+ kSignedExchangeEnabledAcceptHeaderForPrefetch);
+ } else {
+ modified_request_headers_for_accept.SetHeader(
+ network::kAcceptHeader, network::kDefaultAcceptHeader);
+ }
+ loader_->FollowRedirect(base::nullopt, modified_request_headers_for_accept);
+ return;
+ }
+
loader_->FollowRedirect(base::nullopt, base::nullopt);
}
@@ -100,7 +144,8 @@ void PrefetchURLLoader::OnReceiveResponse(
throttling_profile_id_, response, std::move(loader_),
client_binding_.Unbind(), network_loader_factory_,
request_initiator_, url_, url_loader_throttles_getter_,
- resource_context_, request_context_getter_, this);
+ resource_context_, request_context_getter_, this,
+ signed_exchange_prefetch_metric_recorder_);
return;
}
forwarding_client_->OnReceiveResponse(response);
@@ -109,6 +154,7 @@ void PrefetchURLLoader::OnReceiveResponse(
void PrefetchURLLoader::OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& head) {
+ new_url_for_redirect_ = redirect_info.new_url;
forwarding_client_->OnReceiveRedirect(redirect_info, head);
}
diff --git a/chromium/content/browser/loader/prefetch_url_loader.h b/chromium/content/browser/loader/prefetch_url_loader.h
index ef4ff33677d..7fc4bcb594c 100644
--- a/chromium/content/browser/loader/prefetch_url_loader.h
+++ b/chromium/content/browser/loader/prefetch_url_loader.h
@@ -31,6 +31,7 @@ namespace content {
class ResourceContext;
class URLLoaderThrottle;
class SignedExchangePrefetchHandler;
+class SignedExchangePrefetchMetricRecorder;
// PrefetchURLLoader which basically just keeps draining the data.
class CONTENT_EXPORT PrefetchURLLoader : public network::mojom::URLLoader,
@@ -57,7 +58,9 @@ class CONTENT_EXPORT PrefetchURLLoader : public network::mojom::URLLoader,
scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory,
URLLoaderThrottlesGetter url_loader_throttles_getter,
ResourceContext* resource_context,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter);
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder>
+ signed_exchange_prefetch_metric_recorder);
~PrefetchURLLoader() override;
private:
@@ -120,6 +123,11 @@ class CONTENT_EXPORT PrefetchURLLoader : public network::mojom::URLLoader,
std::unique_ptr<SignedExchangePrefetchHandler>
signed_exchange_prefetch_handler_;
+ GURL new_url_for_redirect_;
+
+ scoped_refptr<SignedExchangePrefetchMetricRecorder>
+ signed_exchange_prefetch_metric_recorder_;
+
DISALLOW_COPY_AND_ASSIGN(PrefetchURLLoader);
};
diff --git a/chromium/content/browser/loader/prefetch_url_loader_service.cc b/chromium/content/browser/loader/prefetch_url_loader_service.cc
index b7baa69c5cf..497ee220309 100644
--- a/chromium/content/browser/loader/prefetch_url_loader_service.cc
+++ b/chromium/content/browser/loader/prefetch_url_loader_service.cc
@@ -17,12 +17,13 @@
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "third_party/blink/public/common/features.h"
namespace content {
struct PrefetchURLLoaderService::BindContext {
BindContext(int frame_tree_node_id,
- scoped_refptr<URLLoaderFactoryBundle> factory)
+ scoped_refptr<network::SharedURLLoaderFactory> factory)
: frame_tree_node_id(frame_tree_node_id), factory(factory) {}
explicit BindContext(const std::unique_ptr<BindContext>& other)
@@ -32,10 +33,12 @@ struct PrefetchURLLoaderService::BindContext {
~BindContext() = default;
const int frame_tree_node_id;
- scoped_refptr<URLLoaderFactoryBundle> factory;
+ scoped_refptr<network::SharedURLLoaderFactory> factory;
};
-PrefetchURLLoaderService::PrefetchURLLoaderService() = default;
+PrefetchURLLoaderService::PrefetchURLLoaderService()
+ : signed_exchange_prefetch_metric_recorder_(
+ base::MakeRefCounted<SignedExchangePrefetchMetricRecorder>()) {}
void PrefetchURLLoaderService::InitializeResourceContext(
ResourceContext* resource_context,
@@ -50,10 +53,10 @@ void PrefetchURLLoaderService::InitializeResourceContext(
void PrefetchURLLoaderService::GetFactory(
network::mojom::URLLoaderFactoryRequest request,
int frame_tree_node_id,
- std::unique_ptr<URLLoaderFactoryBundleInfo> factories) {
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo> factories) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
auto factory_bundle =
- base::MakeRefCounted<URLLoaderFactoryBundle>(std::move(factories));
+ network::SharedURLLoaderFactory::Create(std::move(factories));
loader_factory_bindings_.AddBinding(
this, std::move(request),
std::make_unique<BindContext>(frame_tree_node_id, factory_bundle));
@@ -88,7 +91,8 @@ void PrefetchURLLoaderService::CreateLoaderAndStart(
base::BindRepeating(
&PrefetchURLLoaderService::CreateURLLoaderThrottles, this,
resource_request, frame_tree_node_id_getter),
- resource_context_, request_context_getter_),
+ resource_context_, request_context_getter_,
+ signed_exchange_prefetch_metric_recorder_),
std::move(request));
}
@@ -103,7 +107,9 @@ void PrefetchURLLoaderService::CreateLoaderAndStart(
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
+ DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService) ||
+ base::FeatureList::IsEnabled(
+ blink::features::kServiceWorkerServicification));
const auto& dispatch_context = *loader_factory_bindings_.dispatch_context();
int frame_tree_node_id = dispatch_context.frame_tree_node_id;
CreateLoaderAndStart(
diff --git a/chromium/content/browser/loader/prefetch_url_loader_service.h b/chromium/content/browser/loader/prefetch_url_loader_service.h
index 69c241394f2..2fafbffa238 100644
--- a/chromium/content/browser/loader/prefetch_url_loader_service.h
+++ b/chromium/content/browser/loader/prefetch_url_loader_service.h
@@ -8,6 +8,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "content/browser/web_package/signed_exchange_prefetch_metric_recorder.h"
#include "content/common/content_export.h"
#include "content/common/url_loader_factory_bundle.h"
#include "content/public/browser/browser_thread.h"
@@ -20,7 +21,6 @@ class URLRequestContextGetter;
namespace network {
class SharedURLLoaderFactory;
-class URLLoaderFactoryBundleInfo;
}
namespace content {
@@ -42,9 +42,10 @@ class CONTENT_EXPORT PrefetchURLLoaderService final
ResourceContext* resource_context,
scoped_refptr<net::URLRequestContextGetter> request_context_getter);
- void GetFactory(network::mojom::URLLoaderFactoryRequest request,
- int frame_tree_node_id,
- std::unique_ptr<URLLoaderFactoryBundleInfo> factory_info);
+ void GetFactory(
+ network::mojom::URLLoaderFactoryRequest request,
+ int frame_tree_node_id,
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo> factory_info);
// Used only when NetworkService is not enabled (or indirectly via the
// other CreateLoaderAndStart when NetworkService is enabled).
@@ -70,6 +71,11 @@ class CONTENT_EXPORT PrefetchURLLoaderService final
prefetch_load_callback_for_testing_ = prefetch_load_callback;
}
+ scoped_refptr<SignedExchangePrefetchMetricRecorder>
+ signed_exchange_prefetch_metric_recorder() {
+ return signed_exchange_prefetch_metric_recorder_;
+ }
+
private:
friend class base::DeleteHelper<content::PrefetchURLLoaderService>;
friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
@@ -104,6 +110,9 @@ class CONTENT_EXPORT PrefetchURLLoaderService final
base::RepeatingClosure prefetch_load_callback_for_testing_;
+ scoped_refptr<SignedExchangePrefetchMetricRecorder>
+ signed_exchange_prefetch_metric_recorder_;
+
DISALLOW_COPY_AND_ASSIGN(PrefetchURLLoaderService);
};
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
index 2ed617dbab8..8f33f39eb1d 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -373,8 +373,7 @@ void ResourceDispatcherHostImpl::CancelRequestsForContext(
typedef std::vector<std::unique_ptr<ResourceLoader>> LoaderList;
LoaderList loaders_to_cancel;
- for (LoaderMap::iterator i = pending_loaders_.begin();
- i != pending_loaders_.end();) {
+ for (auto i = pending_loaders_.begin(); i != pending_loaders_.end();) {
ResourceLoader* loader = i->second.get();
if (loader->GetRequestInfo()->GetContext() == context) {
loaders_to_cancel.push_back(std::move(i->second));
@@ -389,7 +388,7 @@ void ResourceDispatcherHostImpl::CancelRequestsForContext(
}
}
- for (BlockedLoadersMap::iterator i = blocked_loaders_map_.begin();
+ for (auto i = blocked_loaders_map_.begin();
i != blocked_loaders_map_.end();) {
BlockedLoadersList* loaders = i->second.get();
if (loaders->empty()) {
@@ -771,8 +770,7 @@ void ResourceDispatcherHostImpl::BeginRequest(
// the request needs to be aborted or continued.
for (net::HttpRequestHeaders::Iterator it(request_data.headers);
it.GetNext();) {
- HeaderInterceptorMap::iterator index =
- http_header_interceptor_map_.find(it.name());
+ auto index = http_header_interceptor_map_.find(it.name());
if (index != http_header_interceptor_map_.end()) {
HeaderInterceptorInfo& interceptor_info = index->second;
@@ -896,6 +894,11 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
new_request->set_referrer_policy(request_data.referrer_policy);
new_request->SetExtraRequestHeaders(headers);
+ if (!request_data.requested_with.empty()) {
+ // X-Requested-With header must be set here to avoid breaking CORS checks.
+ new_request->SetExtraRequestHeaderByName("X-Requested-With",
+ request_data.requested_with, true);
+ }
std::unique_ptr<network::ScopedThrottlingToken> throttling_token =
network::ScopedThrottlingToken::MaybeCreate(
@@ -984,6 +987,8 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
-1, // frame_tree_node_id
request_data.plugin_child_id, request_id, request_data.render_frame_id,
request_data.is_main_frame,
+ request_data.fetch_window_id ? *request_data.fetch_window_id
+ : base::UnguessableToken(),
static_cast<ResourceType>(request_data.resource_type),
static_cast<ui::PageTransition>(request_data.transition_type),
false, // is download
@@ -1019,7 +1024,8 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
request_data.fetch_credentials_mode, request_data.fetch_redirect_mode,
request_data.fetch_integrity, request_data.keepalive,
static_cast<ResourceType>(request_data.resource_type),
- static_cast<RequestContextType>(request_data.fetch_request_context_type),
+ static_cast<blink::mojom::RequestContextType>(
+ request_data.fetch_request_context_type),
request_data.fetch_frame_type, request_data.request_body);
// Have the appcache associate its extra info with the request.
@@ -1038,7 +1044,8 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
RecordFetchRequestMode(request_data.url, request_data.method,
request_data.fetch_request_mode);
const bool is_initiated_by_fetch_api =
- request_data.fetch_request_context_type == REQUEST_CONTEXT_TYPE_FETCH;
+ request_data.fetch_request_context_type ==
+ static_cast<int>(blink::mojom::RequestContextType::FETCH);
BeginRequestInternal(std::move(new_request), std::move(handler),
is_initiated_by_fetch_api,
std::move(throttling_token));
@@ -1078,7 +1085,8 @@ ResourceDispatcherHostImpl::CreateResourceHandler(
return AddStandardHandlers(
request, static_cast<ResourceType>(request_data.resource_type),
resource_context, request_data.fetch_request_mode,
- static_cast<RequestContextType>(request_data.fetch_request_context_type),
+ static_cast<blink::mojom::RequestContextType>(
+ request_data.fetch_request_context_type),
url_loader_options, requester_info->appcache_service(), child_id,
route_id, std::move(handler));
}
@@ -1089,7 +1097,7 @@ ResourceDispatcherHostImpl::AddStandardHandlers(
ResourceType resource_type,
ResourceContext* resource_context,
network::mojom::FetchRequestMode fetch_request_mode,
- RequestContextType fetch_request_context_type,
+ blink::mojom::RequestContextType fetch_request_context_type,
uint32_t url_loader_options,
AppCacheService* appcache_service,
int child_id,
@@ -1186,6 +1194,7 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
ChildProcessHost::kInvalidUniqueID, // plugin_child_id
MakeRequestID(), render_frame_route_id,
false, // is_main_frame
+ {}, // fetch_window_id
RESOURCE_TYPE_SUB_RESOURCE, ui::PAGE_TRANSITION_LINK,
download, // is_download
false, // is_stream
@@ -1206,24 +1215,38 @@ ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
false); // initiated_in_secure_context
}
+// static
void ResourceDispatcherHostImpl::OnRenderViewHostCreated(
int child_id,
int route_id,
net::URLRequestContextGetter* url_request_context_getter) {
- scheduler_->OnClientCreated(child_id, route_id,
- url_request_context_getter->GetURLRequestContext()
- ->network_quality_estimator());
+ auto* host = ResourceDispatcherHostImpl::Get();
+ if (host && host->scheduler_) {
+ host->scheduler_->OnClientCreated(
+ child_id, route_id,
+ url_request_context_getter->GetURLRequestContext()
+ ->network_quality_estimator());
+ }
}
+// static
void ResourceDispatcherHostImpl::OnRenderViewHostDeleted(int child_id,
int route_id) {
- scheduler_->OnClientDeleted(child_id, route_id);
+ auto* host = ResourceDispatcherHostImpl::Get();
+ if (host && host->scheduler_) {
+ host->scheduler_->OnClientDeleted(child_id, route_id);
+ }
}
+// static
void ResourceDispatcherHostImpl::OnRenderViewHostSetIsLoading(int child_id,
int route_id,
bool is_loading) {
- scheduler_->DeprecatedOnLoadingStateChanged(child_id, route_id, !is_loading);
+ auto* host = ResourceDispatcherHostImpl::Get();
+ if (host && host->scheduler_) {
+ host->scheduler_->DeprecatedOnLoadingStateChanged(child_id, route_id,
+ !is_loading);
+ }
}
// The object died, so cancel and detach all requests associated with it except
@@ -1273,7 +1296,7 @@ void ResourceDispatcherHostImpl::CancelRequestsForRoute(
// Remove matches.
for (size_t i = 0; i < matching_requests.size(); ++i) {
- LoaderMap::iterator iter = pending_loaders_.find(matching_requests[i]);
+ auto iter = pending_loaders_.find(matching_requests[i]);
// Although every matching request was in pending_requests_ when we built
// matching_requests, it is normal for a matching request to be not found
// in pending_requests_ after we have removed some matching requests from
@@ -1312,8 +1335,7 @@ void ResourceDispatcherHostImpl::CancelRequestsForRoute(
// Cancels the request and removes it from the list.
void ResourceDispatcherHostImpl::RemovePendingRequest(int child_id,
int request_id) {
- LoaderMap::iterator i = pending_loaders_.find(
- GlobalRequestID(child_id, request_id));
+ auto i = pending_loaders_.find(GlobalRequestID(child_id, request_id));
if (i == pending_loaders_.end()) {
NOTREACHED() << "Trying to remove a request that's not here";
return;
@@ -1352,8 +1374,7 @@ void ResourceDispatcherHostImpl::CancelRequest(int child_id,
ResourceDispatcherHostImpl::OustandingRequestsStats
ResourceDispatcherHostImpl::GetOutstandingRequestsStats(
const ResourceRequestInfoImpl& info) {
- OutstandingRequestsStatsMap::iterator entry =
- outstanding_requests_stats_map_.find(info.GetChildID());
+ auto entry = outstanding_requests_stats_map_.find(info.GetChildID());
OustandingRequestsStats stats = { 0, 0 };
if (entry != outstanding_requests_stats_map_.end())
stats = entry->second;
@@ -1502,10 +1523,8 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
headers.AddHeadersFromString(info.begin_params->headers);
std::string accept_value = network::kFrameAcceptHeader;
- // TODO(https://crbug.com/840704): Decide whether the Accept header should
- // advertise the state of kSignedHTTPExchangeOriginTrial before starting the
- // Origin-Trial.
- if (signed_exchange_utils::IsSignedExchangeHandlingEnabled()) {
+ if (signed_exchange_utils::ShouldAdvertiseAcceptHeader(
+ url::Origin::Create(info.common_params.url))) {
DCHECK(!accept_value.empty());
accept_value.append(kAcceptHeaderSignedExchangeSuffix);
}
@@ -1552,8 +1571,9 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
info.frame_tree_node_id,
ChildProcessHost::kInvalidUniqueID, // plugin_child_id
global_request_id.request_id,
- -1, // request_data.render_frame_id,
- info.is_main_frame, resource_type, info.common_params.transition,
+ -1, // request_data.render_frame_id,
+ info.is_main_frame, {}, // fetch_window_id
+ resource_type, info.common_params.transition,
false, // is download
false, // is stream
info.common_params.allow_download, info.common_params.has_user_gesture,
@@ -2047,8 +2067,7 @@ void ResourceDispatcherHostImpl::CancelBlockedRequestsForRoute(
void ResourceDispatcherHostImpl::ProcessBlockedRequestsForRoute(
const GlobalFrameRoutingId& global_routing_id,
bool cancel_requests) {
- BlockedLoadersMap::iterator iter =
- blocked_loaders_map_.find(global_routing_id);
+ auto iter = blocked_loaders_map_.find(global_routing_id);
if (iter == blocked_loaders_map_.end()) {
// It's possible to reach here if the renderer crashed while an interstitial
// page was showing.
@@ -2104,7 +2123,7 @@ ResourceLoader* ResourceDispatcherHostImpl::GetLoader(
const GlobalRequestID& id) const {
DCHECK(io_thread_task_runner_->BelongsToCurrentThread());
- LoaderMap::const_iterator i = pending_loaders_.find(id);
+ auto i = pending_loaders_.find(id);
if (i == pending_loaders_.end())
return nullptr;
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_impl.h b/chromium/content/browser/loader/resource_dispatcher_host_impl.h
index ec89329e361..7e03c2b4bef 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/chromium/content/browser/loader/resource_dispatcher_host_impl.h
@@ -37,13 +37,13 @@
#include "content/public/browser/resource_request_info.h"
#include "content/public/browser/stream_handle.h"
#include "content/public/common/previews_state.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "net/base/load_states.h"
#include "net/base/request_priority.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/keepalive_statistics_recorder.h"
#include "services/network/public/mojom/url_loader.mojom.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "url/gurl.h"
namespace base {
@@ -146,18 +146,18 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
static const int kAvgBytesPerOutstandingRequest = 4400;
// Called when a RenderViewHost is created.
- void OnRenderViewHostCreated(
+ static void OnRenderViewHostCreated(
int child_id,
int route_id,
net::URLRequestContextGetter* url_request_context_getter);
// Called when a RenderViewHost is deleted.
- void OnRenderViewHostDeleted(int child_id, int route_id);
+ static void OnRenderViewHostDeleted(int child_id, int route_id);
// Called when a RenderViewHost starts or stops loading.
- void OnRenderViewHostSetIsLoading(int child_id,
- int route_id,
- bool is_loading);
+ static void OnRenderViewHostSetIsLoading(int child_id,
+ int route_id,
+ bool is_loading);
// Force cancels any pending requests for the given process.
void CancelRequestsForProcess(int child_id);
@@ -596,7 +596,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
ResourceType resource_type,
ResourceContext* resource_context,
network::mojom::FetchRequestMode fetch_request_mode,
- RequestContextType fetch_request_context_type,
+ blink::mojom::RequestContextType fetch_request_context_type,
uint32_t url_loader_options,
AppCacheService* appcache_service,
int child_id,
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc b/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
index 38053a77162..eeaff0cc5a2 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -36,6 +36,7 @@
#include "content/common/appcache_interfaces.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/navigation_params.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/render_frame_host.h"
@@ -77,12 +78,14 @@
#include "net/url_request/url_request_simple_job.h"
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
+#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/resource_scheduler.h"
#include "services/network/resource_scheduler_params_manager.h"
#include "services/network/test/test_url_loader_client.h"
#include "storage/browser/blob/shareable_file_reference.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
// TODO(eroman): Write unit tests for SafeBrowsing that exercise
@@ -118,8 +121,7 @@ static network::ResourceRequest CreateResourceRequest(const char* method,
// This is used to create a filter matching a specified child id.
class TestFilterSpecifyingChild : public ResourceMessageFilter {
public:
- explicit TestFilterSpecifyingChild(ResourceContext* resource_context,
- int process_id)
+ TestFilterSpecifyingChild(BrowserContext* browser_context, int process_id)
: ResourceMessageFilter(
process_id,
nullptr,
@@ -127,10 +129,11 @@ class TestFilterSpecifyingChild : public ResourceMessageFilter {
nullptr,
nullptr,
nullptr,
+ BrowserContext::GetSharedCorsOriginAccessList(browser_context),
base::Bind(&TestFilterSpecifyingChild::GetContexts,
base::Unretained(this)),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)),
- resource_context_(resource_context) {
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})),
+ resource_context_(browser_context->GetResourceContext()) {
InitializeForTest();
set_peer_process_for_testing(base::Process::Current());
}
@@ -161,9 +164,9 @@ class TestFilterSpecifyingChild : public ResourceMessageFilter {
class TestFilter : public TestFilterSpecifyingChild {
public:
- explicit TestFilter(ResourceContext* resource_context)
+ explicit TestFilter(BrowserContext* browser_context)
: TestFilterSpecifyingChild(
- resource_context,
+ browser_context,
ChildProcessHostImpl::GenerateChildProcessUniqueId()) {
ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
}
@@ -630,7 +633,12 @@ class ShareableFileReleaseWaiter {
DISALLOW_COPY_AND_ASSIGN(ShareableFileReleaseWaiter);
};
-class ResourceDispatcherHostTest : public testing::Test {
+enum class TestMode {
+ kWithoutOutOfBlinkCors,
+ kWithOutOfBlinkCors,
+};
+
+class ResourceDispatcherHostTest : public testing::TestWithParam<TestMode> {
public:
typedef ResourceDispatcherHostImpl::LoadInfo LoadInfo;
typedef ResourceDispatcherHostImpl::LoadInfoList LoadInfoList;
@@ -644,6 +652,23 @@ class ResourceDispatcherHostTest : public testing::Test {
use_test_ssl_certificate_(false),
send_data_received_acks_(false),
auto_advance_(false) {
+ switch (GetParam()) {
+ case TestMode::kWithoutOutOfBlinkCors:
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled features
+ {},
+ // Disabled features
+ {network::features::kOutOfBlinkCORS});
+ break;
+ case TestMode::kWithOutOfBlinkCors:
+ scoped_feature_list_.InitWithFeatures(
+ // Enabled features
+ {network::features::kOutOfBlinkCORS,
+ blink::features::kServiceWorkerServicification},
+ // Disabled features
+ {});
+ break;
+ }
host_.SetLoaderDelegate(&loader_delegate_);
browser_context_.reset(new TestBrowserContext());
BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
@@ -676,12 +701,12 @@ class ResourceDispatcherHostTest : public testing::Test {
web_contents_ =
WebContents::Create(WebContents::CreateParams(browser_context_.get()));
web_contents_filter_ = new TestFilterSpecifyingChild(
- browser_context_->GetResourceContext(),
+ browser_context_.get(),
web_contents_->GetMainFrame()->GetProcess()->GetID());
child_ids_.insert(web_contents_->GetMainFrame()->GetProcess()->GetID());
request_context_getter_ = new net::TestURLRequestContextGetter(
- content::BrowserThread::GetTaskRunnerForThread(
- content::BrowserThread::UI));
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {content::BrowserThread::UI}));
}
void TearDown() override {
@@ -691,8 +716,7 @@ class ResourceDispatcherHostTest : public testing::Test {
EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
URLRequestTestDelayedStartJob::ClearQueue();
- for (std::set<int>::iterator it = child_ids_.begin();
- it != child_ids_.end(); ++it) {
+ for (auto it = child_ids_.begin(); it != child_ids_.end(); ++it) {
host_.CancelRequestsForProcess(*it);
}
@@ -712,8 +736,7 @@ class ResourceDispatcherHostTest : public testing::Test {
// Creates a new TestFilter and registers it with |child_ids_| so as not
// to leak per-child state on test shutdown.
scoped_refptr<TestFilter> MakeTestFilter() {
- auto filter = base::MakeRefCounted<TestFilter>(
- browser_context_->GetResourceContext());
+ auto filter = base::MakeRefCounted<TestFilter>(browser_context_.get());
child_ids_.insert(filter->child_id());
return filter;
}
@@ -809,7 +832,8 @@ class ResourceDispatcherHostTest : public testing::Test {
mojom::BeginNavigationParamsPtr begin_params =
mojom::BeginNavigationParams::New(
std::string() /* headers */, net::LOAD_NORMAL,
- false /* skip_service_worker */, REQUEST_CONTEXT_TYPE_LOCATION,
+ false /* skip_service_worker */,
+ blink::mojom::RequestContextType::LOCATION,
blink::WebMixedContentContextType::kBlockable,
false /* is_form_submission */, GURL() /* searchable_form_url */,
std::string() /* searchable_form_encoding */,
@@ -842,6 +866,15 @@ class ResourceDispatcherHostTest : public testing::Test {
request_info->detachable_handler()->is_detached();
}
+ bool IsAborted(const network::TestURLLoaderClient& client) {
+ // TODO(toyoshim): Once NetworkService or OutOfBlinkCORS is enabled, these
+ // expectations below should be receiving a completion with ERR_ABORTED.
+ if (!client.has_received_completion())
+ return client.has_received_connection_error();
+
+ return client.completion_status().error_code == net::ERR_ABORTED;
+ }
+
void SetMaxDelayableRequests(size_t max_delayable_requests) {
network::ResourceSchedulerParamsManager::ParamsForNetworkQualityContainer c;
for (int i = 0; i != net::EFFECTIVE_CONNECTION_TYPE_LAST; ++i) {
@@ -874,6 +907,7 @@ class ResourceDispatcherHostTest : public testing::Test {
RenderViewHostTestEnabler render_view_host_test_enabler_;
bool auto_advance_;
scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
+ base::test::ScopedFeatureList scoped_feature_list_;
};
void ResourceDispatcherHostTest::MakeTestRequest(
@@ -988,7 +1022,7 @@ void CheckSuccessfulRequest(network::TestURLLoaderClient* client,
// Tests whether messages get canceled properly. We issue four requests,
// cancel two of them, and make sure that each sent the proper notifications.
-TEST_F(ResourceDispatcherHostTest, Cancel) {
+TEST_P(ResourceDispatcherHostTest, Cancel) {
network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4;
network::TestURLLoaderClient client1, client2, client3, client4;
MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1(),
@@ -1038,7 +1072,7 @@ TEST_F(ResourceDispatcherHostTest, Cancel) {
// Shows that detachable requests will timeout if the request takes too long to
// complete.
-TEST_F(ResourceDispatcherHostTest, DetachedResourceTimesOut) {
+TEST_P(ResourceDispatcherHostTest, DetachedResourceTimesOut) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
MakeTestRequestWithResourceType(
@@ -1058,6 +1092,7 @@ TEST_F(ResourceDispatcherHostTest, DetachedResourceTimesOut) {
loader = nullptr;
// From the renderer's perspective, the request was cancelled.
+ content::RunAllTasksUntilIdle();
client.RunUntilComplete();
EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code);
@@ -1082,7 +1117,7 @@ TEST_F(ResourceDispatcherHostTest, DetachedResourceTimesOut) {
// If the filter has disappeared then detachable resources should continue to
// load.
-TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) {
+TEST_P(ResourceDispatcherHostTest, DeletedFilterDetached) {
network::mojom::URLLoaderPtr loader1;
network::TestURLLoaderClient client1;
base::test::ScopedFeatureList feature_list;
@@ -1102,8 +1137,8 @@ TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) {
DCHECK_EQ(filter_.get(), info_prefetch->requester_info()->filter());
filter_->OnChannelClosing();
- client1.RunUntilComplete();
- EXPECT_EQ(net::ERR_ABORTED, client1.completion_status().error_code);
+ content::RunAllTasksUntilIdle();
+ DCHECK(IsAborted(client1));
// But it continues detached.
EXPECT_EQ(1, host_.pending_requests());
@@ -1123,7 +1158,7 @@ TEST_F(ResourceDispatcherHostTest, DeletedFilterDetached) {
// If the filter has disappeared (original process dies) then detachable
// resources should continue to load, even when redirected.
-TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
+TEST_P(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
network::ResourceRequest request = CreateResourceRequest(
@@ -1151,8 +1186,8 @@ TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
EXPECT_EQ(1u, url_request->url_chain().size());
// From the renderer's perspective, the request was cancelled.
- client.RunUntilComplete();
- EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code);
+ content::RunAllTasksUntilIdle();
+ DCHECK(IsAborted(client));
content::RunAllTasksUntilIdle();
// Verify that a redirect was followed.
@@ -1171,7 +1206,7 @@ TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachedRedirect) {
EXPECT_EQ(0, network_delegate()->error_count());
}
-TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
+TEST_P(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
bool was_deleted = false;
@@ -1199,7 +1234,7 @@ TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
EXPECT_TRUE(was_deleted);
}
-TEST_F(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) {
+TEST_P(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
bool was_deleted = false;
@@ -1244,7 +1279,7 @@ TEST_F(ResourceDispatcherHostTest, DetachWhileStartIsDeferred) {
// Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
// URLRequest will not be started.
-TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
+TEST_P(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
TestResourceDispatcherHostDelegate delegate;
@@ -1266,7 +1301,7 @@ TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
EXPECT_EQ(0, job_factory_->url_request_jobs_created_count());
}
-TEST_F(ResourceDispatcherHostTest, PausedStartError) {
+TEST_P(ResourceDispatcherHostTest, PausedStartError) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
// Arrange to have requests deferred before processing response headers.
@@ -1286,7 +1321,7 @@ TEST_F(ResourceDispatcherHostTest, PausedStartError) {
EXPECT_EQ(0, host_.pending_requests());
}
-TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
+TEST_P(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
// Arrange to have requests deferred before starting.
@@ -1323,7 +1358,7 @@ TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
}
// Tests that the delegate can cancel a request and provide a error code.
-TEST_F(ResourceDispatcherHostTest, CancelInDelegate) {
+TEST_P(ResourceDispatcherHostTest, CancelInDelegate) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
TestResourceDispatcherHostDelegate delegate;
@@ -1343,7 +1378,7 @@ TEST_F(ResourceDispatcherHostTest, CancelInDelegate) {
EXPECT_EQ(net::ERR_ACCESS_DENIED, client.completion_status().error_code);
}
-TEST_F(ResourceDispatcherHostTest, CancelRequestsForRoute) {
+TEST_P(ResourceDispatcherHostTest, CancelRequestsForRoute) {
network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4;
network::TestURLLoaderClient client1, client2, client3, client4;
base::test::ScopedFeatureList feature_list;
@@ -1397,7 +1432,7 @@ TEST_F(ResourceDispatcherHostTest, CancelRequestsForRoute) {
}
// Tests CancelRequestsForProcess
-TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
+TEST_P(ResourceDispatcherHostTest, TestProcessCancel) {
network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4;
network::TestURLLoaderClient client1, client2, client3, client4;
scoped_refptr<TestFilter> test_filter = MakeTestFilter();
@@ -1471,7 +1506,7 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
// Tests whether the correct requests get canceled when a RenderViewHost is
// deleted.
-TEST_F(ResourceDispatcherHostTest, CancelRequestsOnRenderFrameDeleted) {
+TEST_P(ResourceDispatcherHostTest, CancelRequestsOnRenderFrameDeleted) {
network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4, loader5;
network::TestURLLoaderClient client1, client2, client3, client4, client5;
// Requests all hang once started. This prevents requests from being
@@ -1529,7 +1564,7 @@ TEST_F(ResourceDispatcherHostTest, CancelRequestsOnRenderFrameDeleted) {
EXPECT_EQ(4, network_delegate_.canceled_requests());
}
-TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) {
+TEST_P(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
MakeTestRequestWithResourceType(
@@ -1575,7 +1610,7 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachedTimesOut) {
}
// Tests blocking and resuming requests.
-TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
+TEST_P(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4, loader5,
loader6, loader7;
network::TestURLLoaderClient client1, client2, client3, client4, client5,
@@ -1655,7 +1690,7 @@ TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
}
// Tests blocking and canceling requests.
-TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
+TEST_P(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4, loader5;
network::TestURLLoaderClient client1, client2, client3, client4, client5;
@@ -1689,9 +1724,9 @@ TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
CheckSuccessfulRequest(&client1, net::URLRequestTestJob::test_data_1());
CheckSuccessfulRequest(&client3, net::URLRequestTestJob::test_data_3());
- EXPECT_FALSE(client2.has_received_completion());
- EXPECT_FALSE(client4.has_received_completion());
- EXPECT_FALSE(client5.has_received_completion());
+ EXPECT_FALSE(IsAborted(client2));
+ EXPECT_FALSE(IsAborted(client4));
+ EXPECT_FALSE(IsAborted(client5));
// Cancel requests for RFH 11.
host_.CancelBlockedRequestsForRoute(
@@ -1699,13 +1734,13 @@ TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
content::RunAllTasksUntilIdle();
while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- EXPECT_FALSE(client2.has_received_completion());
- EXPECT_FALSE(client4.has_received_completion());
- EXPECT_FALSE(client5.has_received_completion());
+ EXPECT_TRUE(IsAborted(client2));
+ EXPECT_TRUE(IsAborted(client4));
+ EXPECT_TRUE(IsAborted(client5));
}
// Tests that blocked requests are canceled if their associated process dies.
-TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
+TEST_P(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4, loader5;
network::TestURLLoaderClient client1, client2, client3, client4, client5;
// This second filter is used to emulate a second process.
@@ -1744,9 +1779,9 @@ TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
CheckSuccessfulRequest(&client1, net::URLRequestTestJob::test_data_1());
CheckSuccessfulRequest(&client3, net::URLRequestTestJob::test_data_3());
- EXPECT_FALSE(client2.has_received_completion());
- EXPECT_FALSE(client4.has_received_completion());
- EXPECT_FALSE(client5.has_received_completion());
+ EXPECT_TRUE(IsAborted(client2));
+ EXPECT_TRUE(IsAborted(client4));
+ EXPECT_TRUE(IsAborted(client5));
EXPECT_TRUE(host_.blocked_loaders_map_.empty());
second_filter->OnChannelClosing();
@@ -1756,7 +1791,7 @@ TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
// away. Note that we rely on Purify for finding the leaks if any.
// If this test turns the Purify bot red, check the ResourceDispatcherHost
// destructor to make sure the blocked requests are deleted.
-TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
+TEST_P(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
network::mojom::URLLoaderPtr loader1, loader2, loader3, loader4, loader5,
loader6, loader7, loader8;
network::TestURLLoaderClient client1, client2, client3, client4, client5,
@@ -1813,7 +1848,7 @@ TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
}
// Test the private helper method "CalculateApproximateMemoryCost()".
-TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
+TEST_P(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
net::URLRequestContext context;
std::unique_ptr<net::URLRequest> req(context.CreateRequest(
GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr,
@@ -1843,7 +1878,7 @@ TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
// Test that too much memory for outstanding requests for a particular
// render_process_host_id causes requests to fail.
-TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
+TEST_P(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
// Expected cost of each request as measured by
// ResourceDispatcherHost::CalculateApproximateMemoryCost().
const int kMemoryCostOfTest2Req =
@@ -1927,7 +1962,7 @@ TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) {
// Test that when too many requests are outstanding for a particular
// render_process_host_id, any subsequent request from it fails. Also verify
// that the global limit is honored.
-TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
+TEST_P(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
// Tighten the bound on the ResourceDispatcherHost, to speed things up.
constexpr size_t kMaxRequestsPerProcess = 2;
host_.set_max_num_in_flight_requests_per_process(kMaxRequestsPerProcess);
@@ -1995,7 +2030,7 @@ TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
}
// Tests that we sniff the mime type for a simple request.
-TEST_F(ResourceDispatcherHostTest, MimeSniffed) {
+TEST_P(ResourceDispatcherHostTest, MimeSniffed) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
std::string raw_headers("HTTP/1.1 200 OK\n\n");
@@ -2016,7 +2051,7 @@ TEST_F(ResourceDispatcherHostTest, MimeSniffed) {
}
// Tests that we don't sniff the mime type when the server provides one.
-TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) {
+TEST_P(ResourceDispatcherHostTest, MimeNotSniffed) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
std::string raw_headers("HTTP/1.1 200 OK\n"
@@ -2038,7 +2073,7 @@ TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) {
}
// Tests that we don't sniff the mime type when there is no message body.
-TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) {
+TEST_P(ResourceDispatcherHostTest, MimeNotSniffed2) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
SetResponse("HTTP/1.1 304 Not Modified\n\n");
@@ -2055,7 +2090,7 @@ TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) {
EXPECT_EQ("", client.response_head().mime_type);
}
-TEST_F(ResourceDispatcherHostTest, MimeSniff204) {
+TEST_P(ResourceDispatcherHostTest, MimeSniff204) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
SetResponse("HTTP/1.1 204 No Content\n\n");
@@ -2072,7 +2107,7 @@ TEST_F(ResourceDispatcherHostTest, MimeSniff204) {
EXPECT_EQ("text/plain", client.response_head().mime_type);
}
-TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) {
+TEST_P(ResourceDispatcherHostTest, MimeSniffEmpty) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
SetResponse("HTTP/1.1 200 OK\n\n");
@@ -2090,7 +2125,7 @@ TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) {
}
// Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
-TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) {
+TEST_P(ResourceDispatcherHostTest, ForbiddenDownload) {
std::string raw_headers("HTTP/1.1 403 Forbidden\n"
"Content-disposition: attachment; filename=blah\n"
"Content-type: application/octet-stream\n\n");
@@ -2106,7 +2141,7 @@ TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) {
expected_error_code);
}
-TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextDetached) {
+TEST_P(ResourceDispatcherHostTest, CancelRequestsForContextDetached) {
EXPECT_EQ(0, host_.pending_requests());
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
@@ -2163,7 +2198,7 @@ class ExternalProtocolBrowserClient : public TestContentBrowserClient {
// Verifies that if the embedder says that it didn't handle an unkonown protocol
// the request is cancelled and net::ERR_ABORTED is returned. Otherwise it is
// not aborted and net/ layer cancels it with net::ERR_UNKNOWN_URL_SCHEME.
-TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
+TEST_P(ResourceDispatcherHostTest, UnknownURLScheme) {
EXPECT_EQ(0, host_.pending_requests());
HandleScheme("http");
@@ -2182,7 +2217,7 @@ TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
// Request a very large detachable resource and cancel part way. Some of the
// data should have been sent to the renderer, but not all.
-TEST_F(ResourceDispatcherHostTest, DataSentBeforeDetach) {
+TEST_P(ResourceDispatcherHostTest, DataSentBeforeDetach) {
EXPECT_EQ(0, host_.pending_requests());
constexpr int render_view_id = 0;
@@ -2231,7 +2266,7 @@ WebContents* WebContentsBinder(WebContents* rv) { return rv; }
// Tests GetLoadInfoForAllRoutes when there are 3 requests from the same
// RenderView. The second one is farthest along.
-TEST_F(ResourceDispatcherHostTest, LoadInfo) {
+TEST_P(ResourceDispatcherHostTest, LoadInfo) {
std::unique_ptr<LoadInfoList> infos(new LoadInfoList);
LoadInfo info;
WebContents* wc1 = reinterpret_cast<WebContents*>(0x1);
@@ -2264,7 +2299,7 @@ TEST_F(ResourceDispatcherHostTest, LoadInfo) {
// Tests GetLoadInfoForAllRoutes when there are 2 requests with the same
// priority. The first one (Which will have the lowest ID) should be returned.
-TEST_F(ResourceDispatcherHostTest, LoadInfoSamePriority) {
+TEST_P(ResourceDispatcherHostTest, LoadInfoSamePriority) {
std::unique_ptr<LoadInfoList> infos(new LoadInfoList);
LoadInfo info;
WebContents* wc1 = reinterpret_cast<WebContents*>(0x1);
@@ -2291,7 +2326,7 @@ TEST_F(ResourceDispatcherHostTest, LoadInfoSamePriority) {
}
// Tests GetLoadInfoForAllRoutes when a request is uploading a body.
-TEST_F(ResourceDispatcherHostTest, LoadInfoUploadProgress) {
+TEST_P(ResourceDispatcherHostTest, LoadInfoUploadProgress) {
std::unique_ptr<LoadInfoList> infos(new LoadInfoList);
LoadInfo info;
WebContents* wc1 = reinterpret_cast<WebContents*>(0x1);
@@ -2341,7 +2376,7 @@ TEST_F(ResourceDispatcherHostTest, LoadInfoUploadProgress) {
// Tests GetLoadInfoForAllRoutes when there are 4 requests from 2 different
// RenderViews. Also tests the case where the first / last requests are the
// most interesting ones.
-TEST_F(ResourceDispatcherHostTest, LoadInfoTwoRenderViews) {
+TEST_P(ResourceDispatcherHostTest, LoadInfoTwoRenderViews) {
std::unique_ptr<LoadInfoList> infos(new LoadInfoList);
LoadInfo info;
WebContents* wc1 = reinterpret_cast<WebContents*>(0x1);
@@ -2392,7 +2427,7 @@ TEST_F(ResourceDispatcherHostTest, LoadInfoTwoRenderViews) {
// Tests that a ResourceThrottle that needs to process the response before any
// part of the body is read can do so.
-TEST_F(ResourceDispatcherHostTest, ThrottleMustProcessResponseBeforeRead) {
+TEST_P(ResourceDispatcherHostTest, ThrottleMustProcessResponseBeforeRead) {
// Ensure all jobs will check that no read operation is called.
job_factory_->SetMustNotReadJobGeneration(true);
HandleScheme("http");
@@ -2508,4 +2543,12 @@ net::URLRequestJob* TestURLRequestJobFactory::MaybeInterceptResponse(
return nullptr;
}
+INSTANTIATE_TEST_CASE_P(WithoutOutOfBlinkCors,
+ ResourceDispatcherHostTest,
+ ::testing::Values(TestMode::kWithoutOutOfBlinkCors));
+
+INSTANTIATE_TEST_CASE_P(WithOutOfBlinkCors,
+ ResourceDispatcherHostTest,
+ ::testing::Values(TestMode::kWithOutOfBlinkCors));
+
} // namespace content
diff --git a/chromium/content/browser/loader/resource_hints_impl.cc b/chromium/content/browser/loader/resource_hints_impl.cc
deleted file mode 100644
index bdb06548a3a..00000000000
--- a/chromium/content/browser/loader/resource_hints_impl.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "base/memory/ref_counted.h"
-#include "base/trace_event/trace_event.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/resource_hints.h"
-#include "net/base/address_list.h"
-#include "net/base/load_flags.h"
-#include "net/http/http_network_session.h"
-#include "net/http/http_request_info.h"
-#include "net/http/http_stream_factory.h"
-#include "net/http/http_transaction_factory.h"
-#include "net/log/net_log_with_source.h"
-#include "net/url_request/http_user_agent_settings.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_context_getter.h"
-
-namespace content {
-
-namespace {
-
-void OnResolveComplete(std::unique_ptr<net::AddressList> addresses,
- const net::CompletionCallback& callback,
- int result) {
- // Plumb the resolution result into the callback if future consumers want
- // that information.
- callback.Run(result);
-}
-
-} // namespace
-
-void PreconnectUrl(net::URLRequestContextGetter* getter,
- const GURL& url,
- const GURL& site_for_cookies,
- int count,
- bool allow_credentials) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(getter);
- TRACE_EVENT2("net", "PreconnectUrl", "url", url.spec(), "count", count);
-
- net::URLRequestContext* request_context = getter->GetURLRequestContext();
- if (!request_context)
- return;
-
- net::HttpTransactionFactory* factory =
- request_context->http_transaction_factory();
- net::HttpNetworkSession* session = factory->GetSession();
-
- std::string user_agent;
- if (request_context->http_user_agent_settings())
- user_agent = request_context->http_user_agent_settings()->GetUserAgent();
- net::HttpRequestInfo request_info;
- request_info.url = url;
- request_info.method = "GET";
- request_info.extra_headers.SetHeader(net::HttpRequestHeaders::kUserAgent,
- user_agent);
-
- net::NetworkDelegate* delegate = request_context->network_delegate();
- // NetworkDelegate is not set in tests.
- if (!delegate)
- return;
- if (delegate->CanEnablePrivacyMode(url, site_for_cookies))
- request_info.privacy_mode = net::PRIVACY_MODE_ENABLED;
-
- // TODO(yoav): Fix this layering violation, since when credentials are not
- // allowed we should turn on a flag indicating that, rather then turn on
- // private mode, even if lower layers would treat both the same.
- if (!allow_credentials) {
- request_info.privacy_mode = net::PRIVACY_MODE_ENABLED;
- request_info.load_flags = net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DO_NOT_SEND_AUTH_DATA;
- }
-
- net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
- http_stream_factory->PreconnectStreams(count, request_info);
-}
-
-int PreresolveUrl(net::URLRequestContextGetter* getter,
- const GURL& url,
- const net::CompletionCallback& callback,
- std::unique_ptr<net::HostResolver::Request>* out_request) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(getter);
- TRACE_EVENT1("net", "PreresolveUrl", "url", url.spec());
-
- net::URLRequestContext* request_context = getter->GetURLRequestContext();
- if (!request_context)
- return net::ERR_CONTEXT_SHUT_DOWN;
-
- auto addresses = std::make_unique<net::AddressList>();
-
- // Save raw pointers before the unique_ptr is invalidated by base::Passed().
- net::AddressList* raw_addresses = addresses.get();
-
- net::HostResolver* resolver = request_context->host_resolver();
- net::HostResolver::RequestInfo resolve_info(net::HostPortPair::FromURL(url));
- resolve_info.set_is_speculative(true);
- return resolver->Resolve(
- resolve_info, net::IDLE, raw_addresses,
- base::BindOnce(&OnResolveComplete, std::move(addresses), callback),
- out_request, net::NetLogWithSource());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/loader/resource_message_filter.cc b/chromium/content/browser/loader/resource_message_filter.cc
index 2f531f5ae08..faed15d613f 100644
--- a/chromium/content/browser/loader/resource_message_filter.cc
+++ b/chromium/content/browser/loader/resource_message_filter.cc
@@ -18,6 +18,7 @@
#include "content/common/resource_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_context.h"
+#include "content/public/browser/shared_cors_origin_access_list.h"
#include "content/public/common/content_switches.h"
#include "services/network/cors/cors_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
@@ -44,6 +45,7 @@ ResourceMessageFilter::ResourceMessageFilter(
storage::FileSystemContext* file_system_context,
ServiceWorkerContextWrapper* service_worker_context,
PrefetchURLLoaderService* prefetch_url_loader_service,
+ const SharedCorsOriginAccessList* shared_cors_origin_access_list,
const GetContextsCallback& get_contexts_callback,
const scoped_refptr<base::SingleThreadTaskRunner>& io_thread_runner)
: BrowserMessageFilter(ResourceMsgStart),
@@ -57,6 +59,7 @@ ResourceMessageFilter::ResourceMessageFilter(
service_worker_context,
get_contexts_callback)),
prefetch_url_loader_service_(prefetch_url_loader_service),
+ shared_cors_origin_access_list_(shared_cors_origin_access_list),
io_thread_task_runner_(io_thread_runner),
weak_ptr_factory_(this) {}
@@ -184,7 +187,8 @@ void ResourceMessageFilter::InitializeOnIOThread() {
std::make_unique<URLLoaderFactoryImpl>(requester_info_),
base::BindRepeating(&ResourceDispatcherHostImpl::CancelRequest,
base::Unretained(ResourceDispatcherHostImpl::Get()),
- requester_info_->child_id()));
+ requester_info_->child_id()),
+ &shared_cors_origin_access_list_->GetOriginAccessList());
std::vector<network::mojom::URLLoaderFactoryRequest> requests =
std::move(queued_clone_requests_);
diff --git a/chromium/content/browser/loader/resource_message_filter.h b/chromium/content/browser/loader/resource_message_filter.h
index a0a5a0dc3cb..b2e58d3f169 100644
--- a/chromium/content/browser/loader/resource_message_filter.h
+++ b/chromium/content/browser/loader/resource_message_filter.h
@@ -28,7 +28,6 @@ namespace net {
class URLRequestContext;
} // namespace net
-
namespace content {
class ChromeAppCacheService;
class ChromeBlobStorageContext;
@@ -36,6 +35,7 @@ class PrefetchURLLoaderService;
class ResourceContext;
class ResourceRequesterInfo;
class ServiceWorkerContextWrapper;
+class SharedCorsOriginAccessList;
// This class filters out incoming IPC messages for network requests and
// processes them on the IPC thread. As a result, network requests are not
@@ -62,6 +62,7 @@ class CONTENT_EXPORT ResourceMessageFilter
storage::FileSystemContext* file_system_context,
ServiceWorkerContextWrapper* service_worker_context,
PrefetchURLLoaderService* prefetch_url_loader_service,
+ const SharedCorsOriginAccessList* shared_cors_origin_access_list,
const GetContextsCallback& get_contexts_callback,
const scoped_refptr<base::SingleThreadTaskRunner>& io_thread_runner);
@@ -121,6 +122,9 @@ class CONTENT_EXPORT ResourceMessageFilter
scoped_refptr<PrefetchURLLoaderService> prefetch_url_loader_service_;
+ scoped_refptr<const SharedCorsOriginAccessList>
+ shared_cors_origin_access_list_;
+
// Task runner for the IO thead.
scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_;
diff --git a/chromium/content/browser/loader/resource_request_info_impl.cc b/chromium/content/browser/loader/resource_request_info_impl.cc
index 7fe59fe5542..2786b068dfb 100644
--- a/chromium/content/browser/loader/resource_request_info_impl.cc
+++ b/chromium/content/browser/loader/resource_request_info_impl.cc
@@ -6,6 +6,8 @@
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/loader/resource_message_filter.h"
+#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/web_contents/web_contents_getter_registry.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/net/url_request_service_worker_data.h"
#include "content/common/net/url_request_user_data.h"
@@ -72,6 +74,7 @@ void ResourceRequestInfo::AllocateForTesting(
0, // request_id
render_frame_id, // render_frame_id
is_main_frame, // is_main_frame
+ {}, // fetch_window_id
resource_type, // resource_type
ui::PAGE_TRANSITION_LINK, // transition_type
false, // is_download
@@ -140,6 +143,7 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
int request_id,
int render_frame_id,
bool is_main_frame,
+ const base::UnguessableToken& fetch_window_id,
ResourceType resource_type,
ui::PageTransition transition_type,
bool is_download,
@@ -167,6 +171,7 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
request_id_(request_id),
render_frame_id_(render_frame_id),
is_main_frame_(is_main_frame),
+ fetch_window_id_(fetch_window_id),
is_download_(is_download),
is_stream_(is_stream),
allow_download_(allow_download),
@@ -185,7 +190,6 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
report_raw_headers_(report_raw_headers),
report_security_info_(report_security_info),
is_async_(is_async),
- devtools_status_(DevToolsStatus::kNotCanceled),
previews_state_(previews_state),
body_(body),
initiated_in_secure_context_(initiated_in_secure_context),
@@ -198,10 +202,18 @@ ResourceRequestInfoImpl::~ResourceRequestInfoImpl() {
ResourceRequestInfo::WebContentsGetter
ResourceRequestInfoImpl::GetWebContentsGetterForRequest() const {
- // PlzNavigate: navigation requests are created with a valid FrameTreeNode ID
- // and invalid RenderProcessHost and RenderFrameHost IDs. The FrameTreeNode
- // ID should be used to access the WebContents.
- if (frame_tree_node_id_ != -1) {
+ // If we have a window id, try to use that.
+ if (fetch_window_id_) {
+ ResourceRequestInfo::WebContentsGetter getter =
+ WebContentsGetterRegistry::GetInstance()->Get(fetch_window_id_);
+ if (getter)
+ return getter;
+ }
+
+ // Navigation requests are created with a valid FrameTreeNode ID and invalid
+ // RenderProcessHost and RenderFrameHost IDs. The FrameTreeNode ID should be
+ // used to access the WebContents.
+ if (frame_tree_node_id_ != RenderFrameHost::kNoFrameTreeNodeId) {
DCHECK(IsBrowserSideNavigationEnabled());
return base::Bind(WebContents::FromFrameTreeNodeId, frame_tree_node_id_);
}
@@ -322,11 +334,6 @@ NavigationUIData* ResourceRequestInfoImpl::GetNavigationUIData() const {
return navigation_ui_data_.get();
}
-ResourceRequestInfo::DevToolsStatus ResourceRequestInfoImpl::GetDevToolsStatus()
- const {
- return devtools_status_;
-}
-
void ResourceRequestInfoImpl::SetResourceRequestBlockedReason(
blink::ResourceRequestBlockedReason reason) {
resource_request_blocked_reason_ = reason;
diff --git a/chromium/content/browser/loader/resource_request_info_impl.h b/chromium/content/browser/loader/resource_request_info_impl.h
index ec89c14e24b..ec852ae9294 100644
--- a/chromium/content/browser/loader/resource_request_info_impl.h
+++ b/chromium/content/browser/loader/resource_request_info_impl.h
@@ -52,6 +52,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
int request_id,
int render_frame_id,
bool is_main_frame,
+ const base::UnguessableToken& fetch_window_id,
ResourceType resource_type,
ui::PageTransition transition_type,
bool is_download,
@@ -98,7 +99,6 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
PreviewsState GetPreviewsState() const override;
void SetPreviewsState(PreviewsState previews_state) override;
NavigationUIData* GetNavigationUIData() const override;
- DevToolsStatus GetDevToolsStatus() const override;
void SetResourceRequestBlockedReason(
blink::ResourceRequestBlockedReason reason) override;
base::Optional<blink::ResourceRequestBlockedReason>
@@ -187,10 +187,6 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
navigation_ui_data_ = std::move(navigation_ui_data);
}
- void set_devtools_status(DevToolsStatus devtools_status) {
- devtools_status_ = devtools_status;
- }
-
void SetBlobHandles(BlobHandles blob_handles);
bool blocked_response_from_reaching_renderer() const {
@@ -216,6 +212,10 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
first_auth_attempt_ = first_auth_attempt;
}
+ const base::UnguessableToken& fetch_window_id() const {
+ return fetch_window_id_;
+ }
+
private:
FRIEND_TEST_ALL_PREFIXES(ResourceDispatcherHostTest,
DeletedFilterDetached);
@@ -231,6 +231,7 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
int request_id_;
int render_frame_id_;
bool is_main_frame_;
+ base::UnguessableToken fetch_window_id_;
bool is_download_;
bool is_stream_;
bool allow_download_;
@@ -249,7 +250,6 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
bool report_raw_headers_;
bool report_security_info_;
bool is_async_;
- DevToolsStatus devtools_status_;
base::Optional<blink::ResourceRequestBlockedReason>
resource_request_blocked_reason_;
PreviewsState previews_state_;
diff --git a/chromium/content/browser/loader/shared_cors_origin_access_list_impl.cc b/chromium/content/browser/loader/shared_cors_origin_access_list_impl.cc
new file mode 100644
index 00000000000..dce98468bed
--- /dev/null
+++ b/chromium/content/browser/loader/shared_cors_origin_access_list_impl.cc
@@ -0,0 +1,51 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/loader/shared_cors_origin_access_list_impl.h"
+
+#include "base/bind.h"
+#include "base/feature_list.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "services/network/public/cpp/features.h"
+
+namespace content {
+
+SharedCorsOriginAccessListImpl::SharedCorsOriginAccessListImpl()
+ : SharedCorsOriginAccessList() {}
+
+void SharedCorsOriginAccessListImpl::SetForOrigin(
+ const url::Origin& source_origin,
+ std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
+ std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
+ base::OnceClosure closure) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&SharedCorsOriginAccessListImpl::SetForOriginOnIOThread,
+ base::RetainedRef(this), source_origin,
+ std::move(allow_patterns), std::move(block_patterns)),
+ std::move(closure));
+}
+
+const network::cors::OriginAccessList&
+SharedCorsOriginAccessListImpl::GetOriginAccessList() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ return origin_access_list_;
+}
+
+SharedCorsOriginAccessListImpl::~SharedCorsOriginAccessListImpl() = default;
+
+void SharedCorsOriginAccessListImpl::SetForOriginOnIOThread(
+ const url::Origin source_origin,
+ std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
+ std::vector<network::mojom::CorsOriginPatternPtr> block_patterns) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ origin_access_list_.SetAllowListForOrigin(source_origin, allow_patterns);
+ origin_access_list_.SetBlockListForOrigin(source_origin, block_patterns);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/loader/shared_cors_origin_access_list_impl.h b/chromium/content/browser/loader/shared_cors_origin_access_list_impl.h
new file mode 100644
index 00000000000..18497e5283c
--- /dev/null
+++ b/chromium/content/browser/loader/shared_cors_origin_access_list_impl.h
@@ -0,0 +1,43 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_LOADER_SHARED_CORS_ORIGIN_ACCESS_LIST_IMPL_H_
+#define CONTENT_BROWSER_LOADER_SHARED_CORS_ORIGIN_ACCESS_LIST_IMPL_H_
+
+#include "base/macros.h"
+#include "content/public/browser/shared_cors_origin_access_list.h"
+#include "services/network/public/cpp/cors/origin_access_list.h"
+
+namespace content {
+
+// SharedCorsOriginAccessList implementation class.
+class SharedCorsOriginAccessListImpl final : public SharedCorsOriginAccessList {
+ public:
+ SharedCorsOriginAccessListImpl();
+
+ // SharedCorsOriginAccessList interface.
+ void SetForOrigin(
+ const url::Origin& source_origin,
+ std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
+ std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
+ base::OnceClosure closure) override;
+ const network::cors::OriginAccessList& GetOriginAccessList() const override;
+
+ protected:
+ ~SharedCorsOriginAccessListImpl() override;
+
+ private:
+ void SetForOriginOnIOThread(
+ const url::Origin source_origin,
+ std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
+ std::vector<network::mojom::CorsOriginPatternPtr> block_patterns);
+
+ network::cors::OriginAccessList origin_access_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedCorsOriginAccessListImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_LOADER_SHARED_CORS_ORIGIN_ACCESS_LIST_IMPL_H_
diff --git a/chromium/content/browser/loader/stream_writer.cc b/chromium/content/browser/loader/stream_writer.cc
index 08774aa64b4..70a7502744b 100644
--- a/chromium/content/browser/loader/stream_writer.cc
+++ b/chromium/content/browser/loader/stream_writer.cc
@@ -54,7 +54,7 @@ void StreamWriter::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
DCHECK(buf_size);
DCHECK_LE(min_size, kReadBufSize);
if (!read_buffer_.get())
- read_buffer_ = new net::IOBuffer(kReadBufSize);
+ read_buffer_ = base::MakeRefCounted<net::IOBuffer>(kReadBufSize);
*buf = read_buffer_.get();
*buf_size = kReadBufSize;
}
diff --git a/chromium/content/browser/loader/test_resource_handler.cc b/chromium/content/browser/loader/test_resource_handler.cc
index 0fbeb2706a9..7fc81cd450a 100644
--- a/chromium/content/browser/loader/test_resource_handler.cc
+++ b/chromium/content/browser/loader/test_resource_handler.cc
@@ -272,7 +272,7 @@ void TestResourceHandler::CancelWithError(net::Error net_error) {
}
void TestResourceHandler::SetBufferSize(int buffer_size) {
- buffer_ = new net::IOBuffer(buffer_size);
+ buffer_ = base::MakeRefCounted<net::IOBuffer>(buffer_size);
buffer_size_ = buffer_size;
memset(buffer_->data(), '\0', buffer_size);
}
diff --git a/chromium/content/browser/loader/throttling_resource_handler_unittest.cc b/chromium/content/browser/loader/throttling_resource_handler_unittest.cc
index 838a6b73246..0e6dbf7e424 100644
--- a/chromium/content/browser/loader/throttling_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/throttling_resource_handler_unittest.cc
@@ -10,7 +10,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "content/browser/loader/mock_resource_loader.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/loader/test_resource_handler.h"
@@ -176,7 +176,9 @@ class TestResourceThrottle : public ResourceThrottle {
class ThrottlingResourceHandlerTest : public testing::Test {
public:
ThrottlingResourceHandlerTest()
- : never_started_url_request_(
+ : task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO),
+ never_started_url_request_(
request_context_.CreateRequest(GURL(kInitialUrl),
net::DEFAULT_PRIORITY,
&never_started_url_request_delegate_,
@@ -222,7 +224,7 @@ class ThrottlingResourceHandlerTest : public testing::Test {
protected:
// Needs to be first, so it's destroyed last.
- base::MessageLoopForIO message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
// Machinery to construct a URLRequest that's just used as an argument to
// methods that expect one, and is never actually started.
diff --git a/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc b/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc
index 8231784cc76..6f38daeee39 100644
--- a/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc
+++ b/chromium/content/browser/loader/upload_data_stream_builder_unittest.cc
@@ -152,7 +152,7 @@ TEST(UploadDataStreamBuilderTest,
int kBufferLength = kZeroLength + 1;
std::unique_ptr<char[]> buffer(new char[kBufferLength]);
scoped_refptr<net::IOBuffer> io_buffer =
- new net::WrappedIOBuffer(buffer.get());
+ base::MakeRefCounted<net::WrappedIOBuffer>(buffer.get());
net::TestCompletionCallback read_callback;
int result =
upload->Read(io_buffer.get(), kBufferLength, read_callback.callback());
@@ -195,8 +195,8 @@ TEST(UploadDataStreamBuilderTest, ResetUploadStreamWithBlob) {
// Read part of the data.
const int kBufferLength = 4;
- scoped_refptr<net::IOBufferWithSize> buffer(
- new net::IOBufferWithSize(kBufferLength));
+ scoped_refptr<net::IOBufferWithSize> buffer =
+ base::MakeRefCounted<net::IOBufferWithSize>(kBufferLength);
net::TestCompletionCallback read_callback;
int result =
upload->Read(buffer.get(), buffer->size(), read_callback.callback());
@@ -209,7 +209,7 @@ TEST(UploadDataStreamBuilderTest, ResetUploadStreamWithBlob) {
upload->Init(init_callback.callback(), net::NetLogWithSource()));
// Read all the data.
- buffer = new net::IOBufferWithSize(kBlobDataLength);
+ buffer = base::MakeRefCounted<net::IOBufferWithSize>(kBlobDataLength);
result =
upload->Read(buffer.get(), buffer->size(), read_callback.callback());
EXPECT_EQ(kBlobDataLength, read_callback.GetResult(result));
diff --git a/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc b/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc
index 168eed74072..3fb868c99f8 100644
--- a/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc
+++ b/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc
@@ -18,12 +18,14 @@
#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/loader/mojo_async_resource_handler.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_message_filter.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/loader_delegate_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/resource_dispatcher_host_delegate.h"
#include "content/public/common/content_paths.h"
@@ -74,9 +76,12 @@ class URLLoaderFactoryImplTest : public ::testing::TestWithParam<size_t> {
nullptr,
nullptr,
nullptr,
+ BrowserContext::GetSharedCorsOriginAccessList(
+ browser_context_.get()),
base::Bind(&URLLoaderFactoryImplTest::GetContexts,
base::Unretained(this)),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO))) {
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {BrowserThread::IO}))) {
// Some tests specify request.report_raw_headers, but the RDH checks the
// CanReadRawCookies permission before enabling it.
ChildProcessSecurityPolicyImpl::GetInstance()->Add(kChildId);
diff --git a/chromium/content/browser/mach_broker_mac.mm b/chromium/content/browser/mach_broker_mac.mm
index 21d1a5caf2f..01990f7ab91 100644
--- a/chromium/content/browser/mach_broker_mac.mm
+++ b/chromium/content/browser/mach_broker_mac.mm
@@ -8,7 +8,9 @@
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/task/post_task.h"
#include "content/common/content_constants_internal.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/render_process_host.h"
@@ -34,8 +36,8 @@ void MachBroker::EnsureRunning() {
// Do not attempt to reinitialize in the event of failure.
initialized_ = true;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&MachBroker::RegisterNotifications, base::Unretained(this)));
if (!broker_.Init()) {
diff --git a/chromium/content/browser/manifest/manifest_icon_downloader.cc b/chromium/content/browser/manifest/manifest_icon_downloader.cc
index ac40d4cefb5..0a29672a383 100644
--- a/chromium/content/browser/manifest/manifest_icon_downloader.cc
+++ b/chromium/content/browser/manifest/manifest_icon_downloader.cc
@@ -8,6 +8,8 @@
#include <limits>
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -108,8 +110,8 @@ void ManifestIconDownloader::OnIconFetched(
// webapp storage system as well.
if (chosen.height() > ideal_icon_size_in_px ||
chosen.width() > ideal_icon_size_in_px) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ManifestIconDownloader::ScaleIcon,
ideal_icon_size_in_px, chosen, callback));
return;
@@ -128,8 +130,8 @@ void ManifestIconDownloader::ScaleIcon(
bitmap, skia::ImageOperations::RESIZE_BEST, ideal_icon_size_in_px,
ideal_icon_size_in_px);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(callback, scaled));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(callback, scaled));
}
int ManifestIconDownloader::FindClosestBitmapIndex(
diff --git a/chromium/content/browser/media/android/browser_gpu_video_accelerator_factories.cc b/chromium/content/browser/media/android/browser_gpu_video_accelerator_factories.cc
new file mode 100644
index 00000000000..1b8d471d252
--- /dev/null
+++ b/chromium/content/browser/media/android/browser_gpu_video_accelerator_factories.cc
@@ -0,0 +1,210 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/android/browser_gpu_video_accelerator_factories.h"
+
+#include "content/browser/browser_main_loop.h"
+#include "content/public/browser/android/gpu_video_accelerator_factories_provider.h"
+#include "content/public/common/gpu_stream_constants.h"
+#include "gpu/command_buffer/client/shared_memory_limits.h"
+#include "gpu/command_buffer/common/context_creation_attribs.h"
+#include "gpu/ipc/client/command_buffer_proxy_impl.h"
+#include "gpu/ipc/client/gpu_channel_host.h"
+#include "media/gpu/gpu_video_accelerator_util.h"
+#include "media/gpu/ipc/common/media_messages.h"
+#include "services/ws/public/cpp/gpu/context_provider_command_buffer.h"
+
+namespace content {
+
+namespace {
+
+void OnGpuChannelEstablished(
+ GpuVideoAcceleratorFactoriesCallback callback,
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
+ gpu::ContextCreationAttribs attributes;
+ attributes.alpha_size = -1;
+ attributes.red_size = 8;
+ attributes.green_size = 8;
+ attributes.blue_size = 8;
+ attributes.stencil_size = 0;
+ attributes.depth_size = 0;
+ attributes.samples = 0;
+ attributes.sample_buffers = 0;
+ attributes.bind_generates_resource = false;
+
+ gpu::GpuChannelEstablishFactory* factory =
+ BrowserMainLoop::GetInstance()->gpu_channel_establish_factory();
+
+ int32_t stream_id = kGpuStreamIdDefault;
+ gpu::SchedulingPriority stream_priority = kGpuStreamPriorityUI;
+
+ constexpr bool automatic_flushes = false;
+ constexpr bool support_locking = false;
+ constexpr bool support_grcontext = true;
+
+ auto context_provider =
+ base::MakeRefCounted<ws::ContextProviderCommandBuffer>(
+ std::move(gpu_channel_host), factory->GetGpuMemoryBufferManager(),
+ stream_id, stream_priority, gpu::kNullSurfaceHandle,
+ GURL(std::string("chrome://gpu/"
+ "BrowserGpuVideoAcceleratorFactories::"
+ "CreateGpuVideoAcceleratorFactories")),
+ automatic_flushes, support_locking, support_grcontext,
+ gpu::SharedMemoryLimits::ForMailboxContext(), attributes,
+ ws::command_buffer_metrics::ContextType::UNKNOWN);
+
+ // TODO(xingliu): This is on main thread, move to another thread?
+ context_provider->BindToCurrentThread();
+
+ auto gpu_factories = std::make_unique<BrowserGpuVideoAcceleratorFactories>(
+ std::move(context_provider));
+ std::move(callback).Run(std::move(gpu_factories));
+}
+
+} // namespace
+
+void CreateGpuVideoAcceleratorFactories(
+ GpuVideoAcceleratorFactoriesCallback callback) {
+ BrowserMainLoop::GetInstance()
+ ->gpu_channel_establish_factory()
+ ->EstablishGpuChannel(
+ base::BindOnce(&OnGpuChannelEstablished, std::move(callback)));
+}
+
+BrowserGpuVideoAcceleratorFactories::BrowserGpuVideoAcceleratorFactories(
+ scoped_refptr<ws::ContextProviderCommandBuffer> context_provider)
+ : context_provider_(std::move(context_provider)) {}
+
+BrowserGpuVideoAcceleratorFactories::~BrowserGpuVideoAcceleratorFactories() =
+ default;
+
+bool BrowserGpuVideoAcceleratorFactories::IsGpuVideoAcceleratorEnabled() {
+ return false;
+}
+
+base::UnguessableToken BrowserGpuVideoAcceleratorFactories::GetChannelToken() {
+ if (channel_token_.is_empty()) {
+ context_provider_->GetCommandBufferProxy()->channel()->Send(
+ new GpuCommandBufferMsg_GetChannelToken(&channel_token_));
+ }
+
+ return channel_token_;
+}
+
+int32_t BrowserGpuVideoAcceleratorFactories::GetCommandBufferRouteId() {
+ return context_provider_->GetCommandBufferProxy()->route_id();
+}
+
+bool BrowserGpuVideoAcceleratorFactories::IsDecoderConfigSupported(
+ const media::VideoDecoderConfig& config) {
+ // TODO(sandersd): Add a cache here too?
+ return true;
+}
+
+std::unique_ptr<media::VideoDecoder>
+BrowserGpuVideoAcceleratorFactories::CreateVideoDecoder(
+ media::MediaLog* media_log,
+ const media::RequestOverlayInfoCB& request_overlay_info_cb,
+ const gfx::ColorSpace& target_color_space) {
+ return nullptr;
+}
+
+std::unique_ptr<media::VideoDecodeAccelerator>
+BrowserGpuVideoAcceleratorFactories::CreateVideoDecodeAccelerator() {
+ return nullptr;
+}
+
+std::unique_ptr<media::VideoEncodeAccelerator>
+BrowserGpuVideoAcceleratorFactories::CreateVideoEncodeAccelerator() {
+ return nullptr;
+}
+
+bool BrowserGpuVideoAcceleratorFactories::CreateTextures(
+ int32_t count,
+ const gfx::Size& size,
+ std::vector<uint32_t>* texture_ids,
+ std::vector<gpu::Mailbox>* texture_mailboxes,
+ uint32_t texture_target) {
+ return false;
+}
+
+void BrowserGpuVideoAcceleratorFactories::DeleteTexture(uint32_t texture_id) {}
+
+gpu::SyncToken BrowserGpuVideoAcceleratorFactories::CreateSyncToken() {
+ return gpu::SyncToken();
+}
+
+void BrowserGpuVideoAcceleratorFactories::ShallowFlushCHROMIUM() {}
+
+void BrowserGpuVideoAcceleratorFactories::WaitSyncToken(
+ const gpu::SyncToken& sync_token) {}
+
+void BrowserGpuVideoAcceleratorFactories::SignalSyncToken(
+ const gpu::SyncToken& sync_token,
+ base::OnceClosure callback) {}
+
+std::unique_ptr<gfx::GpuMemoryBuffer>
+BrowserGpuVideoAcceleratorFactories::CreateGpuMemoryBuffer(
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage) {
+ return nullptr;
+}
+
+bool BrowserGpuVideoAcceleratorFactories::
+ ShouldUseGpuMemoryBuffersForVideoFrames(bool for_media_stream) const {
+ return false;
+}
+
+unsigned BrowserGpuVideoAcceleratorFactories::ImageTextureTarget(
+ gfx::BufferFormat format) {
+ return -1;
+}
+
+media::GpuVideoAcceleratorFactories::OutputFormat
+BrowserGpuVideoAcceleratorFactories::VideoFrameOutputFormat(
+ media::VideoPixelFormat pixel_format) {
+ return GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED;
+}
+
+gpu::gles2::GLES2Interface* BrowserGpuVideoAcceleratorFactories::ContextGL() {
+ return nullptr;
+}
+
+std::unique_ptr<base::SharedMemory>
+BrowserGpuVideoAcceleratorFactories::CreateSharedMemory(size_t size) {
+ return nullptr;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+BrowserGpuVideoAcceleratorFactories::GetTaskRunner() {
+ return nullptr;
+}
+
+media::VideoDecodeAccelerator::Capabilities
+BrowserGpuVideoAcceleratorFactories::GetVideoDecodeAcceleratorCapabilities() {
+ DCHECK(context_provider_);
+ auto* proxy = context_provider_->GetCommandBufferProxy();
+ DCHECK(proxy);
+ DCHECK(proxy->channel());
+
+ return media::GpuVideoAcceleratorUtil::ConvertGpuToMediaDecodeCapabilities(
+ proxy->channel()->gpu_info().video_decode_accelerator_capabilities);
+}
+
+media::VideoEncodeAccelerator::SupportedProfiles
+BrowserGpuVideoAcceleratorFactories::
+ GetVideoEncodeAcceleratorSupportedProfiles() {
+ return media::VideoEncodeAccelerator::SupportedProfiles();
+}
+
+scoped_refptr<ws::ContextProviderCommandBuffer>
+BrowserGpuVideoAcceleratorFactories::GetMediaContextProvider() {
+ return context_provider_;
+}
+
+void BrowserGpuVideoAcceleratorFactories::SetRenderingColorSpace(
+ const gfx::ColorSpace& color_space) {}
+
+} // namespace content
diff --git a/chromium/content/browser/media/android/browser_gpu_video_accelerator_factories.h b/chromium/content/browser/media/android/browser_gpu_video_accelerator_factories.h
new file mode 100644
index 00000000000..a51a02d7d0d
--- /dev/null
+++ b/chromium/content/browser/media/android/browser_gpu_video_accelerator_factories.h
@@ -0,0 +1,76 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_GPU_VIDEO_ACCELERATOR_FACTORIES_H_
+#define CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_GPU_VIDEO_ACCELERATOR_FACTORIES_H_
+
+#include "base/macros.h"
+#include "media/video/gpu_video_accelerator_factories.h"
+
+namespace content {
+
+// Provides hardware video decoding contexts in the browser process. Used to
+// generate video thumbnail.
+class BrowserGpuVideoAcceleratorFactories
+ : public media::GpuVideoAcceleratorFactories {
+ public:
+ explicit BrowserGpuVideoAcceleratorFactories(
+ scoped_refptr<ws::ContextProviderCommandBuffer>);
+ ~BrowserGpuVideoAcceleratorFactories() override;
+
+ private:
+ // media::GpuVideoAcceleratorFactories implementation.
+ bool IsGpuVideoAcceleratorEnabled() override;
+ base::UnguessableToken GetChannelToken() override;
+ int32_t GetCommandBufferRouteId() override;
+ bool IsDecoderConfigSupported(
+ const media::VideoDecoderConfig& config) override;
+ std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
+ media::MediaLog* media_log,
+ const media::RequestOverlayInfoCB& request_overlay_info_cb,
+ const gfx::ColorSpace& target_color_space) override;
+ std::unique_ptr<media::VideoDecodeAccelerator> CreateVideoDecodeAccelerator()
+ override;
+ std::unique_ptr<media::VideoEncodeAccelerator> CreateVideoEncodeAccelerator()
+ override;
+ bool CreateTextures(int32_t count,
+ const gfx::Size& size,
+ std::vector<uint32_t>* texture_ids,
+ std::vector<gpu::Mailbox>* texture_mailboxes,
+ uint32_t texture_target) override;
+ void DeleteTexture(uint32_t texture_id) override;
+ gpu::SyncToken CreateSyncToken() override;
+ void ShallowFlushCHROMIUM() override;
+ void WaitSyncToken(const gpu::SyncToken& sync_token) override;
+ void SignalSyncToken(const gpu::SyncToken& sync_token,
+ base::OnceClosure callback) override;
+ std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer(
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage) override;
+ bool ShouldUseGpuMemoryBuffersForVideoFrames(
+ bool for_media_stream) const override;
+ unsigned ImageTextureTarget(gfx::BufferFormat format) override;
+ media::GpuVideoAcceleratorFactories::OutputFormat VideoFrameOutputFormat(
+ media::VideoPixelFormat pixel_format) override;
+ gpu::gles2::GLES2Interface* ContextGL() override;
+ std::unique_ptr<base::SharedMemory> CreateSharedMemory(size_t size) override;
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override;
+ media::VideoDecodeAccelerator::Capabilities
+ GetVideoDecodeAcceleratorCapabilities() override;
+ media::VideoEncodeAccelerator::SupportedProfiles
+ GetVideoEncodeAcceleratorSupportedProfiles() override;
+ scoped_refptr<ws::ContextProviderCommandBuffer> GetMediaContextProvider()
+ override;
+ void SetRenderingColorSpace(const gfx::ColorSpace& color_space) override;
+
+ scoped_refptr<ws::ContextProviderCommandBuffer> context_provider_;
+ base::UnguessableToken channel_token_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserGpuVideoAcceleratorFactories);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_GPU_VIDEO_ACCELERATOR_FACTORIES_H_
diff --git a/chromium/content/browser/media/android/media_player_renderer.cc b/chromium/content/browser/media/android/media_player_renderer.cc
index 05d7c6a039d..4384142774e 100644
--- a/chromium/content/browser/media/android/media_player_renderer.cc
+++ b/chromium/content/browser/media/android/media_player_renderer.cc
@@ -7,11 +7,13 @@
#include <memory>
#include "base/callback_helpers.h"
+#include "base/task/post_task.h"
#include "content/browser/android/scoped_surface_request_manager.h"
#include "content/browser/media/android/media_player_renderer_web_contents_observer.h"
#include "content/browser/media/android/media_resource_getter_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
@@ -89,8 +91,8 @@ void MediaPlayerRenderer::Initialize(media::MediaResource* media_resource,
return;
}
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&MediaPlayerRenderer::CreateMediaPlayer,
weak_factory_.GetWeakPtr(),
media_resource->GetMediaUrlParams(), init_cb),
diff --git a/chromium/content/browser/media/android/media_resource_getter_impl.cc b/chromium/content/browser/media/android/media_resource_getter_impl.cc
index 74a94dfa97d..88841bbd902 100644
--- a/chromium/content/browser/media/android/media_resource_getter_impl.cc
+++ b/chromium/content/browser/media/android/media_resource_getter_impl.cc
@@ -13,6 +13,7 @@
#include "content/browser/fileapi/browser_file_system_helper.h"
#include "content/browser/resource_context_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/storage_partition.h"
@@ -44,8 +45,8 @@ network::mojom::CookieManager* GetCookieServiceForContext(
void ReturnResultOnUIThread(
base::OnceCallback<void(const std::string&)> callback,
const std::string& result) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), result));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), result));
}
// Checks the policy for get cookies and returns the cookie line if allowed.
@@ -76,8 +77,8 @@ void CheckPolicyForCookies(const GURL& url,
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// AllowGetCookie has to be called on IO thread.
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&GetCookiesOnIO, url, site_for_cookies, resource_context,
render_process_id, render_frame_id, cookie_list),
std::move(callback));
@@ -141,6 +142,11 @@ MediaResourceGetterTask::~MediaResourceGetterTask() {}
net::AuthCredentials MediaResourceGetterTask::RequestAuthCredentials(
const GURL& url) const {
DCHECK(GetTaskRunner()->BelongsToCurrentThread());
+ if (!url.IsStandard()) {
+ // Non-standard URLs, such as data, will not be found in HTTP auth cache
+ // anyway, because they have no valid origin, so don't waste the time.
+ return net::AuthCredentials();
+ }
net::HttpTransactionFactory* factory =
context_getter_->GetURLRequestContext()->http_transaction_factory();
if (!factory)
diff --git a/chromium/content/browser/media/audio_input_stream_broker.cc b/chromium/content/browser/media/audio_input_stream_broker.cc
index a93d2ca90f1..0fc989df67f 100644
--- a/chromium/content/browser/media/audio_input_stream_broker.cc
+++ b/chromium/content/browser/media/audio_input_stream_broker.cc
@@ -6,20 +6,24 @@
#include <utility>
+#include "base/bind.h"
#include "base/command_line.h"
+#include "base/location.h"
+#include "base/logging.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/metrics/histogram_macros.h"
+#include "base/optional.h"
+#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/media/media_internals.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/media_observer.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/common/content_client.h"
#include "media/audio/audio_logging.h"
#include "media/base/media_switches.h"
#include "media/base/user_input_monitor.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/system/platform_handle.h"
#if defined(OS_CHROMEOS)
@@ -28,12 +32,42 @@
namespace content {
+namespace {
+
+#if defined(OS_CHROMEOS)
+enum KeyboardMicAction { kRegister, kDeregister };
+
+void UpdateKeyboardMicRegistration(KeyboardMicAction action) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&UpdateKeyboardMicRegistration, action));
+ return;
+ }
+ BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance();
+ // May be null in unit tests.
+ if (!browser_main_loop)
+ return;
+ switch (action) {
+ case kRegister:
+ browser_main_loop->keyboard_mic_registration()->Register();
+ return;
+ case kDeregister:
+ browser_main_loop->keyboard_mic_registration()->Deregister();
+ return;
+ }
+}
+#endif
+
+} // namespace
+
AudioInputStreamBroker::AudioInputStreamBroker(
int render_process_id,
int render_frame_id,
const std::string& device_id,
const media::AudioParameters& params,
uint32_t shared_memory_count,
+ media::UserInputMonitorBase* user_input_monitor,
bool enable_agc,
audio::mojom::AudioProcessingConfigPtr processing_config,
AudioStreamBroker::DeleterCallback deleter,
@@ -42,13 +76,14 @@ AudioInputStreamBroker::AudioInputStreamBroker(
device_id_(device_id),
params_(params),
shared_memory_count_(shared_memory_count),
+ user_input_monitor_(user_input_monitor),
enable_agc_(enable_agc),
deleter_(std::move(deleter)),
processing_config_(std::move(processing_config)),
renderer_factory_client_(std::move(renderer_factory_client)),
observer_binding_(this),
weak_ptr_factory_(this) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(renderer_factory_client_);
DCHECK(deleter_);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("audio", "AudioInputStreamBroker", this);
@@ -57,53 +92,37 @@ AudioInputStreamBroker::AudioInputStreamBroker(
renderer_factory_client_.set_connection_error_handler(base::BindOnce(
&AudioInputStreamBroker::ClientBindingLost, base::Unretained(this)));
- // Notify RenderProcessHost about input stream so the renderer is not
- // background.
- auto* process_host = RenderProcessHost::FromID(render_process_id);
- if (process_host)
- process_host->OnMediaStreamAdded();
+ NotifyProcessHostOfStartedStream(render_process_id);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseFakeDeviceForMediaStream)) {
params_.set_format(media::AudioParameters::AUDIO_FAKE);
}
- BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance();
- // May be null in unit tests.
- if (!browser_main_loop)
- return;
-
#if defined(OS_CHROMEOS)
if (params_.channel_layout() ==
media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) {
- browser_main_loop->keyboard_mic_registration()->Register();
+ UpdateKeyboardMicRegistration(kRegister);
}
-#else
- user_input_monitor_ = static_cast<media::UserInputMonitorBase*>(
- browser_main_loop->user_input_monitor());
#endif
}
AudioInputStreamBroker::~AudioInputStreamBroker() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
#if defined(OS_CHROMEOS)
if (params_.channel_layout() ==
media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) {
- BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance();
-
- // May be null in unit tests.
- if (browser_main_loop)
- browser_main_loop->keyboard_mic_registration()->Deregister();
+ UpdateKeyboardMicRegistration(kDeregister);
}
-#else
+#endif
+
+ // This relies on CreateStream() being called synchronously right after the
+ // constructor.
if (user_input_monitor_)
user_input_monitor_->DisableKeyPressMonitoring();
-#endif
- auto* process_host = RenderProcessHost::FromID(render_process_id());
- if (process_host)
- process_host->OnMediaStreamRemoved();
+ NotifyProcessHostOfStoppedStream(render_process_id());
// TODO(https://crbug.com/829317) update tab recording indicator.
@@ -121,7 +140,7 @@ AudioInputStreamBroker::~AudioInputStreamBroker() {
void AudioInputStreamBroker::CreateStream(
audio::mojom::StreamFactory* factory) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!observer_binding_.is_bound());
DCHECK(!client_request_);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("audio", "CreateStream", this, "device id",
@@ -151,8 +170,6 @@ void AudioInputStreamBroker::CreateStream(
// Note that the component id for AudioLog is used to differentiate between
// several users of the same audio log. Since this audio log is for a single
// stream, the component id used doesn't matter.
- // TODO(https://crbug.com/836226) pass valid user input monitor handle when
- // switching to audio service input streams.
constexpr int log_component_id = 0;
factory->CreateInputStream(
std::move(stream_request), std::move(client), std::move(observer_ptr),
@@ -167,7 +184,7 @@ void AudioInputStreamBroker::CreateStream(
}
void AudioInputStreamBroker::DidStartRecording() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
// TODO(https://crbug.com/829317) update tab recording indicator.
}
@@ -176,7 +193,7 @@ void AudioInputStreamBroker::StreamCreated(
media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
bool initially_muted,
const base::Optional<base::UnguessableToken>& stream_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
awaiting_created_ = false;
TRACE_EVENT_NESTABLE_ASYNC_END1("audio", "CreateStream", this, "success",
!!data_pipe);
@@ -197,7 +214,7 @@ void AudioInputStreamBroker::StreamCreated(
void AudioInputStreamBroker::ObserverBindingLost(
uint32_t reason,
const std::string& description) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
const uint32_t maxValidReason = static_cast<uint32_t>(
media::mojom::AudioInputStreamObserver::DisconnectReason::kMaxValue);
@@ -214,13 +231,14 @@ void AudioInputStreamBroker::ObserverBindingLost(
}
void AudioInputStreamBroker::ClientBindingLost() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
disconnect_reason_ = media::mojom::AudioInputStreamObserver::
DisconnectReason::kTerminatedByClient;
Cleanup();
}
void AudioInputStreamBroker::Cleanup() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::move(deleter_).Run(this);
}
diff --git a/chromium/content/browser/media/audio_input_stream_broker.h b/chromium/content/browser/media/audio_input_stream_broker.h
index 0ed31a6ee2f..397cb49cd8b 100644
--- a/chromium/content/browser/media/audio_input_stream_broker.h
+++ b/chromium/content/browser/media/audio_input_stream_broker.h
@@ -7,12 +7,13 @@
#include <string>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
#include "content/browser/media/audio_stream_broker.h"
#include "content/common/content_export.h"
#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
#include "media/base/audio_parameters.h"
+#include "media/mojo/interfaces/audio_data_pipe.mojom.h"
#include "media/mojo/interfaces/audio_input_stream.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/audio/public/mojom/audio_processing.mojom.h"
@@ -36,6 +37,7 @@ class CONTENT_EXPORT AudioInputStreamBroker final
const std::string& device_id,
const media::AudioParameters& params,
uint32_t shared_memory_count,
+ media::UserInputMonitorBase* user_input_monitor,
bool enable_agc,
audio::mojom::AudioProcessingConfigPtr processing_config,
AudioStreamBroker::DeleterCallback deleter,
@@ -62,8 +64,8 @@ class CONTENT_EXPORT AudioInputStreamBroker final
const std::string device_id_;
media::AudioParameters params_;
const uint32_t shared_memory_count_;
+ media::UserInputMonitorBase* const user_input_monitor_;
const bool enable_agc_;
- media::UserInputMonitorBase* user_input_monitor_ = nullptr;
// Indicates that CreateStream has been called, but not StreamCreated.
bool awaiting_created_ = false;
diff --git a/chromium/content/browser/media/audio_input_stream_broker_unittest.cc b/chromium/content/browser/media/audio_input_stream_broker_unittest.cc
index b68713ab8fc..c21c3176141 100644
--- a/chromium/content/browser/media/audio_input_stream_broker_unittest.cc
+++ b/chromium/content/browser/media/audio_input_stream_broker_unittest.cc
@@ -145,6 +145,7 @@ struct TestEnvironment {
kDeviceId,
TestParams(),
kShMemCount,
+ nullptr /*user_input_monitor*/,
kEnableAgc,
nullptr,
deleter.Get(),
@@ -169,7 +170,8 @@ TEST(AudioInputStreamBrokerTest, StoresProcessAndFrameId) {
AudioInputStreamBroker broker(
kRenderProcessId, kRenderFrameId, kDeviceId, TestParams(), kShMemCount,
- kEnableAgc, nullptr, deleter.Get(), renderer_factory_client.MakePtr());
+ nullptr /*user_input_monitor*/, kEnableAgc, nullptr, deleter.Get(),
+ renderer_factory_client.MakePtr());
EXPECT_EQ(kRenderProcessId, broker.render_process_id());
EXPECT_EQ(kRenderFrameId, broker.render_frame_id());
diff --git a/chromium/content/browser/media/audio_loopback_stream_broker.cc b/chromium/content/browser/media/audio_loopback_stream_broker.cc
index 884508c44f3..1b834987a49 100644
--- a/chromium/content/browser/media/audio_loopback_stream_broker.cc
+++ b/chromium/content/browser/media/audio_loopback_stream_broker.cc
@@ -6,77 +6,39 @@
#include <utility>
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/task/post_task.h"
#include "base/unguessable_token.h"
-#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_process_host.h"
+#include "services/audio/public/mojom/stream_factory.mojom.h"
namespace content {
-AudioStreamBrokerFactory::LoopbackSource::LoopbackSource() = default;
-
-AudioStreamBrokerFactory::LoopbackSource::LoopbackSource(
- WebContents* source_contents)
- : WebContentsObserver(source_contents) {
- DCHECK(source_contents);
-}
-
-AudioStreamBrokerFactory::LoopbackSource::~LoopbackSource() = default;
-
-base::UnguessableToken AudioStreamBrokerFactory::LoopbackSource::GetGroupID() {
- if (WebContentsImpl* source_contents =
- static_cast<WebContentsImpl*>(web_contents())) {
- return source_contents->GetAudioStreamFactory()->group_id();
- }
- return base::UnguessableToken();
-}
-
-void AudioStreamBrokerFactory::LoopbackSource::OnStartCapturing() {
- if (WebContentsImpl* source_contents =
- static_cast<WebContentsImpl*>(web_contents())) {
- source_contents->IncrementCapturerCount(gfx::Size());
- }
-}
-
-void AudioStreamBrokerFactory::LoopbackSource::OnStopCapturing() {
- if (WebContentsImpl* source_contents =
- static_cast<WebContentsImpl*>(web_contents())) {
- source_contents->DecrementCapturerCount();
- }
-}
-
-void AudioStreamBrokerFactory::LoopbackSource::WebContentsDestroyed() {
- if (on_gone_closure_)
- std::move(on_gone_closure_).Run();
-}
-
AudioLoopbackStreamBroker::AudioLoopbackStreamBroker(
int render_process_id,
int render_frame_id,
- std::unique_ptr<AudioStreamBrokerFactory::LoopbackSource> source,
+ AudioStreamBroker::LoopbackSource* source,
const media::AudioParameters& params,
uint32_t shared_memory_count,
bool mute_source,
AudioStreamBroker::DeleterCallback deleter,
mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client)
: AudioStreamBroker(render_process_id, render_frame_id),
- source_(std::move(source)),
+ source_(source),
params_(params),
shared_memory_count_(shared_memory_count),
deleter_(std::move(deleter)),
renderer_factory_client_(std::move(renderer_factory_client)),
observer_binding_(this),
weak_ptr_factory_(this) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(source_);
- DCHECK(source_->GetGroupID());
DCHECK(renderer_factory_client_);
DCHECK(deleter_);
- // Unretained is safe because |this| owns |source_|.
- source_->set_on_gone_closure(base::BindOnce(
- &AudioLoopbackStreamBroker::Cleanup, base::Unretained(this)));
-
if (mute_source) {
muter_.emplace(source_->GetGroupID());
}
@@ -85,31 +47,27 @@ AudioLoopbackStreamBroker::AudioLoopbackStreamBroker(
renderer_factory_client_.set_connection_error_handler(base::BindOnce(
&AudioLoopbackStreamBroker::Cleanup, base::Unretained(this)));
- // Notify the source that we are capturing from it, to prevent its
- // backgrounding.
- source_->OnStartCapturing();
+ // Notify the source that we are capturing from it.
+ source_->AddLoopbackSink(this);
- // Notify RenderProcessHost about the input stream, so that the destination
- // renderer does not get background.
- if (auto* process_host = RenderProcessHost::FromID(render_process_id))
- process_host->OnMediaStreamAdded();
+ NotifyProcessHostOfStartedStream(render_process_id);
}
AudioLoopbackStreamBroker::~AudioLoopbackStreamBroker() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
- source_->OnStopCapturing();
+ if (source_)
+ source_->RemoveLoopbackSink(this);
- if (auto* process_host = RenderProcessHost::FromID(render_process_id()))
- process_host->OnMediaStreamRemoved();
+ NotifyProcessHostOfStoppedStream(render_process_id());
}
void AudioLoopbackStreamBroker::CreateStream(
audio::mojom::StreamFactory* factory) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!observer_binding_.is_bound());
DCHECK(!client_request_);
- DCHECK(source_->GetGroupID());
+ DCHECK(source_);
if (muter_) // Mute the source.
muter_->Connect(factory);
@@ -135,14 +93,21 @@ void AudioLoopbackStreamBroker::CreateStream(
weak_ptr_factory_.GetWeakPtr(), std::move(stream)));
}
+void AudioLoopbackStreamBroker::OnSourceGone() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // No further access to |source_| is allowed.
+ source_ = nullptr;
+ Cleanup();
+}
+
void AudioLoopbackStreamBroker::DidStartRecording() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
void AudioLoopbackStreamBroker::StreamCreated(
media::mojom::AudioInputStreamPtr stream,
media::mojom::ReadOnlyAudioDataPipePtr data_pipe) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!data_pipe) {
Cleanup();
@@ -157,7 +122,7 @@ void AudioLoopbackStreamBroker::StreamCreated(
}
void AudioLoopbackStreamBroker::Cleanup() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::move(deleter_).Run(this);
}
diff --git a/chromium/content/browser/media/audio_loopback_stream_broker.h b/chromium/content/browser/media/audio_loopback_stream_broker.h
index 9853b4c9768..aa1f6f6d529 100644
--- a/chromium/content/browser/media/audio_loopback_stream_broker.h
+++ b/chromium/content/browser/media/audio_loopback_stream_broker.h
@@ -5,19 +5,25 @@
#ifndef CONTENT_BROWSER_MEDIA_AUDIO_LOOPBACK_STREAM_BROKER_H_
#define CONTENT_BROWSER_MEDIA_AUDIO_LOOPBACK_STREAM_BROKER_H_
+#include <cstdint>
#include <string>
+#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
-#include "base/sequence_checker.h"
#include "content/browser/media/audio_muting_session.h"
#include "content/browser/media/audio_stream_broker.h"
#include "content/common/content_export.h"
-#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
#include "media/base/audio_parameters.h"
+#include "media/mojo/interfaces/audio_data_pipe.mojom.h"
#include "media/mojo/interfaces/audio_input_stream.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "services/audio/public/mojom/stream_factory.mojom.h"
+
+namespace audio {
+namespace mojom {
+class StreamFactory;
+}
+} // namespace audio
namespace content {
@@ -25,12 +31,13 @@ namespace content {
// (typically renderer) and the audio service. It is operated on the UI thread.
class CONTENT_EXPORT AudioLoopbackStreamBroker final
: public AudioStreamBroker,
- public media::mojom::AudioInputStreamObserver {
+ public media::mojom::AudioInputStreamObserver,
+ public AudioStreamBroker::LoopbackSink {
public:
AudioLoopbackStreamBroker(
int render_process_id,
int render_frame_id,
- std::unique_ptr<AudioStreamBrokerFactory::LoopbackSource> source,
+ AudioStreamBroker::LoopbackSource* source,
const media::AudioParameters& params,
uint32_t shared_memory_count,
bool mute_source,
@@ -45,12 +52,17 @@ class CONTENT_EXPORT AudioLoopbackStreamBroker final
// media::AudioInputStreamObserver implementation.
void DidStartRecording() final;
+ // AudioStreamBroker::LoopbackSink
+ void OnSourceGone() final;
+
private:
void StreamCreated(media::mojom::AudioInputStreamPtr stream,
media::mojom::ReadOnlyAudioDataPipePtr data_pipe);
void Cleanup();
- const std::unique_ptr<AudioStreamBrokerFactory::LoopbackSource> source_;
+ // Owner of the output streams to be looped back.
+ AudioStreamBroker::LoopbackSource* source_;
+
const media::AudioParameters params_;
const uint32_t shared_memory_count_;
diff --git a/chromium/content/browser/media/audio_loopback_stream_broker_unittest.cc b/chromium/content/browser/media/audio_loopback_stream_broker_unittest.cc
index 14923ed61e4..f72c1d64c4b 100644
--- a/chromium/content/browser/media/audio_loopback_stream_broker_unittest.cc
+++ b/chromium/content/browser/media/audio_loopback_stream_broker_unittest.cc
@@ -35,16 +35,15 @@ media::AudioParameters TestParams() {
return media::AudioParameters::UnavailableDeviceParams();
}
-class MockSource : public AudioStreamBrokerFactory::LoopbackSource {
+class MockSource : public AudioStreamBroker::LoopbackSource {
public:
- explicit MockSource(const base::UnguessableToken& group_id)
- : group_id_(group_id) {}
+ MockSource() : group_id_(base::UnguessableToken::Create()) {}
~MockSource() override {}
// AudioStreamBrokerFactory::LoopbackSource mocking.
- base::UnguessableToken GetGroupID() override { return group_id_; }
- MOCK_METHOD0(OnStartCapturing, void(void));
- MOCK_METHOD0(OnStopCapturing, void(void));
+ const base::UnguessableToken& GetGroupID() override { return group_id_; }
+ MOCK_METHOD1(AddLoopbackSink, void(AudioStreamBroker::LoopbackSink*));
+ MOCK_METHOD1(RemoveLoopbackSink, void(AudioStreamBroker::LoopbackSink*));
private:
base::UnguessableToken group_id_;
@@ -158,19 +157,17 @@ struct TestEnvironment {
TestEnvironment(const base::UnguessableToken& group_id, bool mute_source) {
// Muting should not start until CreateStream() is called.
EXPECT_CALL(stream_factory, IsMuting(_)).Times(0);
- auto mock_source = std::make_unique<NiceMock<MockSource>>(group_id);
- source = mock_source.get();
+ EXPECT_CALL(source, AddLoopbackSink(_));
broker = std::make_unique<AudioLoopbackStreamBroker>(
- kRenderProcessId, kRenderFrameId, std::move(mock_source), TestParams(),
- kShMemCount, mute_source, deleter.Get(),
- renderer_factory_client.MakePtr());
+ kRenderProcessId, kRenderFrameId, &source, TestParams(), kShMemCount,
+ mute_source, deleter.Get(), renderer_factory_client.MakePtr());
}
void RunUntilIdle() { thread_bundle.RunUntilIdle(); }
TestBrowserThreadBundle thread_bundle;
MockDeleterCallback deleter;
- MockSource* source;
+ MockSource source;
StrictMock<MockRendererAudioInputStreamFactoryClient> renderer_factory_client;
std::unique_ptr<AudioLoopbackStreamBroker> broker;
MockStreamFactory stream_factory;
@@ -184,27 +181,24 @@ TEST(AudioLoopbackStreamBrokerTest, StoresProcessAndFrameId) {
TestBrowserThreadBundle thread_bundle;
MockDeleterCallback deleter;
StrictMock<MockRendererAudioInputStreamFactoryClient> renderer_factory_client;
- auto source = std::make_unique<StrictMock<MockSource>>(
- base::UnguessableToken::Create());
- MockSource* mock_source = source.get();
+ MockSource source;
- EXPECT_CALL(*mock_source, OnStartCapturing());
+ EXPECT_CALL(source, AddLoopbackSink(_));
- AudioLoopbackStreamBroker broker(kRenderProcessId, kRenderFrameId,
- std::move(source), TestParams(), kShMemCount,
- !kMuteSource, deleter.Get(),
- renderer_factory_client.MakePtr());
+ AudioLoopbackStreamBroker broker(
+ kRenderProcessId, kRenderFrameId, &source, TestParams(), kShMemCount,
+ !kMuteSource, deleter.Get(), renderer_factory_client.MakePtr());
EXPECT_EQ(kRenderProcessId, broker.render_process_id());
EXPECT_EQ(kRenderFrameId, broker.render_frame_id());
- EXPECT_CALL(*mock_source, OnStopCapturing());
+ EXPECT_CALL(source, RemoveLoopbackSink(&broker));
}
TEST(AudioLoopbackStreamBrokerTest, StreamCreationSuccess_Propagates) {
TestEnvironment env(base::UnguessableToken::Create(), !kMuteSource);
MockStreamFactory::StreamRequestData stream_request_data(
- env.source->GetGroupID(), TestParams());
+ env.source.GetGroupID(), TestParams());
env.stream_factory.ExpectStreamCreation(&stream_request_data);
EXPECT_CALL(env.stream_factory, IsMuting(_)).Times(0);
@@ -234,10 +228,10 @@ TEST(AudioLoopbackStreamBrokerTest, StreamCreationSuccess_Propagates) {
TEST(AudioLoopbackStreamBrokerTest, MutedStreamCreation_Mutes) {
TestEnvironment env(base::UnguessableToken::Create(), kMuteSource);
MockStreamFactory::StreamRequestData stream_request_data(
- env.source->GetGroupID(), TestParams());
+ env.source.GetGroupID(), TestParams());
env.stream_factory.ExpectStreamCreation(&stream_request_data);
- EXPECT_CALL(env.stream_factory, IsMuting(env.source->GetGroupID()));
+ EXPECT_CALL(env.stream_factory, IsMuting(env.source.GetGroupID()));
env.broker->CreateStream(env.factory_ptr.get());
env.RunUntilIdle();
@@ -264,10 +258,10 @@ TEST(AudioLoopbackStreamBrokerTest, MutedStreamCreation_Mutes) {
TEST(AudioLoopbackStreamBrokerTest, SourceGone_CallsDeleter) {
TestEnvironment env(base::UnguessableToken::Create(), kMuteSource);
MockStreamFactory::StreamRequestData stream_request_data(
- env.source->GetGroupID(), TestParams());
+ env.source.GetGroupID(), TestParams());
env.stream_factory.ExpectStreamCreation(&stream_request_data);
- EXPECT_CALL(env.stream_factory, IsMuting(env.source->GetGroupID()));
+ EXPECT_CALL(env.stream_factory, IsMuting(env.source.GetGroupID()));
env.broker->CreateStream(env.factory_ptr.get());
env.RunUntilIdle();
@@ -289,10 +283,12 @@ TEST(AudioLoopbackStreamBrokerTest, SourceGone_CallsDeleter) {
Mock::VerifyAndClear(&env.renderer_factory_client);
- EXPECT_CALL(env.deleter, Run(env.broker.release()))
- .WillOnce(testing::DeleteArg<0>());
+ EXPECT_CALL(env.deleter, Run(env.broker.get()));
+
+ // Accessing source is not allowed after OnSourceGone.
+ EXPECT_CALL(env.source, RemoveLoopbackSink(_)).Times(0);
- env.source->WebContentsDestroyed();
+ env.broker->OnSourceGone();
env.RunUntilIdle();
}
@@ -300,7 +296,7 @@ TEST(AudioLoopbackStreamBrokerTest, SourceGone_CallsDeleter) {
TEST(AudioLoopbackStreamBrokerTest, StreamCreationFailure_CallsDeleter) {
TestEnvironment env(base::UnguessableToken::Create(), !kMuteSource);
MockStreamFactory::StreamRequestData stream_request_data(
- env.source->GetGroupID(), TestParams());
+ env.source.GetGroupID(), TestParams());
env.stream_factory.ExpectStreamCreation(&stream_request_data);
EXPECT_CALL(env.stream_factory, IsMuting(_)).Times(0);
@@ -321,7 +317,7 @@ TEST(AudioLoopbackStreamBrokerTest,
RendererFactoryClientDisconnect_CallsDeleter) {
TestEnvironment env(base::UnguessableToken::Create(), !kMuteSource);
MockStreamFactory::StreamRequestData stream_request_data(
- env.source->GetGroupID(), TestParams());
+ env.source.GetGroupID(), TestParams());
env.stream_factory.ExpectStreamCreation(&stream_request_data);
EXPECT_CALL(env.stream_factory, IsMuting(_)).Times(0);
@@ -343,7 +339,7 @@ TEST(AudioLoopbackStreamBrokerTest,
TEST(AudioLoopbackStreamBrokerTest, ObserverDisconnect_CallsDeleter) {
TestEnvironment env(base::UnguessableToken::Create(), !kMuteSource);
MockStreamFactory::StreamRequestData stream_request_data(
- env.source->GetGroupID(), TestParams());
+ env.source.GetGroupID(), TestParams());
env.stream_factory.ExpectStreamCreation(&stream_request_data);
EXPECT_CALL(env.stream_factory, IsMuting(_)).Times(0);
diff --git a/chromium/content/browser/media/audio_output_stream_broker.cc b/chromium/content/browser/media/audio_output_stream_broker.cc
index 1ddd0ad978d..2ee519d96de 100644
--- a/chromium/content/browser/media/audio_output_stream_broker.cc
+++ b/chromium/content/browser/media/audio_output_stream_broker.cc
@@ -16,6 +16,48 @@
namespace content {
+namespace {
+
+// Used in Media.Audio.Render.StreamBrokerDisconnectReason2 histogram, matches
+// StreamBrokerDisconnectReason2 enum.
+enum class StreamBrokerDisconnectReason {
+ kDefault = 0,
+ kPlatformError,
+ kTerminatedByClient,
+ kTerminatedByClientAwaitingCreated,
+ kStreamCreationFailed,
+ kDocumentDestroyed,
+ kDocumentDestroyedAwaitingCreated,
+ kMaxValue = kDocumentDestroyedAwaitingCreated
+};
+
+using DisconnectReason =
+ media::mojom::AudioOutputStreamObserver::DisconnectReason;
+
+StreamBrokerDisconnectReason GetDisconnectReason(DisconnectReason reason,
+ bool awaiting_created) {
+ switch (reason) {
+ case DisconnectReason::kPlatformError:
+ return StreamBrokerDisconnectReason::kPlatformError;
+ case DisconnectReason::kTerminatedByClient:
+ return awaiting_created
+ ? StreamBrokerDisconnectReason::
+ kTerminatedByClientAwaitingCreated
+ : StreamBrokerDisconnectReason::kTerminatedByClient;
+ case DisconnectReason::kStreamCreationFailed:
+ return StreamBrokerDisconnectReason::kStreamCreationFailed;
+ case DisconnectReason::kDocumentDestroyed:
+ return awaiting_created
+ ? StreamBrokerDisconnectReason::
+ kDocumentDestroyedAwaitingCreated
+ : StreamBrokerDisconnectReason::kDocumentDestroyed;
+ case DisconnectReason::kDefault:
+ return StreamBrokerDisconnectReason::kDefault;
+ }
+}
+
+} // namespace
+
AudioOutputStreamBroker::AudioOutputStreamBroker(
int render_process_id,
int render_frame_id,
@@ -49,23 +91,34 @@ AudioOutputStreamBroker::AudioOutputStreamBroker(
media_observer->OnCreatingAudioStream(render_process_id, render_frame_id);
// Unretained is safe because |this| owns |client_|
- client_.set_connection_error_handler(base::BindOnce(
- &AudioOutputStreamBroker::ClientBindingLost, base::Unretained(this)));
+ client_.set_connection_error_handler(
+ base::BindOnce(&AudioOutputStreamBroker::Cleanup, base::Unretained(this),
+ DisconnectReason::kTerminatedByClient));
}
AudioOutputStreamBroker::~AudioOutputStreamBroker() {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
- if (awaiting_created_) {
+ const StreamBrokerDisconnectReason reason =
+ GetDisconnectReason(disconnect_reason_, AwaitingCreated());
+
+ if (AwaitingCreated()) {
TRACE_EVENT_NESTABLE_ASYNC_END1("audio", "CreateStream", this, "success",
"failed or cancelled");
}
+
TRACE_EVENT_NESTABLE_ASYNC_END1("audio", "AudioOutputStreamBroker", this,
"disconnect reason",
- static_cast<uint32_t>(disconnect_reason_));
+ static_cast<uint32_t>(reason));
+
+ UMA_HISTOGRAM_ENUMERATION("Media.Audio.Render.StreamBrokerDisconnectReason2",
+ reason);
- UMA_HISTOGRAM_ENUMERATION("Media.Audio.Render.StreamBrokerDisconnectReason",
- disconnect_reason_);
+ if (AwaitingCreated()) {
+ UMA_HISTOGRAM_TIMES(
+ "Media.Audio.Render.StreamBrokerDocumentDestroyedAwaitingCreatedTime",
+ base::TimeTicks::Now() - stream_creation_start_time_);
+ }
}
void AudioOutputStreamBroker::CreateStream(
@@ -74,7 +127,7 @@ void AudioOutputStreamBroker::CreateStream(
DCHECK(!observer_binding_.is_bound());
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("audio", "CreateStream", this, "device id",
output_device_id_);
- awaiting_created_ = true;
+ stream_creation_start_time_ = base::TimeTicks::Now();
// Set up observer ptr. Unretained is safe because |this| owns
// |observer_binding_|.
@@ -107,16 +160,15 @@ void AudioOutputStreamBroker::StreamCreated(
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
TRACE_EVENT_NESTABLE_ASYNC_END1("audio", "CreateStream", this, "success",
!!data_pipe);
- awaiting_created_ = false;
+ UMA_HISTOGRAM_TIMES("Media.Audio.Render.StreamBrokerStreamCreationTime",
+ base::TimeTicks::Now() - stream_creation_start_time_);
+ stream_creation_start_time_ = base::TimeTicks();
+
if (!data_pipe) {
// Stream creation failed. Signal error.
client_.ResetWithReason(
- static_cast<uint32_t>(media::mojom::AudioOutputStreamObserver::
- DisconnectReason::kPlatformError),
- std::string());
- disconnect_reason_ = media::mojom::AudioOutputStreamObserver::
- DisconnectReason::kStreamCreationFailed;
- Cleanup();
+ static_cast<uint32_t>(DisconnectReason::kPlatformError), std::string());
+ Cleanup(DisconnectReason::kStreamCreationFailed);
return;
}
@@ -127,39 +179,31 @@ void AudioOutputStreamBroker::ObserverBindingLost(
uint32_t reason,
const std::string& description) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
-
TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("audio", "ObserverBindingLost", this,
"reset reason", reason);
- const uint32_t maxValidReason = static_cast<uint32_t>(
- media::mojom::AudioOutputStreamObserver::DisconnectReason::kMaxValue);
- if (reason > maxValidReason) {
+ if (reason > static_cast<uint32_t>(DisconnectReason::kMaxValue))
NOTREACHED() << "Invalid reason: " << reason;
- } else if (disconnect_reason_ == media::mojom::AudioOutputStreamObserver::
- DisconnectReason::kDocumentDestroyed) {
- disconnect_reason_ =
- static_cast<media::mojom::AudioOutputStreamObserver::DisconnectReason>(
- reason);
- }
+
+ DisconnectReason reason_enum = static_cast<DisconnectReason>(reason);
// TODO(https://crbug.com/787806): Don't propagate errors if we can retry
// instead.
client_.ResetWithReason(
- static_cast<uint32_t>(media::mojom::AudioOutputStreamObserver::
- DisconnectReason::kPlatformError),
- std::string());
-
- Cleanup();
+ static_cast<uint32_t>(DisconnectReason::kPlatformError), std::string());
+ Cleanup((reason_enum == DisconnectReason::kPlatformError && AwaitingCreated())
+ ? DisconnectReason::kStreamCreationFailed
+ : reason_enum);
}
-void AudioOutputStreamBroker::ClientBindingLost() {
- disconnect_reason_ = media::mojom::AudioOutputStreamObserver::
- DisconnectReason::kTerminatedByClient;
- Cleanup();
-}
-
-void AudioOutputStreamBroker::Cleanup() {
+void AudioOutputStreamBroker::Cleanup(DisconnectReason reason) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
+ DCHECK_EQ(DisconnectReason::kDocumentDestroyed, disconnect_reason_);
+ disconnect_reason_ = reason;
std::move(deleter_).Run(this);
}
+bool AudioOutputStreamBroker::AwaitingCreated() const {
+ return stream_creation_start_time_ != base::TimeTicks();
+}
+
} // namespace content
diff --git a/chromium/content/browser/media/audio_output_stream_broker.h b/chromium/content/browser/media/audio_output_stream_broker.h
index 0f044081998..458a78caa6b 100644
--- a/chromium/content/browser/media/audio_output_stream_broker.h
+++ b/chromium/content/browser/media/audio_output_stream_broker.h
@@ -44,11 +44,14 @@ class CONTENT_EXPORT AudioOutputStreamBroker final : public AudioStreamBroker {
void CreateStream(audio::mojom::StreamFactory* factory) final;
private:
+ using DisconnectReason =
+ media::mojom::AudioOutputStreamObserver::DisconnectReason;
+
void StreamCreated(media::mojom::AudioOutputStreamPtr stream,
media::mojom::ReadWriteAudioDataPipePtr data_pipe);
void ObserverBindingLost(uint32_t reason, const std::string& description);
- void ClientBindingLost();
- void Cleanup();
+ void Cleanup(DisconnectReason reason);
+ bool AwaitingCreated() const;
SEQUENCE_CHECKER(owning_sequence_);
@@ -57,8 +60,8 @@ class CONTENT_EXPORT AudioOutputStreamBroker final : public AudioStreamBroker {
const base::UnguessableToken group_id_;
const base::Optional<base::UnguessableToken> processing_id_;
- // Indicates that CreateStream has been called, but not StreamCreated.
- bool awaiting_created_ = false;
+ // Set while CreateStream() has been called, but not StreamCreated().
+ base::TimeTicks stream_creation_start_time_;
DeleterCallback deleter_;
@@ -68,9 +71,7 @@ class CONTENT_EXPORT AudioOutputStreamBroker final : public AudioStreamBroker {
mojo::AssociatedBinding<media::mojom::AudioOutputStreamObserver>
observer_binding_;
- media::mojom::AudioOutputStreamObserver::DisconnectReason disconnect_reason_ =
- media::mojom::AudioOutputStreamObserver::DisconnectReason::
- kDocumentDestroyed;
+ DisconnectReason disconnect_reason_ = DisconnectReason::kDocumentDestroyed;
base::WeakPtrFactory<AudioOutputStreamBroker> weak_ptr_factory_;
diff --git a/chromium/content/browser/media/audio_stream_broker.cc b/chromium/content/browser/media/audio_stream_broker.cc
index 9894ff13d7c..875d810eb3d 100644
--- a/chromium/content/browser/media/audio_stream_broker.cc
+++ b/chromium/content/browser/media/audio_stream_broker.cc
@@ -6,9 +6,15 @@
#include <utility>
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/task/post_task.h"
#include "content/browser/media/audio_input_stream_broker.h"
#include "content/browser/media/audio_loopback_stream_broker.h"
#include "content/browser/media/audio_output_stream_broker.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
namespace content {
@@ -25,6 +31,7 @@ class AudioStreamBrokerFactoryImpl final : public AudioStreamBrokerFactory {
const std::string& device_id,
const media::AudioParameters& params,
uint32_t shared_memory_count,
+ media::UserInputMonitorBase* user_input_monitor,
bool enable_agc,
audio::mojom::AudioProcessingConfigPtr processing_config,
AudioStreamBroker::DeleterCallback deleter,
@@ -32,14 +39,15 @@ class AudioStreamBrokerFactoryImpl final : public AudioStreamBrokerFactory {
final {
return std::make_unique<AudioInputStreamBroker>(
render_process_id, render_frame_id, device_id, params,
- shared_memory_count, enable_agc, std::move(processing_config),
- std::move(deleter), std::move(renderer_factory_client));
+ shared_memory_count, user_input_monitor, enable_agc,
+ std::move(processing_config), std::move(deleter),
+ std::move(renderer_factory_client));
}
std::unique_ptr<AudioStreamBroker> CreateAudioLoopbackStreamBroker(
int render_process_id,
int render_frame_id,
- std::unique_ptr<LoopbackSource> source,
+ AudioStreamBroker::LoopbackSource* source,
const media::AudioParameters& params,
uint32_t shared_memory_count,
bool mute_source,
@@ -47,9 +55,8 @@ class AudioStreamBrokerFactoryImpl final : public AudioStreamBrokerFactory {
mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client)
final {
return std::make_unique<AudioLoopbackStreamBroker>(
- render_process_id, render_frame_id, std::move(source), params,
- shared_memory_count, mute_source, std::move(deleter),
- std::move(renderer_factory_client));
+ render_process_id, render_frame_id, source, params, shared_memory_count,
+ mute_source, std::move(deleter), std::move(renderer_factory_client));
}
std::unique_ptr<AudioStreamBroker> CreateAudioOutputStreamBroker(
@@ -70,11 +77,39 @@ class AudioStreamBrokerFactoryImpl final : public AudioStreamBrokerFactory {
} // namespace
+AudioStreamBroker::LoopbackSink::LoopbackSink() = default;
+AudioStreamBroker::LoopbackSink::~LoopbackSink() = default;
+
+AudioStreamBroker::LoopbackSource::LoopbackSource() = default;
+AudioStreamBroker::LoopbackSource::~LoopbackSource() = default;
+
AudioStreamBroker::AudioStreamBroker(int render_process_id, int render_frame_id)
: render_process_id_(render_process_id),
render_frame_id_(render_frame_id) {}
AudioStreamBroker::~AudioStreamBroker() {}
+// static
+void AudioStreamBroker::NotifyProcessHostOfStartedStream(
+ int render_process_id) {
+ auto impl = [](int id) {
+ if (auto* process_host = RenderProcessHost::FromID(id))
+ process_host->OnMediaStreamAdded();
+ };
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(impl, render_process_id));
+}
+
+// static
+void AudioStreamBroker::NotifyProcessHostOfStoppedStream(
+ int render_process_id) {
+ auto impl = [](int id) {
+ if (auto* process_host = RenderProcessHost::FromID(id))
+ process_host->OnMediaStreamRemoved();
+ };
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(impl, render_process_id));
+}
+
AudioStreamBrokerFactory::AudioStreamBrokerFactory() {}
AudioStreamBrokerFactory::~AudioStreamBrokerFactory() {}
diff --git a/chromium/content/browser/media/audio_stream_broker.h b/chromium/content/browser/media/audio_stream_broker.h
index e8deaa11bae..24d8928f4ba 100644
--- a/chromium/content/browser/media/audio_stream_broker.h
+++ b/chromium/content/browser/media/audio_stream_broker.h
@@ -5,15 +5,15 @@
#ifndef CONTENT_BROWSER_MEDIA_AUDIO_STREAM_BROKER_H_
#define CONTENT_BROWSER_MEDIA_AUDIO_STREAM_BROKER_H_
+#include <cstdint>
#include <memory>
#include <string>
-#include <utility>
#include "base/callback.h"
#include "base/macros.h"
+#include "base/optional.h"
#include "content/common/content_export.h"
#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
-#include "content/public/browser/web_contents_observer.h"
#include "media/mojo/interfaces/audio_input_stream.mojom.h"
#include "media/mojo/interfaces/audio_output_stream.mojom.h"
#include "services/audio/public/mojom/audio_processing.mojom.h"
@@ -30,16 +30,39 @@ class UnguessableToken;
namespace media {
class AudioParameters;
+class UserInputMonitorBase;
}
namespace content {
-class WebContents;
// An AudioStreamBroker is used to broker a connection between a client
// (typically renderer) and the audio service. It also sets up all objects
-// used for monitoring the stream.
+// used for monitoring the stream. All AudioStreamBrokers are used on the IO
+// thread.
class CONTENT_EXPORT AudioStreamBroker {
public:
+ class CONTENT_EXPORT LoopbackSink {
+ public:
+ LoopbackSink();
+ virtual ~LoopbackSink();
+ virtual void OnSourceGone() = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LoopbackSink);
+ };
+
+ class CONTENT_EXPORT LoopbackSource {
+ public:
+ LoopbackSource();
+ virtual ~LoopbackSource();
+ virtual void AddLoopbackSink(LoopbackSink* sink) = 0;
+ virtual void RemoveLoopbackSink(LoopbackSink* sink) = 0;
+ virtual const base::UnguessableToken& GetGroupID() = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LoopbackSource);
+ };
+
using DeleterCallback = base::OnceCallback<void(AudioStreamBroker*)>;
AudioStreamBroker(int render_process_id, int render_frame_id);
@@ -47,6 +70,13 @@ class CONTENT_EXPORT AudioStreamBroker {
virtual void CreateStream(audio::mojom::StreamFactory* factory) = 0;
+ // Thread-safe utility that notifies the process host identified by
+ // |render_process_id| of a started stream to ensure that the renderer is not
+ // backgrounded. Must be paired with a later call to
+ // NotifyRenderProcessOfStoppedStream()
+ static void NotifyProcessHostOfStartedStream(int render_process_id);
+ static void NotifyProcessHostOfStoppedStream(int render_process_id);
+
int render_process_id() const { return render_process_id_; }
int render_frame_id() const { return render_frame_id_; }
@@ -58,41 +88,10 @@ class CONTENT_EXPORT AudioStreamBroker {
DISALLOW_COPY_AND_ASSIGN(AudioStreamBroker);
};
-// Used for dependency injection into ForwardingAudioStreamFactory.
+// Used for dependency injection into ForwardingAudioStreamFactory. Used on the
+// IO thread.
class CONTENT_EXPORT AudioStreamBrokerFactory {
public:
- class CONTENT_EXPORT LoopbackSource : public WebContentsObserver {
- public:
- explicit LoopbackSource(WebContents* source_contents);
- ~LoopbackSource() override;
-
- // Virtual for mocking in tests.
- // Will return an empty token if the source is not present.
-
- virtual base::UnguessableToken GetGroupID();
-
- // Signals the source WebContents that capturing started.
- virtual void OnStartCapturing();
-
- // Signals the source WebContents that capturing stopped.
- virtual void OnStopCapturing();
-
- // Sets the closure to run when the source WebContents is gone.
- void set_on_gone_closure(base::OnceClosure on_gone_closure) {
- on_gone_closure_ = std::move(on_gone_closure);
- }
-
- // WebContentsObserver implementation.
- void WebContentsDestroyed() override;
-
- protected:
- LoopbackSource();
-
- private:
- base::OnceClosure on_gone_closure_;
- DISALLOW_COPY_AND_ASSIGN(LoopbackSource);
- };
-
static std::unique_ptr<AudioStreamBrokerFactory> CreateImpl();
AudioStreamBrokerFactory();
@@ -104,6 +103,7 @@ class CONTENT_EXPORT AudioStreamBrokerFactory {
const std::string& device_id,
const media::AudioParameters& params,
uint32_t shared_memory_count,
+ media::UserInputMonitorBase* user_input_monitor,
bool enable_agc,
audio::mojom::AudioProcessingConfigPtr processing_config,
AudioStreamBroker::DeleterCallback deleter,
@@ -113,7 +113,7 @@ class CONTENT_EXPORT AudioStreamBrokerFactory {
virtual std::unique_ptr<AudioStreamBroker> CreateAudioLoopbackStreamBroker(
int render_process_id,
int render_frame_id,
- std::unique_ptr<LoopbackSource> source,
+ AudioStreamBroker::LoopbackSource* source,
const media::AudioParameters& params,
uint32_t shared_memory_count,
bool mute_source,
@@ -132,8 +132,6 @@ class CONTENT_EXPORT AudioStreamBrokerFactory {
AudioStreamBroker::DeleterCallback deleter,
media::mojom::AudioOutputStreamProviderClientPtr client) = 0;
- // TODO(https://crbug.com/830493): Other kinds of streams.
-
private:
DISALLOW_COPY_AND_ASSIGN(AudioStreamBrokerFactory);
};
diff --git a/chromium/content/browser/media/audio_stream_monitor.cc b/chromium/content/browser/media/audio_stream_monitor.cc
index 17b5cb761c6..35d95f3883d 100644
--- a/chromium/content/browser/media/audio_stream_monitor.cc
+++ b/chromium/content/browser/media/audio_stream_monitor.cc
@@ -7,8 +7,10 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/stl_util.h"
+#include "base/task/post_task.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/invalidate_type.h"
@@ -82,8 +84,8 @@ void AudioStreamMonitor::RenderProcessGone(int render_process_id) {
void AudioStreamMonitor::StartMonitoringStream(int render_process_id,
int render_frame_id,
int stream_id) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
[](const StreamID& sid) {
if (AudioStreamMonitor* monitor = GetMonitorForRenderFrame(
@@ -98,8 +100,8 @@ void AudioStreamMonitor::StartMonitoringStream(int render_process_id,
void AudioStreamMonitor::StopMonitoringStream(int render_process_id,
int render_frame_id,
int stream_id) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
[](const StreamID& sid) {
if (AudioStreamMonitor* monitor = GetMonitorForRenderFrame(
@@ -115,8 +117,8 @@ void AudioStreamMonitor::UpdateStreamAudibleState(int render_process_id,
int render_frame_id,
int stream_id,
bool is_audible) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
[](const StreamID& sid, bool is_audible) {
if (AudioStreamMonitor* monitor = GetMonitorForRenderFrame(
diff --git a/chromium/content/browser/media/capture/audio_mirroring_manager.cc b/chromium/content/browser/media/capture/audio_mirroring_manager.cc
index 32544941366..c630a2b85af 100644
--- a/chromium/content/browser/media/capture/audio_mirroring_manager.cc
+++ b/chromium/content/browser/media/capture/audio_mirroring_manager.cc
@@ -50,7 +50,7 @@ void AudioMirroringManager::RemoveDiverter(Diverter* diverter) {
// Find and remove the entry from the routing table. If the stream is being
// diverted, it is stopped.
- for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
+ for (auto it = routes_.begin(); it != routes_.end(); ++it) {
if (it->diverter == diverter) {
// Stop the diverted flow.
RouteDivertedFlow(&(*it), nullptr);
@@ -103,7 +103,7 @@ void AudioMirroringManager::StopMirroring(MirroringDestination* destination) {
// Each stopped stream becomes a candidate to be diverted to another
// destination.
std::set<GlobalFrameRoutingId> redivert_candidates;
- for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
+ for (auto it = routes_.begin(); it != routes_.end(); ++it) {
if (it->destination == destination) {
RouteDivertedFlow(&(*it), nullptr);
redivert_candidates.insert(it->source_render_frame);
@@ -202,7 +202,7 @@ void AudioMirroringManager::UpdateRoutesToDivertDestination(
// Start/stop diverting based on |matches|. Any stopped stream becomes a
// candidate to be diverted to another destination.
std::set<GlobalFrameRoutingId> redivert_candidates;
- for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
+ for (auto it = routes_.begin(); it != routes_.end(); ++it) {
if (matches.find(it->source_render_frame) != matches.end()) {
// Only change the route if the stream is not already being diverted.
if (!it->destination)
@@ -230,7 +230,7 @@ void AudioMirroringManager::UpdateRoutesToDuplicateDestination(
return; // Query result callback invoked after StopMirroring().
}
- for (StreamRoutes::iterator it = routes_.begin(); it != routes_.end(); ++it) {
+ for (auto it = routes_.begin(); it != routes_.end(); ++it) {
if (matches.find(it->source_render_frame) != matches.end()) {
// The same destination cannot have both a diverted audio flow and a
// duplicated flow from the same source.
diff --git a/chromium/content/browser/media/capture/audio_mirroring_manager_unittest.cc b/chromium/content/browser/media/capture/audio_mirroring_manager_unittest.cc
index d128405139c..a2e413773c8 100644
--- a/chromium/content/browser/media/capture/audio_mirroring_manager_unittest.cc
+++ b/chromium/content/browser/media/capture/audio_mirroring_manager_unittest.cc
@@ -12,6 +12,8 @@
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
@@ -78,9 +80,10 @@ class MockMirroringDestination
render_process_id_, render_frame_id_)) != candidates.end()) {
result.insert(GlobalFrameRoutingId(render_process_id_, render_frame_id_));
}
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(std::move(*results_callback),
- std::move(result), is_duplication_));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(std::move(*results_callback), std::move(result),
+ is_duplication_));
}
media::AudioOutputStream* SimulateAddInput(
@@ -194,7 +197,7 @@ class AudioMirroringManagerTest : public testing::Test {
int CountStreamsDivertedTo(
const std::unique_ptr<MockMirroringDestination>& dest) const {
int count = 0;
- for (StreamRoutes::const_iterator it = mirroring_manager_.routes_.begin();
+ for (auto it = mirroring_manager_.routes_.begin();
it != mirroring_manager_.routes_.end(); ++it) {
if (it->destination == dest.get())
++count;
@@ -205,7 +208,7 @@ class AudioMirroringManagerTest : public testing::Test {
int CountStreamsDuplicatedTo(
const std::unique_ptr<MockMirroringDestination>& dest) const {
int count = 0;
- for (StreamRoutes::const_iterator it = mirroring_manager_.routes_.begin();
+ for (auto it = mirroring_manager_.routes_.begin();
it != mirroring_manager_.routes_.end(); ++it) {
if (it->duplications.find(dest.get()) != it->duplications.end())
++count;
diff --git a/chromium/content/browser/media/capture/aura_window_video_capture_device.cc b/chromium/content/browser/media/capture/aura_window_video_capture_device.cc
index 72b973e16a8..cce6a7d8609 100644
--- a/chromium/content/browser/media/capture/aura_window_video_capture_device.cc
+++ b/chromium/content/browser/media/capture/aura_window_video_capture_device.cc
@@ -11,8 +11,10 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/media/capture/mouse_cursor_overlay_controller.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "media/base/bind_to_current_loop.h"
@@ -43,8 +45,8 @@ class AuraWindowVideoCaptureDevice::WindowTracker
DCHECK(device_task_runner_);
DCHECK(cursor_controller_);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&WindowTracker::ResolveTarget, AsWeakPtr(), source_id));
}
@@ -144,8 +146,8 @@ AuraWindowVideoCaptureDevice::~AuraWindowVideoCaptureDevice() = default;
#if defined(OS_CHROMEOS)
void AuraWindowVideoCaptureDevice::CreateCapturer(
viz::mojom::FrameSinkVideoCapturerRequest request) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
[](base::WeakPtr<WindowTracker> tracker_ptr,
viz::mojom::FrameSinkVideoCapturerRequest request) {
diff --git a/chromium/content/browser/media/capture/aura_window_video_capture_device_browsertest.cc b/chromium/content/browser/media/capture/aura_window_video_capture_device_browsertest.cc
index 7ba9955087b..a82d34d5cb3 100644
--- a/chromium/content/browser/media/capture/aura_window_video_capture_device_browsertest.cc
+++ b/chromium/content/browser/media/capture/aura_window_video_capture_device_browsertest.cc
@@ -8,11 +8,13 @@
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "cc/test/pixel_test_utils.h"
#include "content/browser/media/capture/content_capture_device_browsertest_base.h"
#include "content/browser/media/capture/fake_video_capture_stack.h"
#include "content/browser/media/capture/frame_test_util.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "content/public/browser/web_contents.h"
@@ -152,9 +154,9 @@ class AuraWindowVideoCaptureDeviceBrowserTest
// Wait for at least the minimum capture period before checking for more
// captured frames.
base::RunLoop run_loop;
- BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
- run_loop.QuitClosure(),
- GetMinCapturePeriod());
+ base::PostDelayedTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ run_loop.QuitClosure(),
+ GetMinCapturePeriod());
run_loop.Run();
}
}
@@ -256,9 +258,9 @@ IN_PROC_BROWSER_TEST_F(AuraWindowVideoCaptureDeviceBrowserTest,
// frames were queued because the device should be suspended.
ChangePageContentColor(SK_ColorGREEN);
base::RunLoop run_loop;
- BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
- run_loop.QuitClosure(),
- base::TimeDelta::FromSeconds(5));
+ base::PostDelayedTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ run_loop.QuitClosure(),
+ base::TimeDelta::FromSeconds(5));
run_loop.Run();
EXPECT_FALSE(HasCapturedFramesInQueue());
diff --git a/chromium/content/browser/media/capture/desktop_capture_device.cc b/chromium/content/browser/media/capture/desktop_capture_device.cc
index 50510bdefb7..7e9d1927948 100644
--- a/chromium/content/browser/media/capture/desktop_capture_device.cc
+++ b/chromium/content/browser/media/capture/desktop_capture_device.cc
@@ -19,12 +19,14 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.h"
+#include "base/task/post_task.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/tick_clock.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "content/browser/media/capture/desktop_capture_device_uma_types.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_capture.h"
#include "content/public/browser/desktop_media_id.h"
@@ -254,8 +256,8 @@ void DesktopCaptureDevice::Core::AllocateAndStart(
// TODO(https://crbug.com/823869): Fix DesktopCaptureDeviceTest and remove
// this conditional.
if (BrowserThread::IsThreadInitialized(BrowserThread::UI)) {
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE, base::BindOnce(&GetServiceConnector),
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI}, base::BindOnce(&GetServiceConnector),
base::BindOnce(&DesktopCaptureDevice::Core::RequestWakeLock,
weak_factory_.GetWeakPtr()));
}
diff --git a/chromium/content/browser/media/capture/desktop_capture_device_unittest.cc b/chromium/content/browser/media/capture/desktop_capture_device_unittest.cc
index 636f20a88bd..b517707f920 100644
--- a/chromium/content/browser/media/capture/desktop_capture_device_unittest.cc
+++ b/chromium/content/browser/media/capture/desktop_capture_device_unittest.cc
@@ -230,18 +230,13 @@ class DesktopCaptureDeviceTest : public testing::Test {
std::unique_ptr<media::MockVideoCaptureDeviceClient>
CreateMockVideoCaptureDeviceClient() {
auto result = std::make_unique<media::MockVideoCaptureDeviceClient>();
- ON_CALL(*result, ReserveOutputBuffer(_, _, _))
- .WillByDefault(
- Invoke([](const gfx::Size&, media::VideoPixelFormat format, int) {
- EXPECT_TRUE(format == media::PIXEL_FORMAT_I420);
- return media::VideoCaptureDevice::Client::Buffer();
- }));
- ON_CALL(*result, ResurrectLastOutputBuffer(_, _, _))
- .WillByDefault(
- Invoke([](const gfx::Size&, media::VideoPixelFormat format, int) {
- EXPECT_TRUE(format == media::PIXEL_FORMAT_I420);
- return media::VideoCaptureDevice::Client::Buffer();
- }));
+ ON_CALL(*result, ReserveOutputBuffer(_, _, _, _))
+ .WillByDefault(Invoke([](const gfx::Size&,
+ media::VideoPixelFormat format, int,
+ media::VideoCaptureDevice::Client::Buffer*) {
+ EXPECT_TRUE(format == media::PIXEL_FORMAT_I420);
+ return media::VideoCaptureDevice::Client::ReserveResult::kSucceeded;
+ }));
return result;
}
diff --git a/chromium/content/browser/media/capture/desktop_streams_registry_impl.cc b/chromium/content/browser/media/capture/desktop_streams_registry_impl.cc
index 347e00ab4d1..5c78c89b19e 100644
--- a/chromium/content/browser/media/capture/desktop_streams_registry_impl.cc
+++ b/chromium/content/browser/media/capture/desktop_streams_registry_impl.cc
@@ -9,7 +9,9 @@
#include "base/macros.h"
#include "base/no_destructor.h"
#include "base/stl_util.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "crypto/random.h"
@@ -64,8 +66,8 @@ std::string DesktopStreamsRegistryImpl::RegisterStream(
stream.extension_name = extension_name;
stream.type = type;
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DesktopStreamsRegistryImpl::CleanupStream,
base::Unretained(this), id),
base::TimeDelta::FromSeconds(kApprovedStreamTimeToLiveSeconds));
@@ -82,7 +84,7 @@ DesktopMediaID DesktopStreamsRegistryImpl::RequestMediaForStreamId(
const DesktopStreamRegistryType type) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- StreamsMap::iterator it = approved_streams_.find(id);
+ auto it = approved_streams_.find(id);
// Verify that if there is a request with the specified ID it was created for
// the same origin and the same renderer.
diff --git a/chromium/content/browser/media/capture/fake_video_capture_stack.cc b/chromium/content/browser/media/capture/fake_video_capture_stack.cc
index 11429d03374..288d5564d0e 100644
--- a/chromium/content/browser/media/capture/fake_video_capture_stack.cc
+++ b/chromium/content/browser/media/capture/fake_video_capture_stack.cc
@@ -65,6 +65,8 @@ class FakeVideoCaptureStack::Receiver : public media::VideoFrameReceiver {
mapping.size(), frame_info->timestamp);
CHECK(frame);
frame->metadata()->MergeInternalValuesFrom(frame_info->metadata);
+ if (frame_info->color_space.has_value())
+ frame->set_color_space(frame_info->color_space.value());
// This destruction observer will unmap the shared memory when the
// VideoFrame goes out-of-scope.
frame->AddDestructionObserver(base::BindOnce(
diff --git a/chromium/content/browser/media/capture/frame_sink_video_capture_device.cc b/chromium/content/browser/media/capture/frame_sink_video_capture_device.cc
index cded50f3122..0ff5cc4b692 100644
--- a/chromium/content/browser/media/capture/frame_sink_video_capture_device.cc
+++ b/chromium/content/browser/media/capture/frame_sink_video_capture_device.cc
@@ -14,11 +14,13 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/numerics/safe_conversions.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/media/capture/mouse_cursor_overlay_controller.h"
+#include "content/public/browser/browser_task_traits.h"
#include "media/base/bind_to_current_loop.h"
#include "media/capture/mojom/video_capture_types.mojom.h"
@@ -91,7 +93,7 @@ void FrameSinkVideoCaptureDevice::AllocateAndStartWithReceiver(
base::Unretained(this)));
capturer_->SetFormat(capture_params_.requested_format.pixel_format,
- media::COLOR_SPACE_UNSPECIFIED);
+ gfx::ColorSpace::CreateREC709());
capturer_->SetMinCapturePeriod(
base::TimeDelta::FromMicroseconds(base::saturated_cast<int64_t>(
base::Time::kMicrosecondsPerSecond /
@@ -105,8 +107,8 @@ void FrameSinkVideoCaptureDevice::AllocateAndStartWithReceiver(
capturer_->ChangeTarget(target_);
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&MouseCursorOverlayController::Start,
cursor_controller_->GetWeakPtr(),
capturer_->CreateOverlay(kMouseCursorStackingIndex),
@@ -153,9 +155,9 @@ void FrameSinkVideoCaptureDevice::Resume() {
void FrameSinkVideoCaptureDevice::StopAndDeAllocate() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&MouseCursorOverlayController::Stop,
- cursor_controller_->GetWeakPtr()));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&MouseCursorOverlayController::Stop,
+ cursor_controller_->GetWeakPtr()));
MaybeStopConsuming();
capturer_.reset();
@@ -278,8 +280,8 @@ void FrameSinkVideoCaptureDevice::CreateCapturerViaGlobalManager(
viz::mojom::FrameSinkVideoCapturerRequest request) {
// Send the request to UI thread because that's where HostFrameSinkManager
// lives.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
[](viz::mojom::FrameSinkVideoCapturerRequest request) {
viz::HostFrameSinkManager* const manager =
diff --git a/chromium/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc b/chromium/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc
index 341c3a04df6..c0aee9d274d 100644
--- a/chromium/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc
+++ b/chromium/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc
@@ -11,6 +11,8 @@
#include "base/containers/flat_map.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/shared_memory_mapping.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "media/base/video_frame.h"
@@ -51,7 +53,7 @@ namespace {
// Convenience macro to post a task to run on the device thread.
#define POST_DEVICE_TASK(closure) \
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, closure)
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO}, closure)
// Convenience macro to block the test procedure until all pending tasks have
// run on the device thread.
@@ -86,7 +88,7 @@ class MockFrameSinkVideoCapturer : public viz::mojom::FrameSinkVideoCapturer {
MOCK_METHOD2(SetFormat,
void(media::VideoPixelFormat format,
- media::ColorSpace color_space));
+ const gfx::ColorSpace& color_space));
MOCK_METHOD1(SetMinCapturePeriod, void(base::TimeDelta min_period));
MOCK_METHOD1(SetMinSizeChangePeriod, void(base::TimeDelta));
MOCK_METHOD3(SetResolutionConstraints,
@@ -258,8 +260,8 @@ class FrameSinkVideoCaptureDeviceForTest : public FrameSinkVideoCaptureDevice {
protected:
void CreateCapturer(viz::mojom::FrameSinkVideoCapturerRequest request) final {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
[](MockFrameSinkVideoCapturer* capturer,
viz::mojom::FrameSinkVideoCapturerRequest request) {
@@ -371,7 +373,8 @@ class FrameSinkVideoCaptureDeviceTest : public testing::Test {
media::mojom::VideoFrameInfo::New(
kMinCapturePeriod * frame_number,
base::Value(base::Value::Type::DICTIONARY), kFormat,
- kResolution, gfx::Rect(kResolution)),
+ kResolution, gfx::Rect(kResolution),
+ gfx::ColorSpace::CreateREC709(), nullptr),
gfx::Rect(kResolution), gfx::Rect(kResolution),
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr(
std::move(callbacks_info)));
diff --git a/chromium/content/browser/media/capture/lame_window_capturer_chromeos.cc b/chromium/content/browser/media/capture/lame_window_capturer_chromeos.cc
index 2a9275ecb73..e0e419769ec 100644
--- a/chromium/content/browser/media/capture/lame_window_capturer_chromeos.cc
+++ b/chromium/content/browser/media/capture/lame_window_capturer_chromeos.cc
@@ -48,13 +48,12 @@ LameWindowCapturerChromeOS::~LameWindowCapturerChromeOS() {
}
void LameWindowCapturerChromeOS::SetFormat(media::VideoPixelFormat format,
- media::ColorSpace color_space) {
+ const gfx::ColorSpace& color_space) {
if (format != media::PIXEL_FORMAT_I420) {
LOG(DFATAL) << "Invalid pixel format: Only I420 is supported.";
}
- if (color_space != media::COLOR_SPACE_UNSPECIFIED &&
- color_space != media::COLOR_SPACE_HD_REC709) {
+ if (color_space.IsValid() && color_space != gfx::ColorSpace::CreateREC709()) {
LOG(DFATAL) << "Unsupported color space: Only BT.709 is supported.";
}
}
@@ -263,12 +262,11 @@ void LameWindowCapturerChromeOS::CaptureNextFrame() {
DCHECK(frame);
VideoFrameMetadata* const metadata = frame->metadata();
metadata->SetTimeTicks(VideoFrameMetadata::CAPTURE_BEGIN_TIME, begin_time);
- metadata->SetInteger(VideoFrameMetadata::COLOR_SPACE,
- media::COLOR_SPACE_HD_REC709);
metadata->SetTimeDelta(VideoFrameMetadata::FRAME_DURATION, capture_period_);
metadata->SetDouble(VideoFrameMetadata::FRAME_RATE,
1.0 / capture_period_.InSecondsF());
metadata->SetTimeTicks(VideoFrameMetadata::REFERENCE_TIME, begin_time);
+ frame->set_color_space(gfx::ColorSpace::CreateREC709());
// Compute the region of the VideoFrame that will contain the content. If
// there is nothing to copy from/to (e.g., the target is gone, or is sized too
diff --git a/chromium/content/browser/media/capture/lame_window_capturer_chromeos.h b/chromium/content/browser/media/capture/lame_window_capturer_chromeos.h
index 6af4c60068e..0ba5f913056 100644
--- a/chromium/content/browser/media/capture/lame_window_capturer_chromeos.h
+++ b/chromium/content/browser/media/capture/lame_window_capturer_chromeos.h
@@ -56,7 +56,7 @@ class LameWindowCapturerChromeOS : public viz::mojom::FrameSinkVideoCapturer,
// viz::mojom::FrameSinkVideoCapturer implementation.
void SetFormat(media::VideoPixelFormat format,
- media::ColorSpace color_space) final;
+ const gfx::ColorSpace& color_space) final;
void SetMinCapturePeriod(base::TimeDelta min_capture_period) final;
void SetMinSizeChangePeriod(base::TimeDelta min_period) final;
void SetResolutionConstraints(const gfx::Size& min_size,
diff --git a/chromium/content/browser/media/capture/mouse_cursor_overlay_controller_browsertest.cc b/chromium/content/browser/media/capture/mouse_cursor_overlay_controller_browsertest.cc
index 5a05b17ff0b..324b1c04850 100644
--- a/chromium/content/browser/media/capture/mouse_cursor_overlay_controller_browsertest.cc
+++ b/chromium/content/browser/media/capture/mouse_cursor_overlay_controller_browsertest.cc
@@ -6,6 +6,8 @@
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/content_browser_test.h"
@@ -61,8 +63,9 @@ class MouseCursorOverlayControllerBrowserTest : public ContentBrowserTest {
auto overlay_ptr = std::make_unique<FakeOverlay>();
FakeOverlay* const overlay = overlay_ptr.get();
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- controller_.Start(std::move(overlay_ptr),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI));
+ controller_.Start(
+ std::move(overlay_ptr),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}));
return overlay;
}
diff --git a/chromium/content/browser/media/capture/screen_capture_device_android_unittest.cc b/chromium/content/browser/media/capture/screen_capture_device_android_unittest.cc
index ffbe9c52a13..ef590730d52 100644
--- a/chromium/content/browser/media/capture/screen_capture_device_android_unittest.cc
+++ b/chromium/content/browser/media/capture/screen_capture_device_android_unittest.cc
@@ -45,12 +45,14 @@ class MockDeviceClient : public media::VideoCaptureDevice::Client {
MOCK_METHOD0(OnStarted, void(void));
// Trampoline methods to workaround GMOCK problems with std::unique_ptr<>.
- Buffer ReserveOutputBuffer(const gfx::Size& dimensions,
- media::VideoPixelFormat format,
- int frame_feedback_id) override {
+ media::VideoCaptureDevice::Client::ReserveResult ReserveOutputBuffer(
+ const gfx::Size& dimensions,
+ media::VideoPixelFormat format,
+ int frame_feedback_id,
+ Buffer* buffer) override {
EXPECT_EQ(media::PIXEL_FORMAT_I420, format);
DoReserveOutputBuffer();
- return Buffer();
+ return media::VideoCaptureDevice::Client::ReserveResult::kSucceeded;
}
void OnIncomingCapturedBuffer(Buffer buffer,
const media::VideoCaptureFormat& frame_format,
@@ -67,13 +69,6 @@ class MockDeviceClient : public media::VideoCaptureDevice::Client {
const media::VideoFrameMetadata& additional_metadata) override {
DoOnIncomingCapturedVideoFrame();
}
- Buffer ResurrectLastOutputBuffer(const gfx::Size& dimensions,
- media::VideoPixelFormat format,
- int frame_feedback_id) override {
- EXPECT_EQ(media::PIXEL_FORMAT_I420, format);
- DoResurrectLastOutputBuffer();
- return Buffer();
- }
};
class ScreenCaptureDeviceAndroidTest : public testing::Test {
diff --git a/chromium/content/browser/media/capture/web_contents_audio_input_stream.cc b/chromium/content/browser/media/capture/web_contents_audio_input_stream.cc
index 75d9bee6e9a..0329e1b1a7b 100644
--- a/chromium/content/browser/media/capture/web_contents_audio_input_stream.cc
+++ b/chromium/content/browser/media/capture/web_contents_audio_input_stream.cc
@@ -12,9 +12,11 @@
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_checker.h"
#include "content/browser/media/capture/audio_mirroring_manager.h"
#include "content/browser/media/capture/web_contents_tracker.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "content/public/browser/render_frame_host.h"
@@ -184,8 +186,8 @@ bool WebContentsAudioInputStream::Impl::Open() {
void WebContentsAudioInputStream::Impl::IncrementCapturerCount() {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Impl::IncrementCapturerCount, this));
return;
}
@@ -217,8 +219,8 @@ void WebContentsAudioInputStream::Impl::Start(AudioInputCallback* callback) {
// WebContents audio muting is implemented as audio capture to nowhere.
// Unmuting will stop that audio capture, allowing AudioMirroringManager to
// divert audio capture to here.
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&Impl::UnmuteWebContentsAudio, this));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&Impl::UnmuteWebContentsAudio, this));
}
void WebContentsAudioInputStream::Impl::Stop() {
@@ -253,8 +255,8 @@ void WebContentsAudioInputStream::Impl::Close() {
void WebContentsAudioInputStream::Impl::DecrementCapturerCount() {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Impl::DecrementCapturerCount, this));
return;
}
@@ -273,19 +275,20 @@ void WebContentsAudioInputStream::Impl::ReportError() {
void WebContentsAudioInputStream::Impl::StartMirroring() {
DCHECK(thread_checker_.CalledOnValidThread());
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AudioMirroringManager::StartMirroring,
- base::Unretained(mirroring_manager_),
- base::RetainedRef(this)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&AudioMirroringManager::StartMirroring,
+ base::Unretained(mirroring_manager_),
+ base::RetainedRef(this)));
}
void WebContentsAudioInputStream::Impl::StopMirroring() {
DCHECK(thread_checker_.CalledOnValidThread());
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AudioMirroringManager::StopMirroring,
- base::Unretained(mirroring_manager_),
- base::RetainedRef(this)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&AudioMirroringManager::StopMirroring,
+ base::Unretained(mirroring_manager_),
+ base::RetainedRef(this)));
}
void WebContentsAudioInputStream::Impl::UnmuteWebContentsAudio() {
@@ -299,8 +302,8 @@ void WebContentsAudioInputStream::Impl::UnmuteWebContentsAudio() {
void WebContentsAudioInputStream::Impl::QueryForMatches(
const std::set<GlobalFrameRoutingId>& candidates,
MatchesCallback results_callback) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Impl::QueryForMatchesOnUIThread, this, candidates,
media::BindToCurrentLoop(std::move(results_callback))));
}
diff --git a/chromium/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc b/chromium/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc
index f27817f8604..8846494e5f4 100644
--- a/chromium/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc
+++ b/chromium/content/browser/media/capture/web_contents_audio_input_stream_unittest.cc
@@ -16,10 +16,12 @@
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "content/browser/media/capture/audio_mirroring_manager.h"
#include "content/browser/media/capture/web_contents_tracker.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "media/audio/simple_sources.h"
@@ -281,8 +283,8 @@ class WebContentsAudioInputStreamTest : public testing::TestWithParam<bool> {
// causes our mock to set |destination_|. Block until that has happened.
base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&done)));
done.Wait();
ASSERT_TRUE(destination_);
diff --git a/chromium/content/browser/media/capture/web_contents_audio_muter.cc b/chromium/content/browser/media/capture/web_contents_audio_muter.cc
index c10f52250b5..77ce90160d3 100644
--- a/chromium/content/browser/media/capture/web_contents_audio_muter.cc
+++ b/chromium/content/browser/media/capture/web_contents_audio_muter.cc
@@ -10,8 +10,10 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "content/browser/media/capture/audio_mirroring_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -84,8 +86,8 @@ class WebContentsAudioMuter::MuteDestination
void QueryForMatches(const std::set<GlobalFrameRoutingId>& candidates,
MatchesCallback results_callback) override {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&MuteDestination::QueryForMatchesOnUIThread, this,
candidates,
media::BindToCurrentLoop(std::move(results_callback))));
@@ -139,8 +141,8 @@ void WebContentsAudioMuter::StartMuting() {
if (is_muting_)
return;
is_muting_ = true;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioMirroringManager::StartMirroring,
base::Unretained(AudioMirroringManager::GetInstance()),
base::RetainedRef(destination_)));
@@ -151,8 +153,8 @@ void WebContentsAudioMuter::StopMuting() {
if (!is_muting_)
return;
is_muting_ = false;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioMirroringManager::StopMirroring,
base::Unretained(AudioMirroringManager::GetInstance()),
base::RetainedRef(destination_)));
diff --git a/chromium/content/browser/media/capture/web_contents_tracker.cc b/chromium/content/browser/media/capture/web_contents_tracker.cc
index 64abe70e3bc..de71c4b59ac 100644
--- a/chromium/content/browser/media/capture/web_contents_tracker.cc
+++ b/chromium/content/browser/media/capture/web_contents_tracker.cc
@@ -4,7 +4,9 @@
#include "content/browser/media/capture/web_contents_tracker.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_widget_host_view.h"
@@ -32,8 +34,8 @@ void WebContentsTracker::Start(int render_process_id, int main_render_frame_id,
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
StartObservingWebContents(render_process_id, main_render_frame_id);
} else {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&WebContentsTracker::StartObservingWebContents, this,
render_process_id, main_render_frame_id));
}
@@ -48,9 +50,10 @@ void WebContentsTracker::Stop() {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
WebContentsObserver::Observe(nullptr);
} else {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&WebContentsTracker::Observe, this,
- static_cast<WebContents*>(nullptr)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&WebContentsTracker::Observe, this,
+ static_cast<WebContents*>(nullptr)));
}
}
diff --git a/chromium/content/browser/media/capture/web_contents_video_capture_device.cc b/chromium/content/browser/media/capture/web_contents_video_capture_device.cc
index ff8651a5084..9eab080377b 100644
--- a/chromium/content/browser/media/capture/web_contents_video_capture_device.cc
+++ b/chromium/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -11,9 +11,11 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/media/capture/mouse_cursor_overlay_controller.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_media_capture_id.h"
@@ -43,8 +45,8 @@ class WebContentsVideoCaptureDevice::FrameTracker
DCHECK(device_task_runner_);
DCHECK(cursor_controller_);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
[](base::WeakPtr<FrameTracker> self, int process_id, int frame_id) {
if (self) {
@@ -234,16 +236,16 @@ WebContentsVideoCaptureDevice::Create(const std::string& device_id) {
}
void WebContentsVideoCaptureDevice::WillStart() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&FrameTracker::WillStartCapturingWebContents,
tracker_->AsWeakPtr(),
capture_params().SuggestConstraints().max_frame_size));
}
void WebContentsVideoCaptureDevice::DidStop() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&FrameTracker::DidStopCapturingWebContents,
tracker_->AsWeakPtr()));
}
diff --git a/chromium/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc b/chromium/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
index ec35ff5a5b3..850458675e5 100644
--- a/chromium/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
+++ b/chromium/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
@@ -8,11 +8,13 @@
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "cc/test/pixel_test_utils.h"
#include "content/browser/media/capture/content_capture_device_browsertest_base.h"
#include "content/browser/media/capture/fake_video_capture_stack.h"
#include "content/browser/media/capture/frame_test_util.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@@ -133,9 +135,9 @@ class WebContentsVideoCaptureDeviceBrowserTest
// Wait for at least the minimum capture period before checking for more
// captured frames.
base::RunLoop run_loop;
- BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
- run_loop.QuitClosure(),
- GetMinCapturePeriod());
+ base::PostDelayedTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ run_loop.QuitClosure(),
+ GetMinCapturePeriod());
run_loop.Run();
}
}
@@ -243,9 +245,9 @@ IN_PROC_BROWSER_TEST_F(WebContentsVideoCaptureDeviceBrowserTest,
// frames were queued because the device should be suspended.
ChangePageContentColor(SK_ColorGREEN);
base::RunLoop run_loop;
- BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
- run_loop.QuitClosure(),
- base::TimeDelta::FromSeconds(5));
+ base::PostDelayedTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ run_loop.QuitClosure(),
+ base::TimeDelta::FromSeconds(5));
run_loop.Run();
EXPECT_FALSE(HasCapturedFramesInQueue());
diff --git a/chromium/content/browser/media/cdm_storage_impl.cc b/chromium/content/browser/media/cdm_storage_impl.cc
index dd19f2bde50..fa67789e09c 100644
--- a/chromium/content/browser/media/cdm_storage_impl.cc
+++ b/chromium/content/browser/media/cdm_storage_impl.cc
@@ -36,7 +36,7 @@ void CdmStorageImpl::Create(RenderFrameHost* render_frame_host,
const std::string& cdm_file_system_id,
media::mojom::CdmStorageRequest request) {
DVLOG(3) << __func__;
- DCHECK(!render_frame_host->GetLastCommittedOrigin().unique())
+ DCHECK(!render_frame_host->GetLastCommittedOrigin().opaque())
<< "Invalid origin specified for CdmStorageImpl::Create";
// Take a reference to the FileSystemContext.
diff --git a/chromium/content/browser/media/encrypted_media_browsertest.cc b/chromium/content/browser/media/encrypted_media_browsertest.cc
index db7a34efd8d..86957f7b80d 100644
--- a/chromium/content/browser/media/encrypted_media_browsertest.cc
+++ b/chromium/content/browser/media/encrypted_media_browsertest.cc
@@ -182,9 +182,7 @@ class EncryptedMediaTest
}
void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitchASCII(
- switches::kAutoplayPolicy,
- switches::autoplay::kNoUserGestureRequiredPolicy);
+ MediaBrowserTest::SetUpCommandLine(command_line);
#if defined(SUPPORTS_EXTERNAL_CLEAR_KEY_IN_CONTENT_SHELL)
scoped_feature_list_.InitWithFeatures({media::kExternalClearKeyForTesting},
{});
@@ -274,6 +272,15 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoClearAudio_WebM_Opus) {
TestSimplePlayback("bear-320x240-opus-av_enc-v.webm", kWebMOpusAudioVp9Video);
}
+// TODO(crbug.com/707127): Decide when it's supported on Android. Also support
+// VP9 Profile2 query and update the mime type.
+#if !defined(OS_ANDROID)
+IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VP9Profile2Video_WebM) {
+ TestSimplePlayback("bear-320x240-v-vp9_profile2_subsample_cenc-v.webm",
+ kWebMVp9VideoOnly);
+}
+#endif
+
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_AudioOnly_MP4_FLAC) {
RunMultipleFileTest(std::string(), std::string(), "bear-flac-cenc.mp4",
kMp4FlacAudioOnly, media::kEnded);
@@ -288,6 +295,20 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoOnly_MP4_VP9) {
TestSimplePlayback("bear-320x240-v_frag-vp9-cenc.mp4", kMp4Vp9VideoOnly);
}
+// TODO(crbug.com/707127): Decide when it's supported on Android. Also support
+// VP9 Profile2 query and update the mime type.
+#if !defined(OS_ANDROID)
+IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoOnly_MP4_VP9Profile2) {
+ // MP4 without MSE is not support yet, http://crbug.com/170793.
+ if (CurrentSourceType() != SrcType::MSE) {
+ DVLOG(0) << "Skipping test; Can only play MP4 encrypted streams by MSE.";
+ return;
+ }
+ TestSimplePlayback("bear-320x240-v-vp9_profile2_subsample_cenc-v.mp4",
+ kMp4Vp9VideoOnly);
+}
+#endif
+
// Strictly speaking this is not an "encrypted" media test. Keep it here for
// completeness.
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, ConfigChangeVideo_ClearToClear) {
@@ -307,13 +328,16 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest,
TestConfigChange(ConfigChangeType::ENCRYPTED_TO_ENCRYPTED);
}
-// https://crbug.com/788748 https://crbug.com/794080
-#if (defined(OS_ANDROID) || defined(OS_LINUX)) && defined(ADDRESS_SANITIZER)
-#define MAYBE_FrameSizeChangeVideo DISABLED_FrameSizeChangeVideo
-#else
-#define MAYBE_FrameSizeChangeVideo FrameSizeChangeVideo
+IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, FrameSizeChangeVideo) {
+#if defined(OS_ANDROID)
+ // https://crbug.com/778245
+ if (base::android::BuildInfo::GetInstance()->sdk_int() <=
+ base::android::SDK_VERSION_KITKAT) {
+ DVLOG(0) << "Skipping test - FrameSizeChange is flaky on KitKat devices.";
+ return;
+ }
#endif
-IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, MAYBE_FrameSizeChangeVideo) {
+
TestFrameSizeChange();
}
diff --git a/chromium/content/browser/media/forwarding_audio_stream_factory.cc b/chromium/content/browser/media/forwarding_audio_stream_factory.cc
index f9181735959..ff12ffd69af 100644
--- a/chromium/content/browser/media/forwarding_audio_stream_factory.cc
+++ b/chromium/content/browser/media/forwarding_audio_stream_factory.cc
@@ -6,112 +6,82 @@
#include <utility>
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
-#include "media/audio/audio_device_description.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "media/base/audio_parameters.h"
+#include "media/base/user_input_monitor.h"
#include "services/audio/public/mojom/constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
+#include "ui/gfx/geometry/size.h"
namespace content {
-namespace {
-
-// A mojom::RendererAudioInputStreamFactoryClient that holds a
-// AudioLoopbackStreamCreator::StreamCreatedCallback. The callback runs when the
-// requested audio stream is created.
-class StreamCreatedCallbackAdapter final
- : public mojom::RendererAudioInputStreamFactoryClient {
- public:
- explicit StreamCreatedCallbackAdapter(
- const AudioLoopbackStreamCreator::StreamCreatedCallback& callback)
- : callback_(callback) {
- DCHECK(callback_);
- }
-
- ~StreamCreatedCallbackAdapter() override {}
-
- // mojom::RendererAudioInputStreamFactoryClient implementation.
- void StreamCreated(
- media::mojom::AudioInputStreamPtr stream,
- media::mojom::AudioInputStreamClientRequest client_request,
- media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
- bool initially_muted,
- const base::Optional<base::UnguessableToken>& stream_id) override {
- DCHECK(!initially_muted); // Loopback streams shouldn't be started muted.
- callback_.Run(std::move(stream), std::move(client_request),
- std::move(data_pipe));
- }
-
- private:
- const AudioLoopbackStreamCreator::StreamCreatedCallback callback_;
-
- DISALLOW_COPY_AND_ASSIGN(StreamCreatedCallbackAdapter);
-};
-
-} // namespace
-
-ForwardingAudioStreamFactory::ForwardingAudioStreamFactory(
- WebContents* web_contents,
+ForwardingAudioStreamFactory::Core::Core(
+ base::WeakPtr<ForwardingAudioStreamFactory> owner,
+ media::UserInputMonitorBase* user_input_monitor,
std::unique_ptr<service_manager::Connector> connector,
std::unique_ptr<AudioStreamBrokerFactory> broker_factory)
- : WebContentsObserver(web_contents),
- connector_(std::move(connector)),
+ : user_input_monitor_(user_input_monitor),
+ owner_(std::move(owner)),
broker_factory_(std::move(broker_factory)),
- group_id_(base::UnguessableToken::Create()) {
+ group_id_(base::UnguessableToken::Create()),
+ connector_(std::move(connector)),
+ weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(owner_);
DCHECK(broker_factory_);
+ DCHECK(connector_);
}
-ForwardingAudioStreamFactory::~ForwardingAudioStreamFactory() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ForwardingAudioStreamFactory::Core::~Core() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ for (AudioStreamBroker::LoopbackSink* sink : loopback_sinks_)
+ sink->OnSourceGone();
}
-// static
-ForwardingAudioStreamFactory* ForwardingAudioStreamFactory::ForFrame(
- RenderFrameHost* frame) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- auto* contents =
- static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(frame));
- if (!contents)
- return nullptr;
-
- return contents->GetAudioStreamFactory();
+base::WeakPtr<ForwardingAudioStreamFactory::Core>
+ForwardingAudioStreamFactory::Core::AsWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
}
-void ForwardingAudioStreamFactory::CreateInputStream(
- RenderFrameHost* frame,
+void ForwardingAudioStreamFactory::Core::CreateInputStream(
+ int render_process_id,
+ int render_frame_id,
const std::string& device_id,
const media::AudioParameters& params,
uint32_t shared_memory_count,
bool enable_agc,
audio::mojom::AudioProcessingConfigPtr processing_config,
mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
- const int process_id = frame ? frame->GetProcess()->GetID() : -1;
- const int frame_id = frame ? frame->GetRoutingID() : -1;
+ // |this| owns |inputs_|, so Unretained is safe.
inputs_
.insert(broker_factory_->CreateAudioInputStreamBroker(
- process_id, frame_id, device_id, params, shared_memory_count,
- enable_agc, std::move(processing_config),
- base::BindOnce(&ForwardingAudioStreamFactory::RemoveInput,
+ render_process_id, render_frame_id, device_id, params,
+ shared_memory_count, user_input_monitor_, enable_agc,
+ std::move(processing_config),
+ base::BindOnce(&ForwardingAudioStreamFactory::Core::RemoveInput,
base::Unretained(this)),
std::move(renderer_factory_client)))
.first->get()
->CreateStream(GetFactory());
}
-void ForwardingAudioStreamFactory::AssociateInputAndOutputForAec(
+void ForwardingAudioStreamFactory::Core::AssociateInputAndOutputForAec(
const base::UnguessableToken& input_stream_id,
const std::string& raw_output_device_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Avoid spawning a factory if this for some reason gets called with an
// invalid |input_stream_id| before any streams are created.
if (!inputs_.empty()) {
@@ -120,95 +90,58 @@ void ForwardingAudioStreamFactory::AssociateInputAndOutputForAec(
}
}
-void ForwardingAudioStreamFactory::CreateOutputStream(
- RenderFrameHost* frame,
+void ForwardingAudioStreamFactory::Core::CreateOutputStream(
+ int render_process_id,
+ int render_frame_id,
const std::string& device_id,
const media::AudioParameters& params,
const base::Optional<base::UnguessableToken>& processing_id,
media::mojom::AudioOutputStreamProviderClientPtr client) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- const int process_id = frame->GetProcess()->GetID();
- const int frame_id = frame->GetRoutingID();
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // |this| owns |outputs_|, so Unretained is safe.
outputs_
.insert(broker_factory_->CreateAudioOutputStreamBroker(
- process_id, frame_id, ++stream_id_counter_, device_id, params,
- group_id_, processing_id,
- base::BindOnce(&ForwardingAudioStreamFactory::RemoveOutput,
+ render_process_id, render_frame_id, ++stream_id_counter_, device_id,
+ params, group_id_, processing_id,
+ base::BindOnce(&ForwardingAudioStreamFactory::Core::RemoveOutput,
base::Unretained(this)),
std::move(client)))
.first->get()
->CreateStream(GetFactory());
}
-void ForwardingAudioStreamFactory::CreateLoopbackStream(
- RenderFrameHost* frame,
- RenderFrameHost* frame_of_source_web_contents,
+void ForwardingAudioStreamFactory::Core::CreateLoopbackStream(
+ int render_process_id,
+ int render_frame_id,
+ AudioStreamBroker::LoopbackSource* loopback_source,
const media::AudioParameters& params,
uint32_t shared_memory_count,
bool mute_source,
mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(frame_of_source_web_contents);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(loopback_source);
TRACE_EVENT_BEGIN1("audio", "CreateLoopbackStream", "group",
group_id_.GetLowForSerialization());
- WebContents* source_contents =
- WebContents::FromRenderFrameHost(frame_of_source_web_contents);
- if (!source_contents) {
- TRACE_EVENT_END1("audio", "CreateLoopbackStream", "source",
- "failed to find source");
- return;
- }
-
- const int process_id = frame ? frame->GetProcess()->GetID() : -1;
- const int frame_id = frame ? frame->GetRoutingID() : -1;
+ // |this| owns |inputs_|, so Unretained is safe.
inputs_
.insert(broker_factory_->CreateAudioLoopbackStreamBroker(
- process_id, frame_id,
- std::make_unique<AudioStreamBrokerFactory::LoopbackSource>(
- source_contents),
- params, shared_memory_count, mute_source,
- base::BindOnce(&ForwardingAudioStreamFactory::RemoveInput,
+ render_process_id, render_frame_id, loopback_source, params,
+ shared_memory_count, mute_source,
+ base::BindOnce(&ForwardingAudioStreamFactory::Core::RemoveInput,
base::Unretained(this)),
std::move(renderer_factory_client)))
.first->get()
->CreateStream(GetFactory());
TRACE_EVENT_END1("audio", "CreateLoopbackStream", "source",
- static_cast<WebContentsImpl*>(source_contents)
- ->GetAudioStreamFactory()
- ->group_id()
- .GetLowForSerialization());
+ loopback_source->GetGroupID().GetLowForSerialization());
}
-void ForwardingAudioStreamFactory::CreateInProcessLoopbackStream(
- RenderFrameHost* frame_of_source_web_contents,
- const media::AudioParameters& params,
- uint32_t shared_memory_count,
- const AudioLoopbackStreamCreator::StreamCreatedCallback& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- mojom::RendererAudioInputStreamFactoryClientPtr client;
- mojo::MakeStrongBinding(
- std::make_unique<StreamCreatedCallbackAdapter>(callback),
- mojo::MakeRequest(&client));
- if (frame_of_source_web_contents) {
- CreateLoopbackStream(nullptr, frame_of_source_web_contents, params,
- shared_memory_count, true /* mute_source */,
- std::move(client));
- } else {
- // A null |frame_of_source_web_contents| requests system-wide loopback.
- CreateInputStream(nullptr,
- media::AudioDeviceDescription::kLoopbackWithMuteDeviceId,
- params, shared_memory_count, false /* enable_agc */,
- nullptr /* processing_config */, std::move(client));
- }
-}
-
-void ForwardingAudioStreamFactory::SetMuted(bool muted) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK_NE(muted, IsMuted());
+void ForwardingAudioStreamFactory::Core::SetMuted(bool muted) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_NE(muted, !!muter_);
TRACE_EVENT_INSTANT2("audio", "SetMuted", TRACE_EVENT_SCOPE_THREAD, "group",
group_id_.GetLowForSerialization(), "muted", muted);
@@ -222,35 +155,133 @@ void ForwardingAudioStreamFactory::SetMuted(bool muted) {
muter_->Connect(remote_factory_.get());
}
-bool ForwardingAudioStreamFactory::IsMuted() const {
+void ForwardingAudioStreamFactory::Core::AddLoopbackSink(
+ AudioStreamBroker::LoopbackSink* sink) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ loopback_sinks_.insert(sink);
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&ForwardingAudioStreamFactory::LoopbackStreamStarted,
+ owner_));
+}
+
+void ForwardingAudioStreamFactory::Core::RemoveLoopbackSink(
+ AudioStreamBroker::LoopbackSink* sink) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ loopback_sinks_.erase(sink);
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&ForwardingAudioStreamFactory::LoopbackStreamStopped,
+ owner_));
+}
+
+const base::UnguessableToken& ForwardingAudioStreamFactory::Core::GetGroupID() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ return group_id();
+}
+
+// static
+ForwardingAudioStreamFactory* ForwardingAudioStreamFactory::ForFrame(
+ RenderFrameHost* frame) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- return !!muter_;
+
+ auto* contents =
+ static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(frame));
+ if (!contents)
+ return nullptr;
+
+ return contents->GetAudioStreamFactory();
}
-void ForwardingAudioStreamFactory::FrameDeleted(
- RenderFrameHost* render_frame_host) {
+// static
+ForwardingAudioStreamFactory::Core* ForwardingAudioStreamFactory::CoreForFrame(
+ RenderFrameHost* frame) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ ForwardingAudioStreamFactory* forwarding_factory =
+ ForwardingAudioStreamFactory::ForFrame(frame);
+ return forwarding_factory ? forwarding_factory->core() : nullptr;
+}
+
+ForwardingAudioStreamFactory::ForwardingAudioStreamFactory(
+ WebContents* web_contents,
+ media::UserInputMonitorBase* user_input_monitor,
+ std::unique_ptr<service_manager::Connector> connector,
+ std::unique_ptr<AudioStreamBrokerFactory> broker_factory)
+ : WebContentsObserver(web_contents), core_(), weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- CleanupStreamsBelongingTo(render_frame_host);
+ core_ =
+ std::make_unique<Core>(weak_ptr_factory_.GetWeakPtr(), user_input_monitor,
+ std::move(connector), std::move(broker_factory));
}
-void ForwardingAudioStreamFactory::CleanupStreamsBelongingTo(
+ForwardingAudioStreamFactory::~ForwardingAudioStreamFactory() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Ensure |core_| is deleted on the right thread. DeleteOnIOThread isn't used
+ // as it doesn't post in case it is already executed on the right thread. That
+ // causes issues in unit tests where the UI thread and the IO thread are the
+ // same.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce([](std::unique_ptr<Core>) {}, std::move(core_)));
+}
+
+void ForwardingAudioStreamFactory::LoopbackStreamStarted() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ web_contents()->IncrementCapturerCount(gfx::Size());
+}
+
+void ForwardingAudioStreamFactory::LoopbackStreamStopped() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ web_contents()->DecrementCapturerCount();
+}
+
+void ForwardingAudioStreamFactory::SetMuted(bool muted) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (is_muted_ != muted) {
+ is_muted_ = muted;
+
+ // Unretained is safe since the destruction of |core_| will be posted to the
+ // IO thread later.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&Core::SetMuted, base::Unretained(core_.get()), muted));
+ }
+}
+
+bool ForwardingAudioStreamFactory::IsMuted() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return is_muted_;
+}
+
+void ForwardingAudioStreamFactory::FrameDeleted(
RenderFrameHost* render_frame_host) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(render_frame_host);
+
+ // Unretained is safe since the destruction of |core_| will be posted to the
+ // IO thread later.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&Core::CleanupStreamsBelongingTo,
+ base::Unretained(core_.get()),
+ render_frame_host->GetProcess()->GetID(),
+ render_frame_host->GetRoutingID()));
+}
- const int process_id =
- render_frame_host ? render_frame_host->GetProcess()->GetID() : -1;
- const int frame_id =
- render_frame_host ? render_frame_host->GetRoutingID() : -1;
+void ForwardingAudioStreamFactory::Core::CleanupStreamsBelongingTo(
+ int render_process_id,
+ int render_frame_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
TRACE_EVENT_BEGIN2("audio", "CleanupStreamsBelongingTo", "group",
group_id_.GetLowForSerialization(), "process id",
- process_id);
+ render_process_id);
auto match_rfh =
- [process_id,
- frame_id](const std::unique_ptr<AudioStreamBroker>& broker) -> bool {
- return broker->render_process_id() == process_id &&
- broker->render_frame_id() == frame_id;
+ [render_process_id, render_frame_id](
+ const std::unique_ptr<AudioStreamBroker>& broker) -> bool {
+ return broker->render_process_id() == render_process_id &&
+ broker->render_frame_id() == render_frame_id;
};
base::EraseIf(outputs_, match_rfh);
@@ -258,27 +289,30 @@ void ForwardingAudioStreamFactory::CleanupStreamsBelongingTo(
ResetRemoteFactoryPtrIfIdle();
- TRACE_EVENT_END1("audio", "CleanupStreamsBelongingTo", "frame_id", frame_id);
+ TRACE_EVENT_END1("audio", "CleanupStreamsBelongingTo", "frame_id",
+ render_frame_id);
}
-void ForwardingAudioStreamFactory::RemoveInput(AudioStreamBroker* broker) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+void ForwardingAudioStreamFactory::Core::RemoveInput(
+ AudioStreamBroker* broker) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
size_t removed = inputs_.erase(broker);
DCHECK_EQ(1u, removed);
ResetRemoteFactoryPtrIfIdle();
}
-void ForwardingAudioStreamFactory::RemoveOutput(AudioStreamBroker* broker) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+void ForwardingAudioStreamFactory::Core::RemoveOutput(
+ AudioStreamBroker* broker) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
size_t removed = outputs_.erase(broker);
DCHECK_EQ(1u, removed);
ResetRemoteFactoryPtrIfIdle();
}
-audio::mojom::StreamFactory* ForwardingAudioStreamFactory::GetFactory() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+audio::mojom::StreamFactory* ForwardingAudioStreamFactory::Core::GetFactory() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!remote_factory_) {
TRACE_EVENT_INSTANT1(
"audio", "ForwardingAudioStreamFactory: Binding new factory",
@@ -286,9 +320,9 @@ audio::mojom::StreamFactory* ForwardingAudioStreamFactory::GetFactory() {
connector_->BindInterface(audio::mojom::kServiceName,
mojo::MakeRequest(&remote_factory_));
// Unretained is safe because |this| owns |remote_factory_|.
- remote_factory_.set_connection_error_handler(
- base::BindOnce(&ForwardingAudioStreamFactory::ResetRemoteFactoryPtr,
- base::Unretained(this)));
+ remote_factory_.set_connection_error_handler(base::BindOnce(
+ &ForwardingAudioStreamFactory::Core::ResetRemoteFactoryPtr,
+ base::Unretained(this)));
// Restore the muting session on reconnect.
if (muter_)
@@ -298,14 +332,14 @@ audio::mojom::StreamFactory* ForwardingAudioStreamFactory::GetFactory() {
return remote_factory_.get();
}
-void ForwardingAudioStreamFactory::ResetRemoteFactoryPtrIfIdle() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+void ForwardingAudioStreamFactory::Core::ResetRemoteFactoryPtrIfIdle() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (inputs_.empty() && outputs_.empty())
ResetRemoteFactoryPtr();
}
-void ForwardingAudioStreamFactory::ResetRemoteFactoryPtr() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+void ForwardingAudioStreamFactory::Core::ResetRemoteFactoryPtr() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (remote_factory_) {
TRACE_EVENT_INSTANT1(
"audio", "ForwardingAudioStreamFactory: Resetting factory",
diff --git a/chromium/content/browser/media/forwarding_audio_stream_factory.h b/chromium/content/browser/media/forwarding_audio_stream_factory.h
index 6c1bfbc8dd9..8a995de058f 100644
--- a/chromium/content/browser/media/forwarding_audio_stream_factory.h
+++ b/chromium/content/browser/media/forwarding_audio_stream_factory.h
@@ -5,20 +5,23 @@
#ifndef CONTENT_BROWSER_MEDIA_FORWARDING_AUDIO_STREAM_FACTORY_H_
#define CONTENT_BROWSER_MEDIA_FORWARDING_AUDIO_STREAM_FACTORY_H_
+#include <cstdint>
#include <memory>
#include <string>
#include "base/containers/flat_set.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/unguessable_token.h"
#include "content/browser/media/audio_muting_session.h"
#include "content/browser/media/audio_stream_broker.h"
#include "content/common/content_export.h"
#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
-#include "content/public/browser/audio_loopback_stream_creator.h"
#include "content/public/browser/web_contents_observer.h"
+#include "media/mojo/interfaces/audio_output_stream.mojom.h"
+#include "services/audio/public/mojom/audio_processing.mojom.h"
#include "services/audio/public/mojom/stream_factory.mojom.h"
namespace service_manager {
@@ -27,11 +30,11 @@ class Connector;
namespace media {
class AudioParameters;
+class UserInputMonitorBase;
}
namespace content {
-class AudioStreamBroker;
class RenderFrameHost;
class WebContents;
@@ -40,60 +43,166 @@ class WebContents;
class CONTENT_EXPORT ForwardingAudioStreamFactory final
: public WebContentsObserver {
public:
+ // Note: all methods of Core may only be called on the IO thread except for
+ // the constructor and group_id(). The destruction of Core is posted to the
+ // IO thread when the owning ForwardingAudioStreamFactory is destructed. For
+ // using |core()|, two rules emerges.
+ // 1) If a task is posted from the UI thread to the IO thread while the
+ // owning ForwardingAudioStreamFactory is alive, |core()| may be posted
+ // Unretained.
+ // 2) If |core()| is held until the owning ForwardingAudioStreamFactory could
+ // potentially be destructed, or if a task is posted to the IO thread with
+ // the intention of accessing |core| after that task returns, using a raw
+ // pointer is not safe. In those cases, take a weak pointer using
+ // AsWeakPtr() and check it for validity before every use. The weak
+ // pointer may only be checked/dereferenced on the IO thread.
+ class CONTENT_EXPORT Core final : public AudioStreamBroker::LoopbackSource {
+ public:
+ Core(base::WeakPtr<ForwardingAudioStreamFactory> owner,
+ media::UserInputMonitorBase* user_input_monitor,
+ std::unique_ptr<service_manager::Connector> connector,
+ std::unique_ptr<AudioStreamBrokerFactory> factory);
+ ~Core() final;
+
+ const base::UnguessableToken& group_id() const { return group_id_; }
+
+ // E.g. to override binder.
+ service_manager::Connector* get_connector_for_testing() {
+ return connector_.get();
+ }
+
+ base::WeakPtr<ForwardingAudioStreamFactory::Core> AsWeakPtr();
+
+ // TODO(https://crbug.com/787806): Automatically restore streams on audio
+ // service restart.
+ void CreateInputStream(
+ int render_process_id,
+ int render_frame_id,
+ const std::string& device_id,
+ const media::AudioParameters& params,
+ uint32_t shared_memory_count,
+ bool enable_agc,
+ audio::mojom::AudioProcessingConfigPtr processing_config,
+ mojom::RendererAudioInputStreamFactoryClientPtr
+ renderer_factory_client);
+
+ void AssociateInputAndOutputForAec(
+ const base::UnguessableToken& input_stream_id,
+ const std::string& raw_output_device_id);
+
+ void CreateOutputStream(
+ int render_process_id,
+ int render_frame_id,
+ const std::string& device_id,
+ const media::AudioParameters& params,
+ const base::Optional<base::UnguessableToken>& processing_id,
+ media::mojom::AudioOutputStreamProviderClientPtr client);
+
+ void CreateLoopbackStream(
+ int render_process_id,
+ int render_frame_id,
+ AudioStreamBroker::LoopbackSource* loopback_source,
+ const media::AudioParameters& params,
+ uint32_t shared_memory_count,
+ bool mute_source,
+ mojom::RendererAudioInputStreamFactoryClientPtr
+ renderer_factory_client);
+
+ // Sets the muting state for all output streams created through this
+ // factory.
+ void SetMuted(bool muted);
+
+ // AudioStreamLoopback::Source implementation
+ void AddLoopbackSink(AudioStreamBroker::LoopbackSink* sink) final;
+ void RemoveLoopbackSink(AudioStreamBroker::LoopbackSink* sink) final;
+ const base::UnguessableToken& GetGroupID() final; // Actually const.
+
+ private:
+ // For CleanupStreamsBelongingTo.
+ friend class ForwardingAudioStreamFactory;
+
+ using StreamBrokerSet = base::flat_set<std::unique_ptr<AudioStreamBroker>,
+ base::UniquePtrComparator>;
+
+ void CleanupStreamsBelongingTo(int render_process_id, int render_frame_id);
+
+ void RemoveInput(AudioStreamBroker* handle);
+ void RemoveOutput(AudioStreamBroker* handle);
+
+ audio::mojom::StreamFactory* GetFactory();
+ void ResetRemoteFactoryPtrIfIdle();
+ void ResetRemoteFactoryPtr();
+
+ media::UserInputMonitorBase* const user_input_monitor_;
+
+ // Used for posting tasks the UI thread to communicate when a loopback
+ // stream is started/stopped. Weak since |this| on the IO thread outlives
+ // |owner| on the UI thread.
+ const base::WeakPtr<ForwardingAudioStreamFactory> owner_;
+
+ const std::unique_ptr<AudioStreamBrokerFactory> broker_factory_;
+
+ // Unique id identifying all streams belonging to the WebContents owning
+ // |this|.
+ const base::UnguessableToken group_id_;
+
+ const std::unique_ptr<service_manager::Connector> connector_;
+
+ // Lazily acquired. Reset on connection error and when we no longer have any
+ // streams. Note: we don't want muting to force the connection to be open,
+ // since we want to clean up the service when not in use. If we have active
+ // muting but nothing else, we should stop it and start it again when we
+ // need to reacquire the factory for some other reason.
+ audio::mojom::StreamFactoryPtr remote_factory_;
+
+ // Running id used for tracking audible streams. We keep count here to avoid
+ // collisions.
+ // TODO(https://crbug.com/830494): Refactor to make this unnecessary and
+ // remove it.
+ int stream_id_counter_ = 0;
+
+ // Instantiated when |outputs_| should be muted, empty otherwise.
+ base::Optional<AudioMutingSession> muter_;
+
+ StreamBrokerSet inputs_;
+ StreamBrokerSet outputs_;
+ base::flat_set<AudioStreamBroker::LoopbackSink*> loopback_sinks_;
+
+ base::WeakPtrFactory<ForwardingAudioStreamFactory::Core> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(Core);
+ };
+
+ // Returns the ForwardingAudioStreamFactory which takes care of stream
+ // creation for |frame|. Returns null if |frame| is null or if the frame
+ // doesn't belong to a WebContents.
+ static ForwardingAudioStreamFactory* ForFrame(RenderFrameHost* frame);
+
+ // Returns the ForwardingAudioStreamFactory::Core which takes care of stream
+ // creation for |frame|. Returns null if |frame| is null or if the frame
+ // doesn't belong to a WebContents.
+ static ForwardingAudioStreamFactory::Core* CoreForFrame(
+ RenderFrameHost* frame);
+
// |web_contents| is null in the browser-privileged access case, i.e., when
// the streams created with this factory will not be consumed by a renderer.
+ // |connector| will be used on the IO thread.
ForwardingAudioStreamFactory(
WebContents* web_contents,
+ media::UserInputMonitorBase* user_input_monitor,
std::unique_ptr<service_manager::Connector> connector,
std::unique_ptr<AudioStreamBrokerFactory> factory);
~ForwardingAudioStreamFactory() final;
- // Returns the ForwardingAudioStreamFactory which takes care of stream
- // creation for |frame|. Returns null if |frame| is null or if the frame
- // doesn't belong to a WebContents.
- static ForwardingAudioStreamFactory* ForFrame(RenderFrameHost* frame);
+ const base::UnguessableToken& group_id() const {
+ // Thread-safe since Core::group_id is thread-safe and |core_| outlives
+ // |this|.
+ return core_->group_id();
+ }
- const base::UnguessableToken& group_id() { return group_id_; }
-
- // TODO(https://crbug.com/787806): Automatically restore streams on audio
- // service restart.
- void CreateInputStream(
- RenderFrameHost* frame,
- const std::string& device_id,
- const media::AudioParameters& params,
- uint32_t shared_memory_count,
- bool enable_agc,
- audio::mojom::AudioProcessingConfigPtr processing_config,
- mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client);
-
- void AssociateInputAndOutputForAec(
- const base::UnguessableToken& input_stream_id,
- const std::string& raw_output_device_id);
-
- void CreateOutputStream(
- RenderFrameHost* frame,
- const std::string& device_id,
- const media::AudioParameters& params,
- const base::Optional<base::UnguessableToken>& processing_id,
- media::mojom::AudioOutputStreamProviderClientPtr client);
-
- void CreateLoopbackStream(
- RenderFrameHost* frame,
- RenderFrameHost* frame_of_source_web_contents,
- const media::AudioParameters& params,
- uint32_t shared_memory_count,
- bool mute_source,
- mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client);
-
- // Creates a loopback stream that captures the audio from
- // |frame_of_source_web_contents|, or the default system playback if the
- // source is not provided. The source/system audio is muted during capturing.
- void CreateInProcessLoopbackStream(
- RenderFrameHost* frame_of_source_web_contents,
- const media::AudioParameters& params,
- uint32_t shared_memory_count,
- const AudioLoopbackStreamCreator::StreamCreatedCallback& callback);
+ void LoopbackStreamStarted();
+ void LoopbackStreamStopped();
// Sets the muting state for all output streams created through this factory.
void SetMuted(bool muted);
@@ -105,50 +214,13 @@ class CONTENT_EXPORT ForwardingAudioStreamFactory final
// clean up streams belonging to a frame when that frame is destroyed.
void FrameDeleted(RenderFrameHost* render_frame_host) final;
- // E.g. to override binder.
- service_manager::Connector* get_connector_for_testing() {
- return connector_.get();
- }
+ Core* core() { return core_.get(); }
private:
- using StreamBrokerSet = base::flat_set<std::unique_ptr<AudioStreamBroker>,
- base::UniquePtrComparator>;
-
- void CleanupStreamsBelongingTo(RenderFrameHost* render_frame_host);
-
- void RemoveInput(AudioStreamBroker* handle);
- void RemoveOutput(AudioStreamBroker* handle);
-
- audio::mojom::StreamFactory* GetFactory();
- void ResetRemoteFactoryPtrIfIdle();
- void ResetRemoteFactoryPtr();
-
- const std::unique_ptr<service_manager::Connector> connector_;
- const std::unique_ptr<AudioStreamBrokerFactory> broker_factory_;
-
- // Unique id indentifying all streams belonging to the WebContents owning
- // |this|.
- // TODO(https://crbug.com/824019): Use this for loopback.
- const base::UnguessableToken group_id_;
-
- // Lazily acquired. Reset on connection error and when we no longer have any
- // streams. Note: we don't want muting to force the connection to be open,
- // since we want to clean up the service when not in use. If we have active
- // muting but nothing else, we should stop it and start it again when we need
- // to reacquire the factory for some other reason.
- audio::mojom::StreamFactoryPtr remote_factory_;
-
- // Running id used for tracking audible streams. We keep count here to avoid
- // collisions.
- // TODO(https://crbug.com/830494): Refactor to make this unnecessary and
- // remove it.
- int stream_id_counter_ = 0;
-
- // Instantiated when |outputs_| should be muted, empty otherwise.
- base::Optional<AudioMutingSession> muter_;
+ std::unique_ptr<Core> core_;
+ bool is_muted_ = false;
- StreamBrokerSet inputs_;
- StreamBrokerSet outputs_;
+ base::WeakPtrFactory<ForwardingAudioStreamFactory> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ForwardingAudioStreamFactory);
};
diff --git a/chromium/content/browser/media/forwarding_audio_stream_factory_unittest.cc b/chromium/content/browser/media/forwarding_audio_stream_factory_unittest.cc
index 421f66bdac7..d390f5817e0 100644
--- a/chromium/content/browser/media/forwarding_audio_stream_factory_unittest.cc
+++ b/chromium/content/browser/media/forwarding_audio_stream_factory_unittest.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
+#include "base/run_loop.h"
#include "base/test/mock_callback.h"
#include "base/unguessable_token.h"
#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
@@ -110,6 +111,7 @@ class MockBrokerFactory : public AudioStreamBrokerFactory {
const std::string& device_id,
const media::AudioParameters& params,
uint32_t shared_memory_count,
+ media::UserInputMonitorBase* user_input_monitor,
bool enable_agc,
audio::mojom::AudioProcessingConfigPtr processing_config,
AudioStreamBroker::DeleterCallback deleter,
@@ -148,7 +150,7 @@ class MockBrokerFactory : public AudioStreamBrokerFactory {
std::unique_ptr<AudioStreamBroker> CreateAudioLoopbackStreamBroker(
int render_process_id,
int render_frame_id,
- std::unique_ptr<LoopbackSource> source,
+ AudioStreamBroker::LoopbackSource* source,
const media::AudioParameters& params,
uint32_t shared_memory_count,
bool mute_source,
@@ -172,6 +174,17 @@ class MockBrokerFactory : public AudioStreamBrokerFactory {
DISALLOW_COPY_AND_ASSIGN(MockBrokerFactory);
};
+class MockLoopbackSink : public AudioStreamBroker::LoopbackSink {
+ public:
+ MockLoopbackSink() {}
+ ~MockLoopbackSink() override {}
+
+ MOCK_METHOD0(OnSourceGone, void());
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockLoopbackSink);
+};
+
class ForwardingAudioStreamFactoryTest : public RenderViewHostTestHarness {
public:
ForwardingAudioStreamFactoryTest()
@@ -253,14 +266,16 @@ TEST_F(ForwardingAudioStreamFactoryTest, CreateInputStream_CreatesInputStream) {
mojom::RendererAudioInputStreamFactoryClientPtr client;
base::WeakPtr<MockBroker> broker = ExpectInputBrokerConstruction(main_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
EXPECT_CALL(*broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateInputStream(main_rfh(), kInputDeviceId, kParams,
- kSharedMemoryCount, kEnableAgc, nullptr,
- std::move(client));
+ factory.core()->CreateInputStream(main_rfh()->GetProcess()->GetID(),
+ main_rfh()->GetRoutingID(), kInputDeviceId,
+ kParams, kSharedMemoryCount, kEnableAgc,
+ nullptr, std::move(client));
}
TEST_F(ForwardingAudioStreamFactoryTest,
@@ -270,14 +285,23 @@ TEST_F(ForwardingAudioStreamFactoryTest,
base::WeakPtr<MockBroker> broker =
ExpectLoopbackBrokerConstruction(main_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ std::unique_ptr<service_manager::Connector> other_connector =
+ connector_->Clone();
+
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
+
+ ForwardingAudioStreamFactory source_factory(
+ source_contents.get(), nullptr /*user_input_monitor*/,
+ std::move(other_connector), std::make_unique<MockBrokerFactory>());
EXPECT_CALL(*broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateLoopbackStream(main_rfh(), source_contents->GetMainFrame(),
- kParams, kSharedMemoryCount, kMuteSource,
- std::move(client));
+ factory.core()->CreateLoopbackStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ source_factory.core(), kParams, kSharedMemoryCount, kMuteSource,
+ std::move(client));
}
TEST_F(ForwardingAudioStreamFactoryTest,
@@ -285,13 +309,15 @@ TEST_F(ForwardingAudioStreamFactoryTest,
media::mojom::AudioOutputStreamProviderClientPtr client;
base::WeakPtr<MockBroker> broker = ExpectOutputBrokerConstruction(main_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
EXPECT_CALL(*broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(client));
+ factory.core()->CreateOutputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(client));
}
TEST_F(ForwardingAudioStreamFactoryTest,
@@ -302,23 +328,26 @@ TEST_F(ForwardingAudioStreamFactoryTest,
base::WeakPtr<MockBroker> other_rfh_broker =
ExpectInputBrokerConstruction(other_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
{
EXPECT_CALL(*main_rfh_broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateInputStream(main_rfh(), kInputDeviceId, kParams,
- kSharedMemoryCount, kEnableAgc, nullptr,
- std::move(client));
+ factory.core()->CreateInputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kInputDeviceId, kParams, kSharedMemoryCount, kEnableAgc, nullptr,
+ std::move(client));
testing::Mock::VerifyAndClear(&*main_rfh_broker);
}
{
EXPECT_CALL(*other_rfh_broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateInputStream(other_rfh(), kInputDeviceId, kParams,
- kSharedMemoryCount, kEnableAgc, nullptr,
- std::move(client));
+ factory.core()->CreateInputStream(
+ other_rfh()->GetProcess()->GetID(), other_rfh()->GetRoutingID(),
+ kInputDeviceId, kParams, kSharedMemoryCount, kEnableAgc, nullptr,
+ std::move(client));
testing::Mock::VerifyAndClear(&*other_rfh_broker);
}
@@ -337,23 +366,33 @@ TEST_F(ForwardingAudioStreamFactoryTest,
base::WeakPtr<MockBroker> other_rfh_broker =
ExpectLoopbackBrokerConstruction(other_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ std::unique_ptr<service_manager::Connector> other_connector =
+ connector_->Clone();
+
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
+
+ ForwardingAudioStreamFactory source_factory(
+ source_contents.get(), nullptr /*user_input_monitor*/,
+ std::move(other_connector), std::make_unique<MockBrokerFactory>());
{
EXPECT_CALL(*main_rfh_broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateLoopbackStream(main_rfh(), source_contents->GetMainFrame(),
- kParams, kSharedMemoryCount, kMuteSource,
- std::move(client));
+ factory.core()->CreateLoopbackStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ source_factory.core(), kParams, kSharedMemoryCount, kMuteSource,
+ std::move(client));
testing::Mock::VerifyAndClear(&*main_rfh_broker);
}
{
EXPECT_CALL(*other_rfh_broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateLoopbackStream(other_rfh(), source_contents->GetMainFrame(),
- kParams, kSharedMemoryCount, kMuteSource,
- std::move(client));
+ factory.core()->CreateLoopbackStream(
+ other_rfh()->GetProcess()->GetID(), other_rfh()->GetRoutingID(),
+ source_factory.core(), kParams, kSharedMemoryCount, kMuteSource,
+ std::move(client));
testing::Mock::VerifyAndClear(&*other_rfh_broker);
}
@@ -371,21 +410,24 @@ TEST_F(ForwardingAudioStreamFactoryTest,
base::WeakPtr<MockBroker> other_rfh_broker =
ExpectOutputBrokerConstruction(other_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
{
EXPECT_CALL(*main_rfh_broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(client));
+ factory.core()->CreateOutputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(client));
testing::Mock::VerifyAndClear(&*main_rfh_broker);
}
{
EXPECT_CALL(*other_rfh_broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateOutputStream(other_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(client));
+ factory.core()->CreateOutputStream(
+ other_rfh()->GetProcess()->GetID(), other_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(client));
testing::Mock::VerifyAndClear(&*other_rfh_broker);
}
@@ -415,55 +457,69 @@ TEST_F(ForwardingAudioStreamFactoryTest, DestroyFrame_DestroysRelatedStreams) {
base::WeakPtr<MockBroker> other_rfh_output_broker =
ExpectOutputBrokerConstruction(other_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ std::unique_ptr<service_manager::Connector> other_connector =
+ connector_->Clone();
+
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
+
+ ForwardingAudioStreamFactory source_factory(
+ source_contents.get(), nullptr /*user_input_monitor*/,
+ std::move(other_connector), std::make_unique<MockBrokerFactory>());
{
EXPECT_CALL(*main_rfh_input_broker, CreateStream(NotNull()));
mojo::MakeRequest(&input_client);
- factory.CreateInputStream(main_rfh(), kInputDeviceId, kParams,
- kSharedMemoryCount, kEnableAgc, nullptr,
- std::move(input_client));
+ factory.core()->CreateInputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kInputDeviceId, kParams, kSharedMemoryCount, kEnableAgc, nullptr,
+ std::move(input_client));
testing::Mock::VerifyAndClear(&*main_rfh_input_broker);
}
{
EXPECT_CALL(*other_rfh_input_broker, CreateStream(NotNull()));
mojo::MakeRequest(&input_client);
- factory.CreateInputStream(other_rfh(), kInputDeviceId, kParams,
- kSharedMemoryCount, kEnableAgc, nullptr,
- std::move(input_client));
+ factory.core()->CreateInputStream(
+ other_rfh()->GetProcess()->GetID(), other_rfh()->GetRoutingID(),
+ kInputDeviceId, kParams, kSharedMemoryCount, kEnableAgc, nullptr,
+ std::move(input_client));
testing::Mock::VerifyAndClear(&*other_rfh_input_broker);
}
{
EXPECT_CALL(*main_rfh_loopback_broker, CreateStream(NotNull()));
mojo::MakeRequest(&input_client);
- factory.CreateLoopbackStream(main_rfh(), source_contents->GetMainFrame(),
- kParams, kSharedMemoryCount, kMuteSource,
- std::move(input_client));
+ factory.core()->CreateLoopbackStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ source_factory.core(), kParams, kSharedMemoryCount, kMuteSource,
+ std::move(input_client));
testing::Mock::VerifyAndClear(&*main_rfh_loopback_broker);
}
{
EXPECT_CALL(*other_rfh_loopback_broker, CreateStream(NotNull()));
mojo::MakeRequest(&input_client);
- factory.CreateLoopbackStream(other_rfh(), source_contents->GetMainFrame(),
- kParams, kSharedMemoryCount, kMuteSource,
- std::move(input_client));
+ factory.core()->CreateLoopbackStream(
+ other_rfh()->GetProcess()->GetID(), other_rfh()->GetRoutingID(),
+ source_factory.core(), kParams, kSharedMemoryCount, kMuteSource,
+ std::move(input_client));
testing::Mock::VerifyAndClear(&*other_rfh_loopback_broker);
}
{
EXPECT_CALL(*main_rfh_output_broker, CreateStream(NotNull()));
mojo::MakeRequest(&output_client);
- factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(output_client));
+ factory.core()->CreateOutputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(output_client));
testing::Mock::VerifyAndClear(&*main_rfh_output_broker);
}
{
EXPECT_CALL(*other_rfh_output_broker, CreateStream(NotNull()));
mojo::MakeRequest(&output_client);
- factory.CreateOutputStream(other_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(output_client));
+ factory.core()->CreateOutputStream(
+ other_rfh()->GetProcess()->GetID(), other_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(output_client));
testing::Mock::VerifyAndClear(&*other_rfh_output_broker);
}
@@ -490,19 +546,22 @@ TEST_F(ForwardingAudioStreamFactoryTest, DestroyWebContents_DestroysStreams) {
base::WeakPtr<MockBroker> output_broker =
ExpectOutputBrokerConstruction(main_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
EXPECT_CALL(*input_broker, CreateStream(NotNull()));
mojo::MakeRequest(&input_client);
- factory.CreateInputStream(main_rfh(), kInputDeviceId, kParams,
- kSharedMemoryCount, kEnableAgc, nullptr,
- std::move(input_client));
+ factory.core()->CreateInputStream(main_rfh()->GetProcess()->GetID(),
+ main_rfh()->GetRoutingID(), kInputDeviceId,
+ kParams, kSharedMemoryCount, kEnableAgc,
+ nullptr, std::move(input_client));
EXPECT_CALL(*output_broker, CreateStream(NotNull()));
mojo::MakeRequest(&output_client);
- factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(output_client));
+ factory.core()->CreateOutputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(output_client));
DeleteContents();
base::RunLoop().RunUntilIdle();
@@ -526,38 +585,43 @@ TEST_F(ForwardingAudioStreamFactoryTest, LastStreamDeleted_ClearsFactoryPtr) {
base::WeakPtr<MockBroker> other_rfh_output_broker =
ExpectOutputBrokerConstruction(other_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
{
EXPECT_CALL(*main_rfh_input_broker, CreateStream(NotNull()));
mojo::MakeRequest(&input_client);
- factory.CreateInputStream(main_rfh(), kInputDeviceId, kParams,
- kSharedMemoryCount, kEnableAgc, nullptr,
- std::move(input_client));
+ factory.core()->CreateInputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kInputDeviceId, kParams, kSharedMemoryCount, kEnableAgc, nullptr,
+ std::move(input_client));
testing::Mock::VerifyAndClear(&*main_rfh_input_broker);
}
{
EXPECT_CALL(*other_rfh_input_broker, CreateStream(NotNull()));
mojo::MakeRequest(&input_client);
- factory.CreateInputStream(other_rfh(), kInputDeviceId, kParams,
- kSharedMemoryCount, kEnableAgc, nullptr,
- std::move(input_client));
+ factory.core()->CreateInputStream(
+ other_rfh()->GetProcess()->GetID(), other_rfh()->GetRoutingID(),
+ kInputDeviceId, kParams, kSharedMemoryCount, kEnableAgc, nullptr,
+ std::move(input_client));
testing::Mock::VerifyAndClear(&*other_rfh_input_broker);
}
{
EXPECT_CALL(*main_rfh_output_broker, CreateStream(NotNull()));
mojo::MakeRequest(&output_client);
- factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(output_client));
+ factory.core()->CreateOutputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(output_client));
testing::Mock::VerifyAndClear(&*main_rfh_output_broker);
}
{
EXPECT_CALL(*other_rfh_output_broker, CreateStream(NotNull()));
mojo::MakeRequest(&output_client);
- factory.CreateOutputStream(other_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(output_client));
+ factory.core()->CreateOutputStream(
+ other_rfh()->GetProcess()->GetID(), other_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(output_client));
testing::Mock::VerifyAndClear(&*other_rfh_output_broker);
}
@@ -583,8 +647,9 @@ TEST_F(ForwardingAudioStreamFactoryTest, LastStreamDeleted_ClearsFactoryPtr) {
TEST_F(ForwardingAudioStreamFactoryTest,
MuteNoOutputStreams_DoesNotConnectMuter) {
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
EXPECT_FALSE(factory.IsMuted());
factory.SetMuted(true);
@@ -603,13 +668,15 @@ TEST_F(ForwardingAudioStreamFactoryTest,
TEST_F(ForwardingAudioStreamFactoryTest, MuteWithOutputStream_ConnectsMuter) {
media::mojom::AudioOutputStreamProviderClientPtr client;
base::WeakPtr<MockBroker> broker = ExpectOutputBrokerConstruction(main_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
EXPECT_CALL(*broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(client));
+ factory.core()->CreateOutputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(client));
base::RunLoop().RunUntilIdle();
testing::Mock::VerifyAndClear(&*broker);
@@ -633,8 +700,9 @@ TEST_F(ForwardingAudioStreamFactoryTest,
WhenMuting_ConnectedWhenOutputStreamExists) {
media::mojom::AudioOutputStreamProviderClientPtr client;
base::WeakPtr<MockBroker> broker = ExpectOutputBrokerConstruction(main_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
EXPECT_FALSE(stream_factory_.IsConnected());
EXPECT_FALSE(factory.IsMuted());
@@ -647,8 +715,9 @@ TEST_F(ForwardingAudioStreamFactoryTest,
EXPECT_CALL(*broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(client));
+ factory.core()->CreateOutputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(client));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(factory.IsMuted());
EXPECT_TRUE(stream_factory_.IsConnected());
@@ -669,14 +738,16 @@ TEST_F(ForwardingAudioStreamFactoryTest,
base::WeakPtr<MockBroker> broker = ExpectOutputBrokerConstruction(main_rfh());
base::WeakPtr<MockBroker> another_broker =
ExpectOutputBrokerConstruction(main_rfh());
- ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_),
- std::move(broker_factory_));
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
{
EXPECT_CALL(*broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(client));
+ factory.core()->CreateOutputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(client));
base::RunLoop().RunUntilIdle();
testing::Mock::VerifyAndClear(&*broker);
}
@@ -692,8 +763,9 @@ TEST_F(ForwardingAudioStreamFactoryTest,
{
EXPECT_CALL(*another_broker, CreateStream(NotNull()));
mojo::MakeRequest(&client);
- factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams,
- base::nullopt, std::move(client));
+ factory.core()->CreateOutputStream(
+ main_rfh()->GetProcess()->GetID(), main_rfh()->GetRoutingID(),
+ kOutputDeviceId, kParams, base::nullopt, std::move(client));
base::RunLoop().RunUntilIdle();
testing::Mock::VerifyAndClear(&*another_broker);
}
@@ -711,4 +783,24 @@ TEST_F(ForwardingAudioStreamFactoryTest,
EXPECT_TRUE(stream_factory_.IsMuterConnected());
}
+TEST_F(ForwardingAudioStreamFactoryTest,
+ Destruction_CallsOnSourceGoneOnRegisteredLoopbackSinks) {
+ StrictMock<MockLoopbackSink> sink1;
+ StrictMock<MockLoopbackSink> sink2;
+
+ // We remove |sink1| before |factory| is destructed, so it shouldn't be
+ // called.
+ EXPECT_CALL(sink2, OnSourceGone());
+ {
+ ForwardingAudioStreamFactory factory(
+ web_contents(), nullptr /*user_input_monitor*/, std::move(connector_),
+ std::move(broker_factory_));
+
+ factory.core()->AddLoopbackSink(&sink1);
+ factory.core()->AddLoopbackSink(&sink2);
+ factory.core()->RemoveLoopbackSink(&sink1);
+ }
+ base::RunLoop().RunUntilIdle();
+}
+
} // namespace content
diff --git a/chromium/content/browser/media/in_process_audio_loopback_stream_creator.cc b/chromium/content/browser/media/in_process_audio_loopback_stream_creator.cc
index 618c9b8f3a5..12b51f3f47e 100644
--- a/chromium/content/browser/media/in_process_audio_loopback_stream_creator.cc
+++ b/chromium/content/browser/media/in_process_audio_loopback_stream_creator.cc
@@ -4,16 +4,102 @@
#include "content/browser/media/in_process_audio_loopback_stream_creator.h"
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/task/post_task.h"
+#include "content/browser/browser_main_loop.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/web_contents.h"
#include "content/public/common/service_manager_connection.h"
+#include "media/audio/audio_device_description.h"
+#include "media/base/user_input_monitor.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/service_manager/public/cpp/connector.h"
namespace content {
+namespace {
+
+// A mojom::RendererAudioInputStreamFactoryClient that holds a
+// AudioLoopbackStreamCreator::StreamCreatedCallback. The callback runs when the
+// requested audio stream is created.
+class StreamCreatedCallbackAdapter final
+ : public mojom::RendererAudioInputStreamFactoryClient {
+ public:
+ explicit StreamCreatedCallbackAdapter(
+ const AudioLoopbackStreamCreator::StreamCreatedCallback& callback)
+ : callback_(callback) {
+ DCHECK(callback_);
+ }
+
+ ~StreamCreatedCallbackAdapter() override {}
+
+ // mojom::RendererAudioInputStreamFactoryClient implementation.
+ void StreamCreated(
+ media::mojom::AudioInputStreamPtr stream,
+ media::mojom::AudioInputStreamClientRequest client_request,
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
+ bool initially_muted,
+ const base::Optional<base::UnguessableToken>& stream_id) override {
+ DCHECK(!initially_muted); // Loopback streams shouldn't be started muted.
+ callback_.Run(std::move(stream), std::move(client_request),
+ std::move(data_pipe));
+ }
+
+ private:
+ const AudioLoopbackStreamCreator::StreamCreatedCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(StreamCreatedCallbackAdapter);
+};
+
+void CreateLoopbackStreamHelper(
+ ForwardingAudioStreamFactory::Core* factory,
+ AudioStreamBroker::LoopbackSource* loopback_source,
+ const media::AudioParameters& params,
+ uint32_t total_segments,
+ mojom::RendererAudioInputStreamFactoryClientPtrInfo client_ptr_info) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ const bool mute_source = true;
+ mojom::RendererAudioInputStreamFactoryClientPtr client;
+ client.Bind(std::move(client_ptr_info));
+
+ factory->CreateLoopbackStream(-1, -1, loopback_source, params, total_segments,
+ mute_source, std::move(client));
+}
+
+void CreateSystemWideLoopbackStreamHelper(
+ ForwardingAudioStreamFactory::Core* factory,
+ const media::AudioParameters& params,
+ uint32_t total_segments,
+ mojom::RendererAudioInputStreamFactoryClientPtrInfo client_ptr_info) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ const bool enable_agc = false;
+ mojom::RendererAudioInputStreamFactoryClientPtr client;
+ client.Bind(std::move(client_ptr_info));
+
+ factory->CreateInputStream(
+ -1, -1, media::AudioDeviceDescription::kLoopbackWithMuteDeviceId, params,
+ total_segments, enable_agc, nullptr /* processing_config */,
+ std::move(client));
+}
+
+} // namespace
+
InProcessAudioLoopbackStreamCreator::InProcessAudioLoopbackStreamCreator()
: factory_(nullptr,
+ BrowserMainLoop::GetInstance()
+ ? static_cast<media::UserInputMonitorBase*>(
+ BrowserMainLoop::GetInstance()->user_input_monitor())
+ : nullptr,
content::ServiceManagerConnection::GetForProcess()
->GetConnector()
->Clone(),
@@ -23,7 +109,6 @@ InProcessAudioLoopbackStreamCreator::InProcessAudioLoopbackStreamCreator()
InProcessAudioLoopbackStreamCreator::~InProcessAudioLoopbackStreamCreator() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- factory_.FrameDeleted(nullptr);
}
void InProcessAudioLoopbackStreamCreator::CreateLoopbackStream(
@@ -32,13 +117,27 @@ void InProcessAudioLoopbackStreamCreator::CreateLoopbackStream(
uint32_t total_segments,
const StreamCreatedCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RenderFrameHost* loopback_source_frame = nullptr;
+ mojom::RendererAudioInputStreamFactoryClientPtrInfo client;
+ mojo::MakeStrongBinding(
+ std::make_unique<StreamCreatedCallbackAdapter>(callback),
+ mojo::MakeRequest(&client));
+ // Deletion of factory_.core() is posted to the IO thread when |factory_| is
+ // destroyed, so Unretained is safe below.
if (loopback_source) {
- loopback_source_frame = loopback_source->GetMainFrame();
- DCHECK(loopback_source_frame);
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&CreateLoopbackStreamHelper, factory_.core(),
+ static_cast<WebContentsImpl*>(loopback_source)
+ ->GetAudioStreamFactory()
+ ->core(),
+ params, total_segments, std::move(client)));
+ return;
}
- factory_.CreateInProcessLoopbackStream(loopback_source_frame, params,
- total_segments, callback);
+ // A null |frame_of_source_web_contents| requests system-wide loopback.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&CreateSystemWideLoopbackStreamHelper, factory_.core(),
+ params, total_segments, std::move(client)));
}
} // namespace content
diff --git a/chromium/content/browser/media/media_browsertest.cc b/chromium/content/browser/media/media_browsertest.cc
index 93bea4f82b9..5aabc37b42b 100644
--- a/chromium/content/browser/media/media_browsertest.cc
+++ b/chromium/content/browser/media/media_browsertest.cc
@@ -30,6 +30,9 @@ void MediaBrowserTest::SetUpCommandLine(base::CommandLine* command_line) {
command_line->AppendSwitchASCII(
switches::kAutoplayPolicy,
switches::autoplay::kNoUserGestureRequiredPolicy);
+ // Disable fallback after decode error to avoid unexpected test pass on the
+ // fallback path.
+ scoped_feature_list_.InitAndDisableFeature(media::kFallbackAfterDecodeError);
}
void MediaBrowserTest::RunMediaTestPage(const std::string& html_page,
diff --git a/chromium/content/browser/media/media_browsertest.h b/chromium/content/browser/media/media_browsertest.h
index b8e0b906d15..bc9af5cb690 100644
--- a/chromium/content/browser/media/media_browsertest.h
+++ b/chromium/content/browser/media/media_browsertest.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/strings/string_split.h"
+#include "base/test/scoped_feature_list.h"
#include "content/public/test/content_browser_test.h"
namespace content {
@@ -44,6 +45,9 @@ class MediaBrowserTest : public ContentBrowserTest {
// Adds titles that RunTest() should wait for.
virtual void AddTitlesToAwait(content::TitleWatcher* title_watcher);
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
};
} // namespace content
diff --git a/chromium/content/browser/media/media_color_browsertest.cc b/chromium/content/browser/media/media_color_browsertest.cc
index 6cc930bb586..5f38d7429a7 100644
--- a/chromium/content/browser/media/media_color_browsertest.cc
+++ b/chromium/content/browser/media/media_color_browsertest.cc
@@ -53,9 +53,8 @@ IN_PROC_BROWSER_TEST_F(MediaColorTest, Yuv420pH264) {
RunColorTest("yuv420p.mp4");
}
-// This test fails on Android: http://crbug.com/647818 and OSX:
-// http://crbug.com/647838
-#if defined(OS_MACOSX) || defined(OS_ANDROID)
+// This test fails on Android: http://crbug.com/647818
+#if defined(OS_ANDROID)
#define MAYBE_Yuvj420pH264 DISABLED_Yuvj420pH264
#else
#define MAYBE_Yuvj420pH264 Yuvj420pH264
diff --git a/chromium/content/browser/media/media_devices_permission_checker.cc b/chromium/content/browser/media/media_devices_permission_checker.cc
index 8c16627a4a1..95280c196b0 100644
--- a/chromium/content/browser/media/media_devices_permission_checker.cc
+++ b/chromium/content/browser/media/media_devices_permission_checker.cc
@@ -9,10 +9,12 @@
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/task/post_task.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/common/media/media_devices.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
@@ -114,8 +116,8 @@ void MediaDevicesPermissionChecker::CheckPermission(
return;
}
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&CheckSinglePermissionOnUIThread, device_type,
render_process_id, render_frame_id),
std::move(callback));
@@ -134,8 +136,8 @@ void MediaDevicesPermissionChecker::CheckPermissions(
return;
}
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DoCheckPermissionsOnUIThread, requested,
render_process_id, render_frame_id),
std::move(callback));
diff --git a/chromium/content/browser/media/media_devices_util.cc b/chromium/content/browser/media/media_devices_util.cc
index 58badef2512..59fcb9314f1 100644
--- a/chromium/content/browser/media/media_devices_util.cc
+++ b/chromium/content/browser/media/media_devices_util.cc
@@ -11,10 +11,12 @@
#include "base/command_line.h"
#include "base/strings/string_split.h"
#include "base/strings/string_tokenizer.h"
+#include "base/task/post_task.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/media_device_id.h"
#include "content/public/browser/render_frame_host.h"
@@ -117,8 +119,8 @@ void GetDefaultMediaDeviceID(
}
}
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&GetDefaultMediaDeviceIDOnUIThread, device_type,
render_process_id, render_frame_id),
callback);
diff --git a/chromium/content/browser/media/media_internals.cc b/chromium/content/browser/media/media_internals.cc
index a4257d16db9..fe54364f26d 100644
--- a/chromium/content/browser/media/media_internals.cc
+++ b/chromium/content/browser/media/media_internals.cc
@@ -9,17 +9,21 @@
#include <tuple>
#include <utility>
+#include "base/containers/adapters.h"
+#include "base/feature_list.h"
#include "base/macros.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
+#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
-#include "content/browser/media/session/audio_focus_manager.h"
#include "content/browser/media/session/media_session_impl.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
@@ -27,10 +31,16 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/service_manager_connection.h"
#include "media/base/audio_parameters.h"
#include "media/base/media_log_event.h"
#include "media/filters/gpu_video_decoder.h"
+#include "media/webrtc/webrtc_switches.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/media_session/public/mojom/constants.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/service_manager/sandbox/features.h"
#if !defined(OS_ANDROID)
#include "media/filters/decrypting_video_decoder.h"
@@ -115,6 +125,10 @@ bool IsIncognito(int render_process_id) {
const char kAudioLogStatusKey[] = "status";
const char kAudioLogUpdateFunction[] = "media.updateAudioComponent";
+const char kAudioFocusFunction[] = "media.onReceiveAudioFocusState";
+const char kAudioFocusIdKey[] = "id";
+const char kAudioFocusSessionsKey[] = "sessions";
+
} // namespace
namespace content {
@@ -269,8 +283,8 @@ void MediaInternals::AudioLogImpl::SendWebContentsTitleHelper(
int render_frame_id) {
// Page title information can only be retrieved from the UI thread.
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SendWebContentsTitleHelper, cache_key, std::move(dict),
render_process_id, render_frame_id));
return;
@@ -691,6 +705,27 @@ void MediaInternals::SendHistoricalMediaEvents() {
// second UI still works nicely!
}
+void MediaInternals::SendGeneralAudioInformation() {
+ base::DictionaryValue audio_info_data;
+
+ // Audio feature information.
+ auto set_feature_data = [&](auto& feature) {
+ audio_info_data.SetKey(
+ feature.name,
+ base::Value(base::FeatureList::IsEnabled(feature) ? "Enabled"
+ : "Disabled"));
+ };
+ set_feature_data(features::kAudioServiceAudioStreams);
+ set_feature_data(features::kAudioServiceOutOfProcess);
+ set_feature_data(features::kAudioServiceLaunchOnStartup);
+ set_feature_data(service_manager::features::kAudioServiceSandbox);
+ set_feature_data(features::kWebRtcApmInAudioService);
+
+ base::string16 audio_info_update =
+ SerializeUpdate("media.updateGeneralAudioInformation", &audio_info_data);
+ SendUpdate(audio_info_update);
+}
+
void MediaInternals::SendAudioStreamData() {
base::string16 audio_stream_update;
{
@@ -712,32 +747,20 @@ void MediaInternals::SendVideoCaptureDeviceCapabilities() {
}
void MediaInternals::SendAudioFocusState() {
-#if !defined(OS_ANDROID)
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!CanUpdate())
return;
- base::DictionaryValue audio_focus_data;
- const std::list<AudioFocusManager::StackRow>& stack =
- AudioFocusManager::GetInstance()->audio_focus_stack_;
+ content::ServiceManagerConnection::GetForProcess()
+ ->GetConnector()
+ ->BindInterface(media_session::mojom::kServiceName, &audio_focus_ptr_);
- // We should go backwards through the stack so the top of the stack is always
- // shown first in the list.
- base::ListValue stack_data;
- for (auto iter = stack.rbegin(); iter != stack.rend(); ++iter) {
- MediaSessionImpl::DebugInfo debug_info =
- (*iter).media_session->GetDebugInfo();
- base::DictionaryValue media_session_data;
- media_session_data.SetKey("name", base::Value(debug_info.name));
- media_session_data.SetKey("owner", base::Value(debug_info.owner));
- media_session_data.SetKey("state", base::Value(debug_info.state));
- stack_data.GetList().push_back(std::move(media_session_data));
- }
-
- audio_focus_data.SetKey("sessions", std::move(stack_data));
+ if (!audio_focus_ptr_.is_bound())
+ return;
- SendUpdate(
- SerializeUpdate("media.onReceiveAudioFocusState", &audio_focus_data));
-#endif // !defined(OS_ANDROID)
+ // Get the audio focus state from the media session service.
+ audio_focus_ptr_->GetFocusRequests(base::BindOnce(
+ &MediaInternals::DidGetAudioFocusRequestList, base::Unretained(this)));
}
void MediaInternals::UpdateVideoCaptureDeviceCapabilities(
@@ -821,30 +844,100 @@ void MediaInternals::OnProcessTerminatedForTesting(int process_id) {
}
void MediaInternals::OnFocusGained(
- media_session::mojom::MediaSessionPtr media_session,
+ media_session::mojom::MediaSessionInfoPtr media_session,
media_session::mojom::AudioFocusType type) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&MediaInternals::SendAudioFocusState,
- base::Unretained(this)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&MediaInternals::SendAudioFocusState,
+ base::Unretained(this)));
}
void MediaInternals::OnFocusLost(
- media_session::mojom::MediaSessionPtr media_session) {
+ media_session::mojom::MediaSessionInfoPtr media_session) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&MediaInternals::SendAudioFocusState,
+ base::Unretained(this)));
+}
+
+void MediaInternals::DidGetAudioFocusRequestList(
+ std::vector<media_session::mojom::AudioFocusRequestStatePtr> stack) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (!CanUpdate())
+ return;
+
+ content::ServiceManagerConnection::GetForProcess()
+ ->GetConnector()
+ ->BindInterface(media_session::mojom::kServiceName,
+ &audio_focus_debug_ptr_);
+
+ if (!audio_focus_debug_ptr_.is_bound())
+ return;
+
+ audio_focus_data_.Clear();
+
+ // We should go backwards through the stack so the top of the stack is
+ // always shown first in the list.
+ base::ListValue stack_data;
+ for (const auto& session : base::Reversed(stack)) {
+ if (!session->request_id.has_value())
+ continue;
+
+ std::string id_string = session->request_id.value().ToString();
+ base::DictionaryValue media_session_data;
+ media_session_data.SetKey(kAudioFocusIdKey, base::Value(id_string));
+ stack_data.GetList().push_back(std::move(media_session_data));
+
+ audio_focus_debug_ptr_->GetDebugInfoForRequest(
+ session->request_id.value(),
+ base::BindOnce(&MediaInternals::DidGetAudioFocusDebugInfo,
+ base::Unretained(this), id_string));
+ }
+
+ audio_focus_data_.SetKey(kAudioFocusSessionsKey, std::move(stack_data));
+
+ if (stack.empty())
+ SendUpdate(SerializeUpdate(kAudioFocusFunction, &audio_focus_data_));
+}
+
+void MediaInternals::DidGetAudioFocusDebugInfo(
+ const std::string& id,
+ media_session::mojom::MediaSessionDebugInfoPtr info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&MediaInternals::SendAudioFocusState,
- base::Unretained(this)));
+ if (!CanUpdate())
+ return;
+
+ base::Value* sessions_list =
+ audio_focus_data_.FindKey(kAudioFocusSessionsKey);
+ DCHECK(sessions_list);
+
+ bool updated = false;
+ for (auto& session : sessions_list->GetList()) {
+ if (session.FindKey(kAudioFocusIdKey)->GetString() != id)
+ continue;
+
+ session.SetKey("name", base::Value(info->name));
+ session.SetKey("owner", base::Value(info->owner));
+ session.SetKey("state", base::Value(info->state));
+ updated = true;
+ }
+
+ if (!updated)
+ return;
+
+ SendUpdate(SerializeUpdate(kAudioFocusFunction, &audio_focus_data_));
}
void MediaInternals::SendUpdate(const base::string16& update) {
// SendUpdate() may be called from any thread, but must run on the UI thread.
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&MediaInternals::SendUpdate,
- base::Unretained(this), update));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&MediaInternals::SendUpdate,
+ base::Unretained(this), update));
return;
}
@@ -871,11 +964,9 @@ void MediaInternals::SaveEvent(int process_id,
// Remove all events for a given player as soon as we have to remove a
// single event for that player to avoid showing incomplete players.
const int id_to_remove = saved_events.front().id;
- saved_events.erase(std::remove_if(saved_events.begin(), saved_events.end(),
- [&](const media::MediaLogEvent& event) {
- return event.id == id_to_remove;
- }),
- saved_events.end());
+ base::EraseIf(saved_events, [&](const media::MediaLogEvent& event) {
+ return event.id == id_to_remove;
+ });
}
}
diff --git a/chromium/content/browser/media/media_internals.h b/chromium/content/browser/media/media_internals.h
index 7aa7ddcaaa8..189904c7ca1 100644
--- a/chromium/content/browser/media/media_internals.h
+++ b/chromium/content/browser/media/media_internals.h
@@ -75,6 +75,9 @@ class CONTENT_EXPORT MediaInternals : public media::AudioLogFactory,
// Replay all saved media events.
void SendHistoricalMediaEvents();
+ // Sends general audio information to each registered UpdateCallback.
+ void SendGeneralAudioInformation();
+
// Sends all audio cached data to each registered UpdateCallback.
void SendAudioStreamData();
@@ -121,10 +124,20 @@ class CONTENT_EXPORT MediaInternals : public media::AudioLogFactory,
MediaInternals();
// AudioFocusObserver implementation.
- void OnFocusGained(media_session::mojom::MediaSessionPtr media_session,
+ void OnFocusGained(media_session::mojom::MediaSessionInfoPtr media_session,
media_session::mojom::AudioFocusType type) override;
void OnFocusLost(
- media_session::mojom::MediaSessionPtr media_session) override;
+ media_session::mojom::MediaSessionInfoPtr media_session) override;
+
+ // Called when we receive the list of audio focus requests to display.
+ void DidGetAudioFocusRequestList(
+ std::vector<media_session::mojom::AudioFocusRequestStatePtr>);
+
+ // Called when we receive audio focus debug info to display for a single
+ // audio focus request.
+ void DidGetAudioFocusDebugInfo(
+ const std::string& id,
+ media_session::mojom::MediaSessionDebugInfoPtr info);
// Sends |update| to each registered UpdateCallback. Safe to call from any
// thread, but will forward to the IO thread.
@@ -152,6 +165,10 @@ class CONTENT_EXPORT MediaInternals : public media::AudioLogFactory,
int render_process_id,
int render_frame_id);
+ // Holds a pointer to the media session service and it's debug interface.
+ media_session::mojom::AudioFocusManagerPtr audio_focus_ptr_;
+ media_session::mojom::AudioFocusManagerDebugPtr audio_focus_debug_ptr_;
+
// Must only be accessed on the UI thread.
std::vector<UpdateCallback> update_callbacks_;
@@ -163,6 +180,9 @@ class CONTENT_EXPORT MediaInternals : public media::AudioLogFactory,
NotificationRegistrar registrar_;
+ // Must only be accessed on the UI thread.
+ base::DictionaryValue audio_focus_data_;
+
// All variables below must be accessed under |lock_|.
base::Lock lock_;
bool can_update_;
diff --git a/chromium/content/browser/media/media_internals_proxy.cc b/chromium/content/browser/media/media_internals_proxy.cc
index 8526ebc04a4..bfa38b2ca18 100644
--- a/chromium/content/browser/media/media_internals_proxy.cc
+++ b/chromium/content/browser/media/media_internals_proxy.cc
@@ -6,9 +6,11 @@
#include "base/bind.h"
#include "base/location.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/media/media_internals_handler.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@@ -37,10 +39,14 @@ void MediaInternalsProxy::GetEverything() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
MediaInternals::GetInstance()->SendHistoricalMediaEvents();
+ MediaInternals::GetInstance()->SendGeneralAudioInformation();
+#if !defined(OS_ANDROID)
+ MediaInternals::GetInstance()->SendAudioFocusState();
+#endif
// Ask MediaInternals for its data on IO thread.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&MediaInternalsProxy::GetEverythingOnIOThread, this));
}
@@ -49,10 +55,6 @@ void MediaInternalsProxy::GetEverythingOnIOThread() {
// TODO(xhwang): Investigate whether we can update on UI thread directly.
MediaInternals::GetInstance()->SendAudioStreamData();
MediaInternals::GetInstance()->SendVideoCaptureDeviceCapabilities();
-
-#if !defined(OS_ANDROID)
- MediaInternals::GetInstance()->SendAudioFocusState();
-#endif
}
void MediaInternalsProxy::UpdateUIOnUIThread(const base::string16& update) {
diff --git a/chromium/content/browser/media/media_internals_unittest.cc b/chromium/content/browser/media/media_internals_unittest.cc
index 033385ac2de..32a85ae8abd 100644
--- a/chromium/content/browser/media/media_internals_unittest.cc
+++ b/chromium/content/browser/media/media_internals_unittest.cc
@@ -12,14 +12,15 @@
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/lock.h"
#include "base/test/scoped_command_line.h"
#include "base/test/test_message_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
-#include "content/browser/media/session/audio_focus_manager.h"
#include "content/browser/media/session/media_session_impl.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_service_manager_context.h"
#include "content/test/test_web_contents.h"
#include "media/base/audio_parameters.h"
#include "media/base/channel_layout.h"
@@ -27,6 +28,7 @@
#include "media/base/media_switches.h"
#include "services/media_session/public/cpp/switches.h"
#include "services/media_session/public/mojom/audio_focus.mojom.h"
+#include "services/media_session/public/mojom/constants.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/size.h"
@@ -35,18 +37,27 @@ namespace {
const int kTestComponentID = 0;
const char kTestDeviceID[] = "test-device-id";
+using media_session::mojom::AudioFocusRequestStatePtr;
+
// This class encapsulates a MediaInternals reference. It also has some useful
// methods to receive a callback, deserialize its associated data and expect
// integer/string values.
class MediaInternalsTestBase {
public:
- MediaInternalsTestBase()
- : media_internals_(content::MediaInternals::GetInstance()) {}
+ MediaInternalsTestBase() : media_internals_(nullptr) {
+ scoped_command_line_.GetProcessCommandLine()->AppendSwitch(
+ media_session::switches::kEnableAudioFocus);
+
+ service_manager_context_ =
+ std::make_unique<content::TestServiceManagerContext>();
+ media_internals_ = content::MediaInternals::GetInstance();
+ }
+
virtual ~MediaInternalsTestBase() {}
protected:
// Extracts and deserializes the JSON update data; merges into |update_data_|.
- void UpdateCallbackImpl(const base::string16& update) {
+ virtual void UpdateCallbackImpl(const base::string16& update) {
// Each update string looks like "<JavaScript Function Name>({<JSON>});"
// or for video capabilities: "<JavaScript Function Name>([{<JSON>}]);".
// In the second case we will be able to extract the dictionary if it is the
@@ -98,7 +109,14 @@ class MediaInternalsTestBase {
const content::TestBrowserThreadBundle thread_bundle_;
base::DictionaryValue update_data_;
- content::MediaInternals* const media_internals_;
+
+ content::MediaInternals* media_internals() const { return media_internals_; }
+
+ private:
+ content::MediaInternals* media_internals_;
+
+ base::test::ScopedCommandLine scoped_command_line_;
+ std::unique_ptr<content::TestServiceManagerContext> service_manager_context_;
};
} // namespace
@@ -114,11 +132,11 @@ class MediaInternalsVideoCaptureDeviceTest : public testing::Test,
: update_cb_(base::Bind(
&MediaInternalsVideoCaptureDeviceTest::UpdateCallbackImpl,
base::Unretained(this))) {
- media_internals_->AddUpdateCallback(update_cb_);
+ media_internals()->AddUpdateCallback(update_cb_);
}
~MediaInternalsVideoCaptureDeviceTest() override {
- media_internals_->RemoveUpdateCallback(update_cb_);
+ media_internals()->RemoveUpdateCallback(update_cb_);
}
protected:
@@ -176,7 +194,7 @@ TEST_F(MediaInternalsVideoCaptureDeviceTest,
// a JSON array of objects to string. So here, the |UpdateCallbackImpl| will
// deserialize the first object in the array. This means we have to have
// exactly one device_info in the |descriptors_and_formats|.
- media_internals_->UpdateVideoCaptureDeviceCapabilities(
+ media_internals()->UpdateVideoCaptureDeviceCapabilities(
descriptors_and_formats);
#if defined(OS_LINUX)
@@ -208,13 +226,13 @@ class MediaInternalsAudioLogTest
base::Unretained(this))),
test_params_(MakeAudioParams()),
test_component_(GetParam()),
- audio_log_(media_internals_->CreateAudioLog(test_component_,
- kTestComponentID)) {
- media_internals_->AddUpdateCallback(update_cb_);
+ audio_log_(media_internals()->CreateAudioLog(test_component_,
+ kTestComponentID)) {
+ media_internals()->AddUpdateCallback(update_cb_);
}
virtual ~MediaInternalsAudioLogTest() {
- media_internals_->RemoveUpdateCallback(update_cb_);
+ media_internals()->RemoveUpdateCallback(update_cb_);
}
protected:
@@ -309,11 +327,14 @@ class MediaInternalsAudioFocusTest : public testing::Test,
base::BindRepeating(&MediaInternalsAudioFocusTest::UpdateCallbackImpl,
base::Unretained(this));
- scoped_command_line_.GetProcessCommandLine()->AppendSwitch(
- media_session::switches::kEnableAudioFocus);
+ browser_context_.reset(new TestBrowserContext());
+ run_loop_ = std::make_unique<base::RunLoop>();
+
+ content::ServiceManagerConnection::GetForProcess()
+ ->GetConnector()
+ ->BindInterface(media_session::mojom::kServiceName, &audio_focus_ptr_);
content::MediaInternals::GetInstance()->AddUpdateCallback(update_cb_);
- browser_context_.reset(new TestBrowserContext());
}
void TearDown() override {
@@ -322,10 +343,33 @@ class MediaInternalsAudioFocusTest : public testing::Test,
}
protected:
- void ExpectValue(base::ListValue expected_list) {
+ void UpdateCallbackImpl(const base::string16& update) override {
+ base::AutoLock auto_lock(lock_);
+ MediaInternalsTestBase::UpdateCallbackImpl(update);
+ call_count_++;
+
+ if (call_count_ == wanted_call_count_)
+ run_loop_->Quit();
+ }
+
+ void ExpectValueAndReset(base::ListValue expected_list) {
+ base::AutoLock auto_lock(lock_);
+
base::DictionaryValue expected_data;
expected_data.SetKey("sessions", std::move(expected_list));
EXPECT_EQ(expected_data, update_data_);
+
+ update_data_.Clear();
+ run_loop_ = std::make_unique<base::RunLoop>();
+ call_count_ = 0;
+ }
+
+ void Reset() {
+ base::AutoLock auto_lock(lock_);
+
+ update_data_.Clear();
+ run_loop_ = std::make_unique<base::RunLoop>();
+ call_count_ = 0;
}
std::unique_ptr<TestWebContents> CreateWebContents() {
@@ -343,16 +387,43 @@ class MediaInternalsAudioFocusTest : public testing::Test,
session->RemoveAllPlayersForTest();
}
- void WaitForCallback() {
- AudioFocusManager::GetInstance()->FlushForTesting();
- base::RunLoop().RunUntilIdle();
+ void WaitForCallbackCount(int count) {
+ wanted_call_count_ = count;
+
+ {
+ base::AutoLock auto_lock(lock_);
+ if (!update_data_.empty() && call_count_ == wanted_call_count_)
+ return;
+ }
+
+ run_loop_->Run();
+ }
+
+ std::string GetRequestIdForTopFocusRequest() {
+ std::string result;
+
+ audio_focus_ptr_->GetFocusRequests(base::BindOnce(
+ [](std::string* out, std::vector<AudioFocusRequestStatePtr> requests) {
+ DCHECK(!requests.empty());
+ *out = requests.back()->request_id.value().ToString();
+ },
+ &result));
+
+ audio_focus_ptr_.FlushForTesting();
+ return result;
}
MediaInternals::UpdateCallback update_cb_;
private:
- base::test::ScopedCommandLine scoped_command_line_;
+ int call_count_ = 0;
+ int wanted_call_count_ = 0;
+
+ base::Lock lock_;
+ std::unique_ptr<base::RunLoop> run_loop_;
std::unique_ptr<TestBrowserContext> browser_context_;
+
+ media_session::mojom::AudioFocusManagerPtr audio_focus_ptr_;
};
TEST_F(MediaInternalsAudioFocusTest, AudioFocusStateIsUpdated) {
@@ -361,18 +432,22 @@ TEST_F(MediaInternalsAudioFocusTest, AudioFocusStateIsUpdated) {
web_contents1->SetTitle(base::UTF8ToUTF16(kTestTitle1));
MediaSessionImpl* media_session1 = MediaSessionImpl::Get(web_contents1.get());
media_session1->RequestSystemAudioFocus(AudioFocusType::kGain);
- WaitForCallback();
+ WaitForCallbackCount(1);
+
+ // Get the |request_id| for the top session.
+ std::string request_id1 = GetRequestIdForTopFocusRequest();
// Check JSON is what we expect.
{
base::DictionaryValue expected_session;
+ expected_session.SetKey("id", base::Value(request_id1));
expected_session.SetKey("name", GetAddressAsValue(media_session1));
expected_session.SetKey("owner", base::Value(kTestTitle1));
expected_session.SetKey("state", base::Value("Active"));
base::ListValue expected_list;
expected_list.GetList().push_back(std::move(expected_session));
- ExpectValue(std::move(expected_list));
+ ExpectValueAndReset(std::move(expected_list));
}
// Create another media session.
@@ -381,16 +456,22 @@ TEST_F(MediaInternalsAudioFocusTest, AudioFocusStateIsUpdated) {
MediaSessionImpl* media_session2 = MediaSessionImpl::Get(web_contents2.get());
media_session2->RequestSystemAudioFocus(
AudioFocusType::kGainTransientMayDuck);
- WaitForCallback();
+ WaitForCallbackCount(2);
+
+ // Get the |request_id| for the top session.
+ std::string request_id2 = GetRequestIdForTopFocusRequest();
+ DCHECK_NE(request_id1, request_id2);
// Check JSON is what we expect.
{
base::DictionaryValue expected_session1;
+ expected_session1.SetKey("id", base::Value(request_id2));
expected_session1.SetKey("name", GetAddressAsValue(media_session2));
expected_session1.SetKey("owner", base::Value(kTestTitle2));
expected_session1.SetKey("state", base::Value("Active"));
base::DictionaryValue expected_session2;
+ expected_session2.SetKey("id", base::Value(request_id1));
expected_session2.SetKey("name", GetAddressAsValue(media_session1));
expected_session2.SetKey("owner", base::Value(kTestTitle1));
expected_session2.SetKey("state", base::Value("Active Ducked"));
@@ -398,33 +479,34 @@ TEST_F(MediaInternalsAudioFocusTest, AudioFocusStateIsUpdated) {
base::ListValue expected_list;
expected_list.GetList().push_back(std::move(expected_session1));
expected_list.GetList().push_back(std::move(expected_session2));
- ExpectValue(std::move(expected_list));
+ ExpectValueAndReset(std::move(expected_list));
}
// Abandon audio focus.
RemoveAllPlayersForTest(media_session2);
- WaitForCallback();
+ WaitForCallbackCount(1);
// Check JSON is what we expect.
{
base::DictionaryValue expected_session;
+ expected_session.SetKey("id", base::Value(request_id1));
expected_session.SetKey("name", GetAddressAsValue(media_session1));
expected_session.SetKey("owner", base::Value(kTestTitle1));
expected_session.SetKey("state", base::Value("Active"));
base::ListValue expected_list;
expected_list.GetList().push_back(std::move(expected_session));
- ExpectValue(std::move(expected_list));
+ ExpectValueAndReset(std::move(expected_list));
}
// Abandon audio focus.
RemoveAllPlayersForTest(media_session1);
- WaitForCallback();
+ WaitForCallbackCount(1);
// Check JSON is what we expect.
{
base::ListValue expected_list;
- ExpectValue(std::move(expected_list));
+ ExpectValueAndReset(std::move(expected_list));
}
}
diff --git a/chromium/content/browser/media/media_source_browsertest.cc b/chromium/content/browser/media/media_source_browsertest.cc
index c03bf22239e..593ae9b0215 100644
--- a/chromium/content/browser/media/media_source_browsertest.cc
+++ b/chromium/content/browser/media/media_source_browsertest.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "base/command_line.h"
-#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/media/media_browsertest.h"
#include "media/base/media_switches.h"
@@ -37,7 +36,7 @@ const char kMp2tAudioVideo[] = "video/mp2t; codecs=\"mp4a.40.2, avc1.42E01E\"";
namespace content {
-class MediaSourceTest : public content::MediaBrowserTest {
+class MediaSourceTest : public MediaBrowserTest {
public:
void TestSimplePlayback(const std::string& media_file,
const std::string& media_type,
@@ -48,15 +47,6 @@ class MediaSourceTest : public content::MediaBrowserTest {
RunMediaTestPage("media_source_player.html", query_params, expectation,
false);
}
-
- void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitchASCII(
- switches::kAutoplayPolicy,
- switches::autoplay::kNoUserGestureRequiredPolicy);
- }
-
- protected:
- base::test::ScopedFeatureList scoped_feature_list_;
};
IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_VideoAudio_WebM) {
diff --git a/chromium/content/browser/media/media_suspend_browsertest.cc b/chromium/content/browser/media/media_suspend_browsertest.cc
index d0059690e25..1cd1a66f57a 100644
--- a/chromium/content/browser/media/media_suspend_browsertest.cc
+++ b/chromium/content/browser/media/media_suspend_browsertest.cc
@@ -24,13 +24,13 @@ static void SuspendAllMediaPlayersInRenderFrame(RenderFrameHost* rfh) {
// and that players suspended in this way can be resumed. Note: This does not
// test suspend in various ready states; those tests are handled by layout tests
// for ease of writing and ready state manipulation.
-class MediaSuspendTest : public content::MediaBrowserTest {
+class MediaSuspendTest : public MediaBrowserTest {
public:
void RunSuspendTest(const std::string& load_until) {
base::StringPairs query_params;
query_params.emplace_back("event", load_until);
- GURL gurl = content::GetFileUrlWithQuery(
+ GURL gurl = GetFileUrlWithQuery(
media::GetTestDataFilePath("media_suspend_test.html"),
media::GetURLQueryString(query_params));
@@ -74,7 +74,7 @@ class MediaSuspendTest : public content::MediaBrowserTest {
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
- content::MediaBrowserTest::SetUpCommandLine(command_line);
+ MediaBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kExposeInternalsForTesting);
}
};
diff --git a/chromium/content/browser/media/media_web_contents_observer.cc b/chromium/content/browser/media/media_web_contents_observer.cc
index c605c930a59..e636fcad80b 100644
--- a/chromium/content/browser/media/media_web_contents_observer.cc
+++ b/chromium/content/browser/media/media_web_contents_observer.cc
@@ -330,7 +330,8 @@ void MediaWebContentsObserver::OnPictureInPictureModeStarted(
int delegate_id,
const viz::SurfaceId& surface_id,
const gfx::Size& natural_size,
- int request_id) {
+ int request_id,
+ bool show_play_pause_button) {
DCHECK(surface_id.is_valid());
pip_player_ = MediaPlayerId(render_frame_host, delegate_id);
@@ -339,6 +340,11 @@ void MediaWebContentsObserver::OnPictureInPictureModeStarted(
gfx::Size window_size =
web_contents_impl()->EnterPictureInPicture(surface_id, natural_size);
+ if (auto* pip_controller =
+ PictureInPictureWindowControllerImpl::FromWebContents(
+ web_contents_impl()))
+ pip_controller->SetAlwaysHidePlayPauseButton(show_play_pause_button);
+
render_frame_host->Send(
new MediaPlayerDelegateMsg_OnPictureInPictureModeStarted_ACK(
render_frame_host->GetRoutingID(), delegate_id, request_id,
@@ -371,19 +377,20 @@ void MediaWebContentsObserver::OnPictureInPictureSurfaceChanged(
RenderFrameHost* render_frame_host,
int delegate_id,
const viz::SurfaceId& surface_id,
- const gfx::Size& natural_size) {
+ const gfx::Size& natural_size,
+ bool show_play_pause_button) {
DCHECK(surface_id.is_valid());
pip_player_ = MediaPlayerId(render_frame_host, delegate_id);
- PictureInPictureWindowControllerImpl* pip_controller =
- PictureInPictureWindowControllerImpl::FromWebContents(
- web_contents_impl());
-
// The PictureInPictureWindowController instance may not have been created by
// the embedder.
- if (pip_controller)
+ if (auto* pip_controller =
+ PictureInPictureWindowControllerImpl::FromWebContents(
+ web_contents_impl())) {
pip_controller->EmbedSurface(surface_id, natural_size);
+ pip_controller->SetAlwaysHidePlayPauseButton(show_play_pause_button);
+ }
}
void MediaWebContentsObserver::ClearWakeLocks(
diff --git a/chromium/content/browser/media/media_web_contents_observer.h b/chromium/content/browser/media/media_web_contents_observer.h
index febe37fe409..5994a563d4a 100644
--- a/chromium/content/browser/media/media_web_contents_observer.h
+++ b/chromium/content/browser/media/media_web_contents_observer.h
@@ -136,7 +136,8 @@ class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver {
int delegate_id,
const viz::SurfaceId&,
const gfx::Size& natural_size,
- int request_id);
+ int request_id,
+ bool show_play_pause_button);
void OnPictureInPictureModeEnded(RenderFrameHost* render_frame_host,
int delegate_id,
int request_id);
@@ -147,7 +148,8 @@ class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver {
void OnPictureInPictureSurfaceChanged(RenderFrameHost*,
int delegate_id,
const viz::SurfaceId&,
- const gfx::Size&);
+ const gfx::Size&,
+ bool show_play_pause_button);
// Clear |render_frame_host|'s tracking entry for its WakeLocks.
void ClearWakeLocks(RenderFrameHost* render_frame_host);
diff --git a/chromium/content/browser/media/midi_host_unittest.cc b/chromium/content/browser/media/midi_host_unittest.cc
index 869ea9701ae..88406488ab6 100644
--- a/chromium/content/browser/media/midi_host_unittest.cc
+++ b/chromium/content/browser/media/midi_host_unittest.cc
@@ -9,9 +9,9 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
+#include "base/test/scoped_task_environment.h"
#include "content/common/media/midi_messages.h"
#include "content/public/test/test_browser_thread.h"
#include "media/midi/midi_manager.h"
@@ -118,7 +118,8 @@ class MidiHostForTesting : public MidiHost {
class MidiHostTest : public testing::Test {
public:
MidiHostTest()
- : io_browser_thread_(BrowserThread::IO, &message_loop_),
+ : io_browser_thread_(BrowserThread::IO,
+ task_environment_.GetMainThreadTaskRunner()),
data_(kNoteOn, kNoteOn + arraysize(kNoteOn)),
port_id_(0) {
std::unique_ptr<FakeMidiManagerFactory> factory =
@@ -173,7 +174,7 @@ class MidiHostTest : public testing::Test {
}
private:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
TestBrowserThread io_browser_thread_;
std::vector<uint8_t> data_;
diff --git a/chromium/content/browser/media/session/audio_focus_delegate.h b/chromium/content/browser/media/session/audio_focus_delegate.h
index ba23f16f875..38eb74add84 100644
--- a/chromium/content/browser/media/session/audio_focus_delegate.h
+++ b/chromium/content/browser/media/session/audio_focus_delegate.h
@@ -5,13 +5,7 @@
#ifndef CONTENT_BROWSER_MEDIA_SESSION_AUDIO_FOCUS_DELEGATE_H_
#define CONTENT_BROWSER_MEDIA_SESSION_AUDIO_FOCUS_DELEGATE_H_
-#include "content/browser/media/session/audio_focus_manager.h"
-
-namespace media_session {
-namespace mojom {
-enum class AudioFocusType;
-} // namespace mojom
-} // namespace media_session
+#include "services/media_session/public/mojom/audio_focus.mojom.h"
namespace content {
@@ -27,12 +21,23 @@ class AudioFocusDelegate {
virtual ~AudioFocusDelegate() = default;
- virtual bool RequestAudioFocus(
+ enum class AudioFocusResult {
+ kSuccess,
+ kFailed,
+ kDelayed,
+ };
+
+ virtual AudioFocusResult RequestAudioFocus(
media_session::mojom::AudioFocusType audio_focus_type) = 0;
virtual void AbandonAudioFocus() = 0;
// Retrieves the current |AudioFocusType| for the associated |MediaSession|.
- virtual media_session::mojom::AudioFocusType GetCurrentFocusType() const = 0;
+ virtual base::Optional<media_session::mojom::AudioFocusType>
+ GetCurrentFocusType() const = 0;
+
+ // |MediaSession| should call this when it's state changes.
+ virtual void MediaSessionInfoChanged(
+ media_session::mojom::MediaSessionInfoPtr) = 0;
};
} // namespace content
diff --git a/chromium/content/browser/media/session/audio_focus_delegate_android.cc b/chromium/content/browser/media/session/audio_focus_delegate_android.cc
index 211aad42013..bb4e9cc7943 100644
--- a/chromium/content/browser/media/session/audio_focus_delegate_android.cc
+++ b/chromium/content/browser/media/session/audio_focus_delegate_android.cc
@@ -30,14 +30,17 @@ void AudioFocusDelegateAndroid::Initialize() {
Java_AudioFocusDelegate_create(env, reinterpret_cast<intptr_t>(this)));
}
-bool AudioFocusDelegateAndroid::RequestAudioFocus(
+AudioFocusDelegate::AudioFocusResult
+AudioFocusDelegateAndroid::RequestAudioFocus(
media_session::mojom::AudioFocusType audio_focus_type) {
JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env);
- return Java_AudioFocusDelegate_requestAudioFocus(
+ bool success = Java_AudioFocusDelegate_requestAudioFocus(
env, j_media_session_delegate_,
audio_focus_type ==
media_session::mojom::AudioFocusType::kGainTransientMayDuck);
+ return success ? AudioFocusDelegate::AudioFocusResult::kSuccess
+ : AudioFocusDelegate::AudioFocusResult::kFailed;
}
void AudioFocusDelegateAndroid::AbandonAudioFocus() {
@@ -46,7 +49,7 @@ void AudioFocusDelegateAndroid::AbandonAudioFocus() {
Java_AudioFocusDelegate_abandonAudioFocus(env, j_media_session_delegate_);
}
-media_session::mojom::AudioFocusType
+base::Optional<media_session::mojom::AudioFocusType>
AudioFocusDelegateAndroid::GetCurrentFocusType() const {
JNIEnv* env = base::android::AttachCurrentThread();
DCHECK(env);
@@ -61,7 +64,7 @@ void AudioFocusDelegateAndroid::OnSuspend(JNIEnv*,
if (!media_session_->IsActive())
return;
- media_session_->Suspend(MediaSession::SuspendType::SYSTEM);
+ media_session_->Suspend(MediaSession::SuspendType::kSystem);
}
void AudioFocusDelegateAndroid::OnResume(JNIEnv*,
@@ -69,7 +72,7 @@ void AudioFocusDelegateAndroid::OnResume(JNIEnv*,
if (!media_session_->IsSuspended())
return;
- media_session_->Resume(MediaSession::SuspendType::SYSTEM);
+ media_session_->Resume(MediaSession::SuspendType::kSystem);
}
void AudioFocusDelegateAndroid::OnStartDucking(JNIEnv*, jobject) {
diff --git a/chromium/content/browser/media/session/audio_focus_delegate_android.h b/chromium/content/browser/media/session/audio_focus_delegate_android.h
index 8c18679e42e..f4a3b13c9aa 100644
--- a/chromium/content/browser/media/session/audio_focus_delegate_android.h
+++ b/chromium/content/browser/media/session/audio_focus_delegate_android.h
@@ -27,10 +27,11 @@ class AudioFocusDelegateAndroid : public AudioFocusDelegate {
void Initialize();
- bool RequestAudioFocus(
+ AudioFocusResult RequestAudioFocus(
media_session::mojom::AudioFocusType audio_focus_type) override;
void AbandonAudioFocus() override;
- media_session::mojom::AudioFocusType GetCurrentFocusType() const override;
+ base::Optional<media_session::mojom::AudioFocusType> GetCurrentFocusType()
+ const override;
// Called when the Android system requests the MediaSession to be suspended.
// Called by Java through JNI.
@@ -53,6 +54,10 @@ class AudioFocusDelegateAndroid : public AudioFocusDelegate {
void RecordSessionDuck(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
+ // This is not used by this delegate.
+ void MediaSessionInfoChanged(
+ media_session::mojom::MediaSessionInfoPtr) override {}
+
private:
// Weak pointer because |this| is owned by |media_session_|.
MediaSessionImpl* media_session_;
diff --git a/chromium/content/browser/media/session/audio_focus_delegate_default.cc b/chromium/content/browser/media/session/audio_focus_delegate_default.cc
index eb7ec76aaf2..10fd87a95a5 100644
--- a/chromium/content/browser/media/session/audio_focus_delegate_default.cc
+++ b/chromium/content/browser/media/session/audio_focus_delegate_default.cc
@@ -4,9 +4,13 @@
#include "content/browser/media/session/audio_focus_delegate.h"
-#include "content/browser/media/session/audio_focus_manager.h"
+#include "content/browser/media/session/media_session_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/service_manager_connection.h"
#include "services/media_session/public/cpp/switches.h"
#include "services/media_session/public/mojom/audio_focus.mojom.h"
+#include "services/media_session/public/mojom/constants.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
namespace content {
@@ -14,6 +18,8 @@ using media_session::mojom::AudioFocusType;
namespace {
+const char kAudioFocusSourceName[] = "web";
+
// AudioFocusDelegateDefault is the default implementation of
// AudioFocusDelegate which only handles audio focus between WebContents.
class AudioFocusDelegateDefault : public AudioFocusDelegate {
@@ -22,49 +28,134 @@ class AudioFocusDelegateDefault : public AudioFocusDelegate {
~AudioFocusDelegateDefault() override;
// AudioFocusDelegate implementation.
- bool RequestAudioFocus(AudioFocusType audio_focus_type) override;
+ AudioFocusResult RequestAudioFocus(AudioFocusType audio_focus_type) override;
void AbandonAudioFocus() override;
- AudioFocusType GetCurrentFocusType() const override;
+ base::Optional<media_session::mojom::AudioFocusType> GetCurrentFocusType()
+ const override;
+ void MediaSessionInfoChanged(
+ media_session::mojom::MediaSessionInfoPtr) override;
private:
+ // Finishes an async audio focus request.
+ void FinishAudioFocusRequest(AudioFocusType type);
+
+ // Ensures that |audio_focus_ptr_| is connected.
+ void EnsureServiceConnection();
+
+ // Holds the latest MediaSessionInfo for |media_session_|.
+ media_session::mojom::MediaSessionInfoPtr session_info_;
+
+ // Holds a pointer to the Media Session service.
+ media_session::mojom::AudioFocusManagerPtr audio_focus_ptr_;
+
+ // If the media session has acquired audio focus then this will contain a
+ // pointer to that requests AudioFocusRequestClient.
+ media_session::mojom::AudioFocusRequestClientPtr request_client_ptr_;
+
// Weak pointer because |this| is owned by |media_session_|.
MediaSessionImpl* media_session_;
// The last requested AudioFocusType by the associated |media_session_|.
- AudioFocusType audio_focus_type_if_disabled_;
+ base::Optional<AudioFocusType> audio_focus_type_;
};
} // anonymous namespace
AudioFocusDelegateDefault::AudioFocusDelegateDefault(
MediaSessionImpl* media_session)
- : media_session_(media_session) {}
+ : media_session_(media_session) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+}
AudioFocusDelegateDefault::~AudioFocusDelegateDefault() = default;
-bool AudioFocusDelegateDefault::RequestAudioFocus(
- AudioFocusType audio_focus_type) {
- audio_focus_type_if_disabled_ = audio_focus_type;
+AudioFocusDelegate::AudioFocusResult
+AudioFocusDelegateDefault::RequestAudioFocus(AudioFocusType audio_focus_type) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!media_session::IsAudioFocusEnabled())
- return true;
+ if (!media_session::IsAudioFocusEnabled()) {
+ audio_focus_type_ = audio_focus_type;
+ return AudioFocusDelegate::AudioFocusResult::kSuccess;
+ }
+
+ if (request_client_ptr_.is_bound()) {
+ // We have an existing request so we should request an updated focus type.
+ request_client_ptr_->RequestAudioFocus(
+ session_info_.Clone(), audio_focus_type,
+ base::BindOnce(&AudioFocusDelegateDefault::FinishAudioFocusRequest,
+ base::Unretained(this), audio_focus_type));
+ } else {
+ EnsureServiceConnection();
+
+ // Create a mojo interface pointer to our media session.
+ media_session::mojom::MediaSessionPtr media_session;
+ media_session_->BindToMojoRequest(mojo::MakeRequest(&media_session));
+
+ audio_focus_ptr_->RequestAudioFocus(
+ mojo::MakeRequest(&request_client_ptr_), std::move(media_session),
+ session_info_.Clone(), audio_focus_type,
+ base::BindOnce(&AudioFocusDelegateDefault::FinishAudioFocusRequest,
+ base::Unretained(this), audio_focus_type));
+ }
- AudioFocusManager::GetInstance()->RequestAudioFocus(media_session_,
- audio_focus_type);
- return true;
+ // Return delayed as we make the async call to request audio focus.
+ return AudioFocusDelegate::AudioFocusResult::kDelayed;
}
void AudioFocusDelegateDefault::AbandonAudioFocus() {
- AudioFocusManager::GetInstance()->AbandonAudioFocus(media_session_);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ audio_focus_type_.reset();
+
+ if (!request_client_ptr_.is_bound())
+ return;
+
+ request_client_ptr_->AbandonAudioFocus();
+ request_client_ptr_.reset();
}
-AudioFocusType AudioFocusDelegateDefault::GetCurrentFocusType() const {
- if (media_session::IsAudioFocusEnabled()) {
- return AudioFocusManager::GetInstance()->GetFocusTypeForSession(
- media_session_);
- }
+base::Optional<media_session::mojom::AudioFocusType>
+AudioFocusDelegateDefault::GetCurrentFocusType() const {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return audio_focus_type_;
+}
+
+void AudioFocusDelegateDefault::MediaSessionInfoChanged(
+ media_session::mojom::MediaSessionInfoPtr session_info) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (request_client_ptr_.is_bound())
+ request_client_ptr_->MediaSessionInfoChanged(session_info.Clone());
+
+ session_info_ = std::move(session_info);
+}
+
+void AudioFocusDelegateDefault::FinishAudioFocusRequest(AudioFocusType type) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(request_client_ptr_.is_bound());
+
+ audio_focus_type_ = type;
+ media_session_->FinishSystemAudioFocusRequest(type, true /* result */);
+}
+
+void AudioFocusDelegateDefault::EnsureServiceConnection() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (!media_session::IsAudioFocusEnabled())
+ return;
+
+ if (audio_focus_ptr_.is_bound() && !audio_focus_ptr_.encountered_error())
+ return;
+
+ audio_focus_ptr_.reset();
+
+ // Connect to the Media Session service and bind |audio_focus_ptr_| to it.
+ service_manager::Connector* connector =
+ ServiceManagerConnection::GetForProcess()->GetConnector();
+ connector->BindInterface(media_session::mojom::kServiceName,
+ mojo::MakeRequest(&audio_focus_ptr_));
- return audio_focus_type_if_disabled_;
+ audio_focus_ptr_->SetSourceName(kAudioFocusSourceName);
}
// static
diff --git a/chromium/content/browser/media/session/audio_focus_delegate_default_browsertest.cc b/chromium/content/browser/media/session/audio_focus_delegate_default_browsertest.cc
index 8d5e777f70a..97d63ea2ef2 100644
--- a/chromium/content/browser/media/session/audio_focus_delegate_default_browsertest.cc
+++ b/chromium/content/browser/media/session/audio_focus_delegate_default_browsertest.cc
@@ -5,45 +5,183 @@
#include "base/command_line.h"
#include "content/browser/media/session/media_session_impl.h"
#include "content/browser/media/session/mock_media_session_player_observer.h"
+#include "content/public/common/service_manager_connection.h"
#include "content/public/test/content_browser_test.h"
#include "content/shell/browser/shell.h"
#include "media/base/media_content_type.h"
#include "services/media_session/public/cpp/switches.h"
+#include "services/media_session/public/cpp/test/audio_focus_test_util.h"
+#include "services/media_session/public/mojom/audio_focus.mojom.h"
+#include "services/media_session/public/mojom/constants.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
namespace content {
+using media_session::test::TestAudioFocusObserver;
+
+namespace {
+
+const char kExpectedSourceName[] = "web";
+
+} // namespace
+
+class MediaSessionStateObserver
+ : public media_session::mojom::MediaSessionObserver {
+ public:
+ explicit MediaSessionStateObserver(
+ media_session::mojom::MediaSession* media_session)
+ : binding_(this) {
+ media_session::mojom::MediaSessionObserverPtr observer;
+ binding_.Bind(mojo::MakeRequest(&observer));
+ media_session->AddObserver(std::move(observer));
+ }
+
+ ~MediaSessionStateObserver() override = default;
+
+ // media_session::mojom::MediaSessionObserver
+ void MediaSessionInfoChanged(
+ media_session::mojom::MediaSessionInfoPtr session_info) override {
+ if (desired_state_.has_value() &&
+ desired_state_.value() == session_info->state) {
+ run_loop_.Quit();
+ return;
+ }
+
+ session_info_ = std::move(session_info);
+ }
+
+ void WaitForState(
+ media_session::mojom::MediaSessionInfo::SessionState state) {
+ if (session_info_ && state == session_info_->state)
+ return;
+
+ desired_state_ = state;
+ run_loop_.Run();
+ }
+
+ protected:
+ base::RunLoop run_loop_;
+ mojo::Binding<media_session::mojom::MediaSessionObserver> binding_;
+ base::Optional<media_session::mojom::MediaSessionInfo::SessionState>
+ desired_state_;
+ media_session::mojom::MediaSessionInfoPtr session_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaSessionStateObserver);
+};
+
class AudioFocusDelegateDefaultBrowserTest : public ContentBrowserTest {
protected:
+ void SetUpOnMainThread() override {
+ service_manager::Connector* connector =
+ ServiceManagerConnection::GetForProcess()->GetConnector();
+ connector->BindInterface(media_session::mojom::kServiceName,
+ mojo::MakeRequest(&audio_focus_ptr_));
+ }
+
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(media_session::switches::kEnableAudioFocus);
}
+ void CheckSessionSourceName() {
+ audio_focus_ptr_->GetFocusRequests(base::BindOnce(
+ [](std::vector<media_session::mojom::AudioFocusRequestStatePtr>
+ requests) {
+ for (auto& request : requests)
+ EXPECT_EQ(kExpectedSourceName, request->source_name.value());
+ }));
+
+ audio_focus_ptr_.FlushForTesting();
+ }
+
void Run(WebContents* start_contents, WebContents* interrupt_contents) {
std::unique_ptr<MockMediaSessionPlayerObserver>
player_observer(new MockMediaSessionPlayerObserver);
MediaSessionImpl* media_session = MediaSessionImpl::Get(start_contents);
- ASSERT_TRUE(media_session);
+ EXPECT_TRUE(media_session);
MediaSessionImpl* other_media_session =
MediaSessionImpl::Get(interrupt_contents);
- ASSERT_TRUE(other_media_session);
+ EXPECT_TRUE(other_media_session);
player_observer->StartNewPlayer();
- media_session->AddPlayer(player_observer.get(), 0,
- media::MediaContentType::Persistent);
- EXPECT_TRUE(media_session->IsActive());
- EXPECT_FALSE(other_media_session->IsActive());
+
+ {
+ std::unique_ptr<TestAudioFocusObserver> observer = CreateObserver();
+ media_session->AddPlayer(player_observer.get(), 0,
+ media::MediaContentType::Persistent);
+ observer->WaitForGainedEvent();
+ }
+
+ {
+ MediaSessionStateObserver state_observer(media_session);
+ state_observer.WaitForState(
+ media_session::mojom::MediaSessionInfo::SessionState::kActive);
+ }
+
+ {
+ MediaSessionStateObserver state_observer(other_media_session);
+ state_observer.WaitForState(
+ media_session::mojom::MediaSessionInfo::SessionState::kInactive);
+ }
+
+ CheckSessionSourceName();
player_observer->StartNewPlayer();
- other_media_session->AddPlayer(player_observer.get(), 1,
- media::MediaContentType::Persistent);
- EXPECT_FALSE(media_session->IsActive());
- EXPECT_TRUE(other_media_session->IsActive());
- media_session->Stop(MediaSessionImpl::SuspendType::UI);
- other_media_session->Stop(MediaSessionImpl::SuspendType::UI);
+ {
+ std::unique_ptr<TestAudioFocusObserver> observer = CreateObserver();
+ other_media_session->AddPlayer(player_observer.get(), 1,
+ media::MediaContentType::Persistent);
+ observer->WaitForGainedEvent();
+ }
+
+ {
+ MediaSessionStateObserver state_observer(media_session);
+ state_observer.WaitForState(
+ media_session::mojom::MediaSessionInfo::SessionState::kSuspended);
+ }
+
+ {
+ MediaSessionStateObserver state_observer(other_media_session);
+ state_observer.WaitForState(
+ media_session::mojom::MediaSessionInfo::SessionState::kActive);
+ }
+
+ CheckSessionSourceName();
+
+ {
+ std::unique_ptr<TestAudioFocusObserver> observer = CreateObserver();
+ media_session->Stop(MediaSessionImpl::SuspendType::kUI);
+ other_media_session->Stop(MediaSessionImpl::SuspendType::kUI);
+ observer->WaitForLostEvent();
+ }
+
+ {
+ MediaSessionStateObserver state_observer(media_session);
+ state_observer.WaitForState(
+ media_session::mojom::MediaSessionInfo::SessionState::kInactive);
+ }
+
+ {
+ MediaSessionStateObserver state_observer(other_media_session);
+ state_observer.WaitForState(
+ media_session::mojom::MediaSessionInfo::SessionState::kInactive);
+ }
+ }
+
+ private:
+ std::unique_ptr<TestAudioFocusObserver> CreateObserver() {
+ std::unique_ptr<TestAudioFocusObserver> observer =
+ std::make_unique<TestAudioFocusObserver>();
+ media_session::mojom::AudioFocusObserverPtr observer_ptr;
+ observer->BindToMojoRequest(mojo::MakeRequest(&observer_ptr));
+ audio_focus_ptr_->AddObserver(std::move(observer_ptr));
+ audio_focus_ptr_.FlushForTesting();
+ return observer;
}
+
+ media_session::mojom::AudioFocusManagerPtr audio_focus_ptr_;
};
// Two windows from the same BrowserContext.
diff --git a/chromium/content/browser/media/session/audio_focus_manager.cc b/chromium/content/browser/media/session/audio_focus_manager.cc
deleted file mode 100644
index fbd8af4da47..00000000000
--- a/chromium/content/browser/media/session/audio_focus_manager.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/media/session/audio_focus_manager.h"
-
-#include "content/browser/media/session/audio_focus_observer.h"
-#include "content/browser/media/session/media_session_impl.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/web_contents.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
-#include "services/media_session/public/mojom/audio_focus.mojom.h"
-
-namespace content {
-
-using media_session::mojom::AudioFocusType;
-
-namespace {
-
-media_session::mojom::MediaSessionPtr GetSessionMojoPtr(
- MediaSessionImpl* session) {
- media_session::mojom::MediaSessionPtr media_session_ptr;
- session->BindToMojoRequest(mojo::MakeRequest(&media_session_ptr));
- return media_session_ptr;
-}
-
-} // namespace
-
-// static
-AudioFocusManager* AudioFocusManager::GetInstance() {
- return base::Singleton<AudioFocusManager>::get();
-}
-
-void AudioFocusManager::RequestAudioFocus(MediaSessionImpl* media_session,
- AudioFocusType type) {
- if (!audio_focus_stack_.empty() &&
- audio_focus_stack_.back().media_session == media_session &&
- audio_focus_stack_.back().audio_focus_type == type &&
- audio_focus_stack_.back().media_session->IsActive()) {
- // Early returning if |media_session| is already on top (has focus) and is
- // active.
- return;
- }
-
- MaybeRemoveFocusEntry(media_session);
-
- // TODO(zqzhang): It seems like MediaSessionImpl is exposed to
- // AudioFocusManager
- // too much. Maybe it's better to do some abstraction and refactoring to clean
- // up the relation between AudioFocusManager and MediaSessionImpl.
- // See https://crbug.com/651069
- if (type == AudioFocusType::kGainTransientMayDuck) {
- for (auto& old_session : audio_focus_stack_) {
- old_session.media_session->StartDucking();
- }
- } else {
- for (auto& old_session : audio_focus_stack_) {
- if (old_session.media_session->IsActive()) {
- if (old_session.media_session->HasPepper())
- old_session.media_session->StartDucking();
- else
- old_session.media_session->Suspend(
- MediaSessionImpl::SuspendType::SYSTEM);
- }
- }
- }
-
- // Store the MediaSession and requested focus type.
- audio_focus_stack_.emplace_back(media_session, type);
- audio_focus_stack_.back().media_session->StopDucking();
-
- // Notify observers that we were gained audio focus.
- observers_.ForAllPtrs(
- [media_session,
- type](media_session::mojom::AudioFocusObserver* observer) {
- observer->OnFocusGained(GetSessionMojoPtr(media_session), type);
- });
-}
-
-void AudioFocusManager::AbandonAudioFocus(MediaSessionImpl* media_session) {
- if (audio_focus_stack_.empty())
- return;
-
- if (audio_focus_stack_.back().media_session != media_session) {
- MaybeRemoveFocusEntry(media_session);
- return;
- }
-
- audio_focus_stack_.pop_back();
- if (audio_focus_stack_.empty()) {
- // Notify observers that we lost audio focus.
- observers_.ForAllPtrs(
- [media_session](media_session::mojom::AudioFocusObserver* observer) {
- observer->OnFocusLost(GetSessionMojoPtr(media_session));
- });
- return;
- }
-
- // Allow the top-most MediaSessionImpl having Pepper to unduck pepper even if
- // it's
- // not active.
- for (auto iter = audio_focus_stack_.rbegin();
- iter != audio_focus_stack_.rend(); ++iter) {
- if (!iter->media_session->HasPepper())
- continue;
-
- MediaSessionImpl* pepper_session = iter->media_session;
- AudioFocusType focus_type = iter->audio_focus_type;
- pepper_session->StopDucking();
- MaybeRemoveFocusEntry(pepper_session);
- audio_focus_stack_.emplace_back(pepper_session, focus_type);
- return;
- }
- // Only try to unduck the new MediaSessionImpl on top. The session might be
- // still
- // inactive but it will not be resumed (so it doesn't surprise the user).
- audio_focus_stack_.back().media_session->StopDucking();
-
- // Notify observers that we lost audio focus.
- observers_.ForAllPtrs(
- [media_session](media_session::mojom::AudioFocusObserver* observer) {
- observer->OnFocusLost(GetSessionMojoPtr(media_session));
- });
-}
-
-mojo::InterfacePtrSetElementId AudioFocusManager::AddObserver(
- media_session::mojom::AudioFocusObserverPtr observer) {
- return observers_.AddPtr(std::move(observer));
-}
-
-AudioFocusType AudioFocusManager::GetFocusTypeForSession(
- MediaSessionImpl* media_session) const {
- for (auto row : audio_focus_stack_) {
- if (row.media_session == media_session)
- return row.audio_focus_type;
- }
-
- NOTREACHED();
- return AudioFocusType::kGain;
-}
-
-void AudioFocusManager::RemoveObserver(mojo::InterfacePtrSetElementId id) {
- observers_.RemovePtr(id);
-}
-
-void AudioFocusManager::ResetForTesting() {
- audio_focus_stack_.clear();
- observers_.CloseAll();
-}
-
-void AudioFocusManager::FlushForTesting() {
- observers_.FlushForTesting();
-}
-
-AudioFocusManager::AudioFocusManager() {
- // Make sure we start AudioFocusManager on the browser UI thread. This is to
- // ensure thread consistency for mojo::InterfaceSetPtr.
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-}
-
-AudioFocusManager::~AudioFocusManager() = default;
-
-void AudioFocusManager::MaybeRemoveFocusEntry(MediaSessionImpl* media_session) {
- for (auto iter = audio_focus_stack_.begin(); iter != audio_focus_stack_.end();
- ++iter) {
- if (iter->media_session == media_session) {
- audio_focus_stack_.erase(iter);
- break;
- }
- }
-}
-
-} // namespace content
diff --git a/chromium/content/browser/media/session/audio_focus_manager.h b/chromium/content/browser/media/session/audio_focus_manager.h
deleted file mode 100644
index 3bc2cc78253..00000000000
--- a/chromium/content/browser/media/session/audio_focus_manager.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_
-#define CONTENT_BROWSER_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_
-
-#include <list>
-#include <unordered_map>
-
-#include "base/memory/singleton.h"
-#include "content/common/content_export.h"
-#include "content/public/browser/web_contents_observer.h"
-#include "mojo/public/cpp/bindings/interface_ptr_set.h"
-#include "services/media_session/public/mojom/audio_focus.mojom.h"
-
-namespace content {
-
-class MediaSessionImpl;
-
-class CONTENT_EXPORT AudioFocusManager {
- public:
- // Returns Chromium's internal AudioFocusManager.
- static AudioFocusManager* GetInstance();
-
- void RequestAudioFocus(MediaSessionImpl* media_session,
- media_session::mojom::AudioFocusType type);
-
- void AbandonAudioFocus(MediaSessionImpl* media_session);
-
- media_session::mojom::AudioFocusType GetFocusTypeForSession(
- MediaSessionImpl* media_session) const;
-
- // Adds/removes audio focus observers.
- mojo::InterfacePtrSetElementId AddObserver(
- media_session::mojom::AudioFocusObserverPtr);
- void RemoveObserver(mojo::InterfacePtrSetElementId);
-
- private:
- friend struct base::DefaultSingletonTraits<AudioFocusManager>;
- friend class AudioFocusManagerTest;
-
- // Media internals UI needs access to internal state.
- friend class MediaInternalsAudioFocusTest;
- friend class MediaInternals;
-
- // Flush for testing will flush any pending messages to the observers.
- void FlushForTesting();
-
- // Reset for testing will clear any built up internal state.
- void ResetForTesting();
-
- AudioFocusManager();
- ~AudioFocusManager();
-
- void MaybeRemoveFocusEntry(MediaSessionImpl* media_session);
-
- // Weak reference of managed observers. Observers are expected to remove
- // themselves before being destroyed.
- mojo::InterfacePtrSet<media_session::mojom::AudioFocusObserver> observers_;
-
- // Weak reference of managed MediaSessions and their requested focus type.
- // A MediaSession must abandon audio focus before its destruction.
- struct StackRow {
- StackRow(MediaSessionImpl* media_session,
- media_session::mojom::AudioFocusType audio_focus_type)
- : media_session(media_session), audio_focus_type(audio_focus_type) {}
- MediaSessionImpl* media_session;
- media_session::mojom::AudioFocusType audio_focus_type;
- };
- std::list<StackRow> audio_focus_stack_;
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_MEDIA_SESSION_AUDIO_FOCUS_MANAGER_H_
diff --git a/chromium/content/browser/media/session/audio_focus_manager_unittest.cc b/chromium/content/browser/media/session/audio_focus_manager_unittest.cc
deleted file mode 100644
index fc4a5974244..00000000000
--- a/chromium/content/browser/media/session/audio_focus_manager_unittest.cc
+++ /dev/null
@@ -1,550 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/media/session/audio_focus_manager.h"
-
-#include <memory>
-
-#include "base/command_line.h"
-#include "base/optional.h"
-#include "base/run_loop.h"
-#include "content/browser/media/session/audio_focus_observer.h"
-#include "content/browser/media/session/media_session_impl.h"
-#include "content/browser/media/session/media_session_player_observer.h"
-#include "content/public/test/mock_render_process_host.h"
-#include "content/public/test/test_browser_context.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "content/test/test_web_contents.h"
-#include "media/base/media_content_type.h"
-#include "services/media_session/public/cpp/switches.h"
-#include "services/media_session/public/mojom/audio_focus.mojom.h"
-
-namespace content {
-
-using media_session::mojom::AudioFocusType;
-using media_session::mojom::MediaSessionPtr;
-
-namespace {
-
-class MockAudioFocusObserver : public AudioFocusObserver {
- public:
- MockAudioFocusObserver() { RegisterAudioFocusObserver(); }
-
- void OnFocusGained(MediaSessionPtr session, AudioFocusType type) override {
- EXPECT_TRUE(session.is_bound());
- focus_gained_call_ = type;
- focus_lost_call_ = false;
- }
-
- void OnFocusLost(MediaSessionPtr session) override {
- EXPECT_TRUE(session.is_bound());
- focus_lost_call_ = true;
- focus_gained_call_.reset();
- }
-
- base::Optional<AudioFocusType> focus_gained_call_;
- bool focus_lost_call_ = false;
-};
-
-class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
- public:
- void OnSuspend(int player_id) override {}
- void OnResume(int player_id) override {}
- void OnSeekForward(int player_id, base::TimeDelta seek_time) override {}
- void OnSeekBackward(int player_id, base::TimeDelta seek_time) override {}
- void OnSetVolumeMultiplier(
- int player_id, double volume_multiplier) override {}
- RenderFrameHost* render_frame_host() const override { return nullptr; }
-};
-
-} // anonymous namespace
-
-using SuspendType = MediaSession::SuspendType;
-
-class AudioFocusManagerTest : public testing::Test {
- public:
- AudioFocusManagerTest() = default;
-
- void SetUp() override {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- media_session::switches::kEnableAudioFocus);
- rph_factory_.reset(new MockRenderProcessHostFactory());
- RenderProcessHostImpl::set_render_process_host_factory_for_testing(
- rph_factory_.get());
- browser_context_.reset(new TestBrowserContext());
- pepper_observer_.reset(new MockMediaSessionPlayerObserver());
-
- // AudioFocusManager is a singleton so we should make sure we reset any
- // state in between tests.
- AudioFocusManager::GetInstance()->ResetForTesting();
- }
-
- void TearDown() override {
- // Run pending tasks.
- base::RunLoop().RunUntilIdle();
-
- browser_context_.reset();
- RenderProcessHostImpl::set_render_process_host_factory_for_testing(nullptr);
- rph_factory_.reset();
- }
-
- MediaSessionImpl* GetAudioFocusedSession() const {
- const AudioFocusManager* manager = AudioFocusManager::GetInstance();
- const auto& audio_focus_stack = manager->audio_focus_stack_;
-
- for (auto iter = audio_focus_stack.rbegin();
- iter != audio_focus_stack.rend(); ++iter) {
- if ((*iter).audio_focus_type == AudioFocusType::kGain)
- return (*iter).media_session;
- }
- return nullptr;
- }
-
- int GetTransientMaybeDuckCount() const {
- const AudioFocusManager* manager = AudioFocusManager::GetInstance();
- const auto& audio_focus_stack = manager->audio_focus_stack_;
- int count = 0;
-
- for (auto iter = audio_focus_stack.rbegin();
- iter != audio_focus_stack.rend(); ++iter) {
- if ((*iter).audio_focus_type == AudioFocusType::kGainTransientMayDuck)
- ++count;
- else
- break;
- }
-
- return count;
- }
-
- double IsSessionDucking(MediaSessionImpl* session) {
- return session->is_ducking_; // Quack! Quack!
- }
-
- void RequestAudioFocus(MediaSessionImpl* session,
- AudioFocusType audio_focus_type) {
- session->RequestSystemAudioFocus(audio_focus_type);
- }
-
- void AbandonAudioFocus(MediaSessionImpl* session) {
- session->AbandonSystemAudioFocusIfNeeded();
- }
-
- void FlushForTesting() {
- AudioFocusManager::GetInstance()->FlushForTesting();
- }
-
- std::unique_ptr<WebContents> CreateWebContents() {
- return TestWebContents::Create(browser_context_.get(),
- SiteInstance::SiteInstance::Create(browser_context_.get()));
- }
-
- std::unique_ptr<MediaSessionPlayerObserver> pepper_observer_;
-
- private:
- TestBrowserThreadBundle test_browser_thread_bundle_;
-
- std::unique_ptr<MockRenderProcessHostFactory> rph_factory_;
- std::unique_ptr<TestBrowserContext> browser_context_;
-};
-
-TEST_F(AudioFocusManagerTest, InstanceAvailableAndSame) {
- AudioFocusManager* audio_focus_manager = AudioFocusManager::GetInstance();
- ASSERT_TRUE(!!audio_focus_manager);
- ASSERT_EQ(audio_focus_manager, AudioFocusManager::GetInstance());
-}
-
-TEST_F(AudioFocusManagerTest, RequestAudioFocusGain_ReplaceFocusedEntry) {
- std::unique_ptr<WebContents> web_contents_1(CreateWebContents());
- MediaSessionImpl* media_session_1 =
- MediaSessionImpl::Get(web_contents_1.get());
-
- std::unique_ptr<WebContents> web_contents_2(CreateWebContents());
- MediaSessionImpl* media_session_2 =
- MediaSessionImpl::Get(web_contents_2.get());
-
- std::unique_ptr<WebContents> web_contents_3(CreateWebContents());
- MediaSessionImpl* media_session_3 =
- MediaSessionImpl::Get(web_contents_3.get());
-
- ASSERT_EQ(nullptr, GetAudioFocusedSession());
-
- RequestAudioFocus(media_session_1, AudioFocusType::kGain);
- ASSERT_EQ(media_session_1, GetAudioFocusedSession());
-
- RequestAudioFocus(media_session_2, AudioFocusType::kGain);
- ASSERT_EQ(media_session_2, GetAudioFocusedSession());
-
- RequestAudioFocus(media_session_3, AudioFocusType::kGain);
- ASSERT_EQ(media_session_3, GetAudioFocusedSession());
-}
-
-TEST_F(AudioFocusManagerTest, RequestAudioFocusGain_Duplicate) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- ASSERT_EQ(nullptr, GetAudioFocusedSession());
-
- RequestAudioFocus(media_session, AudioFocusType::kGain);
- ASSERT_EQ(media_session, GetAudioFocusedSession());
-
- RequestAudioFocus(media_session, AudioFocusType::kGain);
- ASSERT_EQ(media_session, GetAudioFocusedSession());
-}
-
-TEST_F(AudioFocusManagerTest, RequestAudioFocusGain_FromTransient) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- RequestAudioFocus(media_session, AudioFocusType::kGainTransientMayDuck);
- ASSERT_EQ(nullptr, GetAudioFocusedSession());
- ASSERT_EQ(1, GetTransientMaybeDuckCount());
-
- RequestAudioFocus(media_session, AudioFocusType::kGain);
- ASSERT_EQ(media_session, GetAudioFocusedSession());
- ASSERT_EQ(0, GetTransientMaybeDuckCount());
-}
-
-TEST_F(AudioFocusManagerTest, RequestAudioFocusTransient_FromGain) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- RequestAudioFocus(media_session, AudioFocusType::kGain);
- ASSERT_EQ(media_session, GetAudioFocusedSession());
- ASSERT_EQ(0, GetTransientMaybeDuckCount());
-
- RequestAudioFocus(media_session, AudioFocusType::kGainTransientMayDuck);
- ASSERT_EQ(nullptr, GetAudioFocusedSession());
- ASSERT_EQ(1, GetTransientMaybeDuckCount());
- ASSERT_FALSE(IsSessionDucking(media_session));
-}
-
-TEST_F(AudioFocusManagerTest, RequestAudioFocusTransient_FromGainWhileDucking) {
- std::unique_ptr<WebContents> web_contents_1(CreateWebContents());
- MediaSessionImpl* media_session_1 =
- MediaSessionImpl::Get(web_contents_1.get());
-
- std::unique_ptr<WebContents> web_contents_2(CreateWebContents());
- MediaSessionImpl* media_session_2 =
- MediaSessionImpl::Get(web_contents_2.get());
-
- RequestAudioFocus(media_session_1, AudioFocusType::kGain);
- ASSERT_EQ(0, GetTransientMaybeDuckCount());
- ASSERT_FALSE(IsSessionDucking(media_session_1));
-
- RequestAudioFocus(media_session_2, AudioFocusType::kGainTransientMayDuck);
- ASSERT_EQ(1, GetTransientMaybeDuckCount());
- ASSERT_TRUE(IsSessionDucking(media_session_1));
-
- RequestAudioFocus(media_session_1, AudioFocusType::kGainTransientMayDuck);
- ASSERT_EQ(2, GetTransientMaybeDuckCount());
- ASSERT_FALSE(IsSessionDucking(media_session_1));
-}
-
-TEST_F(AudioFocusManagerTest, AbandonAudioFocus_RemovesFocusedEntry) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- RequestAudioFocus(media_session, AudioFocusType::kGain);
- ASSERT_EQ(media_session, GetAudioFocusedSession());
-
- AbandonAudioFocus(media_session);
- ASSERT_EQ(nullptr, GetAudioFocusedSession());
-}
-
-TEST_F(AudioFocusManagerTest, AbandonAudioFocus_NoAssociatedEntry) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- AbandonAudioFocus(media_session);
- ASSERT_EQ(nullptr, GetAudioFocusedSession());
-}
-
-TEST_F(AudioFocusManagerTest, AbandonAudioFocus_RemovesTransientEntry) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- RequestAudioFocus(media_session, AudioFocusType::kGainTransientMayDuck);
- ASSERT_EQ(1, GetTransientMaybeDuckCount());
-
- {
- MockAudioFocusObserver observer;
- AbandonAudioFocus(media_session);
- FlushForTesting();
-
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_TRUE(observer.focus_lost_call_);
- }
-}
-
-TEST_F(AudioFocusManagerTest, AbandonAudioFocus_WhileDuckingThenResume) {
- std::unique_ptr<WebContents> web_contents_1(CreateWebContents());
- MediaSessionImpl* media_session_1 =
- MediaSessionImpl::Get(web_contents_1.get());
-
- std::unique_ptr<WebContents> web_contents_2(CreateWebContents());
- MediaSessionImpl* media_session_2 =
- MediaSessionImpl::Get(web_contents_2.get());
-
- RequestAudioFocus(media_session_1, AudioFocusType::kGain);
- ASSERT_EQ(0, GetTransientMaybeDuckCount());
- ASSERT_FALSE(IsSessionDucking(media_session_1));
-
- RequestAudioFocus(media_session_2, AudioFocusType::kGainTransientMayDuck);
- ASSERT_EQ(1, GetTransientMaybeDuckCount());
- ASSERT_TRUE(IsSessionDucking(media_session_1));
-
- AbandonAudioFocus(media_session_1);
- ASSERT_EQ(1, GetTransientMaybeDuckCount());
-
- AbandonAudioFocus(media_session_2);
- ASSERT_EQ(0, GetTransientMaybeDuckCount());
-
- RequestAudioFocus(media_session_1, AudioFocusType::kGain);
- ASSERT_FALSE(IsSessionDucking(media_session_1));
-}
-
-TEST_F(AudioFocusManagerTest, AbandonAudioFocus_StopsDucking) {
- std::unique_ptr<WebContents> web_contents_1(CreateWebContents());
- MediaSessionImpl* media_session_1 =
- MediaSessionImpl::Get(web_contents_1.get());
-
- std::unique_ptr<WebContents> web_contents_2(CreateWebContents());
- MediaSessionImpl* media_session_2 =
- MediaSessionImpl::Get(web_contents_2.get());
-
- RequestAudioFocus(media_session_1, AudioFocusType::kGain);
- ASSERT_EQ(0, GetTransientMaybeDuckCount());
- ASSERT_FALSE(IsSessionDucking(media_session_1));
-
- RequestAudioFocus(media_session_2, AudioFocusType::kGainTransientMayDuck);
- ASSERT_EQ(1, GetTransientMaybeDuckCount());
- ASSERT_TRUE(IsSessionDucking(media_session_1));
-
- AbandonAudioFocus(media_session_2);
- ASSERT_EQ(0, GetTransientMaybeDuckCount());
- ASSERT_FALSE(IsSessionDucking(media_session_1));
-}
-
-TEST_F(AudioFocusManagerTest, DuckWhilePlaying) {
- std::unique_ptr<WebContents> web_contents_1(CreateWebContents());
- MediaSessionImpl* media_session_1 =
- MediaSessionImpl::Get(web_contents_1.get());
-
- std::unique_ptr<WebContents> web_contents_2(CreateWebContents());
- MediaSessionImpl* media_session_2 =
- MediaSessionImpl::Get(web_contents_2.get());
-
- RequestAudioFocus(media_session_1, AudioFocusType::kGain);
- ASSERT_FALSE(IsSessionDucking(media_session_1));
-
- RequestAudioFocus(media_session_2, AudioFocusType::kGainTransientMayDuck);
- ASSERT_TRUE(IsSessionDucking(media_session_1));
-}
-
-TEST_F(AudioFocusManagerTest, GainSuspendsTransient) {
- std::unique_ptr<WebContents> web_contents_1(CreateWebContents());
- MediaSessionImpl* media_session_1 =
- MediaSessionImpl::Get(web_contents_1.get());
-
- std::unique_ptr<WebContents> web_contents_2(CreateWebContents());
- MediaSessionImpl* media_session_2 =
- MediaSessionImpl::Get(web_contents_2.get());
-
- RequestAudioFocus(media_session_2, AudioFocusType::kGainTransientMayDuck);
-
- RequestAudioFocus(media_session_1, AudioFocusType::kGain);
- ASSERT_TRUE(media_session_2->IsSuspended());
-}
-
-TEST_F(AudioFocusManagerTest, DuckWithMultipleTransients) {
- std::unique_ptr<WebContents> web_contents_1(CreateWebContents());
- MediaSessionImpl* media_session_1 =
- MediaSessionImpl::Get(web_contents_1.get());
-
- std::unique_ptr<WebContents> web_contents_2(CreateWebContents());
- MediaSessionImpl* media_session_2 =
- MediaSessionImpl::Get(web_contents_2.get());
-
- std::unique_ptr<WebContents> web_contents_3(CreateWebContents());
- MediaSessionImpl* media_session_3 =
- MediaSessionImpl::Get(web_contents_3.get());
-
- RequestAudioFocus(media_session_1, AudioFocusType::kGain);
- ASSERT_FALSE(IsSessionDucking(media_session_1));
-
- RequestAudioFocus(media_session_2, AudioFocusType::kGainTransientMayDuck);
- ASSERT_TRUE(IsSessionDucking(media_session_1));
-
- RequestAudioFocus(media_session_3, AudioFocusType::kGainTransientMayDuck);
- ASSERT_TRUE(IsSessionDucking(media_session_1));
-
- AbandonAudioFocus(media_session_2);
- ASSERT_TRUE(IsSessionDucking(media_session_1));
-
- AbandonAudioFocus(media_session_3);
- ASSERT_FALSE(IsSessionDucking(media_session_1));
-}
-
-TEST_F(AudioFocusManagerTest, WebContentsDestroyed_ReleasesFocus) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- RequestAudioFocus(media_session, AudioFocusType::kGain);
- ASSERT_EQ(media_session, GetAudioFocusedSession());
-
- web_contents.reset();
- ASSERT_EQ(nullptr, GetAudioFocusedSession());
-}
-
-TEST_F(AudioFocusManagerTest, WebContentsDestroyed_ReleasesTransients) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- RequestAudioFocus(media_session, AudioFocusType::kGainTransientMayDuck);
- ASSERT_EQ(1, GetTransientMaybeDuckCount());
-
- web_contents.reset();
- ASSERT_EQ(0, GetTransientMaybeDuckCount());
-}
-
-TEST_F(AudioFocusManagerTest, WebContentsDestroyed_StopsDucking) {
- std::unique_ptr<WebContents> web_contents_1(CreateWebContents());
- MediaSessionImpl* media_session_1 =
- MediaSessionImpl::Get(web_contents_1.get());
-
- std::unique_ptr<WebContents> web_contents_2(CreateWebContents());
- MediaSessionImpl* media_session_2 =
- MediaSessionImpl::Get(web_contents_2.get());
-
- RequestAudioFocus(media_session_1, AudioFocusType::kGain);
- ASSERT_FALSE(IsSessionDucking(media_session_1));
-
- RequestAudioFocus(media_session_2, AudioFocusType::kGainTransientMayDuck);
- ASSERT_TRUE(IsSessionDucking(media_session_1));
-
- web_contents_2.reset();
- ASSERT_FALSE(IsSessionDucking(media_session_1));
-}
-
-TEST_F(AudioFocusManagerTest, PepperRequestsGainFocus) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- media_session->AddPlayer(
- pepper_observer_.get(), 0, media::MediaContentType::Pepper);
- ASSERT_EQ(media_session, GetAudioFocusedSession());
-
- media_session->RemovePlayer(pepper_observer_.get(), 0);
- ASSERT_EQ(nullptr, GetAudioFocusedSession());
-}
-
-TEST_F(AudioFocusManagerTest, GainDucksPepper) {
- std::unique_ptr<WebContents> web_contents_1(CreateWebContents());
- MediaSessionImpl* media_session_1 =
- MediaSessionImpl::Get(web_contents_1.get());
-
- std::unique_ptr<WebContents> web_contents_2(CreateWebContents());
- MediaSessionImpl* media_session_2 =
- MediaSessionImpl::Get(web_contents_2.get());
-
- media_session_1->AddPlayer(
- pepper_observer_.get(), 0, media::MediaContentType::Pepper);
-
- RequestAudioFocus(media_session_2, AudioFocusType::kGain);
-
- ASSERT_EQ(media_session_2, GetAudioFocusedSession());
- ASSERT_TRUE(media_session_1->IsActive());
- ASSERT_TRUE(IsSessionDucking(media_session_1));
-}
-
-TEST_F(AudioFocusManagerTest, AbandoningGainFocusRevokesTopMostPepperSession) {
- std::unique_ptr<WebContents> web_contents_1(CreateWebContents());
- MediaSessionImpl* media_session_1 =
- MediaSessionImpl::Get(web_contents_1.get());
-
- std::unique_ptr<WebContents> web_contents_2(CreateWebContents());
- MediaSessionImpl* media_session_2 =
- MediaSessionImpl::Get(web_contents_2.get());
-
- std::unique_ptr<WebContents> web_contents_3(CreateWebContents());
- MediaSessionImpl* media_session_3 =
- MediaSessionImpl::Get(web_contents_3.get());
-
- media_session_1->AddPlayer(
- pepper_observer_.get(), 0, media::MediaContentType::Pepper);
-
- RequestAudioFocus(media_session_2, AudioFocusType::kGain);
- RequestAudioFocus(media_session_3, AudioFocusType::kGain);
-
- ASSERT_EQ(media_session_3, GetAudioFocusedSession());
- ASSERT_TRUE(media_session_2->IsSuspended());
- ASSERT_TRUE(media_session_1->IsActive());
- ASSERT_TRUE(IsSessionDucking(media_session_1));
-
- AbandonAudioFocus(media_session_3);
- ASSERT_EQ(media_session_1, GetAudioFocusedSession());
-}
-
-TEST_F(AudioFocusManagerTest, AudioFocusObserver_AbandonNoop) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- {
- MockAudioFocusObserver observer;
- AbandonAudioFocus(media_session);
- FlushForTesting();
-
- EXPECT_EQ(nullptr, GetAudioFocusedSession());
- EXPECT_FALSE(observer.focus_lost_call_);
- }
-}
-
-TEST_F(AudioFocusManagerTest, AudioFocusObserver_RequestNoop) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- {
- MockAudioFocusObserver observer;
- RequestAudioFocus(media_session, AudioFocusType::kGain);
- FlushForTesting();
-
- EXPECT_EQ(media_session, GetAudioFocusedSession());
- EXPECT_EQ(AudioFocusType::kGain, observer.focus_gained_call_.value());
- }
-
- {
- MockAudioFocusObserver observer;
- RequestAudioFocus(media_session, AudioFocusType::kGain);
- FlushForTesting();
-
- EXPECT_EQ(media_session, GetAudioFocusedSession());
- EXPECT_FALSE(observer.focus_gained_call_.has_value());
- }
-}
-
-TEST_F(AudioFocusManagerTest, AudioFocusObserver_TransientMayDuck) {
- std::unique_ptr<WebContents> web_contents(CreateWebContents());
- MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
-
- {
- MockAudioFocusObserver observer;
- RequestAudioFocus(media_session, AudioFocusType::kGainTransientMayDuck);
- FlushForTesting();
-
- EXPECT_EQ(1, GetTransientMaybeDuckCount());
- EXPECT_EQ(AudioFocusType::kGainTransientMayDuck,
- observer.focus_gained_call_.value());
- }
-
- {
- MockAudioFocusObserver observer;
- AbandonAudioFocus(media_session);
- FlushForTesting();
-
- EXPECT_EQ(0, GetTransientMaybeDuckCount());
- EXPECT_TRUE(observer.focus_lost_call_);
- }
-}
-
-} // namespace content
diff --git a/chromium/content/browser/media/session/audio_focus_observer.cc b/chromium/content/browser/media/session/audio_focus_observer.cc
index b78c54c4b5f..33077b1109c 100644
--- a/chromium/content/browser/media/session/audio_focus_observer.cc
+++ b/chromium/content/browser/media/session/audio_focus_observer.cc
@@ -4,41 +4,52 @@
#include "content/browser/media/session/audio_focus_observer.h"
-#include "build/build_config.h"
-#include "content/browser/media/session/audio_focus_manager.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/common/service_manager_connection.h"
#include "mojo/public/cpp/bindings/interface_request.h"
+#include "services/media_session/public/mojom/constants.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
namespace content {
AudioFocusObserver::AudioFocusObserver() : binding_(this) {}
void AudioFocusObserver::RegisterAudioFocusObserver() {
- if (observer_id_.has_value())
+ ConnectToService();
+
+ if (!audio_focus_ptr_.is_bound() || audio_focus_ptr_.encountered_error())
+ return;
+
+ if (binding_.is_bound())
return;
-#if !defined(OS_ANDROID)
- // TODO(https://crbug.com/873320): Add support for Android.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
media_session::mojom::AudioFocusObserverPtr observer;
binding_.Bind(mojo::MakeRequest(&observer));
- observer_id_ =
- AudioFocusManager::GetInstance()->AddObserver(std::move(observer));
-#endif
+ audio_focus_ptr_->AddObserver(std::move(observer));
}
void AudioFocusObserver::UnregisterAudioFocusObserver() {
- if (!observer_id_.has_value())
- return;
-
-#if !defined(OS_ANDROID)
- // TODO(https://crbug.com/873320): Add support for Android.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
binding_.Close();
- AudioFocusManager::GetInstance()->RemoveObserver(observer_id_.value());
-#endif
+}
+
+void AudioFocusObserver::ConnectToService() {
+ if (audio_focus_ptr_.encountered_error())
+ audio_focus_ptr_.reset();
+
+ if (audio_focus_ptr_.is_bound())
+ return;
+
+ ServiceManagerConnection* connection =
+ ServiceManagerConnection::GetForProcess();
+
+ if (!connection)
+ return;
- observer_id_.reset();
+ service_manager::Connector* connector = connection->GetConnector();
+ connector->BindInterface(media_session::mojom::kServiceName,
+ mojo::MakeRequest(&audio_focus_ptr_));
}
AudioFocusObserver::~AudioFocusObserver() = default;
diff --git a/chromium/content/browser/media/session/audio_focus_observer.h b/chromium/content/browser/media/session/audio_focus_observer.h
index c4eae2b9f56..0e3f481d68c 100644
--- a/chromium/content/browser/media/session/audio_focus_observer.h
+++ b/chromium/content/browser/media/session/audio_focus_observer.h
@@ -6,10 +6,8 @@
#define CONTENT_BROWSER_MEDIA_SESSION_AUDIO_FOCUS_OBSERVER_H_
#include "base/macros.h"
-#include "base/optional.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "services/media_session/public/mojom/audio_focus.mojom.h"
namespace content {
@@ -23,11 +21,11 @@ class CONTENT_EXPORT AudioFocusObserver
~AudioFocusObserver() override;
// The given media session gained audio focus with the specified type.
- void OnFocusGained(::media_session::mojom::MediaSessionPtr,
+ void OnFocusGained(::media_session::mojom::MediaSessionInfoPtr,
media_session::mojom::AudioFocusType) override {}
// The given media session lost audio focus.
- void OnFocusLost(::media_session::mojom::MediaSessionPtr) override {}
+ void OnFocusLost(::media_session::mojom::MediaSessionInfoPtr) override {}
protected:
// Called by subclasses to (un-)register the observer with AudioFocusManager.
@@ -35,7 +33,8 @@ class CONTENT_EXPORT AudioFocusObserver
void UnregisterAudioFocusObserver();
private:
- base::Optional<mojo::InterfacePtrSetElementId> observer_id_;
+ void ConnectToService();
+ media_session::mojom::AudioFocusManagerPtr audio_focus_ptr_;
mojo::Binding<media_session::mojom::AudioFocusObserver> binding_;
diff --git a/chromium/content/browser/media/session/media_session_android.cc b/chromium/content/browser/media/session/media_session_android.cc
index e110c52ea5e..d8505beca20 100644
--- a/chromium/content/browser/media/session/media_session_android.cc
+++ b/chromium/content/browser/media/session/media_session_android.cc
@@ -119,21 +119,21 @@ void MediaSessionAndroid::Resume(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& j_obj) {
DCHECK(media_session());
- media_session()->Resume(MediaSession::SuspendType::UI);
+ media_session()->Resume(MediaSession::SuspendType::kUI);
}
void MediaSessionAndroid::Suspend(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& j_obj) {
DCHECK(media_session());
- media_session()->Suspend(MediaSession::SuspendType::UI);
+ media_session()->Suspend(MediaSession::SuspendType::kUI);
}
void MediaSessionAndroid::Stop(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& j_obj) {
DCHECK(media_session());
- media_session()->Stop(MediaSession::SuspendType::UI);
+ media_session()->Stop(MediaSession::SuspendType::kUI);
}
void MediaSessionAndroid::SeekForward(
diff --git a/chromium/content/browser/media/session/media_session_browsertest.cc b/chromium/content/browser/media/session/media_session_browsertest.cc
index f89836e50a4..b6c4fcb1bb8 100644
--- a/chromium/content/browser/media/session/media_session_browsertest.cc
+++ b/chromium/content/browser/media/session/media_session_browsertest.cc
@@ -127,7 +127,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, MediaSessionNoOpWhenDisabled) {
StartPlaybackAndWait(shell(), "long-video");
StartPlaybackAndWait(shell(), "long-audio");
- media_session->Suspend(MediaSession::SuspendType::SYSTEM);
+ media_session->Suspend(MediaSession::SuspendType::kSystem);
StopPlaybackAndWait(shell(), "long-audio");
// At that point, only "long-audio" is paused.
@@ -146,11 +146,11 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, SimplePlayPause) {
StartPlaybackAndWait(shell(), "long-video");
- media_session->Suspend(MediaSession::SuspendType::SYSTEM);
+ media_session->Suspend(MediaSession::SuspendType::kSystem);
WaitForStop(shell());
EXPECT_FALSE(IsPlaying(shell(), "long-video"));
- media_session->Resume(MediaSession::SuspendType::SYSTEM);
+ media_session->Resume(MediaSession::SuspendType::kSystem);
WaitForStart(shell());
EXPECT_TRUE(IsPlaying(shell(), "long-video"));
}
@@ -166,12 +166,12 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, MultiplePlayersPlayPause) {
StartPlaybackAndWait(shell(), "long-video");
StartPlaybackAndWait(shell(), "long-audio");
- media_session->Suspend(MediaSession::SuspendType::SYSTEM);
+ media_session->Suspend(MediaSession::SuspendType::kSystem);
WaitForStop(shell());
EXPECT_FALSE(IsPlaying(shell(), "long-video"));
EXPECT_FALSE(IsPlaying(shell(), "long-audio"));
- media_session->Resume(MediaSession::SuspendType::SYSTEM);
+ media_session->Resume(MediaSession::SuspendType::kSystem);
WaitForStart(shell());
EXPECT_TRUE(IsPlaying(shell(), "long-video"));
EXPECT_TRUE(IsPlaying(shell(), "long-audio"));
@@ -217,22 +217,22 @@ IN_PROC_BROWSER_TEST_F(MediaSessionBrowserTest, MultipleTabsPlayPause) {
StartPlaybackAndWait(shell(), "long-video");
StartPlaybackAndWait(other_shell, "long-video");
- media_session->Suspend(MediaSession::SuspendType::SYSTEM);
+ media_session->Suspend(MediaSession::SuspendType::kSystem);
WaitForStop(shell());
EXPECT_FALSE(IsPlaying(shell(), "long-video"));
EXPECT_TRUE(IsPlaying(other_shell, "long-video"));
- other_media_session->Suspend(MediaSession::SuspendType::SYSTEM);
+ other_media_session->Suspend(MediaSession::SuspendType::kSystem);
WaitForStop(other_shell);
EXPECT_FALSE(IsPlaying(shell(), "long-video"));
EXPECT_FALSE(IsPlaying(other_shell, "long-video"));
- media_session->Resume(MediaSession::SuspendType::SYSTEM);
+ media_session->Resume(MediaSession::SuspendType::kSystem);
WaitForStart(shell());
EXPECT_TRUE(IsPlaying(shell(), "long-video"));
EXPECT_FALSE(IsPlaying(other_shell, "long-video"));
- other_media_session->Resume(MediaSession::SuspendType::SYSTEM);
+ other_media_session->Resume(MediaSession::SuspendType::kSystem);
WaitForStart(other_shell);
EXPECT_TRUE(IsPlaying(shell(), "long-video"));
EXPECT_TRUE(IsPlaying(other_shell, "long-video"));
diff --git a/chromium/content/browser/media/session/media_session_controllers_manager_unittest.cc b/chromium/content/browser/media/session/media_session_controllers_manager_unittest.cc
index 0c8afb247db..9841b8ce7b0 100644
--- a/chromium/content/browser/media/session/media_session_controllers_manager_unittest.cc
+++ b/chromium/content/browser/media/session/media_session_controllers_manager_unittest.cc
@@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "build/build_config.h"
#include "content/browser/media/session/media_session_controller.h"
+#include "content/public/test/test_service_manager_context.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "media/base/media_content_type.h"
@@ -54,6 +55,8 @@ class MediaSessionControllersManagerTest
}
#endif
+ service_manager_context_ = std::make_unique<TestServiceManagerContext>();
+
media_player_id_ = MediaSessionControllersManager::MediaPlayerId(
contents()->GetMainFrame(), 1);
mock_media_session_controller_ =
@@ -86,6 +89,7 @@ class MediaSessionControllersManagerTest
void TearDown() override {
manager_.reset();
+ service_manager_context_.reset();
RenderViewHostImplTestHarness::TearDown();
}
@@ -98,6 +102,7 @@ class MediaSessionControllersManagerTest
StrictMock<MockMediaSessionController>* mock_media_session_controller_ptr_ =
nullptr;
std::unique_ptr<MediaSessionControllersManager> manager_;
+ std::unique_ptr<TestServiceManagerContext> service_manager_context_;
};
TEST_P(MediaSessionControllersManagerTest, RequestPlayAddsSessionsToMap) {
diff --git a/chromium/content/browser/media/session/media_session_impl.cc b/chromium/content/browser/media/session/media_session_impl.cc
index 15bab907e47..19cf17e9c0b 100644
--- a/chromium/content/browser/media/session/media_session_impl.cc
+++ b/chromium/content/browser/media/session/media_session_impl.cc
@@ -29,6 +29,7 @@
namespace content {
using MediaSessionUserAction = MediaSessionUmaHelper::MediaSessionUserAction;
+using media_session::mojom::MediaSessionInfo;
namespace {
@@ -43,6 +44,11 @@ const char kDebugInfoStateSeparator[] = " ";
using MapRenderFrameHostToDepth = std::map<RenderFrameHost*, size_t>;
+using media_session::mojom::AudioFocusType;
+
+using MediaSessionSuspendedSource =
+ MediaSessionUmaHelper::MediaSessionSuspendedSource;
+
size_t ComputeFrameDepth(RenderFrameHost* rfh,
MapRenderFrameHostToDepth* map_rfh_to_depth) {
DCHECK(rfh);
@@ -90,11 +96,6 @@ void MaybePushBackString(std::vector<std::string>& vector,
} // anonymous namespace
-using media_session::mojom::AudioFocusType;
-
-using MediaSessionSuspendedSource =
- MediaSessionUmaHelper::MediaSessionSuspendedSource;
-
MediaSessionImpl::PlayerIdentifier::PlayerIdentifier(
MediaSessionPlayerObserver* observer,
int player_id)
@@ -105,6 +106,12 @@ bool MediaSessionImpl::PlayerIdentifier::operator==(
return this->observer == other.observer && this->player_id == other.player_id;
}
+bool MediaSessionImpl::PlayerIdentifier::operator<(
+ const PlayerIdentifier& other) const {
+ return MediaSessionImpl::PlayerIdentifier::Hash()(*this) <
+ MediaSessionImpl::PlayerIdentifier::Hash()(other);
+}
+
size_t MediaSessionImpl::PlayerIdentifier::Hash::operator()(
const PlayerIdentifier& player_identifier) const {
size_t hash = BASE_HASH_NAMESPACE::hash<MediaSessionPlayerObserver*>()(
@@ -151,6 +158,7 @@ void MediaSessionImpl::WebContentsDestroyed() {
normal_players_.clear();
pepper_players_.clear();
one_shot_players_.clear();
+
AbandonSystemAudioFocusIfNeeded();
}
@@ -217,19 +225,27 @@ bool MediaSessionImpl::AddPlayer(MediaSessionPlayerObserver* observer,
else
required_audio_focus_type = AudioFocusType::kGainTransientMayDuck;
+ PlayerIdentifier key(observer, player_id);
+
// If the audio focus is already granted and is of type Content, there is
// nothing to do. If it is granted of type Transient the requested type is
// also transient, there is also nothing to do. Otherwise, the session needs
// to request audio focus again.
if (audio_focus_state_ == State::ACTIVE) {
- AudioFocusType current_focus_type = delegate_->GetCurrentFocusType();
+ base::Optional<AudioFocusType> current_focus_type =
+ delegate_->GetCurrentFocusType();
if (current_focus_type == AudioFocusType::kGain ||
current_focus_type == required_audio_focus_type) {
- normal_players_.insert(PlayerIdentifier(observer, player_id));
+ auto iter = normal_players_.find(key);
+ if (iter == normal_players_.end())
+ normal_players_.emplace(std::move(key), required_audio_focus_type);
+ else
+ iter->second = required_audio_focus_type;
return true;
}
}
+ bool old_controllable = IsControllable();
State old_audio_focus_state = audio_focus_state_;
RequestSystemAudioFocus(required_audio_focus_type);
@@ -241,10 +257,19 @@ bool MediaSessionImpl::AddPlayer(MediaSessionPlayerObserver* observer,
if (old_audio_focus_state != State::ACTIVE)
normal_players_.clear();
- normal_players_.insert(PlayerIdentifier(observer, player_id));
+ auto iter = normal_players_.find(key);
+ if (iter == normal_players_.end())
+ normal_players_.emplace(std::move(key), required_audio_focus_type);
+ else
+ iter->second = required_audio_focus_type;
UpdateRoutedService();
- NotifyAboutStateChange();
+
+ if (old_audio_focus_state != audio_focus_state_ ||
+ old_controllable != IsControllable()) {
+ NotifyAboutStateChange();
+ }
+
return true;
}
@@ -254,11 +279,11 @@ void MediaSessionImpl::RemovePlayer(MediaSessionPlayerObserver* observer,
PlayerIdentifier identifier(observer, player_id);
- auto it = normal_players_.find(identifier);
- if (it != normal_players_.end())
- normal_players_.erase(it);
+ auto iter = normal_players_.find(identifier);
+ if (iter != normal_players_.end())
+ normal_players_.erase(iter);
- it = pepper_players_.find(identifier);
+ auto it = pepper_players_.find(identifier);
if (it != pepper_players_.end())
pepper_players_.erase(it);
@@ -280,7 +305,7 @@ void MediaSessionImpl::RemovePlayers(MediaSessionPlayerObserver* observer) {
bool was_controllable = IsControllable();
for (auto it = normal_players_.begin(); it != normal_players_.end();) {
- if (it->observer == observer)
+ if (it->first.observer == observer)
normal_players_.erase(it++);
else
++it;
@@ -345,27 +370,30 @@ void MediaSessionImpl::OnPlayerPaused(MediaSessionPlayerObserver* observer,
// Otherwise, suspend the session.
DCHECK(IsActive());
- OnSuspendInternal(SuspendType::CONTENT, State::SUSPENDED);
+ OnSuspendInternal(SuspendType::kContent, State::SUSPENDED);
}
void MediaSessionImpl::Resume(SuspendType suspend_type) {
if (!IsSuspended())
return;
- if (suspend_type == SuspendType::UI) {
+ if (suspend_type == SuspendType::kUI) {
MediaSessionUmaHelper::RecordMediaSessionUserAction(
MediaSessionUmaHelper::MediaSessionUserAction::PlayDefault);
}
// When the resume requests comes from another source than system, audio focus
// must be requested.
- if (suspend_type != SuspendType::SYSTEM) {
+ if (suspend_type != SuspendType::kSystem) {
// Request audio focus again in case we lost it because another app started
- // playing while the playback was paused.
- State audio_focus_state = RequestSystemAudioFocus(desired_audio_focus_type_)
- ? State::ACTIVE
- : State::INACTIVE;
- SetAudioFocusState(audio_focus_state);
+ // playing while the playback was paused. If the audio focus request is
+ // delayed we will resume the player when the request completes.
+ AudioFocusDelegate::AudioFocusResult result =
+ RequestSystemAudioFocus(desired_audio_focus_type_);
+
+ SetAudioFocusState(result != AudioFocusDelegate::AudioFocusResult::kFailed
+ ? State::ACTIVE
+ : State::INACTIVE);
if (audio_focus_state_ != State::ACTIVE)
return;
@@ -378,7 +406,7 @@ void MediaSessionImpl::Suspend(SuspendType suspend_type) {
if (!IsActive())
return;
- if (suspend_type == SuspendType::UI) {
+ if (suspend_type == SuspendType::kUI) {
MediaSessionUmaHelper::RecordMediaSessionUserAction(
MediaSessionUserAction::PauseDefault);
}
@@ -388,16 +416,16 @@ void MediaSessionImpl::Suspend(SuspendType suspend_type) {
void MediaSessionImpl::Stop(SuspendType suspend_type) {
DCHECK(audio_focus_state_ != State::INACTIVE);
- DCHECK(suspend_type != SuspendType::CONTENT);
+ DCHECK(suspend_type != SuspendType::kContent);
DCHECK(!HasPepper());
- if (suspend_type == SuspendType::UI) {
+ if (suspend_type == SuspendType::kUI) {
MediaSessionUmaHelper::RecordMediaSessionUserAction(
MediaSessionUmaHelper::MediaSessionUserAction::StopDefault);
}
// TODO(mlamouri): merge the logic between UI and SYSTEM.
- if (suspend_type == SuspendType::SYSTEM) {
+ if (suspend_type == SuspendType::kSystem) {
OnSuspendInternal(suspend_type, State::INACTIVE);
return;
}
@@ -413,12 +441,12 @@ void MediaSessionImpl::Stop(SuspendType suspend_type) {
void MediaSessionImpl::SeekForward(base::TimeDelta seek_time) {
for (const auto& it : normal_players_)
- it.observer->OnSeekForward(it.player_id, seek_time);
+ it.first.observer->OnSeekForward(it.first.player_id, seek_time);
}
void MediaSessionImpl::SeekBackward(base::TimeDelta seek_time) {
for (const auto& it : normal_players_)
- it.observer->OnSeekBackward(it.player_id, seek_time);
+ it.first.observer->OnSeekBackward(it.first.player_id, seek_time);
}
bool MediaSessionImpl::IsControllable() const {
@@ -448,6 +476,7 @@ void MediaSessionImpl::StartDucking() {
return;
is_ducking_ = true;
UpdateVolumeMultiplier();
+ NotifyObserversInfoChanged();
}
void MediaSessionImpl::StopDucking() {
@@ -455,11 +484,15 @@ void MediaSessionImpl::StopDucking() {
return;
is_ducking_ = false;
UpdateVolumeMultiplier();
+ NotifyObserversInfoChanged();
}
void MediaSessionImpl::UpdateVolumeMultiplier() {
- for (const auto& it : normal_players_)
- it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier());
+ for (const auto& it : normal_players_) {
+ it.first.observer->OnSetVolumeMultiplier(it.first.player_id,
+ GetVolumeMultiplier());
+ }
+
for (const auto& it : pepper_players_)
it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier());
}
@@ -502,13 +535,19 @@ void MediaSessionImpl::RemoveAllPlayersForTest() {
AbandonSystemAudioFocusIfNeeded();
}
+void MediaSessionImpl::OnSystemAudioFocusRequested(bool result) {
+ uma_helper_.RecordRequestAudioFocusResult(result);
+ if (result)
+ StopDucking();
+}
+
void MediaSessionImpl::OnSuspendInternal(SuspendType suspend_type,
State new_state) {
DCHECK(!HasPepper());
DCHECK(new_state == State::SUSPENDED || new_state == State::INACTIVE);
// UI suspend cannot use State::INACTIVE.
- DCHECK(suspend_type == SuspendType::SYSTEM || new_state == State::SUSPENDED);
+ DCHECK(suspend_type == SuspendType::kSystem || new_state == State::SUSPENDED);
if (!one_shot_players_.empty())
return;
@@ -517,10 +556,10 @@ void MediaSessionImpl::OnSuspendInternal(SuspendType suspend_type,
return;
switch (suspend_type) {
- case SuspendType::UI:
+ case SuspendType::kUI:
uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::UI);
break;
- case SuspendType::SYSTEM:
+ case SuspendType::kSystem:
switch (new_state) {
case State::SUSPENDED:
uma_helper_.RecordSessionSuspended(
@@ -535,7 +574,7 @@ void MediaSessionImpl::OnSuspendInternal(SuspendType suspend_type,
break;
}
break;
- case SuspendType::CONTENT:
+ case SuspendType::kContent:
uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::CONTENT);
break;
}
@@ -543,12 +582,12 @@ void MediaSessionImpl::OnSuspendInternal(SuspendType suspend_type,
SetAudioFocusState(new_state);
suspend_type_ = suspend_type;
- if (suspend_type != SuspendType::CONTENT) {
+ if (suspend_type != SuspendType::kContent) {
// SuspendType::CONTENT happens when the suspend action came from
// the page in which case the player is already paused.
// Otherwise, the players need to be paused.
for (const auto& it : normal_players_)
- it.observer->OnSuspend(it.player_id);
+ it.first.observer->OnSuspend(it.first.player_id);
}
for (const auto& it : pepper_players_)
@@ -559,13 +598,13 @@ void MediaSessionImpl::OnSuspendInternal(SuspendType suspend_type,
}
void MediaSessionImpl::OnResumeInternal(SuspendType suspend_type) {
- if (suspend_type == SuspendType::SYSTEM && suspend_type_ != suspend_type)
+ if (suspend_type == SuspendType::kSystem && suspend_type_ != suspend_type)
return;
SetAudioFocusState(State::ACTIVE);
for (const auto& it : normal_players_)
- it.observer->OnResume(it.player_id);
+ it.first.observer->OnResume(it.first.player_id);
for (const auto& it : pepper_players_)
it.observer->OnSetVolumeMultiplier(it.player_id, GetVolumeMultiplier());
@@ -587,31 +626,44 @@ MediaSessionImpl::MediaSessionImpl(WebContents* web_contents)
void MediaSessionImpl::Initialize() {
delegate_ = AudioFocusDelegate::Create(this);
+ delegate_->MediaSessionInfoChanged(GetMediaSessionInfoSync());
}
-bool MediaSessionImpl::RequestSystemAudioFocus(
+AudioFocusDelegate::AudioFocusResult MediaSessionImpl::RequestSystemAudioFocus(
AudioFocusType audio_focus_type) {
- bool result = delegate_->RequestAudioFocus(audio_focus_type);
- uma_helper_.RecordRequestAudioFocusResult(result);
-
- // Make sure we are unducked.
- if (result)
- StopDucking();
+ // |kGainTransient| is not used in MediaSessionImpl.
+ DCHECK_NE(media_session::mojom::AudioFocusType::kGainTransient,
+ audio_focus_type);
- // MediaSessionImpl must change its state & audio focus type AFTER requesting
- // audio focus.
- SetAudioFocusState(result ? State::ACTIVE : State::INACTIVE);
+ AudioFocusDelegate::AudioFocusResult result =
+ delegate_->RequestAudioFocus(audio_focus_type);
desired_audio_focus_type_ = audio_focus_type;
+
+ bool success = result != AudioFocusDelegate::AudioFocusResult::kFailed;
+ SetAudioFocusState(success ? State::ACTIVE : State::INACTIVE);
+
+ // If we are delayed then we should return now and wait for the response from
+ // the audio focus delegate.
+ if (result == AudioFocusDelegate::AudioFocusResult::kDelayed)
+ return result;
+
+ OnSystemAudioFocusRequested(success);
return result;
}
-const MediaSessionImpl::DebugInfo MediaSessionImpl::GetDebugInfo() {
- MediaSessionImpl::DebugInfo debug_info;
+void MediaSessionImpl::BindToMojoRequest(
+ mojo::InterfaceRequest<media_session::mojom::MediaSession> request) {
+ bindings_.AddBinding(this, std::move(request));
+}
+
+void MediaSessionImpl::GetDebugInfo(GetDebugInfoCallback callback) {
+ media_session::mojom::MediaSessionDebugInfoPtr info(
+ media_session::mojom::MediaSessionDebugInfo::New());
// Convert the address of |this| to a string and use it as the name.
std::stringstream stream;
stream << this;
- debug_info.name = stream.str();
+ info->name = stream.str();
// Add the title and the url to the owner.
std::vector<std::string> owner_parts;
@@ -619,21 +671,88 @@ const MediaSessionImpl::DebugInfo MediaSessionImpl::GetDebugInfo() {
base::UTF16ToUTF8(web_contents()->GetTitle()));
MaybePushBackString(owner_parts,
web_contents()->GetLastCommittedURL().spec());
- debug_info.owner = base::JoinString(owner_parts, kDebugInfoOwnerSeparator);
+ info->owner = base::JoinString(owner_parts, kDebugInfoOwnerSeparator);
// Add the ducking state to state.
std::vector<std::string> state_parts;
MaybePushBackString(state_parts,
IsActive() ? kDebugInfoActive : kDebugInfoInactive);
MaybePushBackString(state_parts, is_ducking_ ? kDebugInfoDucked : "");
- debug_info.state = base::JoinString(state_parts, kDebugInfoStateSeparator);
+ info->state = base::JoinString(state_parts, kDebugInfoStateSeparator);
- return debug_info;
+ std::move(callback).Run(std::move(info));
}
-void MediaSessionImpl::BindToMojoRequest(
- mojo::InterfaceRequest<media_session::mojom::MediaSession> request) {
- bindings_.AddBinding(this, std::move(request));
+media_session::mojom::MediaSessionInfoPtr
+MediaSessionImpl::GetMediaSessionInfoSync() {
+ media_session::mojom::MediaSessionInfoPtr info(
+ media_session::mojom::MediaSessionInfo::New());
+
+ switch (audio_focus_state_) {
+ case State::ACTIVE:
+ info->state = MediaSessionInfo::SessionState::kActive;
+ break;
+ case State::SUSPENDED:
+ info->state = MediaSessionInfo::SessionState::kSuspended;
+ break;
+ case State::INACTIVE:
+ info->state = MediaSessionInfo::SessionState::kInactive;
+ break;
+ }
+
+ // The state should always be kDucked if we are ducked.
+ if (is_ducking_)
+ info->state = MediaSessionInfo::SessionState::kDucking;
+
+ // If we have Pepper players then we should force ducking.
+ info->force_duck = HasPepper();
+ return info;
+}
+
+void MediaSessionImpl::GetMediaSessionInfo(
+ GetMediaSessionInfoCallback callback) {
+ std::move(callback).Run(GetMediaSessionInfoSync());
+}
+
+void MediaSessionImpl::AddObserver(
+ media_session::mojom::MediaSessionObserverPtr observer) {
+ observer->MediaSessionInfoChanged(GetMediaSessionInfoSync());
+ mojo_observers_.AddPtr(std::move(observer));
+}
+
+void MediaSessionImpl::FinishSystemAudioFocusRequest(
+ AudioFocusType audio_focus_type,
+ bool result) {
+ // If the media session is not active then we do not need to enforce the
+ // result of the audio focus request.
+ if (audio_focus_state_ != State::ACTIVE) {
+ AbandonSystemAudioFocusIfNeeded();
+ return;
+ }
+
+ OnSystemAudioFocusRequested(result);
+
+ if (!result) {
+ switch (audio_focus_type) {
+ case AudioFocusType::kGain:
+ // If the gain audio focus request failed then we should suspend the
+ // media session.
+ OnSuspendInternal(SuspendType::kSystem, State::SUSPENDED);
+ break;
+ case AudioFocusType::kGainTransient:
+ // MediaSessionImpl does not use |kGainTransient|.
+ NOTREACHED();
+ break;
+ case AudioFocusType::kGainTransientMayDuck:
+ // The focus request failed, we should suspend any players that have
+ // the same audio focus type.
+ for (auto& player : normal_players_) {
+ if (audio_focus_type == player.second)
+ player.first.observer->OnSuspend(player.first.player_id);
+ }
+ break;
+ }
+ }
}
void MediaSessionImpl::AbandonSystemAudioFocusIfNeeded() {
@@ -672,24 +791,46 @@ void MediaSessionImpl::SetAudioFocusState(State audio_focus_state) {
uma_helper_.OnSessionInactive();
break;
}
+
+ NotifyObserversInfoChanged();
+}
+
+void MediaSessionImpl::FlushForTesting() {
+ mojo_observers_.FlushForTesting();
+}
+
+void MediaSessionImpl::NotifyObserversInfoChanged() {
+ media_session::mojom::MediaSessionInfoPtr current_info =
+ GetMediaSessionInfoSync();
+
+ mojo_observers_.ForAllPtrs(
+ [&current_info](media_session::mojom::MediaSessionObserver* observer) {
+ observer->MediaSessionInfoChanged(current_info.Clone());
+ });
+
+ delegate_->MediaSessionInfoChanged(current_info.Clone());
}
bool MediaSessionImpl::AddPepperPlayer(MediaSessionPlayerObserver* observer,
int player_id) {
- bool success = RequestSystemAudioFocus(AudioFocusType::kGain);
- DCHECK(success);
+ AudioFocusDelegate::AudioFocusResult result =
+ RequestSystemAudioFocus(AudioFocusType::kGain);
+ DCHECK_NE(AudioFocusDelegate::AudioFocusResult::kFailed, result);
pepper_players_.insert(PlayerIdentifier(observer, player_id));
observer->OnSetVolumeMultiplier(player_id, GetVolumeMultiplier());
NotifyAboutStateChange();
- return success;
+ return result != AudioFocusDelegate::AudioFocusResult::kFailed;
}
bool MediaSessionImpl::AddOneShotPlayer(MediaSessionPlayerObserver* observer,
int player_id) {
- if (!RequestSystemAudioFocus(AudioFocusType::kGain))
+ AudioFocusDelegate::AudioFocusResult result =
+ RequestSystemAudioFocus(AudioFocusType::kGain);
+
+ if (result == AudioFocusDelegate::AudioFocusResult::kFailed)
return false;
one_shot_players_.insert(PlayerIdentifier(observer, player_id));
@@ -762,8 +903,8 @@ void MediaSessionImpl::DidReceiveAction(
RenderFrameHost* rfh_of_routed_service =
routed_service_ ? routed_service_->GetRenderFrameHost() : nullptr;
for (const auto& player : normal_players_) {
- if (player.observer->render_frame_host() != rfh_of_routed_service)
- player.observer->OnSuspend(player.player_id);
+ if (player.first.observer->render_frame_host() != rfh_of_routed_service)
+ player.first.observer->OnSuspend(player.first.player_id);
}
for (const auto& player : pepper_players_) {
if (player.observer->render_frame_host() != rfh_of_routed_service) {
@@ -806,7 +947,7 @@ MediaSessionServiceImpl* MediaSessionImpl::ComputeServiceForRouting() {
// prefer the top-most frame.
std::set<RenderFrameHost*> frames;
for (const auto& player : normal_players_) {
- RenderFrameHost* frame = player.observer->render_frame_host();
+ RenderFrameHost* frame = player.first.observer->render_frame_host();
if (frame)
frames.insert(frame);
}
diff --git a/chromium/content/browser/media/session/media_session_impl.h b/chromium/content/browser/media/session/media_session_impl.h
index 42f85c71133..3c1e003c2b6 100644
--- a/chromium/content/browser/media/session/media_session_impl.h
+++ b/chromium/content/browser/media/session/media_session_impl.h
@@ -15,7 +15,7 @@
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/optional.h"
-#include "content/browser/media/session/audio_focus_manager.h"
+#include "content/browser/media/session/audio_focus_delegate.h"
#include "content/browser/media/session/media_session_uma_helper.h"
#include "content/common/content_export.h"
#include "content/public/browser/media_session.h"
@@ -25,6 +25,7 @@
#include "content/public/common/media_metadata.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "services/media_session/public/mojom/audio_focus.mojom.h"
#if defined(OS_ANDROID)
@@ -37,15 +38,8 @@ namespace media {
enum class MediaContentType;
} // namespace media
-namespace media_session {
-namespace mojom {
-enum class AudioFocusType;
-} // namespace mojom
-} // namespace media_session
-
namespace content {
-class AudioFocusDelegate;
class AudioFocusManagerTest;
class MediaSessionImplServiceRoutingTest;
class MediaSessionImplStateObserver;
@@ -124,43 +118,6 @@ class MediaSessionImpl : public MediaSession,
CONTENT_EXPORT void OnPlayerPaused(MediaSessionPlayerObserver* observer,
int player_id);
- // Resume the media session.
- // |type| represents the origin of the request.
- CONTENT_EXPORT void Resume(MediaSession::SuspendType suspend_type) override;
-
- // Suspend the media session.
- // |type| represents the origin of the request.
- CONTENT_EXPORT void Suspend(MediaSession::SuspendType suspend_type) override;
-
- // Stop the media session.
- // |type| represents the origin of the request.
- CONTENT_EXPORT void Stop(MediaSession::SuspendType suspend_type) override;
-
- // Seek the media session forward.
- CONTENT_EXPORT void SeekForward(base::TimeDelta seek_time) override;
-
- // Seek the media session backward.
- CONTENT_EXPORT void SeekBackward(base::TimeDelta seek_time) override;
-
- // Returns if the session can be controlled by Resume() and Suspend() calls
- // above.
- CONTENT_EXPORT bool IsControllable() const override;
-
- // Compute if the actual playback state is paused by combining the
- // MediaSessionService declared state and guessed state (audio_focus_state_).
- CONTENT_EXPORT bool IsActuallyPaused() const override;
-
- // Set the volume multiplier applied during ducking.
- CONTENT_EXPORT void SetDuckingVolumeMultiplier(double multiplier) override;
-
- // Let the media session start ducking such that the volume multiplier is
- // reduced.
- CONTENT_EXPORT void StartDucking() override;
-
- // Let the media session stop ducking such that the volume multiplier is
- // recovered.
- CONTENT_EXPORT void StopDucking() override;
-
void AddObserver(MediaSessionObserver* observer) override;
void RemoveObserver(MediaSessionObserver* observer) override;
@@ -198,31 +155,77 @@ class MediaSessionImpl : public MediaSession,
// observers if the service is currently routed.
void OnMediaSessionActionsChanged(MediaSessionServiceImpl* service);
+ // Requests audio focus to the AudioFocusDelegate.
+ // Returns whether the request was granted.
+ CONTENT_EXPORT AudioFocusDelegate::AudioFocusResult RequestSystemAudioFocus(
+ media_session::mojom::AudioFocusType audio_focus_type);
+
+ // Creates a binding between |this| and |request|.
+ void BindToMojoRequest(
+ mojo::InterfaceRequest<media_session::mojom::MediaSession> request);
+
+ // Returns information about the MediaSession.
+ media_session::mojom::MediaSessionInfoPtr GetMediaSessionInfoSync();
+
+ // MediaSession overrides ---------------------------------------------------
+
+ // Resume the media session.
+ // |type| represents the origin of the request.
+ CONTENT_EXPORT void Resume(MediaSession::SuspendType suspend_type) override;
+
+ // Stop the media session.
+ // |type| represents the origin of the request.
+ CONTENT_EXPORT void Stop(MediaSession::SuspendType suspend_type) override;
+
+ // Seek the media session forward.
+ CONTENT_EXPORT void SeekForward(base::TimeDelta seek_time) override;
+
+ // Seek the media session backward.
+ CONTENT_EXPORT void SeekBackward(base::TimeDelta seek_time) override;
+
+ // Returns if the session can be controlled by Resume() and Suspend() calls
+ // above.
+ CONTENT_EXPORT bool IsControllable() const override;
+
+ // Compute if the actual playback state is paused by combining the
+ // MediaSessionService declared state and guessed state (audio_focus_state_).
+ CONTENT_EXPORT bool IsActuallyPaused() const override;
+
// Called when a MediaSessionAction is received. The action will be forwarded
// to blink::MediaSession corresponding to the current routed service.
void DidReceiveAction(blink::mojom::MediaSessionAction action) override;
- // Requests audio focus to the AudioFocusDelegate.
- // Returns whether the request was granted.
- CONTENT_EXPORT bool RequestSystemAudioFocus(
- media_session::mojom::AudioFocusType audio_focus_type);
+ // Set the volume multiplier applied during ducking.
+ CONTENT_EXPORT void SetDuckingVolumeMultiplier(double multiplier) override;
- // Returns debugging information to be displayed on chrome://media-internals.
- struct DebugInfo {
- // A unique name for the MediaSession.
- std::string name;
+ // Suspend the media session.
+ // |type| represents the origin of the request.
+ CONTENT_EXPORT void Suspend(MediaSession::SuspendType suspend_type) override;
- // The title and URL of the owning WebContents.
- std::string owner;
+ // Let the media session start ducking such that the volume multiplier is
+ // reduced.
+ CONTENT_EXPORT void StartDucking() override;
- // State information stored in a string e.g. Ducked.
- std::string state;
- };
- const DebugInfo GetDebugInfo();
+ // Let the media session stop ducking such that the volume multiplier is
+ // recovered.
+ CONTENT_EXPORT void StopDucking() override;
- // Creates a binding between |this| and |request|.
- void BindToMojoRequest(
- mojo::InterfaceRequest<media_session::mojom::MediaSession> request);
+ // Returns information about the MediaSession. The sync method is not actually
+ // slower and should be used over the async one which is available over mojo.
+ void GetMediaSessionInfo(GetMediaSessionInfoCallback callback) override;
+
+ // Returns debugging information to be displayed on chrome://media-internals.
+ void GetDebugInfo(GetDebugInfoCallback) override;
+
+ // Adds a mojo based observer to listen to events related to this session.
+ void AddObserver(
+ media_session::mojom::MediaSessionObserverPtr observer) override;
+
+ // Called by |AudioFocusDelegate| when an async audio focus request is
+ // completed.
+ CONTENT_EXPORT void FinishSystemAudioFocusRequest(
+ media_session::mojom::AudioFocusType type,
+ bool result);
private:
friend class content::WebContentsUserData<MediaSessionImpl>;
@@ -232,6 +235,7 @@ class MediaSessionImpl : public MediaSession,
friend class content::MediaSessionImplServiceRoutingTest;
friend class content::MediaSessionImplStateObserver;
friend class content::MediaSessionServiceImplBrowserTest;
+ friend class MediaSessionImplTest;
friend class MediaInternalsAudioFocusTest;
CONTENT_EXPORT void SetDelegateForTests(
@@ -246,6 +250,7 @@ class MediaSessionImpl : public MediaSession,
void operator=(const PlayerIdentifier&) = delete;
bool operator==(const PlayerIdentifier& player_identifier) const;
+ bool operator<(const PlayerIdentifier&) const;
// Hash operator for base::hash_map<>.
struct Hash {
@@ -262,6 +267,10 @@ class MediaSessionImpl : public MediaSession,
void Initialize();
+ // Called when system audio focus has been requested and whether the request
+ // was granted.
+ void OnSystemAudioFocusRequested(bool result);
+
CONTENT_EXPORT void OnSuspendInternal(MediaSession::SuspendType suspend_type,
State new_state);
CONTENT_EXPORT void OnResumeInternal(MediaSession::SuspendType suspend_type);
@@ -280,6 +289,12 @@ class MediaSessionImpl : public MediaSession,
// It sets audio_focus_state_ and notifies observers about the state change.
void SetAudioFocusState(State audio_focus_state);
+ // Flushes any mojo bindings for testing.
+ CONTENT_EXPORT void FlushForTesting();
+
+ // Notifies mojo observers that the MediaSessionInfo has changed.
+ void NotifyObserversInfoChanged();
+
// Update the volume multiplier when ducking state changes.
void UpdateVolumeMultiplier();
@@ -311,7 +326,8 @@ class MediaSessionImpl : public MediaSession,
CONTENT_EXPORT MediaSessionServiceImpl* ComputeServiceForRouting();
std::unique_ptr<AudioFocusDelegate> delegate_;
- PlayersMap normal_players_;
+ std::map<PlayerIdentifier, media_session::mojom::AudioFocusType>
+ normal_players_;
PlayersMap pepper_players_;
PlayersMap one_shot_players_;
@@ -352,6 +368,9 @@ class MediaSessionImpl : public MediaSession,
// Bindings for Mojo pointers to |this| held by media route providers.
mojo::BindingSet<media_session::mojom::MediaSession> bindings_;
+ mojo::InterfacePtrSet<media_session::mojom::MediaSessionObserver>
+ mojo_observers_;
+
DISALLOW_COPY_AND_ASSIGN(MediaSessionImpl);
};
diff --git a/chromium/content/browser/media/session/media_session_impl_browsertest.cc b/chromium/content/browser/media/session/media_session_impl_browsertest.cc
index a39d86d6a83..7e686667fa4 100644
--- a/chromium/content/browser/media/session/media_session_impl_browsertest.cc
+++ b/chromium/content/browser/media/session/media_session_impl_browsertest.cc
@@ -51,21 +51,47 @@ const double kDifferentDuckingVolumeMultiplier = 0.018;
class MockAudioFocusDelegate : public AudioFocusDelegate {
public:
- MockAudioFocusDelegate() {}
+ MockAudioFocusDelegate(MediaSessionImpl* media_session, bool async_mode)
+ : media_session_(media_session), async_mode_(async_mode) {}
MOCK_METHOD0(AbandonAudioFocus, void());
- bool RequestAudioFocus(AudioFocusType audio_focus_type) {
- audio_focus_type_ = audio_focus_type;
- return true;
+ AudioFocusDelegate::AudioFocusResult RequestAudioFocus(
+ AudioFocusType audio_focus_type) {
+ if (async_mode_) {
+ requests_.push_back(audio_focus_type);
+ return AudioFocusDelegate::AudioFocusResult::kDelayed;
+ } else {
+ audio_focus_type_ = audio_focus_type;
+ return AudioFocusDelegate::AudioFocusResult::kSuccess;
+ }
}
- AudioFocusType GetCurrentFocusType() const {
- DCHECK(audio_focus_type_.has_value());
- return audio_focus_type_.value();
+ base::Optional<AudioFocusType> GetCurrentFocusType() const {
+ return audio_focus_type_;
}
+ void MediaSessionInfoChanged(
+ media_session::mojom::MediaSessionInfoPtr session_info) override {}
+
+ void ResolveRequest(bool result) {
+ if (!async_mode_)
+ return;
+
+ audio_focus_type_ = requests_.front();
+ requests_.pop_front();
+
+ media_session_->FinishSystemAudioFocusRequest(audio_focus_type_.value(),
+ result);
+ }
+
+ bool HasRequests() const { return !requests_.empty(); }
+
private:
+ MediaSessionImpl* media_session_;
+ const bool async_mode_ = false;
+
+ std::list<AudioFocusType> requests_;
base::Optional<AudioFocusType> audio_focus_type_;
};
@@ -88,7 +114,8 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest {
media_session_ = MediaSessionImpl::Get(shell()->web_contents());
mock_media_session_observer_.reset(
new NiceMock<content::MockMediaSessionObserver>(media_session_));
- mock_audio_focus_delegate_ = new NiceMock<MockAudioFocusDelegate>;
+ mock_audio_focus_delegate_ = new NiceMock<MockAudioFocusDelegate>(
+ media_session_, true /* async_mode */);
media_session_->SetDelegateForTests(
base::WrapUnique(mock_audio_focus_delegate_));
ASSERT_TRUE(media_session_);
@@ -106,8 +133,10 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest {
void StartNewPlayer(MockMediaSessionPlayerObserver* player_observer,
media::MediaContentType media_content_type) {
- bool result = AddPlayer(player_observer, player_observer->StartNewPlayer(),
- media_content_type);
+ int player_id = player_observer->StartNewPlayer();
+
+ bool result = AddPlayer(player_observer, player_id, media_content_type);
+
EXPECT_TRUE(result);
}
@@ -133,22 +162,22 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest {
bool IsActive() { return media_session_->IsActive(); }
- AudioFocusType GetSessionAudioFocusType() {
+ base::Optional<AudioFocusType> GetSessionAudioFocusType() {
return mock_audio_focus_delegate_->GetCurrentFocusType();
}
bool IsControllable() { return media_session_->IsControllable(); }
- void UIResume() { media_session_->Resume(MediaSession::SuspendType::UI); }
+ void UIResume() { media_session_->Resume(MediaSession::SuspendType::kUI); }
void SystemResume() {
- media_session_->OnResumeInternal(MediaSession::SuspendType::SYSTEM);
+ media_session_->OnResumeInternal(MediaSession::SuspendType::kSystem);
}
- void UISuspend() { media_session_->Suspend(MediaSession::SuspendType::UI); }
+ void UISuspend() { media_session_->Suspend(MediaSession::SuspendType::kUI); }
void SystemSuspend(bool temporary) {
- media_session_->OnSuspendInternal(MediaSession::SuspendType::SYSTEM,
+ media_session_->OnSuspendInternal(MediaSession::SuspendType::kSystem,
temporary
? MediaSessionImpl::State::SUSPENDED
: MediaSessionImpl::State::INACTIVE);
@@ -175,6 +204,18 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest {
mock_media_session_service_->SetPlaybackState(state);
}
+ void ResolveAudioFocusSuccess() {
+ mock_audio_focus_delegate()->ResolveRequest(true /* result */);
+ }
+
+ void ResolveAudioFocusFailure() {
+ mock_audio_focus_delegate()->ResolveRequest(false /* result */);
+ }
+
+ bool HasUnresolvedAudioFocusRequest() {
+ return mock_audio_focus_delegate()->HasRequests();
+ }
+
content::MockMediaSessionObserver* mock_media_session_observer() {
return mock_media_session_observer_.get();
}
@@ -191,6 +232,14 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest {
return media_session_->uma_helper_for_test();
}
+ void SetAudioFocusDelegateForTests(MockAudioFocusDelegate* delegate) {
+ mock_audio_focus_delegate_ = delegate;
+ media_session_->SetDelegateForTests(
+ base::WrapUnique(mock_audio_focus_delegate_));
+ }
+
+ bool IsDucking() const { return media_session_->is_ducking_; }
+
protected:
MediaSessionImpl* media_session_;
std::unique_ptr<content::MockMediaSessionObserver>
@@ -201,20 +250,37 @@ class MediaSessionImplBrowserTest : public content::ContentBrowserTest {
DISALLOW_COPY_AND_ASSIGN(MediaSessionImplBrowserTest);
};
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+class MediaSessionImplParamBrowserTest
+ : public MediaSessionImplBrowserTest,
+ public testing::WithParamInterface<bool> {
+ protected:
+ MediaSessionImplParamBrowserTest() = default;
+
+ void SetUpOnMainThread() override {
+ MediaSessionImplBrowserTest::SetUpOnMainThread();
+
+ SetAudioFocusDelegateForTests(
+ new NiceMock<MockAudioFocusDelegate>(media_session_, GetParam()));
+ }
+};
+
+INSTANTIATE_TEST_CASE_P(, MediaSessionImplParamBrowserTest, testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
PlayersFromSameObserverDoNotStopEachOtherInSameSession) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
EXPECT_TRUE(player_observer->IsPlaying(0));
EXPECT_TRUE(player_observer->IsPlaying(1));
EXPECT_TRUE(player_observer->IsPlaying(2));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
PlayersFromManyObserverDoNotStopEachOtherInSameSession) {
auto player_observer_1 = std::make_unique<MockMediaSessionPlayerObserver>();
auto player_observer_2 = std::make_unique<MockMediaSessionPlayerObserver>();
@@ -223,19 +289,21 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
StartNewPlayer(player_observer_1.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer_2.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer_3.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
EXPECT_TRUE(player_observer_1->IsPlaying(0));
EXPECT_TRUE(player_observer_2->IsPlaying(0));
EXPECT_TRUE(player_observer_3->IsPlaying(0));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
SuspendedMediaSessionStopsPlayers) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
@@ -244,13 +312,14 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_FALSE(player_observer->IsPlaying(2));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ResumedMediaSessionRestartsPlayers) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
SystemResume();
@@ -260,11 +329,12 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_TRUE(player_observer->IsPlaying(2));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
StartedPlayerOnSuspendedSessionPlaysAlone) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
EXPECT_TRUE(player_observer->IsPlaying(0));
@@ -273,6 +343,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_FALSE(player_observer->IsPlaying(0));
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
EXPECT_FALSE(player_observer->IsPlaying(0));
EXPECT_TRUE(player_observer->IsPlaying(1));
@@ -284,7 +355,8 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_TRUE(player_observer->IsPlaying(2));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, InitialVolumeMultiplier) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ InitialVolumeMultiplier) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
@@ -292,9 +364,14 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, InitialVolumeMultiplier) {
EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(0));
EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(1));
+
+ ResolveAudioFocusSuccess();
+
+ EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(0));
+ EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(1));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
StartDuckingReducesVolumeMultiplier) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
@@ -310,7 +387,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(kDuckingVolumeMultiplier, player_observer->GetVolumeMultiplier(2));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
StopDuckingRecoversVolumeMultiplier) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
@@ -327,7 +404,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(2));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
DuckingUsesConfiguredMultiplier) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
@@ -344,14 +421,16 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(1));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, AudioFocusInitialState) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ AudioFocusInitialState) {
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
AddPlayerOnSuspendedFocusUnducks) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
UISuspend();
EXPECT_FALSE(IsActive());
@@ -361,53 +440,65 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_TRUE(
AddPlayer(player_observer.get(), 0, media::MediaContentType::Persistent));
+ ResolveAudioFocusSuccess();
EXPECT_EQ(kDefaultVolumeMultiplier, player_observer->GetVolumeMultiplier(0));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
CanRequestFocusBeforePlayerCreation) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
media_session_->RequestSystemAudioFocus(AudioFocusType::kGain);
EXPECT_TRUE(IsActive());
+ ResolveAudioFocusSuccess();
+ EXPECT_TRUE(IsActive());
+
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, StartPlayerGivesFocus) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ StartPlayerGivesFocus) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_TRUE(IsActive());
+ ResolveAudioFocusSuccess();
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
SuspendGivesAwayAudioFocus) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, StopGivesAwayAudioFocus) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ StopGivesAwayAudioFocus) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
- media_session_->Stop(MediaSession::SuspendType::UI);
+ media_session_->Stop(MediaSession::SuspendType::kUI);
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumeGivesBackAudioFocus) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ SystemResumeGivesBackAudioFocus) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
SystemResume();
@@ -415,13 +506,30 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumeGivesBackAudioFocus) {
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ UIResumeGivesBackAudioFocus) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
+
+ UISuspend();
+
+ UIResume();
+ EXPECT_TRUE(IsActive());
+
+ ResolveAudioFocusSuccess();
+ EXPECT_TRUE(IsActive());
+}
+
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
RemovingLastPlayerDropsAudioFocus) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
RemovePlayer(player_observer.get(), 0);
EXPECT_TRUE(IsActive());
@@ -431,7 +539,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
RemovingLastPlayerFromManyObserversDropsAudioFocus) {
auto player_observer_1 = std::make_unique<MockMediaSessionPlayerObserver>();
auto player_observer_2 = std::make_unique<MockMediaSessionPlayerObserver>();
@@ -440,6 +548,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
StartNewPlayer(player_observer_1.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer_2.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer_3.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
RemovePlayer(player_observer_1.get(), 0);
EXPECT_TRUE(IsActive());
@@ -449,7 +558,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
RemovingAllPlayersFromObserversDropsAudioFocus) {
auto player_observer_1 = std::make_unique<MockMediaSessionPlayerObserver>();
auto player_observer_2 = std::make_unique<MockMediaSessionPlayerObserver>();
@@ -458,6 +567,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
StartNewPlayer(player_observer_1.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer_2.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer_2.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
RemovePlayers(player_observer_1.get());
EXPECT_TRUE(IsActive());
@@ -465,29 +575,40 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumePlayGivesAudioFocus) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ ResumePlayGivesAudioFocus) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
RemovePlayer(player_observer.get(), 0);
EXPECT_FALSE(IsActive());
EXPECT_TRUE(
AddPlayer(player_observer.get(), 0, media::MediaContentType::Persistent));
+ ResolveAudioFocusSuccess();
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ResumeSuspendSeekAreSentOnlyOncePerPlayers) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+ EXPECT_EQ(0, player_observer->received_suspend_calls());
+ EXPECT_EQ(0, player_observer->received_resume_calls());
+
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
EXPECT_EQ(0, player_observer->received_suspend_calls());
EXPECT_EQ(0, player_observer->received_resume_calls());
+
+ ResolveAudioFocusSuccess();
+
+ EXPECT_EQ(0, player_observer->received_suspend_calls());
+ EXPECT_EQ(0, player_observer->received_resume_calls());
EXPECT_EQ(0, player_observer->received_seek_forward_calls());
EXPECT_EQ(0, player_observer->received_seek_backward_calls());
@@ -504,14 +625,22 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(3, player_observer->received_seek_backward_calls());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ResumeSuspendSeekAreSentOnlyOncePerPlayersAddedTwice) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+ EXPECT_EQ(0, player_observer->received_suspend_calls());
+ EXPECT_EQ(0, player_observer->received_resume_calls());
+
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_EQ(0, player_observer->received_suspend_calls());
+ EXPECT_EQ(0, player_observer->received_resume_calls());
+
+ ResolveAudioFocusSuccess();
+
// Adding the three players above again.
EXPECT_TRUE(
AddPlayer(player_observer.get(), 0, media::MediaContentType::Persistent));
@@ -538,33 +667,38 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(3, player_observer->received_seek_backward_calls());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
RemovingTheSamePlayerTwiceIsANoop) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
RemovePlayer(player_observer.get(), 0);
RemovePlayer(player_observer.get(), 0);
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, AudioFocusType) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, AudioFocusType) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
// Starting a player with a given type should set the session to that type.
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+ ResolveAudioFocusSuccess();
EXPECT_EQ(AudioFocusType::kGainTransientMayDuck, GetSessionAudioFocusType());
// Adding a player of the same type should have no effect on the type.
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+ EXPECT_FALSE(HasUnresolvedAudioFocusRequest());
EXPECT_EQ(AudioFocusType::kGainTransientMayDuck, GetSessionAudioFocusType());
// Adding a player of Content type should override the current type.
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
EXPECT_EQ(AudioFocusType::kGain, GetSessionAudioFocusType());
// Adding a player of the Transient type should have no effect on the type.
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+ EXPECT_FALSE(HasUnresolvedAudioFocusRequest());
EXPECT_EQ(AudioFocusType::kGain, GetSessionAudioFocusType());
EXPECT_TRUE(player_observer->IsPlaying(0));
@@ -591,7 +725,8 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, AudioFocusType) {
EXPECT_EQ(AudioFocusType::kGain, GetSessionAudioFocusType());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ControlsShowForContent) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ ControlsShowForContent) {
EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -599,12 +734,13 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ControlsShowForContent) {
// Starting a player with a content type should show the media controls.
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
EXPECT_TRUE(IsControllable());
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsNoShowForTransient) {
EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(false, false));
@@ -613,12 +749,14 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
// Starting a player with a transient type should not show the media controls.
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+ ResolveAudioFocusSuccess();
EXPECT_FALSE(IsControllable());
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ControlsHideWhenStopped) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ ControlsHideWhenStopped) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
EXPECT_CALL(*mock_media_session_observer(),
@@ -628,6 +766,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ControlsHideWhenStopped) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
RemovePlayers(player_observer.get());
@@ -635,7 +774,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ControlsHideWhenStopped) {
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsShownAcceptTransient) {
EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -643,6 +782,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
// Transient player join the session without affecting the controls.
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
@@ -651,7 +791,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsShownAfterContentAdded) {
Expectation dontShowControls = EXPECT_CALL(
*mock_media_session_observer(), MediaSessionStateChanged(false, false));
@@ -662,15 +802,17 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+ ResolveAudioFocusSuccess();
// The controls are shown when the content player is added.
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
EXPECT_TRUE(IsControllable());
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsStayIfOnlyOnePlayerHasBeenPaused) {
EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -678,6 +820,8 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
+
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
// Removing only content player doesn't hide the controls since the session
@@ -688,7 +832,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsHideWhenTheLastPlayerIsRemoved) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -700,6 +844,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
RemovePlayer(player_observer.get(), 0);
@@ -712,7 +857,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsHideWhenAllThePlayersAreRemoved) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -724,6 +869,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
RemovePlayers(player_observer.get());
@@ -731,7 +877,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsNotHideWhenTheLastPlayerIsPaused) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -743,6 +889,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
OnPlayerPaused(player_observer.get(), 0);
@@ -755,7 +902,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
SuspendTemporaryUpdatesControls) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -766,6 +913,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
@@ -773,7 +921,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsUpdatedWhenResumed) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -787,6 +935,8 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
+
SystemSuspend(true);
SystemResume();
@@ -794,7 +944,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsHideWhenSessionSuspendedPermanently) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -805,6 +955,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(false);
@@ -812,8 +963,8 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
- ConstrolsHideWhenSessionStops) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ ControlsHideWhenSessionStops) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
Expectation pauseControls = EXPECT_CALL(*mock_media_session_observer(),
@@ -826,14 +977,15 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
- media_session_->Stop(MediaSession::SuspendType::UI);
+ media_session_->Stop(MediaSession::SuspendType::kUI);
EXPECT_FALSE(IsControllable());
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsHideWhenSessionChangesFromContentToTransient) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -847,17 +999,19 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
// This should reset the session and change it to a transient, so
// hide the controls.
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+ ResolveAudioFocusSuccess();
EXPECT_FALSE(IsControllable());
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsUpdatedWhenNewPlayerResetsSession) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -871,16 +1025,18 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
// This should reset the session and update the controls.
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
EXPECT_TRUE(IsControllable());
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsResumedWhenPlayerIsResumed) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -894,16 +1050,18 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
// This should resume the session and update the controls.
AddPlayer(player_observer.get(), 0, media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
EXPECT_TRUE(IsControllable());
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsUpdatedDueToResumeSessionAction) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -914,13 +1072,14 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
UISuspend();
EXPECT_TRUE(IsControllable());
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsUpdatedDueToSuspendSessionAction) {
Expectation showControls = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(true, false));
@@ -934,14 +1093,19 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
UISuspend();
+
UIResume();
+ EXPECT_TRUE(IsControllable());
+ EXPECT_TRUE(IsActive());
+ ResolveAudioFocusSuccess();
EXPECT_TRUE(IsControllable());
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsDontShowWhenOneShotIsPresent) {
EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(false, false));
@@ -949,6 +1113,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
+ ResolveAudioFocusSuccess();
EXPECT_FALSE(IsControllable());
EXPECT_TRUE(IsActive());
@@ -962,7 +1127,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsHiddenAfterRemoveOneShotWithoutOtherPlayers) {
Expectation expect_1 = EXPECT_CALL(*mock_media_session_observer(),
MediaSessionStateChanged(false, false));
@@ -976,13 +1141,14 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
+ ResolveAudioFocusSuccess();
RemovePlayer(player_observer.get(), 0);
EXPECT_FALSE(IsControllable());
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ControlsShowAfterRemoveOneShotWithPersistentPresent) {
Expectation uncontrollable = EXPECT_CALL(
*mock_media_session_observer(), MediaSessionStateChanged(false, false));
@@ -996,6 +1162,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
RemovePlayer(player_observer.get(), 0);
@@ -1003,13 +1170,14 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
DontSuspendWhenOneShotIsPresent) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(false);
@@ -1019,11 +1187,12 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(0, player_observer->received_suspend_calls());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
DontResumeBySystemUISuspendedSessions) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
UISuspend();
EXPECT_TRUE(IsControllable());
@@ -1034,80 +1203,103 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_FALSE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
AllowUIResumeForSystemSuspend) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
EXPECT_TRUE(IsControllable());
EXPECT_FALSE(IsActive());
UIResume();
+ ResolveAudioFocusSuccess();
+
EXPECT_TRUE(IsControllable());
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumeSuspendFromUI) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, ResumeSuspendFromUI) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
UISuspend();
EXPECT_TRUE(IsControllable());
EXPECT_FALSE(IsActive());
UIResume();
+ EXPECT_TRUE(IsActive());
+
+ ResolveAudioFocusSuccess();
EXPECT_TRUE(IsControllable());
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, ResumeSuspendFromSystem) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ ResumeSuspendFromSystem) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
EXPECT_TRUE(IsControllable());
EXPECT_FALSE(IsActive());
SystemResume();
+ EXPECT_FALSE(HasUnresolvedAudioFocusRequest());
EXPECT_TRUE(IsControllable());
EXPECT_TRUE(IsActive());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, OneShotTakesGainFocus) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ OneShotTakesGainFocus) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
+ ResolveAudioFocusSuccess();
+
StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+ EXPECT_FALSE(HasUnresolvedAudioFocusRequest());
+
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_FALSE(HasUnresolvedAudioFocusRequest());
EXPECT_EQ(AudioFocusType::kGain,
mock_audio_focus_delegate()->GetCurrentFocusType());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, RemovingOneShotDropsFocus) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ RemovingOneShotDropsFocus) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
EXPECT_CALL(*mock_audio_focus_delegate(), AbandonAudioFocus());
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
+ ResolveAudioFocusSuccess();
+
RemovePlayer(player_observer.get(), 0);
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
RemovingOneShotWhileStillHavingOtherPlayersKeepsFocus) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
EXPECT_CALL(*mock_audio_focus_delegate(), AbandonAudioFocus())
.Times(1); // Called in TearDown
StartNewPlayer(player_observer.get(), media::MediaContentType::OneShot);
+ ResolveAudioFocusSuccess();
+
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_FALSE(HasUnresolvedAudioFocusRequest());
+
RemovePlayer(player_observer.get(), 0);
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ActualPlaybackStateWhilePlayerPaused) {
EnsureMediaSessionService();
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
@@ -1131,6 +1323,8 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
.InSequence(s);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
+
OnPlayerPaused(player_observer.get(), 0);
SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PLAYING);
SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PAUSED);
@@ -1141,7 +1335,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
::testing::Mock::VerifyAndClear(mock_media_session_observer());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ActualPlaybackStateWhilePlayerPlaying) {
EnsureMediaSessionService();
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
@@ -1161,6 +1355,8 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
.InSequence(s);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
+
SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PLAYING);
SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PAUSED);
SetPlaybackState(blink::mojom::MediaSessionPlaybackState::NONE);
@@ -1170,7 +1366,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
::testing::Mock::VerifyAndClear(mock_media_session_observer());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
ActualPlaybackStateWhilePlayerRemoved) {
EnsureMediaSessionService();
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
@@ -1185,6 +1381,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
.InSequence(s);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
RemovePlayer(player_observer.get(), 0);
SetPlaybackState(blink::mojom::MediaSessionPlaybackState::PLAYING);
@@ -1196,12 +1393,13 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
::testing::Mock::VerifyAndClear(mock_media_session_observer());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
UMA_Suspended_SystemTransient) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
std::unique_ptr<base::HistogramSamples> samples(
@@ -1212,12 +1410,13 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(0, samples->GetCount(2)); // UI
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
UMA_Suspended_SystemPermantent) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
SystemSuspend(false);
std::unique_ptr<base::HistogramSamples> samples(
@@ -1228,12 +1427,13 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(0, samples->GetCount(2)); // UI
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_UI) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, UMA_Suspended_UI) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
UISuspend();
std::unique_ptr<base::HistogramSamples> samples(
@@ -1244,20 +1444,24 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_UI) {
EXPECT_EQ(1, samples->GetCount(2)); // UI
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_Multiple) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ UMA_Suspended_Multiple) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
UISuspend();
UIResume();
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
SystemResume();
UISuspend();
UIResume();
+ ResolveAudioFocusSuccess();
SystemSuspend(false);
@@ -1269,16 +1473,19 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_Multiple) {
EXPECT_EQ(2, samples->GetCount(2)); // UI
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_Crossing) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
+ UMA_Suspended_Crossing) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
UISuspend();
SystemSuspend(true);
SystemSuspend(false);
UIResume();
+ ResolveAudioFocusSuccess();
SystemSuspend(true);
SystemSuspend(true);
@@ -1293,12 +1500,13 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_Crossing) {
EXPECT_EQ(1, samples->GetCount(2)); // UI
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_Stop) {
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, UMA_Suspended_Stop) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
- media_session_->Stop(MediaSession::SuspendType::UI);
+ ResolveAudioFocusSuccess();
+ media_session_->Stop(MediaSession::SuspendType::kUI);
std::unique_ptr<base::HistogramSamples> samples(
tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
@@ -1308,7 +1516,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, UMA_Suspended_Stop) {
EXPECT_EQ(1, samples->GetCount(2)); // UI
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
UMA_ActiveTime_NoActivation) {
base::HistogramTester tester;
@@ -1321,7 +1529,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(0, samples->TotalCount());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
UMA_ActiveTime_SimpleActivation) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
@@ -1332,9 +1540,10 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
clock.Advance(base::TimeDelta::FromMilliseconds(1000));
- media_session_->Stop(MediaSession::SuspendType::UI);
+ media_session_->Stop(MediaSession::SuspendType::kUI);
std::unique_ptr<base::HistogramSamples> samples(
tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
@@ -1342,7 +1551,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(1, samples->GetCount(1000));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
UMA_ActiveTime_ActivationWithUISuspension) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
@@ -1353,15 +1562,17 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
clock.Advance(base::TimeDelta::FromMilliseconds(1000));
UISuspend();
clock.Advance(base::TimeDelta::FromMilliseconds(2000));
UIResume();
+ ResolveAudioFocusSuccess();
clock.Advance(base::TimeDelta::FromMilliseconds(1000));
- media_session_->Stop(MediaSession::SuspendType::UI);
+ media_session_->Stop(MediaSession::SuspendType::kUI);
std::unique_ptr<base::HistogramSamples> samples(
tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
@@ -1369,7 +1580,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(1, samples->GetCount(2000));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
UMA_ActiveTime_ActivationWithSystemSuspension) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
@@ -1380,6 +1591,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
clock.Advance(base::TimeDelta::FromMilliseconds(1000));
SystemSuspend(true);
@@ -1388,7 +1600,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
SystemResume();
clock.Advance(base::TimeDelta::FromMilliseconds(1000));
- media_session_->Stop(MediaSession::SuspendType::UI);
+ media_session_->Stop(MediaSession::SuspendType::kUI);
std::unique_ptr<base::HistogramSamples> samples(
tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
@@ -1396,7 +1608,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(1, samples->GetCount(2000));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
UMA_ActiveTime_ActivateSuspendedButNotStopped) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
@@ -1407,6 +1619,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
clock.Advance(base::TimeDelta::FromMilliseconds(500));
SystemSuspend(true);
@@ -1427,7 +1640,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
}
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
UMA_ActiveTime_ActivateSuspendStopTwice) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
@@ -1438,14 +1651,16 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
clock.Advance(base::TimeDelta::FromMilliseconds(500));
SystemSuspend(true);
- media_session_->Stop(MediaSession::SuspendType::UI);
+ media_session_->Stop(MediaSession::SuspendType::kUI);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
clock.Advance(base::TimeDelta::FromMilliseconds(5000));
SystemResume();
- media_session_->Stop(MediaSession::SuspendType::UI);
+ media_session_->Stop(MediaSession::SuspendType::kUI);
std::unique_ptr<base::HistogramSamples> samples(
tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
@@ -1454,7 +1669,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(1, samples->GetCount(5000));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
UMA_ActiveTime_MultipleActivations) {
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
base::HistogramTester tester;
@@ -1465,12 +1680,14 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
media_session_uma_helper->SetClockForTest(&clock);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
clock.Advance(base::TimeDelta::FromMilliseconds(10000));
RemovePlayer(player_observer.get(), 0);
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
clock.Advance(base::TimeDelta::FromMilliseconds(1000));
- media_session_->Stop(MediaSession::SuspendType::UI);
+ media_session_->Stop(MediaSession::SuspendType::kUI);
std::unique_ptr<base::HistogramSamples> samples(
tester.GetHistogramSamplesSinceCreation("Media.Session.ActiveTime"));
@@ -1479,7 +1696,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
EXPECT_EQ(1, samples->GetCount(10000));
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
AddingObserverNotifiesCurrentInformation_EmptyInfo) {
media_session_->RemoveObserver(mock_media_session_observer());
EXPECT_CALL(*mock_media_session_observer(),
@@ -1492,7 +1709,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
media_session_->AddObserver(mock_media_session_observer());
}
-IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
AddingObserverNotifiesCurrentInformation_WithInfo) {
// Set up the service and information.
EnsureMediaSessionService();
@@ -1512,6 +1729,7 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
shell()->web_contents()->GetMainFrame());
StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ ResolveAudioFocusSuccess();
// Check if the expectations are met when the observer is newly added.
media_session_->RemoveObserver(mock_media_session_observer());
@@ -1523,3 +1741,217 @@ IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
MediaSessionActionsChanged(Eq(expectedActions)));
media_session_->AddObserver(mock_media_session_observer());
}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_RequestFailure_Gain) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+ EXPECT_TRUE(player_observer->IsPlaying(1));
+ EXPECT_TRUE(IsActive());
+
+ // The gain request failed so we should suspend the whole session.
+ ResolveAudioFocusFailure();
+ EXPECT_FALSE(player_observer->IsPlaying(0));
+ EXPECT_FALSE(player_observer->IsPlaying(1));
+ EXPECT_FALSE(IsActive());
+
+ ResolveAudioFocusSuccess();
+ EXPECT_FALSE(player_observer->IsPlaying(0));
+ EXPECT_FALSE(player_observer->IsPlaying(1));
+ EXPECT_FALSE(IsActive());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+ Async_RequestFailure_GainTransient) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+ EXPECT_TRUE(player_observer->IsPlaying(1));
+ EXPECT_TRUE(IsActive());
+
+ ResolveAudioFocusSuccess();
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+ EXPECT_TRUE(player_observer->IsPlaying(1));
+ EXPECT_TRUE(IsActive());
+
+ // A transient audio focus failure should only affect transient players.
+ ResolveAudioFocusFailure();
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+ EXPECT_FALSE(player_observer->IsPlaying(1));
+ EXPECT_TRUE(IsActive());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_GainThenTransient) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+ EXPECT_TRUE(player_observer->IsPlaying(1));
+
+ ResolveAudioFocusSuccess();
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+ EXPECT_TRUE(player_observer->IsPlaying(1));
+
+ ResolveAudioFocusSuccess();
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+ EXPECT_TRUE(player_observer->IsPlaying(1));
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_TransientThenGain) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+ EXPECT_TRUE(player_observer->IsPlaying(1));
+
+ ResolveAudioFocusSuccess();
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+ EXPECT_TRUE(player_observer->IsPlaying(1));
+
+ ResolveAudioFocusSuccess();
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+ EXPECT_TRUE(player_observer->IsPlaying(1));
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest,
+ Async_SuspendBeforeResolve) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+
+ SystemSuspend(true);
+ EXPECT_FALSE(player_observer->IsPlaying(0));
+ EXPECT_FALSE(IsActive());
+
+ ResolveAudioFocusSuccess();
+ EXPECT_FALSE(player_observer->IsPlaying(0));
+ EXPECT_FALSE(IsActive());
+
+ SystemResume();
+ EXPECT_TRUE(IsActive());
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_ResumeBeforeResolve) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_TRUE(IsActive());
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+
+ UISuspend();
+ EXPECT_FALSE(IsActive());
+ EXPECT_FALSE(player_observer->IsPlaying(0));
+
+ UIResume();
+ EXPECT_TRUE(IsActive());
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+
+ ResolveAudioFocusSuccess();
+ EXPECT_TRUE(IsActive());
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+
+ ResolveAudioFocusFailure();
+ EXPECT_FALSE(IsActive());
+ EXPECT_FALSE(player_observer->IsPlaying(0));
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_RemoveBeforeResolve) {
+ {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ EXPECT_CALL(*mock_audio_focus_delegate(), AbandonAudioFocus());
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+
+ RemovePlayer(player_observer.get(), 0);
+ }
+
+ ResolveAudioFocusSuccess();
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_StopBeforeResolve) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Transient);
+ ResolveAudioFocusSuccess();
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_TRUE(player_observer->IsPlaying(1));
+
+ media_session_->Stop(MediaSession::SuspendType::kUI);
+ ResolveAudioFocusSuccess();
+
+ EXPECT_FALSE(player_observer->IsPlaying(0));
+ EXPECT_FALSE(player_observer->IsPlaying(1));
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_Unducking_Failure) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_TRUE(IsActive());
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+
+ SystemStartDucking();
+ EXPECT_TRUE(IsDucking());
+
+ ResolveAudioFocusFailure();
+ EXPECT_TRUE(IsDucking());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_Unducking_Inactive) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_TRUE(IsActive());
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+
+ media_session_->Stop(MediaSession::SuspendType::kUI);
+ SystemStartDucking();
+ EXPECT_TRUE(IsDucking());
+
+ ResolveAudioFocusSuccess();
+ EXPECT_TRUE(IsDucking());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_Unducking_Success) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_TRUE(IsActive());
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+
+ SystemStartDucking();
+ EXPECT_TRUE(IsDucking());
+
+ ResolveAudioFocusSuccess();
+ EXPECT_FALSE(IsDucking());
+}
+
+IN_PROC_BROWSER_TEST_F(MediaSessionImplBrowserTest, Async_Unducking_Suspended) {
+ auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>();
+
+ StartNewPlayer(player_observer.get(), media::MediaContentType::Persistent);
+ EXPECT_TRUE(IsActive());
+ EXPECT_TRUE(player_observer->IsPlaying(0));
+
+ UISuspend();
+ SystemStartDucking();
+ EXPECT_TRUE(IsDucking());
+
+ ResolveAudioFocusSuccess();
+ EXPECT_TRUE(IsDucking());
+}
diff --git a/chromium/content/browser/media/session/media_session_impl_uma_unittest.cc b/chromium/content/browser/media/session/media_session_impl_uma_unittest.cc
index 1efa52b4fd1..df1e97b29cf 100644
--- a/chromium/content/browser/media/session/media_session_impl_uma_unittest.cc
+++ b/chromium/content/browser/media/session/media_session_impl_uma_unittest.cc
@@ -96,7 +96,7 @@ class MediaSessionImplUmaTest : public RenderViewHostImplTestHarness {
};
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUISuspend) {
- GetSession()->Suspend(SuspendType::UI);
+ GetSession()->Suspend(SuspendType::kUI);
std::unique_ptr<base::HistogramSamples> samples(
GetHistogramSamplesSinceTestStart("Media.Session.UserAction"));
EXPECT_EQ(1, samples->TotalCount());
@@ -105,22 +105,22 @@ TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUISuspend) {
}
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnSystemSuspend) {
- GetSession()->Suspend(SuspendType::SYSTEM);
+ GetSession()->Suspend(SuspendType::kSystem);
std::unique_ptr<base::HistogramSamples> samples(
GetHistogramSamplesSinceTestStart("Media.Session.UserAction"));
EXPECT_EQ(0, samples->TotalCount());
}
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnContentSuspend) {
- GetSession()->Suspend(SuspendType::CONTENT);
+ GetSession()->Suspend(SuspendType::kContent);
std::unique_ptr<base::HistogramSamples> samples(
GetHistogramSamplesSinceTestStart("Media.Session.UserAction"));
EXPECT_EQ(0, samples->TotalCount());
}
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUIResume) {
- GetSession()->Suspend(SuspendType::SYSTEM);
- GetSession()->Resume(SuspendType::UI);
+ GetSession()->Suspend(SuspendType::kSystem);
+ GetSession()->Resume(SuspendType::kUI);
std::unique_ptr<base::HistogramSamples> samples(
GetHistogramSamplesSinceTestStart("Media.Session.UserAction"));
EXPECT_EQ(1, samples->TotalCount());
@@ -129,8 +129,8 @@ TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUIResume) {
}
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnSystemResume) {
- GetSession()->Suspend(SuspendType::SYSTEM);
- GetSession()->Resume(SuspendType::SYSTEM);
+ GetSession()->Suspend(SuspendType::kSystem);
+ GetSession()->Resume(SuspendType::kSystem);
std::unique_ptr<base::HistogramSamples> samples(
GetHistogramSamplesSinceTestStart("Media.Session.UserAction"));
EXPECT_EQ(0, samples->TotalCount());
@@ -138,15 +138,15 @@ TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnSystemResume) {
// This should never happen but just check this to be safe.
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnContentResume) {
- GetSession()->Suspend(SuspendType::SYSTEM);
- GetSession()->Resume(SuspendType::CONTENT);
+ GetSession()->Suspend(SuspendType::kSystem);
+ GetSession()->Resume(SuspendType::kContent);
std::unique_ptr<base::HistogramSamples> samples(
GetHistogramSamplesSinceTestStart("Media.Session.UserAction"));
EXPECT_EQ(0, samples->TotalCount());
}
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUIStop) {
- GetSession()->Stop(SuspendType::UI);
+ GetSession()->Stop(SuspendType::kUI);
std::unique_ptr<base::HistogramSamples> samples(
GetHistogramSamplesSinceTestStart("Media.Session.UserAction"));
EXPECT_EQ(1, samples->TotalCount());
@@ -156,7 +156,7 @@ TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnUIStop) {
// This should never happen but just check this to be safe.
TEST_F(MediaSessionImplUmaTest, RecordPauseDefaultOnSystemStop) {
- GetSession()->Stop(SuspendType::SYSTEM);
+ GetSession()->Stop(SuspendType::kSystem);
std::unique_ptr<base::HistogramSamples> samples(
GetHistogramSamplesSinceTestStart("Media.Session.UserAction"));
EXPECT_EQ(0, samples->TotalCount());
diff --git a/chromium/content/browser/media/session/media_session_impl_unittest.cc b/chromium/content/browser/media/session/media_session_impl_unittest.cc
new file mode 100644
index 00000000000..12ead50c781
--- /dev/null
+++ b/chromium/content/browser/media/session/media_session_impl_unittest.cc
@@ -0,0 +1,427 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/session/media_session_impl.h"
+
+#include <memory>
+
+#include "base/command_line.h"
+#include "build/build_config.h"
+#include "content/browser/media/session/media_session_player_observer.h"
+#include "content/public/test/mock_render_process_host.h"
+#include "content/public/test/test_browser_context.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_service_manager_context.h"
+#include "content/test/test_web_contents.h"
+#include "media/base/media_content_type.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "services/media_session/public/cpp/switches.h"
+#include "services/media_session/public/cpp/test/audio_focus_test_util.h"
+#include "services/media_session/public/mojom/audio_focus.mojom.h"
+#include "services/media_session/public/mojom/constants.mojom.h"
+#include "services/media_session/public/mojom/media_session.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+namespace content {
+
+using media_session::mojom::AudioFocusType;
+using media_session::mojom::MediaSessionInfo;
+using media_session::mojom::MediaSessionInfoPtr;
+using media_session::test::TestAudioFocusObserver;
+
+namespace {
+
+class MockMediaSessionPlayerObserver : public MediaSessionPlayerObserver {
+ public:
+ void OnSuspend(int player_id) override {}
+ void OnResume(int player_id) override {}
+ void OnSeekForward(int player_id, base::TimeDelta seek_time) override {}
+ void OnSeekBackward(int player_id, base::TimeDelta seek_time) override {}
+ void OnSetVolumeMultiplier(int player_id, double volume_multiplier) override {
+ }
+ RenderFrameHost* render_frame_host() const override { return nullptr; }
+};
+
+class MockMediaSessionMojoObserver
+ : public media_session::mojom::MediaSessionObserver {
+ public:
+ explicit MockMediaSessionMojoObserver(MediaSessionImpl* media_session)
+ : binding_(this) {
+ media_session::mojom::MediaSessionObserverPtr observer;
+ binding_.Bind(mojo::MakeRequest(&observer));
+ media_session->AddObserver(std::move(observer));
+ }
+
+ void MediaSessionInfoChanged(MediaSessionInfoPtr session) override {
+ session_info_ = std::move(session);
+
+ if (wanted_state_.has_value() &&
+ wanted_state_.value() == session_info_->state) {
+ run_loop_.Quit();
+ }
+ }
+
+ void WaitForState(MediaSessionInfo::SessionState wanted_state) {
+ if (session_info_ && session_info_->state == wanted_state)
+ return;
+
+ wanted_state_ = wanted_state;
+ run_loop_.Run();
+ }
+
+ MediaSessionInfoPtr session_info_;
+
+ private:
+ base::Optional<MediaSessionInfo::SessionState> wanted_state_;
+ base::RunLoop run_loop_;
+
+ mojo::Binding<media_session::mojom::MediaSessionObserver> binding_;
+};
+
+class MockAudioFocusDelegate : public AudioFocusDelegate {
+ public:
+ MockAudioFocusDelegate() = default;
+ ~MockAudioFocusDelegate() override = default;
+
+ void AbandonAudioFocus() override {}
+ AudioFocusResult RequestAudioFocus(AudioFocusType type) override {
+ return AudioFocusResult::kSuccess;
+ }
+ base::Optional<AudioFocusType> GetCurrentFocusType() const override {
+ return AudioFocusType::kGain;
+ }
+
+ void MediaSessionInfoChanged(MediaSessionInfoPtr session_info) override {
+ session_info_ = std::move(session_info);
+ }
+
+ MediaSessionInfo::SessionState GetState() const {
+ DCHECK(!session_info_.is_null());
+ return session_info_->state;
+ }
+
+ private:
+ MediaSessionInfoPtr session_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockAudioFocusDelegate);
+};
+
+} // anonymous namespace
+
+class MediaSessionImplTest : public testing::Test {
+ public:
+ MediaSessionImplTest() = default;
+
+ void SetUp() override {
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ media_session::switches::kEnableAudioFocus);
+
+ rph_factory_.reset(new MockRenderProcessHostFactory());
+ RenderProcessHostImpl::set_render_process_host_factory_for_testing(
+ rph_factory_.get());
+ browser_context_.reset(new TestBrowserContext());
+ pepper_observer_.reset(new MockMediaSessionPlayerObserver());
+
+ // Connect to the Media Session service and bind |audio_focus_ptr_| to it.
+ service_manager_context_ = std::make_unique<TestServiceManagerContext>();
+ service_manager::Connector* connector =
+ ServiceManagerConnection::GetForProcess()->GetConnector();
+ connector->BindInterface(media_session::mojom::kServiceName,
+ mojo::MakeRequest(&audio_focus_ptr_));
+ }
+
+ void TearDown() override {
+ service_manager_context_.reset();
+ browser_context_.reset();
+ RenderProcessHostImpl::set_render_process_host_factory_for_testing(nullptr);
+ rph_factory_.reset();
+ }
+
+ void RequestAudioFocus(MediaSessionImpl* session,
+ AudioFocusType audio_focus_type) {
+ session->RequestSystemAudioFocus(audio_focus_type);
+ }
+
+ void AbandonAudioFocus(MediaSessionImpl* session) {
+ session->AbandonSystemAudioFocusIfNeeded();
+ }
+
+ bool GetForceDuck(MediaSessionImpl* session) {
+ return media_session::test::GetMediaSessionInfoSync(session)->force_duck;
+ }
+
+ MediaSessionInfo::SessionState GetState(MediaSessionImpl* session) {
+ return media_session::test::GetMediaSessionInfoSync(session)->state;
+ }
+
+ bool HasMojoObservers(MediaSessionImpl* session) {
+ return !session->mojo_observers_.empty();
+ }
+
+ void FlushForTesting(MediaSessionImpl* session) {
+ session->FlushForTesting();
+ }
+
+ std::unique_ptr<WebContents> CreateWebContents() {
+ return TestWebContents::Create(
+ browser_context_.get(), SiteInstance::Create(browser_context_.get()));
+ }
+
+ std::unique_ptr<TestAudioFocusObserver> CreateAudioFocusObserver() {
+ std::unique_ptr<TestAudioFocusObserver> observer =
+ std::make_unique<TestAudioFocusObserver>();
+
+ media_session::mojom::AudioFocusObserverPtr observer_ptr;
+ observer->BindToMojoRequest(mojo::MakeRequest(&observer_ptr));
+ audio_focus_ptr_->AddObserver(std::move(observer_ptr));
+ audio_focus_ptr_.FlushForTesting();
+
+ return observer;
+ }
+
+ std::unique_ptr<MediaSessionPlayerObserver> pepper_observer_;
+
+ void SetDelegateForTests(MediaSessionImpl* session,
+ AudioFocusDelegate* delegate) {
+ session->SetDelegateForTests(base::WrapUnique(delegate));
+ }
+
+ private:
+ TestBrowserThreadBundle test_browser_thread_bundle_;
+
+ media_session::mojom::AudioFocusManagerPtr audio_focus_ptr_;
+
+ std::unique_ptr<TestServiceManagerContext> service_manager_context_;
+ std::unique_ptr<MockRenderProcessHostFactory> rph_factory_;
+ std::unique_ptr<TestBrowserContext> browser_context_;
+};
+
+TEST_F(MediaSessionImplTest, SessionInfoState) {
+ std::unique_ptr<WebContents> web_contents(CreateWebContents());
+ MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
+ EXPECT_EQ(MediaSessionInfo::SessionState::kInactive, GetState(media_session));
+
+ {
+ MockMediaSessionMojoObserver observer(media_session);
+ RequestAudioFocus(media_session, AudioFocusType::kGain);
+ FlushForTesting(media_session);
+ observer.WaitForState(MediaSessionInfo::SessionState::kActive);
+
+ EXPECT_TRUE(observer.session_info_.Equals(
+ media_session::test::GetMediaSessionInfoSync(media_session)));
+ }
+
+ {
+ MockMediaSessionMojoObserver observer(media_session);
+ media_session->StartDucking();
+ FlushForTesting(media_session);
+ observer.WaitForState(MediaSessionInfo::SessionState::kDucking);
+
+ EXPECT_TRUE(observer.session_info_.Equals(
+ media_session::test::GetMediaSessionInfoSync(media_session)));
+ }
+
+ {
+ MockMediaSessionMojoObserver observer(media_session);
+ media_session->StopDucking();
+ FlushForTesting(media_session);
+ observer.WaitForState(MediaSessionInfo::SessionState::kActive);
+
+ EXPECT_TRUE(observer.session_info_.Equals(
+ media_session::test::GetMediaSessionInfoSync(media_session)));
+ }
+
+ {
+ MockMediaSessionMojoObserver observer(media_session);
+ media_session->Suspend(MediaSession::SuspendType::kSystem);
+ FlushForTesting(media_session);
+ observer.WaitForState(MediaSessionInfo::SessionState::kSuspended);
+
+ EXPECT_TRUE(observer.session_info_.Equals(
+ media_session::test::GetMediaSessionInfoSync(media_session)));
+ }
+
+ {
+ MockMediaSessionMojoObserver observer(media_session);
+ media_session->Resume(MediaSession::SuspendType::kSystem);
+ FlushForTesting(media_session);
+ observer.WaitForState(MediaSessionInfo::SessionState::kActive);
+
+ EXPECT_TRUE(observer.session_info_.Equals(
+ media_session::test::GetMediaSessionInfoSync(media_session)));
+ }
+
+ {
+ MockMediaSessionMojoObserver observer(media_session);
+ AbandonAudioFocus(media_session);
+ FlushForTesting(media_session);
+ observer.WaitForState(MediaSessionInfo::SessionState::kInactive);
+
+ EXPECT_TRUE(observer.session_info_.Equals(
+ media_session::test::GetMediaSessionInfoSync(media_session)));
+ }
+}
+
+TEST_F(MediaSessionImplTest, NotifyDelegateOnStateChange) {
+ std::unique_ptr<WebContents> web_contents(CreateWebContents());
+ MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
+ MockAudioFocusDelegate* delegate = new MockAudioFocusDelegate();
+ SetDelegateForTests(media_session, delegate);
+
+ RequestAudioFocus(media_session, AudioFocusType::kGain);
+ EXPECT_EQ(MediaSessionInfo::SessionState::kActive, delegate->GetState());
+
+ media_session->StartDucking();
+ EXPECT_EQ(MediaSessionInfo::SessionState::kDucking, delegate->GetState());
+
+ media_session->StopDucking();
+ EXPECT_EQ(MediaSessionInfo::SessionState::kActive, delegate->GetState());
+
+ media_session->Suspend(MediaSession::SuspendType::kSystem);
+ EXPECT_EQ(MediaSessionInfo::SessionState::kSuspended, delegate->GetState());
+
+ media_session->Resume(MediaSession::SuspendType::kSystem);
+ EXPECT_EQ(MediaSessionInfo::SessionState::kActive, delegate->GetState());
+
+ AbandonAudioFocus(media_session);
+ EXPECT_EQ(MediaSessionInfo::SessionState::kInactive, delegate->GetState());
+}
+
+TEST_F(MediaSessionImplTest, PepperForcesDuckAndRequestsFocus) {
+ std::unique_ptr<WebContents> web_contents(CreateWebContents());
+ MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
+
+ media_session->AddPlayer(pepper_observer_.get(), 0,
+ media::MediaContentType::Pepper);
+
+ {
+ MockMediaSessionMojoObserver observer(media_session);
+ observer.WaitForState(MediaSessionInfo::SessionState::kActive);
+ }
+
+ EXPECT_TRUE(GetForceDuck(media_session));
+
+ media_session->RemovePlayer(pepper_observer_.get(), 0);
+
+ {
+ MockMediaSessionMojoObserver observer(media_session);
+ observer.WaitForState(MediaSessionInfo::SessionState::kInactive);
+ }
+
+ EXPECT_FALSE(GetForceDuck(media_session));
+}
+
+TEST_F(MediaSessionImplTest, RegisterMojoObserver) {
+ std::unique_ptr<WebContents> web_contents(CreateWebContents());
+ MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
+
+ EXPECT_FALSE(HasMojoObservers(media_session));
+
+ MockMediaSessionMojoObserver observer(media_session);
+ FlushForTesting(media_session);
+
+ EXPECT_TRUE(HasMojoObservers(media_session));
+}
+
+#if !defined(OS_ANDROID)
+
+TEST_F(MediaSessionImplTest, WebContentsDestroyed_ReleasesFocus) {
+ std::unique_ptr<WebContents> web_contents(CreateWebContents());
+ MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
+
+ {
+ std::unique_ptr<TestAudioFocusObserver> observer =
+ CreateAudioFocusObserver();
+ RequestAudioFocus(media_session, AudioFocusType::kGain);
+ observer->WaitForGainedEvent();
+ }
+
+ {
+ MockMediaSessionMojoObserver observer(media_session);
+ observer.WaitForState(MediaSessionInfo::SessionState::kActive);
+ }
+
+ {
+ std::unique_ptr<TestAudioFocusObserver> observer =
+ CreateAudioFocusObserver();
+ web_contents.reset();
+ observer->WaitForLostEvent();
+ }
+}
+
+TEST_F(MediaSessionImplTest, WebContentsDestroyed_ReleasesTransients) {
+ std::unique_ptr<WebContents> web_contents(CreateWebContents());
+ MediaSessionImpl* media_session = MediaSessionImpl::Get(web_contents.get());
+
+ {
+ std::unique_ptr<TestAudioFocusObserver> observer =
+ CreateAudioFocusObserver();
+ RequestAudioFocus(media_session, AudioFocusType::kGainTransientMayDuck);
+ observer->WaitForGainedEvent();
+ }
+
+ {
+ MockMediaSessionMojoObserver observer(media_session);
+ observer.WaitForState(MediaSessionInfo::SessionState::kActive);
+ }
+
+ {
+ std::unique_ptr<TestAudioFocusObserver> observer =
+ CreateAudioFocusObserver();
+ web_contents.reset();
+ observer->WaitForLostEvent();
+ }
+}
+
+TEST_F(MediaSessionImplTest, WebContentsDestroyed_StopsDucking) {
+ std::unique_ptr<WebContents> web_contents_1(CreateWebContents());
+ MediaSessionImpl* media_session_1 =
+ MediaSessionImpl::Get(web_contents_1.get());
+
+ std::unique_ptr<WebContents> web_contents_2(CreateWebContents());
+ MediaSessionImpl* media_session_2 =
+ MediaSessionImpl::Get(web_contents_2.get());
+
+ {
+ std::unique_ptr<TestAudioFocusObserver> observer =
+ CreateAudioFocusObserver();
+ RequestAudioFocus(media_session_1, AudioFocusType::kGain);
+ observer->WaitForGainedEvent();
+ }
+
+ {
+ MockMediaSessionMojoObserver observer(media_session_1);
+ observer.WaitForState(MediaSessionInfo::SessionState::kActive);
+ }
+
+ {
+ std::unique_ptr<TestAudioFocusObserver> observer =
+ CreateAudioFocusObserver();
+ RequestAudioFocus(media_session_2, AudioFocusType::kGainTransientMayDuck);
+ observer->WaitForGainedEvent();
+ }
+
+
+ {
+ MockMediaSessionMojoObserver observer(media_session_1);
+ observer.WaitForState(MediaSessionInfo::SessionState::kDucking);
+ }
+
+ {
+ std::unique_ptr<TestAudioFocusObserver> observer =
+ CreateAudioFocusObserver();
+ web_contents_2.reset();
+ observer->WaitForLostEvent();
+ }
+
+ {
+ MockMediaSessionMojoObserver observer(media_session_1);
+ observer.WaitForState(MediaSessionInfo::SessionState::kActive);
+ }
+}
+
+#endif // !defined(OS_ANDROID)
+
+} // namespace content
diff --git a/chromium/content/browser/media/webaudio/audio_context_manager_browsertest.cc b/chromium/content/browser/media/webaudio/audio_context_manager_browsertest.cc
index 9ab3e351ae6..d01bf8cbbf9 100644
--- a/chromium/content/browser/media/webaudio/audio_context_manager_browsertest.cc
+++ b/chromium/content/browser/media/webaudio/audio_context_manager_browsertest.cc
@@ -2,11 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
+#include "net/dns/mock_host_resolver.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
namespace content {
@@ -51,7 +54,14 @@ class WaitForAudioContextSilent : WebContentsObserver {
} // namespace
-class AudioContextManagerTest : public ContentBrowserTest {};
+class AudioContextManagerTest : public ContentBrowserTest {
+ public:
+ void SetUpOnMainThread() override {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ content::SetupCrossSiteRedirector(embedded_test_server());
+ ASSERT_TRUE(embedded_test_server()->Start());
+ }
+};
IN_PROC_BROWSER_TEST_F(AudioContextManagerTest, AudioContextPlaybackRecorded) {
NavigateToURL(shell(),
@@ -72,4 +82,57 @@ IN_PROC_BROWSER_TEST_F(AudioContextManagerTest, AudioContextPlaybackRecorded) {
}
}
+IN_PROC_BROWSER_TEST_F(AudioContextManagerTest, AudioContextPlaybackTimeUkm) {
+ ukm::TestAutoSetUkmRecorder test_ukm_recorder;
+ using Entry = ukm::builders::Media_WebAudio_AudioContext_AudibleTime;
+
+ GURL url = embedded_test_server()->GetURL(
+ "example.com", "/media/webaudio/playback-test.html");
+ NavigateToURL(shell(), url);
+
+ EXPECT_EQ(0u, test_ukm_recorder.GetEntriesByName(Entry::kEntryName).size());
+
+ // Play/pause something audible, it should lead to new Ukm entry.
+ {
+ ASSERT_TRUE(ExecuteScript(shell()->web_contents(), "gain.gain.value = 1;"));
+ WaitForAudioContextAudible wait_audible(shell()->web_contents());
+
+ ASSERT_TRUE(ExecuteScript(shell()->web_contents(), "gain.gain.value = 0;"));
+ WaitForAudioContextSilent wait_silent(shell()->web_contents());
+ }
+
+ EXPECT_EQ(1u, test_ukm_recorder.GetEntriesByName(Entry::kEntryName).size());
+
+ // Playback must have been recorded.
+ {
+ auto ukm_entries = test_ukm_recorder.GetEntriesByName(Entry::kEntryName);
+
+ ASSERT_EQ(1u, ukm_entries.size());
+ auto* entry = ukm_entries[0];
+
+ // The test doesn't check the URL because not the full Ukm stack is running
+ // in //content.
+
+ EXPECT_TRUE(
+ test_ukm_recorder.EntryHasMetric(entry, Entry::kAudibleTimeName));
+ EXPECT_GE(*test_ukm_recorder.GetEntryMetric(entry, Entry::kAudibleTimeName),
+ 0);
+
+ EXPECT_TRUE(
+ test_ukm_recorder.EntryHasMetric(entry, Entry::kIsMainFrameName));
+ test_ukm_recorder.ExpectEntryMetric(entry, Entry::kIsMainFrameName, true);
+ }
+
+ // Play/pause again and check that there is a new entry.
+ {
+ ASSERT_TRUE(ExecuteScript(shell()->web_contents(), "gain.gain.value = 1;"));
+ WaitForAudioContextAudible wait_audible(shell()->web_contents());
+
+ ASSERT_TRUE(ExecuteScript(shell()->web_contents(), "gain.gain.value = 0;"));
+ WaitForAudioContextSilent wait_silent(shell()->web_contents());
+ }
+
+ EXPECT_EQ(2u, test_ukm_recorder.GetEntriesByName(Entry::kEntryName).size());
+}
+
} // namespace content
diff --git a/chromium/content/browser/media/webaudio/audio_context_manager_impl.cc b/chromium/content/browser/media/webaudio/audio_context_manager_impl.cc
index 889ccb0026a..1ed05d21f0f 100644
--- a/chromium/content/browser/media/webaudio/audio_context_manager_impl.cc
+++ b/chromium/content/browser/media/webaudio/audio_context_manager_impl.cc
@@ -4,14 +4,30 @@
#include "content/browser/media/webaudio/audio_context_manager_impl.h"
+#include "base/time/default_tick_clock.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
namespace content {
+namespace {
+
+// Returns the time in milleseconds following these rules:
+// - if the time is below 10 seconds, return the raw value;
+// - otherwise, return the value rounded to the closes second.
+int64_t GetBucketedTimeInMilliseconds(const base::TimeDelta& time) {
+ if (time.InMilliseconds() < 10 * base::Time::kMillisecondsPerSecond)
+ return time.InMilliseconds();
+ return time.InSeconds() * base::Time::kMillisecondsPerSecond;
+}
+
+} // namespace
+
void AudioContextManagerImpl::Create(
RenderFrameHost* render_frame_host,
blink::mojom::AudioContextManagerRequest request) {
@@ -27,24 +43,56 @@ AudioContextManagerImpl::AudioContextManagerImpl(
blink::mojom::AudioContextManagerRequest request)
: FrameServiceBase(render_frame_host, std::move(request)),
render_frame_host_impl_(
- static_cast<RenderFrameHostImpl*>(render_frame_host)) {
+ static_cast<RenderFrameHostImpl*>(render_frame_host)),
+ clock_(base::DefaultTickClock::GetInstance()) {
DCHECK(render_frame_host);
}
-AudioContextManagerImpl::~AudioContextManagerImpl() = default;
+AudioContextManagerImpl::~AudioContextManagerImpl() {
+ // Takes care pending "audible start" times.
+ base::TimeTicks now = clock_->NowTicks();
+ for (const auto& entry : pending_audible_durations_) {
+ if (!entry.second.is_null())
+ RecordAudibleTime(now - entry.second);
+ }
+ pending_audible_durations_.clear();
+}
void AudioContextManagerImpl::AudioContextAudiblePlaybackStarted(
int32_t audio_context_id) {
- // Notify observers that audible audio started playing from a WebAudio
- // AudioContext.
+ DCHECK(pending_audible_durations_[audio_context_id].is_null());
+
+ // Keeps track of the start audible time for this context.
+ pending_audible_durations_[audio_context_id] = clock_->NowTicks();
+
render_frame_host_impl_->AudioContextPlaybackStarted(audio_context_id);
}
void AudioContextManagerImpl::AudioContextAudiblePlaybackStopped(
int32_t audio_context_id) {
- // Notify observers that audible audio stopped playing from a WebAudio
- // AudioContext.
+ base::TimeTicks then = pending_audible_durations_[audio_context_id];
+ DCHECK(!then.is_null());
+
+ RecordAudibleTime(clock_->NowTicks() - then);
+
+ // Resets the context slot because the context is not audible.
+ pending_audible_durations_[audio_context_id] = base::TimeTicks();
+
render_frame_host_impl_->AudioContextPlaybackStopped(audio_context_id);
}
+void AudioContextManagerImpl::RecordAudibleTime(base::TimeDelta audible_time) {
+ DCHECK(!audible_time.is_zero());
+
+ ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
+ DCHECK(ukm_recorder);
+
+ ukm::builders::Media_WebAudio_AudioContext_AudibleTime(
+ static_cast<WebContentsImpl*>(web_contents())
+ ->GetUkmSourceIdForLastCommittedSource())
+ .SetIsMainFrame(web_contents()->GetMainFrame() == render_frame_host_impl_)
+ .SetAudibleTime(GetBucketedTimeInMilliseconds(audible_time))
+ .Record(ukm_recorder);
+}
+
} // namespace content
diff --git a/chromium/content/browser/media/webaudio/audio_context_manager_impl.h b/chromium/content/browser/media/webaudio/audio_context_manager_impl.h
index 06d1c6b4220..0df4d2d6c07 100644
--- a/chromium/content/browser/media/webaudio/audio_context_manager_impl.h
+++ b/chromium/content/browser/media/webaudio/audio_context_manager_impl.h
@@ -17,7 +17,10 @@ class RenderFrameHostImpl;
// Implements the mojo interface between WebAudio and the browser so that
// WebAudio can report when audible sounds from an AudioContext starts and
-// stops.
+// stops. A manager instance can be associated with multiple AudioContexts.
+//
+// We do not expect to see more than 3~4 AudioContexts per render frame, so
+// handling multiple contexts would not be a significant bottle neck.
class CONTENT_EXPORT AudioContextManagerImpl final
: public content::FrameServiceBase<blink::mojom::AudioContextManager> {
public:
@@ -29,13 +32,28 @@ class CONTENT_EXPORT AudioContextManagerImpl final
static void Create(RenderFrameHost* render_frame_host,
blink::mojom::AudioContextManagerRequest request);
- // Called when AudioContext starts or stops playing audible audio.
+ // Notify observers that audible audio started/stopped playing from an
+ // AudioContext.
void AudioContextAudiblePlaybackStarted(int32_t audio_context_id) final;
void AudioContextAudiblePlaybackStopped(int32_t audio_context_id) final;
+ void set_clock_for_testing(base::TickClock* clock) { clock_ = clock; }
+
private:
+ // Send measured audible duration to UKM database.
+ void RecordAudibleTime(base::TimeDelta);
+
RenderFrameHostImpl* const render_frame_host_impl_;
+ // To track pending audible time. Stores ID of AudioContext (int32_t) and
+ // the start time of audible period (base::TimeTicks).
+ base::flat_map<int32_t, base::TimeTicks> pending_audible_durations_;
+
+ // Clock used to calculate time between start and stop event. Can be override
+ // by tests.
+ // It is not owned by the implementation.
+ const base::TickClock* clock_;
+
DISALLOW_COPY_AND_ASSIGN(AudioContextManagerImpl);
};
diff --git a/chromium/content/browser/media/webaudio/audio_context_manager_impl_unittest.cc b/chromium/content/browser/media/webaudio/audio_context_manager_impl_unittest.cc
new file mode 100644
index 00000000000..0d229d84101
--- /dev/null
+++ b/chromium/content/browser/media/webaudio/audio_context_manager_impl_unittest.cc
@@ -0,0 +1,102 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/webaudio/audio_context_manager_impl.h"
+
+#include "base/test/simple_test_tick_clock.h"
+#include "components/ukm/test_ukm_recorder.h"
+#include "content/public/test/test_renderer_host.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+
+namespace content {
+
+class AudioContextManagerImplTest : public RenderViewHostTestHarness {
+ public:
+ using UkmEntry = ukm::builders::Media_WebAudio_AudioContext_AudibleTime;
+
+ void SetUp() override {
+ RenderViewHostTestHarness::SetUp();
+
+ clock_.SetNowTicks(base::TimeTicks::Now());
+
+ blink::mojom::AudioContextManagerPtr service_ptr;
+ audio_context_manager_ = new AudioContextManagerImpl(
+ main_rfh(), mojo::MakeRequest(&service_ptr));
+ audio_context_manager_->set_clock_for_testing(&clock_);
+ }
+
+ AudioContextManagerImpl* audio_context_manager() {
+ return audio_context_manager_;
+ }
+
+ const ukm::TestAutoSetUkmRecorder& test_ukm_recorder() const {
+ return test_ukm_recorder_;
+ }
+
+ base::SimpleTestTickClock& clock() { return clock_; }
+
+ private:
+ AudioContextManagerImpl* audio_context_manager_ = nullptr;
+ ukm::TestAutoSetUkmRecorder test_ukm_recorder_;
+ base::SimpleTestTickClock clock_;
+};
+
+TEST_F(AudioContextManagerImplTest, TimeBelow10SecondsIsRaw) {
+ // Entry for 42 milliseconds.
+ audio_context_manager()->AudioContextAudiblePlaybackStarted(0);
+ clock().Advance(base::TimeDelta::FromMilliseconds(42));
+ audio_context_manager()->AudioContextAudiblePlaybackStopped(0);
+
+ // Entry for 4242 milliseconds.
+ audio_context_manager()->AudioContextAudiblePlaybackStarted(0);
+ clock().Advance(base::TimeDelta::FromMilliseconds(4242));
+ audio_context_manager()->AudioContextAudiblePlaybackStopped(0);
+
+ // Entry for 9999 milliseconds.
+ audio_context_manager()->AudioContextAudiblePlaybackStarted(0);
+ clock().Advance(base::TimeDelta::FromMilliseconds(9999));
+ audio_context_manager()->AudioContextAudiblePlaybackStopped(0);
+
+ auto ukm_entries = test_ukm_recorder().GetEntriesByName(UkmEntry::kEntryName);
+ EXPECT_EQ(3u, ukm_entries.size());
+
+ const std::vector<int> expected = {42, 4242, 9999};
+ for (size_t i = 0; i < expected.size(); ++i) {
+ EXPECT_EQ(expected[i], *test_ukm_recorder().GetEntryMetric(
+ ukm_entries[i], UkmEntry::kAudibleTimeName));
+ }
+}
+
+TEST_F(AudioContextManagerImplTest, TimeGreater10SecondsIsRoundedDown) {
+ // Entry for 42 seconds.
+ audio_context_manager()->AudioContextAudiblePlaybackStarted(0);
+ clock().Advance(base::TimeDelta::FromSeconds(42));
+ audio_context_manager()->AudioContextAudiblePlaybackStopped(0);
+
+ // Entry for 42.42 seconds.
+ audio_context_manager()->AudioContextAudiblePlaybackStarted(0);
+ clock().Advance(base::TimeDelta::FromSecondsD(42.42));
+ audio_context_manager()->AudioContextAudiblePlaybackStopped(0);
+
+ // Entry for 10.01 seconds.
+ audio_context_manager()->AudioContextAudiblePlaybackStarted(0);
+ clock().Advance(base::TimeDelta::FromSecondsD(10.01));
+ audio_context_manager()->AudioContextAudiblePlaybackStopped(0);
+
+ // Entry for 10.99 seconds.
+ audio_context_manager()->AudioContextAudiblePlaybackStarted(0);
+ clock().Advance(base::TimeDelta::FromSecondsD(10.99));
+ audio_context_manager()->AudioContextAudiblePlaybackStopped(0);
+
+ auto ukm_entries = test_ukm_recorder().GetEntriesByName(UkmEntry::kEntryName);
+ EXPECT_EQ(4u, ukm_entries.size());
+
+ const std::vector<int> expected = {42000, 42000, 10000, 10000};
+ for (size_t i = 0; i < expected.size(); ++i) {
+ EXPECT_EQ(expected[i], *test_ukm_recorder().GetEntryMetric(
+ ukm_entries[i], UkmEntry::kAudibleTimeName));
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/browser/memory/memory_coordinator_impl_browsertest.cc b/chromium/content/browser/memory/memory_coordinator_impl_browsertest.cc
index 3a84581863b..730dae4272c 100644
--- a/chromium/content/browser/memory/memory_coordinator_impl_browsertest.cc
+++ b/chromium/content/browser/memory/memory_coordinator_impl_browsertest.cc
@@ -4,10 +4,12 @@
#include "content/browser/memory/memory_coordinator_impl.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/common/content_features.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
@@ -45,8 +47,8 @@ IN_PROC_BROWSER_TEST_F(MemoryCoordinatorImplBrowserTest, HandleAdded) {
// Query the GPU process ID from the IO thread.
int gpu_process_id = -1;
base::WaitableEvent io_event;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&GetGpuProcessIDOnIO, &gpu_process_id, &io_event));
io_event.Wait();
ASSERT_NE(gpu_process_id, -1);
diff --git a/chromium/content/browser/memory/memory_monitor_android.cc b/chromium/content/browser/memory/memory_monitor_android.cc
index 64ddf5ba53d..4125dff458a 100644
--- a/chromium/content/browser/memory/memory_monitor_android.cc
+++ b/chromium/content/browser/memory/memory_monitor_android.cc
@@ -5,8 +5,8 @@
#include "content/browser/memory/memory_monitor_android.h"
#include "base/android/jni_android.h"
+#include "base/memory/memory_pressure_listener.h"
#include "base/memory/ptr_util.h"
-#include "content/browser/memory/memory_coordinator_impl.h"
#include "jni/MemoryMonitorAndroid_jni.h"
namespace content {
@@ -69,12 +69,10 @@ static void JNI_MemoryMonitorAndroid_OnTrimMemory(
const base::android::JavaParamRef<jclass>& jcaller,
jint level) {
DCHECK(level >= 0 && level <= kTrimMemoryLevelMax);
- auto* coordinator = MemoryCoordinatorImpl::GetInstance();
- DCHECK(coordinator);
if (level >= kTrimMemoryRunningCritical) {
- coordinator->ForceSetMemoryCondition(MemoryCondition::CRITICAL,
- base::TimeDelta::FromMinutes(1));
+ base::MemoryPressureListener::NotifyMemoryPressure(
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
}
}
@@ -88,10 +86,6 @@ MemoryMonitorAndroid::MemoryMonitorAndroid(std::unique_ptr<Delegate> delegate)
: delegate_(std::move(delegate)) {
DCHECK(delegate_.get());
RegisterComponentCallbacks();
- application_state_listener_ =
- std::make_unique<base::android::ApplicationStatusListener>(
- base::Bind(&MemoryMonitorAndroid::OnApplicationStateChange,
- base::Unretained(this)));
}
MemoryMonitorAndroid::~MemoryMonitorAndroid() {}
@@ -106,19 +100,6 @@ void MemoryMonitorAndroid::GetMemoryInfo(MemoryInfo* out) {
delegate_->GetMemoryInfo(out);
}
-void MemoryMonitorAndroid::OnApplicationStateChange(
- base::android::ApplicationState state) {
- auto* coordinator = MemoryCoordinatorImpl::GetInstance();
- if (!coordinator)
- return;
-
- if (state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
- coordinator->OnForegrounded();
- } else if (state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES) {
- coordinator->OnBackgrounded();
- }
-}
-
// Implementation of a factory function defined in memory_monitor.h.
std::unique_ptr<MemoryMonitor> CreateMemoryMonitor() {
return MemoryMonitorAndroid::Create();
diff --git a/chromium/content/browser/memory/memory_monitor_android.h b/chromium/content/browser/memory/memory_monitor_android.h
index 7f06897a6d9..2e123672e6a 100644
--- a/chromium/content/browser/memory/memory_monitor_android.h
+++ b/chromium/content/browser/memory/memory_monitor_android.h
@@ -47,11 +47,7 @@ class CONTENT_EXPORT MemoryMonitorAndroid : public MemoryMonitor {
Delegate* delegate() { return delegate_.get(); }
private:
- void OnApplicationStateChange(base::android::ApplicationState state);
-
std::unique_ptr<Delegate> delegate_;
- std::unique_ptr<base::android::ApplicationStatusListener>
- application_state_listener_;
DISALLOW_COPY_AND_ASSIGN(MemoryMonitorAndroid);
};
diff --git a/chromium/content/browser/memory/memory_monitor_win.cc b/chromium/content/browser/memory/memory_monitor_win.cc
index bf336c16ee2..979bb287ae7 100644
--- a/chromium/content/browser/memory/memory_monitor_win.cc
+++ b/chromium/content/browser/memory/memory_monitor_win.cc
@@ -15,10 +15,6 @@ namespace {
const int kKBperMB = 1024;
-// A global static instance of the default delegate. Used by default by
-// MemoryMonitorWin.
-MemoryMonitorDelegate g_memory_monitor_win_delegate;
-
} // namespace
// A system is considered 'large memory' if it has more than 1.5GB of system
@@ -73,7 +69,7 @@ int MemoryMonitorWin::GetTargetFreeMB(MemoryMonitorDelegate* delegate) {
// Implementation of factory function defined in memory_monitor.h.
std::unique_ptr<MemoryMonitor> CreateMemoryMonitor() {
- return MemoryMonitorWin::Create(&g_memory_monitor_win_delegate);
+ return MemoryMonitorWin::Create(MemoryMonitorDelegate::GetInstance());
}
} // namespace content
diff --git a/chromium/content/browser/message_port_provider.cc b/chromium/content/browser/message_port_provider.cc
index e5d8f6681d5..70893810d98 100644
--- a/chromium/content/browser/message_port_provider.cc
+++ b/chromium/content/browser/message_port_provider.cc
@@ -9,7 +9,7 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
#include "content/public/browser/browser_thread.h"
-#include "third_party/blink/public/common/message_port/string_message_codec.h"
+#include "third_party/blink/public/common/messaging/string_message_codec.h"
#if defined(OS_ANDROID)
#include "base/android/jni_string.h"
diff --git a/chromium/content/browser/mojo_sandbox_browsertest.cc b/chromium/content/browser/mojo_sandbox_browsertest.cc
index 89168cc96c9..05cbca2b0cb 100644
--- a/chromium/content/browser/mojo_sandbox_browsertest.cc
+++ b/chromium/content/browser/mojo_sandbox_browsertest.cc
@@ -9,8 +9,10 @@
#include "base/bind.h"
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "content/browser/utility_process_host.h"
#include "content/browser/utility_process_host_client.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/bind_interface_helpers.h"
#include "content/public/test/content_browser_test.h"
@@ -28,8 +30,8 @@ class MojoSandboxTest : public ContentBrowserTest {
void SetUpOnMainThread() override {
base::RunLoop run_loop;
- BrowserThread::PostTaskAndReply(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&MojoSandboxTest::StartUtilityProcessOnIoThread,
base::Unretained(this)),
run_loop.QuitClosure());
@@ -38,8 +40,8 @@ class MojoSandboxTest : public ContentBrowserTest {
void TearDownOnMainThread() override {
base::RunLoop run_loop;
- BrowserThread::PostTaskAndReply(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&MojoSandboxTest::StopUtilityProcessOnIoThread,
base::Unretained(this)),
run_loop.QuitClosure());
diff --git a/chromium/content/browser/browser_side_navigation_browsertest.cc b/chromium/content/browser/navigation_browsertest.cc
index 852370df647..64be3e158be 100644
--- a/chromium/content/browser/browser_side_navigation_browsertest.cc
+++ b/chromium/content/browser/navigation_browsertest.cc
@@ -8,6 +8,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/child_process_security_policy_impl.h"
@@ -16,7 +17,10 @@
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
+#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_manager_delegate.h"
#include "content/public/browser/navigation_controller.h"
@@ -136,33 +140,52 @@ class NavigationRecorder : public WebContentsObserver {
std::vector<std::string> records_;
};
+// Used to wait for an observed IPC to be received.
+class BrowserMessageObserver : public content::BrowserMessageFilter {
+ public:
+ BrowserMessageObserver(uint32_t observed_message_class,
+ uint32_t observed_message_type)
+ : content::BrowserMessageFilter(observed_message_class),
+ observed_message_type_(observed_message_type) {}
+
+ bool OnMessageReceived(const IPC::Message& message) override {
+ if (message.type() == observed_message_type_)
+ loop.Quit();
+ return false;
+ }
+
+ void Wait() { loop.Run(); }
+
+ private:
+ ~BrowserMessageObserver() override {}
+ uint32_t observed_message_type_;
+ base::RunLoop loop;
+ DISALLOW_COPY_AND_ASSIGN(BrowserMessageObserver);
+};
+
} // namespace
-// Test with BrowserSideNavigation enabled (aka PlzNavigate).
+// Test about navigation.
// If you don't need a custom embedded test server, please use the next class
-// below (BrowserSideNavigationBrowserTest), it will automatically start the
+// below (NavigationBrowserTest), it will automatically start the
// default server.
-// TODO(clamy): Rename those NavigationBrowserTests.
-class BrowserSideNavigationBaseBrowserTest : public ContentBrowserTest {
+class NavigationBaseBrowserTest : public ContentBrowserTest {
protected:
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
}
};
-class BrowserSideNavigationBrowserTest
- : public BrowserSideNavigationBaseBrowserTest {
+class NavigationBrowserTest : public NavigationBaseBrowserTest {
protected:
void SetUpOnMainThread() override {
- BrowserSideNavigationBaseBrowserTest::SetUpOnMainThread();
+ NavigationBaseBrowserTest::SetUpOnMainThread();
ASSERT_TRUE(embedded_test_server()->Start());
}
};
-// Ensure that browser initiated basic navigations work with browser side
-// navigation.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
- BrowserInitiatedNavigations) {
+// Ensure that browser initiated basic navigations work.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, BrowserInitiatedNavigations) {
// Perform a navigation with no live renderer.
{
TestNavigationObserver observer(shell()->web_contents());
@@ -174,7 +197,9 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
RenderFrameHost* initial_rfh =
static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()->root()->current_frame_host();
+ ->GetFrameTree()
+ ->root()
+ ->current_frame_host();
// Perform a same site navigation.
{
@@ -187,7 +212,9 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
// The RenderFrameHost should not have changed.
EXPECT_EQ(initial_rfh, static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()->root()->current_frame_host());
+ ->GetFrameTree()
+ ->root()
+ ->current_frame_host());
// Perform a cross-site navigation.
{
@@ -200,12 +227,13 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
// The RenderFrameHost should have changed.
EXPECT_NE(initial_rfh, static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()->root()->current_frame_host());
+ ->GetFrameTree()
+ ->root()
+ ->current_frame_host());
}
-// Ensure that renderer initiated same-site navigations work with browser side
-// navigation.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+// Ensure that renderer initiated same-site navigations work.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
RendererInitiatedSameSiteNavigation) {
// Perform a navigation with no live renderer.
{
@@ -218,7 +246,9 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
RenderFrameHost* initial_rfh =
static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()->root()->current_frame_host();
+ ->GetFrameTree()
+ ->root()
+ ->current_frame_host();
// Simulate clicking on a same-site link.
{
@@ -236,12 +266,13 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
// The RenderFrameHost should not have changed.
EXPECT_EQ(initial_rfh, static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()->root()->current_frame_host());
+ ->GetFrameTree()
+ ->root()
+ ->current_frame_host());
}
-// Ensure that renderer initiated cross-site navigations work with browser side
-// navigation.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+// Ensure that renderer initiated cross-site navigations work.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
RendererInitiatedCrossSiteNavigation) {
// Perform a navigation with no live renderer.
{
@@ -254,13 +285,15 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
RenderFrameHost* initial_rfh =
static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()->root()->current_frame_host();
+ ->GetFrameTree()
+ ->root()
+ ->current_frame_host();
// Simulate clicking on a cross-site link.
{
TestNavigationObserver observer(shell()->web_contents());
const char kReplacePortNumber[] =
- "window.domAutomationController.send(setPortNumber(%d));";
+ "window.domAutomationController.send(setPortNumber(%d));";
uint16_t port_number = embedded_test_server()->port();
GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html");
bool success = false;
@@ -294,8 +327,8 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
}
}
-// Ensure that browser side navigation handles navigation failures.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest, FailedNavigation) {
+// Ensure navigation failures are handled.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, FailedNavigation) {
// Perform a navigation with no live renderer.
{
TestNavigationObserver observer(shell()->web_contents());
@@ -309,8 +342,8 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest, FailedNavigation) {
{
TestNavigationObserver observer(shell()->web_contents());
GURL error_url(embedded_test_server()->GetURL("/close-socket"));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&net::URLRequestFailedJob::AddUrlHandler));
NavigateToURL(shell(), error_url);
EXPECT_EQ(error_url, observer.last_navigation_url());
@@ -320,9 +353,8 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest, FailedNavigation) {
}
}
-// Ensure that browser side navigation can load browser initiated navigations
-// to view-source URLs.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+// Ensure that browser initiated navigations to view-source URLs works.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
ViewSourceNavigation_BrowserInitiated) {
TestNavigationObserver observer(shell()->web_contents());
GURL url(embedded_test_server()->GetURL("/title1.html"));
@@ -333,9 +365,8 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
EXPECT_TRUE(observer.last_navigation_succeeded());
}
-// Ensure that browser side navigation blocks content initiated navigations to
-// view-source URLs.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+// Ensure that content initiated navigations to view-sources URLs are blocked.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
ViewSourceNavigation_RendererInitiated) {
TestNavigationObserver observer(shell()->web_contents());
GURL kUrl(embedded_test_server()->GetURL("/simple_links.html"));
@@ -366,21 +397,20 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
// Ensure that closing a page by running its beforeunload handler doesn't hang
// if there's an ongoing navigation.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
- UnloadDuringNavigation) {
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, UnloadDuringNavigation) {
content::WindowedNotificationObserver close_observer(
content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
content::Source<content::WebContents>(shell()->web_contents()));
GURL url("chrome://resources/css/tabs.css");
NavigationHandleObserver handle_observer(shell()->web_contents(), url);
shell()->LoadURL(url);
- shell()->web_contents()->DispatchBeforeUnload();
+ shell()->web_contents()->DispatchBeforeUnload(false /* auto_cancel */);
close_observer.Wait();
EXPECT_EQ(net::ERR_ABORTED, handle_observer.net_error_code());
}
// Ensure that the referrer of a navigation is properly sanitized.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest, SanitizeReferrer) {
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, SanitizeReferrer) {
const GURL kInsecureUrl(embedded_test_server()->GetURL("/title1.html"));
const Referrer kSecureReferrer(
GURL("https://secure-url.com"),
@@ -412,8 +442,7 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest, SanitizeReferrer) {
// Test to verify that an exploited renderer process trying to upload a file
// it hasn't been explicitly granted permissions to is correctly terminated.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
- PostUploadIllegalFilePath) {
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, PostUploadIllegalFilePath) {
GURL form_url(
embedded_test_server()->GetURL("/form_that_posts_to_echoall.html"));
EXPECT_TRUE(NavigateToURL(shell(), form_url));
@@ -475,7 +504,7 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
// based on Blink's state instead of the history state in the browser process,
// which ends up loading the originally blocked URL. With PlzNavigate, the
// reload uses the NavigationEntry state to create a navigation and commit it.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
VerifyBlockedErrorPageURL_Reload) {
NavigationControllerImpl& controller = static_cast<NavigationControllerImpl&>(
shell()->web_contents()->GetController());
@@ -507,17 +536,16 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
controller.GetLastCommittedEntry()->GetVirtualURL());
}
-class BrowserSideNavigationBrowserDisableWebSecurityTest
- : public BrowserSideNavigationBrowserTest {
+class NavigationDisableWebSecurityTest : public NavigationBrowserTest {
public:
- BrowserSideNavigationBrowserDisableWebSecurityTest() {}
+ NavigationDisableWebSecurityTest() {}
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
// Simulate a compromised renderer, otherwise the cross-origin request to
// file: is blocked.
command_line->AppendSwitch(switches::kDisableWebSecurity);
- BrowserSideNavigationBrowserTest::SetUpCommandLine(command_line);
+ NavigationBrowserTest::SetUpCommandLine(command_line);
}
};
@@ -527,7 +555,7 @@ class BrowserSideNavigationBrowserDisableWebSecurityTest
// TODO(nasko): This test case belongs better in
// security_exploit_browsertest.cc, so move it there once PlzNavigate is on
// by default.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserDisableWebSecurityTest,
+IN_PROC_BROWSER_TEST_F(NavigationDisableWebSecurityTest,
ValidateBaseUrlForDataUrl) {
GURL start_url(embedded_test_server()->GetURL("/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), start_url));
@@ -557,14 +585,13 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserDisableWebSecurityTest,
GURL() /* history_url_for_data_url */, PREVIEWS_UNSPECIFIED,
base::TimeTicks::Now() /* navigation_start */, "GET",
nullptr /* post_data */, base::Optional<SourceLocation>(),
- CSPDisposition::CHECK, false /* started_from_context_menu */,
- false /* has_user_gesture */,
- std::vector<ContentSecurityPolicy>() /* initiator_csp */,
- CSPSource() /* initiator_self_source */);
+ false /* started_from_context_menu */, false /* has_user_gesture */,
+ InitiatorCSPInfo());
mojom::BeginNavigationParamsPtr begin_params =
mojom::BeginNavigationParams::New(
std::string() /* headers */, net::LOAD_NORMAL,
- false /* skip_service_worker */, REQUEST_CONTEXT_TYPE_LOCATION,
+ false /* skip_service_worker */,
+ blink::mojom::RequestContextType::LOCATION,
blink::WebMixedContentContextType::kBlockable,
false /* is_form_submission */, GURL() /* searchable_form_url */,
std::string() /* searchable_form_encoding */,
@@ -581,10 +608,10 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserDisableWebSecurityTest,
mojo::MakeRequestAssociatedWithDedicatedPipe(&navigation_client);
rfh->frame_host_binding_for_testing().impl()->BeginNavigation(
common_params, std::move(begin_params), nullptr,
- navigation_client.PassInterface());
+ navigation_client.PassInterface(), nullptr);
} else {
rfh->frame_host_binding_for_testing().impl()->BeginNavigation(
- common_params, std::move(begin_params), nullptr, nullptr);
+ common_params, std::move(begin_params), nullptr, nullptr, nullptr);
}
EXPECT_EQ(bad_message::RFH_BASE_URL_FOR_DATA_URL_SPECIFIED,
process_kill_waiter.Wait());
@@ -610,7 +637,7 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserDisableWebSecurityTest,
EXPECT_TRUE(result.empty());
}
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest, BackFollowedByReload) {
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, BackFollowedByReload) {
// First, make two history entries.
GURL url1(embedded_test_server()->GetURL("/title1.html"));
GURL url2(embedded_test_server()->GetURL("/title2.html"));
@@ -630,7 +657,7 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest, BackFollowedByReload) {
// Test that a navigation response can be entirely fetched, even after the
// NavigationURLLoader has been deleted.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
+IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
FetchResponseAfterNavigationURLLoaderDeleted) {
net::test_server::ControllableHttpResponse response(embedded_test_server(),
"/main_document");
@@ -678,11 +705,11 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
}
// Navigation are started in the browser process. After the headers are
-// received, the URLLoaderClient is transfered from the browser process to the
+// received, the URLLoaderClient is transferred from the browser process to the
// renderer process. This test ensures that when the the URLLoader is deleted
// (in the browser process), the URLLoaderClient (in the renderer process) stops
// properly.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
+IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
CancelRequestAfterReadyToCommit) {
// This test cancels the request using the ResourceDispatchHost. With the
// NetworkService, it is not used so the request is not canceled.
@@ -728,8 +755,8 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
static_cast<ResourceDispatcherHostImpl*>(ResourceDispatcherHost::Get());
rdh->CancelRequest(global_id.child_id, global_id.request_id);
};
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(cancel_request, global_id));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(cancel_request, global_id));
// 3) Check that the load stops properly.
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
@@ -737,8 +764,7 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
// Data URLs can have a reference fragment like any other URLs. This test makes
// sure it is taken into account.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
- DataURLWithReferenceFragment) {
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, DataURLWithReferenceFragment) {
GURL url("data:text/html,body#foo");
EXPECT_TRUE(NavigateToURL(shell(), url));
@@ -762,7 +788,7 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
// 1) Start on a document with history.length == 1.
// 2) Create an iframe and call history.pushState at the same time.
// 3) history.back() must work.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
IframeAndPushStateSimultaneously) {
GURL main_url = embedded_test_server()->GetURL("/simple_page.html");
GURL iframe_url = embedded_test_server()->GetURL("/hello.html");
@@ -809,7 +835,7 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
// Regression test for https://crbug.com/260144
// Back/Forward navigation in an iframe must not stop ongoing XHR.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
+IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
IframeNavigationsDoNotStopXHR) {
// A response for the XHR request. It will be delayed until the end of all the
// navigations.
@@ -898,7 +924,7 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
}
// Regression test for https://crbug.com/856396.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
+IN_PROC_BROWSER_TEST_F(NavigationBaseBrowserTest,
ReplacingDocumentLoaderFiresLoadEvent) {
net::test_server::ControllableHttpResponse main_document_response(
embedded_test_server(), "/main_document");
@@ -952,11 +978,10 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
}
}
-class NavigationDownloadBrowserTest
- : public BrowserSideNavigationBaseBrowserTest {
+class NavigationDownloadBrowserTest : public NavigationBaseBrowserTest {
protected:
void SetUpOnMainThread() override {
- BrowserSideNavigationBaseBrowserTest::SetUpOnMainThread();
+ NavigationBaseBrowserTest::SetUpOnMainThread();
// Set up a test download directory, in order to prevent prompting for
// handling downloads.
@@ -1028,7 +1053,7 @@ IN_PROC_BROWSER_TEST_F(NavigationDownloadBrowserTest,
// 4) The browser gets notified of the commit of the first navigation. This
// should not destroy the NavigationRequest corresponding to the second
// navigation.
-IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
RaceNewNavigationCommitWhileOldOneFinishesLoading) {
// Start the test with an initial document.
GURL main_url(embedded_test_server()->GetURL("/simple_page.html"));
@@ -1100,4 +1125,95 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
recorder.records()[5].c_str());
}
+// Renderer initiated back/forward navigation in beforeunload should not prevent
+// the user to navigate away from a website.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, HistoryBackInBeforeUnload) {
+ GURL url_1(embedded_test_server()->GetURL("/title1.html"));
+ GURL url_2(embedded_test_server()->GetURL("/title2.html"));
+
+ EXPECT_TRUE(NavigateToURL(shell(), url_1));
+ EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
+ "onbeforeunload = function() {"
+ " history.pushState({}, null, '/');"
+ " history.back();"
+ "};"));
+ EXPECT_TRUE(NavigateToURL(shell(), url_2));
+}
+
+// Same as 'HistoryBackInBeforeUnload', but wraps history.back() inside
+// window.setTimeout(). Thus it is executed "outside" of its beforeunload
+// handler and thus avoid basic navigation circumventions.
+// Regression test for: https://crbug.com/879965.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
+ HistoryBackInBeforeUnloadAfterSetTimeout) {
+ GURL url_1(embedded_test_server()->GetURL("/title1.html"));
+ GURL url_2(embedded_test_server()->GetURL("/title2.html"));
+
+ EXPECT_TRUE(NavigateToURL(shell(), url_1));
+ EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
+ "onbeforeunload = function() {"
+ " history.pushState({}, null, '/');"
+ " setTimeout(()=>history.back());"
+ "};"));
+ TestNavigationManager navigation(shell()->web_contents(), url_2);
+ auto ipc_observer = base::MakeRefCounted<BrowserMessageObserver>(
+ ViewMsgStart, ViewHostMsg_GoToEntryAtOffset::ID);
+ static_cast<RenderFrameHostImpl*>(shell()->web_contents()->GetMainFrame())
+ ->GetProcess()
+ ->AddFilter(ipc_observer.get());
+
+ shell()->LoadURL(url_2);
+ ipc_observer->Wait();
+ navigation.WaitForNavigationFinished();
+
+ EXPECT_TRUE(navigation.was_successful());
+}
+
+// Renderer initiated back/forward navigation can't cancel an ongoing browser
+// initiated navigation if it is not user initiated.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
+ HistoryBackCancelPendingNavigationNoUserGesture) {
+ GURL url_1(embedded_test_server()->GetURL("/title1.html"));
+ GURL url_2(embedded_test_server()->GetURL("/title2.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), url_1));
+
+ // 1) A pending browser initiated navigation (omnibox, ...) starts.
+ TestNavigationManager navigation(shell()->web_contents(), url_2);
+ shell()->LoadURL(url_2);
+ EXPECT_TRUE(navigation.WaitForRequestStart());
+
+ // 2) history.back() is sent but is not user initiated.
+ EXPECT_TRUE(
+ ExecuteScriptWithoutUserGesture(shell()->web_contents(),
+ "history.pushState({}, null, '/');"
+ "history.back();"));
+
+ // 3) The first pending navigation is not canceled and can continue.
+ navigation.WaitForNavigationFinished(); // Resume navigation.
+ EXPECT_TRUE(navigation.was_successful());
+}
+
+// Renderer initiated back/forward navigation can cancel an ongoing browser
+// initiated navigation if it is user initiated.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest,
+ HistoryBackCancelPendingNavigationUserGesture) {
+ GURL url_1(embedded_test_server()->GetURL("/title1.html"));
+ GURL url_2(embedded_test_server()->GetURL("/title2.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), url_1));
+
+ // 1) A pending browser initiated navigation (omnibox, ...) starts.
+ TestNavigationManager navigation(shell()->web_contents(), url_2);
+ shell()->LoadURL(url_2);
+ EXPECT_TRUE(navigation.WaitForRequestStart());
+
+ // 2) history.back() is sent and is user initiated.
+ EXPECT_TRUE(ExecuteScript(shell()->web_contents(),
+ "history.pushState({}, null, '/');"
+ "history.back();"));
+
+ // 3) Check the first pending navigation has been canceled.
+ navigation.WaitForNavigationFinished(); // Resume navigation.
+ EXPECT_FALSE(navigation.was_successful());
+}
+
} // namespace content
diff --git a/chromium/content/browser/net/network_quality_observer_impl.cc b/chromium/content/browser/net/network_quality_observer_impl.cc
index dafe9179271..6aecc4332e4 100644
--- a/chromium/content/browser/net/network_quality_observer_impl.cc
+++ b/chromium/content/browser/net/network_quality_observer_impl.cc
@@ -5,15 +5,14 @@
#include "content/browser/net/network_quality_observer_impl.h"
#include "base/metrics/histogram_macros.h"
-#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/common/renderer.mojom.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/network_quality_observer_factory.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_process_host.h"
-#include "net/nqe/network_quality_estimator.h"
namespace {
@@ -57,121 +56,22 @@ bool MetricChangedMeaningfully(int32_t past_value, int32_t current_value) {
namespace content {
-// UiThreadObserver observes the changes to the network quality on the UI
-// thread, and notifies the renderers of the change in the network quality.
-class NetworkQualityObserverImpl::UiThreadObserver
- : public content::NotificationObserver {
- public:
- UiThreadObserver()
- : last_notified_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {}
-
- ~UiThreadObserver() override {
- if (!registrar_.IsRegistered(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
- NotificationService::AllSources())) {
- return;
- }
- registrar_.Remove(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
- NotificationService::AllSources());
- }
-
- void InitOnUIThread() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
- NotificationService::AllSources());
- }
-
- void OnEffectiveConnectionTypeChanged(net::EffectiveConnectionType type) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- if (last_notified_type_ == type)
- return;
-
- last_notified_type_ = type;
-
- // Notify all the existing renderers of the change in the network quality.
- for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
- !it.IsAtEnd(); it.Advance()) {
- if (it.GetCurrentValue()->IsInitializedAndNotDead()) {
- it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
- last_notified_type_, last_notified_network_quality_.http_rtt(),
- last_notified_network_quality_.transport_rtt(),
- last_notified_network_quality_.downstream_throughput_kbps());
- }
- }
- }
-
- void OnRTTOrThroughputEstimatesComputed(
- const net::nqe::internal::NetworkQuality& network_quality) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- last_notified_network_quality_ = network_quality;
-
- // Notify all the existing renderers of the change in the network quality.
- for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
- !it.IsAtEnd(); it.Advance()) {
- if (it.GetCurrentValue()->IsInitializedAndNotDead()) {
- it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
- last_notified_type_, last_notified_network_quality_.http_rtt(),
- last_notified_network_quality_.transport_rtt(),
- last_notified_network_quality_.downstream_throughput_kbps());
- }
- }
- }
-
- private:
- // NotificationObserver implementation:
- void Observe(int type,
- const NotificationSource& source,
- const NotificationDetails& details) override {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK_EQ(NOTIFICATION_RENDERER_PROCESS_CREATED, type);
-
- RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
-
- // Notify the newly created renderer of the current network quality.
- rph->GetRendererInterface()->OnNetworkQualityChanged(
- last_notified_type_, last_notified_network_quality_.http_rtt(),
- last_notified_network_quality_.transport_rtt(),
- last_notified_network_quality_.downstream_throughput_kbps());
- }
-
- content::NotificationRegistrar registrar_;
-
- // The network quality that was last sent to the renderers.
- net::EffectiveConnectionType last_notified_type_;
- net::nqe::internal::NetworkQuality last_notified_network_quality_;
-
- DISALLOW_COPY_AND_ASSIGN(UiThreadObserver);
-};
-
NetworkQualityObserverImpl::NetworkQualityObserverImpl(
- net::NetworkQualityEstimator* network_quality_estimator)
- : network_quality_estimator_(network_quality_estimator),
+ network::NetworkQualityTracker* network_quality_tracker)
+ : network_quality_tracker_(network_quality_tracker),
last_notified_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {
- network_quality_estimator_->AddRTTAndThroughputEstimatesObserver(this);
- network_quality_estimator_->AddEffectiveConnectionTypeObserver(this);
-
- ui_thread_observer_ = std::make_unique<UiThreadObserver>();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&UiThreadObserver::InitOnUIThread,
- base::Unretained(ui_thread_observer_.get())));
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
+ NotificationService::AllSources());
+ network_quality_tracker_->AddRTTAndThroughputEstimatesObserver(this);
+ network_quality_tracker_->AddEffectiveConnectionTypeObserver(this);
}
NetworkQualityObserverImpl::~NetworkQualityObserverImpl() {
DCHECK(thread_checker_.CalledOnValidThread());
- network_quality_estimator_->RemoveRTTAndThroughputEstimatesObserver(this);
- network_quality_estimator_->RemoveEffectiveConnectionTypeObserver(this);
-
- DCHECK(ui_thread_observer_);
-
- // If possible, delete |ui_thread_observer_| on UI thread.
- UiThreadObserver* ui_thread_observer_ptr = ui_thread_observer_.release();
- bool posted = BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE,
- ui_thread_observer_ptr);
-
- if (!posted)
- delete ui_thread_observer_ptr;
+ network_quality_tracker_->RemoveRTTAndThroughputEstimatesObserver(this);
+ network_quality_tracker_->RemoveEffectiveConnectionTypeObserver(this);
}
void NetworkQualityObserverImpl::OnEffectiveConnectionTypeChanged(
@@ -183,11 +83,31 @@ void NetworkQualityObserverImpl::OnEffectiveConnectionTypeChanged(
last_notified_type_ = type;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&UiThreadObserver::OnEffectiveConnectionTypeChanged,
- base::Unretained(ui_thread_observer_.get()),
- last_notified_type_));
+ // Notify all the existing renderers of the change in the network quality.
+ for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd(); it.Advance()) {
+ if (it.GetCurrentValue()->IsInitializedAndNotDead()) {
+ it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
+ last_notified_type_, last_notified_network_quality_.http_rtt(),
+ last_notified_network_quality_.transport_rtt(),
+ last_notified_network_quality_.downstream_throughput_kbps());
+ }
+ }
+}
+
+void NetworkQualityObserverImpl::Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_EQ(NOTIFICATION_RENDERER_PROCESS_CREATED, type);
+
+ RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
+
+ // Notify the newly created renderer of the current network quality.
+ rph->GetRendererInterface()->OnNetworkQualityChanged(
+ last_notified_type_, last_notified_network_quality_.http_rtt(),
+ last_notified_network_quality_.transport_rtt(),
+ last_notified_network_quality_.downstream_throughput_kbps());
}
void NetworkQualityObserverImpl::OnRTTOrThroughputEstimatesComputed(
@@ -223,18 +143,23 @@ void NetworkQualityObserverImpl::OnRTTOrThroughputEstimatesComputed(
last_notified_network_quality_ = net::nqe::internal::NetworkQuality(
http_rtt, transport_rtt, downstream_throughput_kbps);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&UiThreadObserver::OnRTTOrThroughputEstimatesComputed,
- base::Unretained(ui_thread_observer_.get()),
- last_notified_network_quality_));
+ // Notify all the existing renderers of the change in the network quality.
+ for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd(); it.Advance()) {
+ if (it.GetCurrentValue()->IsInitializedAndNotDead()) {
+ it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
+ last_notified_type_, last_notified_network_quality_.http_rtt(),
+ last_notified_network_quality_.transport_rtt(),
+ last_notified_network_quality_.downstream_throughput_kbps());
+ }
+ }
}
-std::unique_ptr<net::RTTAndThroughputEstimatesObserver>
+std::unique_ptr<
+ network::NetworkQualityTracker::RTTAndThroughputEstimatesObserver>
CreateNetworkQualityObserver(
- net::NetworkQualityEstimator* network_quality_estimator) {
- return std::make_unique<NetworkQualityObserverImpl>(
- network_quality_estimator);
+ network::NetworkQualityTracker* network_quality_tracker) {
+ return std::make_unique<NetworkQualityObserverImpl>(network_quality_tracker);
}
-} // namespace content \ No newline at end of file
+} // namespace content
diff --git a/chromium/content/browser/net/network_quality_observer_impl.h b/chromium/content/browser/net/network_quality_observer_impl.h
index 2c5a1818839..4a6fe632edd 100644
--- a/chromium/content/browser/net/network_quality_observer_impl.h
+++ b/chromium/content/browser/net/network_quality_observer_impl.h
@@ -13,31 +13,31 @@
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
-#include "content/public/browser/network_quality_observer_factory.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
#include "net/nqe/effective_connection_type.h"
-#include "net/nqe/effective_connection_type_observer.h"
#include "net/nqe/network_quality.h"
-#include "net/nqe/rtt_throughput_estimates_observer.h"
-
-namespace net {
-class NetworkQualityEstimator;
-}
+#include "services/network/public/cpp/network_quality_tracker.h"
namespace content {
// Listens for changes to the network quality and manages sending updates to
// each RenderProcess via mojo.
class CONTENT_EXPORT NetworkQualityObserverImpl
- : public net::EffectiveConnectionTypeObserver,
- public net::RTTAndThroughputEstimatesObserver {
+ : public network::NetworkQualityTracker::EffectiveConnectionTypeObserver,
+ public network::NetworkQualityTracker::RTTAndThroughputEstimatesObserver,
+ public content::NotificationObserver {
public:
explicit NetworkQualityObserverImpl(
- net::NetworkQualityEstimator* network_quality_estimator);
+ network::NetworkQualityTracker* network_quality_tracker);
~NetworkQualityObserverImpl() override;
private:
- class UiThreadObserver;
+ // content::NotificationObserver:
+ void Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) override;
// net::EffectiveConnectionTypeObserver implementation:
void OnEffectiveConnectionTypeChanged(
@@ -49,20 +49,16 @@ class CONTENT_EXPORT NetworkQualityObserverImpl
base::TimeDelta transport_rtt,
int32_t downstream_throughput_kbps) override;
- // |ui_thread_observer_| is owned by |this|, and interacts with
- // the render processes. It is created on the IO thread but afterwards, should
- // only be accessed on the UI thread. |ui_thread_observer_| is guaranteed to
- // be non-null during the lifetime of |this|.
- std::unique_ptr<UiThreadObserver> ui_thread_observer_;
-
- // |network_quality_estimator_| is guaranteed to be non-null during the
+ // |network_quality_tracker_| is guaranteed to be non-null during the
// lifetime of |this|.
- net::NetworkQualityEstimator* network_quality_estimator_;
+ network::NetworkQualityTracker* network_quality_tracker_;
// The network quality when the |ui_thread_observer_| was last notified.
net::EffectiveConnectionType last_notified_type_;
net::nqe::internal::NetworkQuality last_notified_network_quality_;
+ content::NotificationRegistrar registrar_;
+
base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(NetworkQualityObserverImpl);
@@ -70,4 +66,4 @@ class CONTENT_EXPORT NetworkQualityObserverImpl
} // namespace content
-#endif // CONTENT_BROWSER_NET_NETWORK_QUALITY_OBSERVER_IMPL_H_ \ No newline at end of file
+#endif // CONTENT_BROWSER_NET_NETWORK_QUALITY_OBSERVER_IMPL_H_
diff --git a/chromium/content/browser/net/network_quality_observer_impl_unittest.cc b/chromium/content/browser/net/network_quality_observer_impl_unittest.cc
index cd9ab62b89b..eeba7c7ee5c 100644
--- a/chromium/content/browser/net/network_quality_observer_impl_unittest.cc
+++ b/chromium/content/browser/net/network_quality_observer_impl_unittest.cc
@@ -9,7 +9,7 @@
#include "base/time/time.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/nqe/effective_connection_type.h"
-#include "net/nqe/network_quality_estimator_test_util.h"
+#include "services/network/test/test_network_quality_tracker.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
@@ -19,25 +19,32 @@ TEST(NetworkQualityObserverImplTest, TestObserverNotified) {
content::TestBrowserThreadBundle thread_bundle(
content::TestBrowserThreadBundle::Options::IO_MAINLOOP);
- net::TestNetworkQualityEstimator estimator;
- estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(1));
+ network::TestNetworkQualityTracker test_network_quality_tracker;
+
+ NetworkQualityObserverImpl impl(&test_network_quality_tracker);
+
+ test_network_quality_tracker.ReportRTTsAndThroughputForTesting(
+ base::TimeDelta::FromMilliseconds(1), 100);
- NetworkQualityObserverImpl observer(&estimator);
- // Give a chance for |observer| to register with the |estimator|.
base::RunLoop().RunUntilIdle();
base::HistogramTester histogram_tester;
- estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(500));
+
+ test_network_quality_tracker.ReportRTTsAndThroughputForTesting(
+ base::TimeDelta::FromMilliseconds(500), 100);
+
// RTT changed from 1 msec to 500 msec.
histogram_tester.ExpectBucketCount(
"NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 1);
- estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(625));
+ test_network_quality_tracker.ReportRTTsAndThroughputForTesting(
+ base::TimeDelta::FromMilliseconds(625), 100);
// RTT changed from 500 msec to 625 msec.
histogram_tester.ExpectBucketCount(
"NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 2);
- estimator.SetStartTimeNullHttpRtt(base::TimeDelta::FromMilliseconds(626));
+ test_network_quality_tracker.ReportRTTsAndThroughputForTesting(
+ base::TimeDelta::FromMilliseconds(626), 100);
// RTT changed from 625 msec to 626 msec which is not a meaningful change.
histogram_tester.ExpectBucketCount(
"NQE.ContentObserver.NetworkQualityMeaningfullyChanged", 1, 2);
diff --git a/chromium/content/browser/net/quota_policy_cookie_store.cc b/chromium/content/browser/net/quota_policy_cookie_store.cc
index ecf284fd0d9..7416a8606d3 100644
--- a/chromium/content/browser/net/quota_policy_cookie_store.cc
+++ b/chromium/content/browser/net/quota_policy_cookie_store.cc
@@ -14,6 +14,7 @@
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/cookie_store_factory.h"
#include "net/cookies/canonical_cookie.h"
@@ -83,12 +84,12 @@ std::unique_ptr<net::CookieStore> CreateCookieStore(
if (!client_task_runner.get()) {
client_task_runner =
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
}
if (!background_task_runner.get()) {
background_task_runner = base::CreateSequencedTaskRunnerWithTraits(
- {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+ {base::MayBlock(), net::GetCookieStoreBackgroundSequencePriority(),
base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
}
diff --git a/chromium/content/browser/net_info_browsertest.cc b/chromium/content/browser/net_info_browsertest.cc
index e5bf126c3c4..e506f12bbfe 100644
--- a/chromium/content/browser/net_info_browsertest.cc
+++ b/chromium/content/browser/net_info_browsertest.cc
@@ -22,7 +22,7 @@
#include "net/dns/mock_host_resolver.h"
#include "net/log/test_net_log.h"
#include "net/nqe/effective_connection_type.h"
-#include "net/nqe/network_quality_estimator_test_util.h"
+#include "services/network/test/test_network_quality_tracker.h"
namespace {
@@ -49,7 +49,9 @@ void VerifyRtt(base::TimeDelta expected_rtt, int32_t got_rtt_milliseconds) {
// For example, if sample is 300 msec, after adding noise, it may become 330,
// and after rounding off, it would spill over to the next bucket of 350 msec.
EXPECT_GE((expected_rtt.InMilliseconds() * 0.1) + 50,
- std::abs(expected_rtt.InMilliseconds() - got_rtt_milliseconds));
+ std::abs(expected_rtt.InMilliseconds() - got_rtt_milliseconds))
+ << " expected_rtt=" << expected_rtt
+ << " got_rtt_milliseconds=" << got_rtt_milliseconds;
}
void VerifyDownlinkKbps(double expected_kbps, double got_kbps) {
@@ -74,7 +76,8 @@ void VerifyDownlinkKbps(double expected_kbps, double got_kbps) {
// sample may spill over to the next bucket due to the added noise of 10%.
// For example, if sample is 300 kbps, after adding noise, it may become 330,
// and after rounding off, it would spill over to the next bucket of 350 kbps.
- EXPECT_GE((expected_kbps * 0.1) + 50, std::abs(expected_kbps - got_kbps));
+ EXPECT_GE((expected_kbps * 0.1) + 50, std::abs(expected_kbps - got_kbps))
+ << " expected_kbps=" << expected_kbps << " got_kbps=" << got_kbps;
}
} // namespace
@@ -82,6 +85,15 @@ void VerifyDownlinkKbps(double expected_kbps, double got_kbps) {
namespace content {
class NetInfoBrowserTest : public content::ContentBrowserTest {
+ public:
+ NetInfoBrowserTest()
+ : test_network_quality_tracker_(
+ std::make_unique<network::TestNetworkQualityTracker>()) {}
+
+ network::NetworkQualityTracker* GetNetworkQualityTracker() const {
+ return test_network_quality_tracker_.get();
+ }
+
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
// TODO(jkarlin): Once NetInfo is enabled on all platforms remove this
@@ -145,6 +157,10 @@ class NetInfoBrowserTest : public content::ContentBrowserTest {
EXPECT_TRUE(ExecuteScriptAndExtractInt(shell(), script, &data));
return data;
}
+
+ private:
+ std::unique_ptr<network::TestNetworkQualityTracker>
+ test_network_quality_tracker_;
};
// Make sure the type is correct when the page is first opened.
@@ -219,10 +235,7 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, TwoRenderViewsInOneProcess) {
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest,
NetworkQualityEstimatorNotInitialized) {
base::HistogramTester histogram_tester;
- net::TestNetworkQualityEstimator estimator(
- std::map<std::string, std::string>(), false, false, true,
- std::make_unique<net::BoundTestNetLog>());
- NetworkQualityObserverImpl impl(&estimator);
+ NetworkQualityObserverImpl impl(GetNetworkQualityTracker());
EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(
@@ -234,20 +247,17 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest,
VerifyDownlinkKbps(10000, RunScriptExtractDouble("getDownlink()") * 1000);
}
-// Make sure the changes in the effective connection typeare notified to the
+// Make sure the changes in the effective connection type are notified to the
// render thread.
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest,
- EffectiveConnectionTypeChangeNotfied) {
+ EffectiveConnectionTypeChangeNotified) {
base::HistogramTester histogram_tester;
- net::TestNetworkQualityEstimator estimator(
- std::map<std::string, std::string>(), false, false, true,
- std::make_unique<net::BoundTestNetLog>());
- NetworkQualityObserverImpl impl(&estimator);
+ NetworkQualityObserverImpl impl(GetNetworkQualityTracker());
- net::nqe::internal::NetworkQuality network_quality_1(
- base::TimeDelta::FromSeconds(1), base::TimeDelta::FromSeconds(2), 300);
- estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
- network_quality_1);
+ base::TimeDelta http_rtt(base::TimeDelta::FromMilliseconds(1000));
+ int32_t downstream_throughput_kbps = 300;
+ GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
+ http_rtt, downstream_throughput_kbps);
EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(
@@ -263,11 +273,11 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest,
// Changing the effective connection type from 2G to 3G is guaranteed to
// generate the notification to the renderers, irrespective of the current
// effective connection type.
- estimator.NotifyObserversOfEffectiveConnectionType(
+ GetNetworkQualityTracker()->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_2G);
base::RunLoop().RunUntilIdle();
EXPECT_EQ("2g", RunScriptExtractString("getEffectiveType()"));
- estimator.NotifyObserversOfEffectiveConnectionType(
+ GetNetworkQualityTracker()->ReportEffectiveConnectionTypeForTesting(
net::EFFECTIVE_CONNECTION_TYPE_3G);
base::RunLoop().RunUntilIdle();
EXPECT_EQ("3g", RunScriptExtractString("getEffectiveType()"));
@@ -281,15 +291,13 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest,
// thread, and the changed network quality is accessible via Javascript API.
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeNotified) {
base::HistogramTester histogram_tester;
- net::TestNetworkQualityEstimator estimator(
- std::map<std::string, std::string>(), false, false, true,
- std::make_unique<net::BoundTestNetLog>());
- NetworkQualityObserverImpl impl(&estimator);
+ NetworkQualityObserverImpl impl(GetNetworkQualityTracker());
+
+ base::TimeDelta http_rtt(base::TimeDelta::FromMilliseconds(1000));
+ int32_t downstream_throughput_kbps = 300;
- net::nqe::internal::NetworkQuality network_quality_1(
- base::TimeDelta::FromSeconds(1), base::TimeDelta::FromSeconds(2), 300);
- estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
- network_quality_1);
+ GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
+ http_rtt, downstream_throughput_kbps);
EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(
@@ -299,18 +307,18 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeNotified) {
EXPECT_FALSE(
histogram_tester.GetAllSamples("NQE.RenderThreadNotified").empty());
- VerifyRtt(network_quality_1.http_rtt(), RunScriptExtractInt("getRtt()"));
- VerifyDownlinkKbps(network_quality_1.downstream_throughput_kbps(),
+ VerifyRtt(http_rtt, RunScriptExtractInt("getRtt()"));
+ VerifyDownlinkKbps(downstream_throughput_kbps,
RunScriptExtractDouble("getDownlink()") * 1000);
// Verify that the network quality change is accessible via Javascript API.
- net::nqe::internal::NetworkQuality network_quality_2(
- base::TimeDelta::FromSeconds(10), base::TimeDelta::FromSeconds(20), 3000);
- estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
- network_quality_2);
+ http_rtt = base::TimeDelta::FromSeconds(10);
+ downstream_throughput_kbps = 3000;
+ GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
+ http_rtt, downstream_throughput_kbps);
base::RunLoop().RunUntilIdle();
- VerifyRtt(network_quality_2.http_rtt(), RunScriptExtractInt("getRtt()"));
- VerifyDownlinkKbps(network_quality_2.downstream_throughput_kbps(),
+ VerifyRtt(http_rtt, RunScriptExtractInt("getRtt()"));
+ VerifyDownlinkKbps(downstream_throughput_kbps,
RunScriptExtractDouble("getDownlink()") * 1000);
}
@@ -318,43 +326,37 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeNotified) {
// 50 milliseconds or 50 kbps.
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeRounded) {
base::HistogramTester histogram_tester;
- net::TestNetworkQualityEstimator estimator(
- std::map<std::string, std::string>(), false, false, true,
- std::make_unique<net::BoundTestNetLog>());
- NetworkQualityObserverImpl impl(&estimator);
+ NetworkQualityObserverImpl impl(GetNetworkQualityTracker());
// Verify that the network quality is rounded properly.
- net::nqe::internal::NetworkQuality network_quality_1(
- base::TimeDelta::FromMilliseconds(103),
- base::TimeDelta::FromMilliseconds(212), 8303);
- estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
- network_quality_1);
+ base::TimeDelta http_rtt(base::TimeDelta::FromMilliseconds(103));
+ int32_t downstream_throughput_kbps = 8303;
+ GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
+ http_rtt, downstream_throughput_kbps);
EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(
NavigateToURL(shell(), embedded_test_server()->GetURL("/net_info.html")));
- VerifyRtt(network_quality_1.http_rtt(), RunScriptExtractInt("getRtt()"));
- VerifyDownlinkKbps(network_quality_1.downstream_throughput_kbps(),
+ VerifyRtt(http_rtt, RunScriptExtractInt("getRtt()"));
+ VerifyDownlinkKbps(downstream_throughput_kbps,
RunScriptExtractDouble("getDownlink()") * 1000);
- net::nqe::internal::NetworkQuality network_quality_2(
- base::TimeDelta::FromMilliseconds(1103),
- base::TimeDelta::FromMilliseconds(212), 1307);
- estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
- network_quality_2);
+ http_rtt = base::TimeDelta::FromMilliseconds(1103);
+ downstream_throughput_kbps = 1307;
+ GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
+ http_rtt, downstream_throughput_kbps);
base::RunLoop().RunUntilIdle();
- VerifyRtt(network_quality_2.http_rtt(), RunScriptExtractInt("getRtt()"));
- VerifyDownlinkKbps(network_quality_2.downstream_throughput_kbps(),
+ VerifyRtt(http_rtt, RunScriptExtractInt("getRtt()"));
+ VerifyDownlinkKbps(downstream_throughput_kbps,
RunScriptExtractDouble("getDownlink()") * 1000);
- net::nqe::internal::NetworkQuality network_quality_3(
- base::TimeDelta::FromMilliseconds(2112),
- base::TimeDelta::FromMilliseconds(2112), 2112);
- estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
- network_quality_3);
+ http_rtt = base::TimeDelta::FromMilliseconds(2112);
+ downstream_throughput_kbps = 2112;
+ GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
+ http_rtt, downstream_throughput_kbps);
base::RunLoop().RunUntilIdle();
- VerifyRtt(network_quality_3.http_rtt(), RunScriptExtractInt("getRtt()"));
- VerifyDownlinkKbps(network_quality_3.downstream_throughput_kbps(),
+ VerifyRtt(http_rtt, RunScriptExtractInt("getRtt()"));
+ VerifyDownlinkKbps(downstream_throughput_kbps,
RunScriptExtractDouble("getDownlink()") * 1000);
}
@@ -362,43 +364,39 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeRounded) {
// limit.
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeUpperLimit) {
base::HistogramTester histogram_tester;
- net::TestNetworkQualityEstimator estimator(
- std::map<std::string, std::string>(), false, false, true,
- std::make_unique<net::BoundTestNetLog>());
- NetworkQualityObserverImpl impl(&estimator);
+ NetworkQualityObserverImpl impl(GetNetworkQualityTracker());
- net::nqe::internal::NetworkQuality network_quality(
- base::TimeDelta::FromMilliseconds(12003),
- base::TimeDelta::FromMilliseconds(212), 30300);
- estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(network_quality);
+ base::TimeDelta http_rtt(base::TimeDelta::FromMilliseconds(12003));
+ int32_t downstream_throughput_kbps = 30300;
+
+ GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
+ http_rtt, downstream_throughput_kbps);
EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(
NavigateToURL(shell(), embedded_test_server()->GetURL("/net_info.html")));
- VerifyRtt(network_quality.http_rtt(), RunScriptExtractInt("getRtt()"));
- VerifyDownlinkKbps(network_quality.downstream_throughput_kbps(),
+ VerifyRtt(http_rtt, RunScriptExtractInt("getRtt()"));
+ VerifyDownlinkKbps(downstream_throughput_kbps,
RunScriptExtractDouble("getDownlink()") * 1000);
}
// Make sure the noise added to the network quality varies with the hostname.
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityRandomized) {
base::HistogramTester histogram_tester;
- net::TestNetworkQualityEstimator estimator(
- std::map<std::string, std::string>(), false, false, true,
- std::make_unique<net::BoundTestNetLog>());
- NetworkQualityObserverImpl impl(&estimator);
+ NetworkQualityObserverImpl impl(GetNetworkQualityTracker());
+
+ base::TimeDelta http_rtt(base::TimeDelta::FromMilliseconds(2000));
+ int32_t downstream_throughput_kbps = 3000;
- net::nqe::internal::NetworkQuality network_quality(
- base::TimeDelta::FromMilliseconds(2000),
- base::TimeDelta::FromMilliseconds(200), 3000);
- estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(network_quality);
+ GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
+ http_rtt, downstream_throughput_kbps);
EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(
NavigateToURL(shell(), embedded_test_server()->GetURL("/net_info.html")));
- VerifyRtt(network_quality.http_rtt(), RunScriptExtractInt("getRtt()"));
- VerifyDownlinkKbps(network_quality.downstream_throughput_kbps(),
+ VerifyRtt(http_rtt, RunScriptExtractInt("getRtt()"));
+ VerifyDownlinkKbps(downstream_throughput_kbps,
RunScriptExtractDouble("getDownlink()") * 1000);
const int32_t rtt_noise_milliseconds = RunScriptExtractInt("getRtt()") - 2000;
@@ -408,8 +406,8 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityRandomized) {
// When the hostname is not changed, the noise should not change.
EXPECT_TRUE(
NavigateToURL(shell(), embedded_test_server()->GetURL("/net_info.html")));
- VerifyRtt(network_quality.http_rtt(), RunScriptExtractInt("getRtt()"));
- VerifyDownlinkKbps(network_quality.downstream_throughput_kbps(),
+ VerifyRtt(http_rtt, RunScriptExtractInt("getRtt()"));
+ VerifyDownlinkKbps(downstream_throughput_kbps,
RunScriptExtractDouble("getDownlink()") * 1000);
EXPECT_EQ(rtt_noise_milliseconds, RunScriptExtractInt("getRtt()") - 2000);
EXPECT_EQ(downlink_noise_kbps,
@@ -425,8 +423,8 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityRandomized) {
std::string fake_hostname = "example" + base::IntToString(i) + ".com";
EXPECT_TRUE(NavigateToURL(shell(), embedded_test_server()->GetURL(
fake_hostname, "/net_info.html")));
- VerifyRtt(network_quality.http_rtt(), RunScriptExtractInt("getRtt()"));
- VerifyDownlinkKbps(network_quality.downstream_throughput_kbps(),
+ VerifyRtt(http_rtt, RunScriptExtractInt("getRtt()"));
+ VerifyDownlinkKbps(downstream_throughput_kbps,
RunScriptExtractDouble("getDownlink()") * 1000);
int32_t new_rtt_noise_milliseconds = RunScriptExtractInt("getRtt()") - 2000;
@@ -444,32 +442,27 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityRandomized) {
// Make sure the minor changes (<10%) in the network quality are not notified.
IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeNotNotified) {
base::HistogramTester histogram_tester;
- net::TestNetworkQualityEstimator estimator(
- std::map<std::string, std::string>(), false, false, true,
- std::make_unique<net::BoundTestNetLog>());
- NetworkQualityObserverImpl impl(&estimator);
+ NetworkQualityObserverImpl impl(GetNetworkQualityTracker());
// Verify that the network quality is rounded properly.
- net::nqe::internal::NetworkQuality network_quality_1(
- base::TimeDelta::FromMilliseconds(1123),
- base::TimeDelta::FromMilliseconds(1212), 1303);
- estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
- network_quality_1);
+ base::TimeDelta http_rtt(base::TimeDelta::FromMilliseconds(1123));
+ int32_t downstream_throughput_kbps = 1303;
+ GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
+ http_rtt, downstream_throughput_kbps);
EXPECT_TRUE(embedded_test_server()->Start());
EXPECT_TRUE(
NavigateToURL(shell(), embedded_test_server()->GetURL("/net_info.html")));
- VerifyRtt(network_quality_1.http_rtt(), RunScriptExtractInt("getRtt()"));
- VerifyDownlinkKbps(network_quality_1.downstream_throughput_kbps(),
+ VerifyRtt(http_rtt, RunScriptExtractInt("getRtt()"));
+ VerifyDownlinkKbps(downstream_throughput_kbps,
RunScriptExtractDouble("getDownlink()") * 1000);
// All the 3 metrics change by less than 10%. So, the observers are not
// notified.
- net::nqe::internal::NetworkQuality network_quality_2(
- base::TimeDelta::FromMilliseconds(1223),
- base::TimeDelta::FromMilliseconds(1312), 1403);
- estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
- network_quality_2);
+ http_rtt = base::TimeDelta::FromMilliseconds(1223);
+ downstream_throughput_kbps = 1403;
+ GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
+ http_rtt, downstream_throughput_kbps);
base::RunLoop().RunUntilIdle();
VerifyRtt(base::TimeDelta::FromMilliseconds(1100),
RunScriptExtractInt("getRtt()"));
@@ -477,11 +470,10 @@ IN_PROC_BROWSER_TEST_F(NetInfoBrowserTest, NetworkQualityChangeNotNotified) {
// HTTP RTT has changed by more than 10% from the last notified value of
// |network_quality_1|. The observers should be notified.
- net::nqe::internal::NetworkQuality network_quality_3(
- base::TimeDelta::FromMilliseconds(2223),
- base::TimeDelta::FromMilliseconds(1312), 1403);
- estimator.NotifyObserversOfRTTOrThroughputEstimatesComputed(
- network_quality_3);
+ http_rtt = base::TimeDelta::FromMilliseconds(2223);
+ downstream_throughput_kbps = 1403;
+ GetNetworkQualityTracker()->ReportRTTsAndThroughputForTesting(
+ http_rtt, downstream_throughput_kbps);
base::RunLoop().RunUntilIdle();
VerifyRtt(base::TimeDelta::FromMilliseconds(2200),
RunScriptExtractInt("getRtt()"));
diff --git a/chromium/content/browser/network_service_browsertest.cc b/chromium/content/browser/network_service_browsertest.cc
index 25c031a14ea..85ee34408d6 100644
--- a/chromium/content/browser/network_service_browsertest.cc
+++ b/chromium/content/browser/network_service_browsertest.cc
@@ -7,6 +7,7 @@
#include "build/build_config.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/url_data_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
@@ -18,10 +19,19 @@
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/simple_url_loader_test_helper.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "net/dns/mock_host_resolver.h"
+#include "net/http/http_response_headers.h"
+#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+
+#if defined(OS_ANDROID)
+#include "base/android/application_status_listener.h"
+#endif
namespace content {
@@ -79,12 +89,10 @@ class WebUITestWebUIControllerFactory : public WebUIControllerFactory {
}
};
-class WebUIDataSource : public URLDataSource {
+class TestWebUIDataSource : public URLDataSource {
public:
- WebUIDataSource() {}
-
- private:
- ~WebUIDataSource() override {}
+ TestWebUIDataSource() {}
+ ~TestWebUIDataSource() override {}
std::string GetSource() const override { return "webui"; }
@@ -102,7 +110,8 @@ class WebUIDataSource : public URLDataSource {
return "text/html";
}
- DISALLOW_COPY_AND_ASSIGN(WebUIDataSource);
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestWebUIDataSource);
};
class NetworkServiceBrowserTest : public ContentBrowserTest {
@@ -111,6 +120,7 @@ class NetworkServiceBrowserTest : public ContentBrowserTest {
scoped_feature_list_.InitAndEnableFeature(
network::features::kNetworkService);
EXPECT_TRUE(embedded_test_server()->Start());
+ EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
WebUIControllerFactory::RegisterFactory(&factory_);
}
@@ -148,7 +158,7 @@ class NetworkServiceBrowserTest : public ContentBrowserTest {
void SetUpOnMainThread() override {
URLDataSource::Add(shell()->web_contents()->GetBrowserContext(),
- new WebUIDataSource);
+ std::make_unique<TestWebUIDataSource>());
}
void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -158,9 +168,32 @@ class NetworkServiceBrowserTest : public ContentBrowserTest {
IsolateAllSitesForTesting(command_line);
}
+ base::FilePath GetCacheDirectory() { return temp_dir_.GetPath(); }
+
+ base::FilePath GetCacheIndexDirectory() {
+ return GetCacheDirectory().AppendASCII("index-dir");
+ }
+
+ void LoadURL(const GURL& url,
+ network::mojom::URLLoaderFactory* loader_factory) {
+ std::unique_ptr<network::ResourceRequest> request =
+ std::make_unique<network::ResourceRequest>();
+ request->url = url;
+ content::SimpleURLLoaderTestHelper simple_loader_helper;
+ std::unique_ptr<network::SimpleURLLoader> simple_loader =
+ network::SimpleURLLoader::Create(std::move(request),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+ loader_factory, simple_loader_helper.GetCallback());
+ simple_loader_helper.WaitForCallback();
+ ASSERT_TRUE(simple_loader_helper.response_body());
+ }
+
private:
WebUITestWebUIControllerFactory factory_;
base::test::ScopedFeatureList scoped_feature_list_;
+ base::ScopedTempDir temp_dir_;
DISALLOW_COPY_AND_ASSIGN(NetworkServiceBrowserTest);
};
@@ -196,6 +229,75 @@ IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserTest,
EXPECT_FALSE(FetchResource(file_url));
}
+IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserTest,
+ SimpleUrlLoader_NoAuthWhenNoWebContents) {
+ auto request = std::make_unique<network::ResourceRequest>();
+ request->url = embedded_test_server()->GetURL("/auth-basic?password=");
+ auto loader = network::SimpleURLLoader::Create(std::move(request),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ auto loader_factory = BrowserContext::GetDefaultStoragePartition(
+ shell()->web_contents()->GetBrowserContext())
+ ->GetURLLoaderFactoryForBrowserProcess();
+ scoped_refptr<net::HttpResponseHeaders> headers;
+ base::RunLoop loop;
+ loader->DownloadHeadersOnly(
+ loader_factory.get(),
+ base::BindOnce(
+ [](base::OnceClosure quit_closure,
+ scoped_refptr<net::HttpResponseHeaders>* rh_out,
+ scoped_refptr<net::HttpResponseHeaders> rh_in) {
+ *rh_out = rh_in;
+ std::move(quit_closure).Run();
+ },
+ loop.QuitClosure(), &headers));
+ loop.Run();
+ ASSERT_TRUE(headers.get());
+ ASSERT_EQ(headers->response_code(), 401);
+}
+
+#if defined(OS_ANDROID)
+IN_PROC_BROWSER_TEST_F(NetworkServiceBrowserTest,
+ HttpCacheWrittenToDiskOnApplicationStateChange) {
+ base::ScopedAllowBlockingForTesting allow_blocking;
+
+ // Create network context with cache pointing to the temp cache dir.
+ network::mojom::NetworkContextPtr network_context;
+ network::mojom::NetworkContextParamsPtr context_params =
+ network::mojom::NetworkContextParams::New();
+ context_params->http_cache_path = GetCacheDirectory();
+ GetNetworkService()->CreateNetworkContext(mojo::MakeRequest(&network_context),
+ std::move(context_params));
+
+ network::mojom::URLLoaderFactoryParamsPtr params =
+ network::mojom::URLLoaderFactoryParams::New();
+ params->process_id = network::mojom::kBrowserProcessId;
+ params->is_corb_enabled = false;
+ network::mojom::URLLoaderFactoryPtr loader_factory;
+ network_context->CreateURLLoaderFactory(mojo::MakeRequest(&loader_factory),
+ std::move(params));
+
+ // Load a URL and check the cache index size.
+ LoadURL(embedded_test_server()->GetURL("/cachetime"), loader_factory.get());
+ int64_t directory_size = base::ComputeDirectorySize(GetCacheIndexDirectory());
+
+ // Load another URL, cache index should not be written to disk yet.
+ LoadURL(embedded_test_server()->GetURL("/cachetime?foo"),
+ loader_factory.get());
+ EXPECT_EQ(directory_size,
+ base::ComputeDirectorySize(GetCacheIndexDirectory()));
+
+ // After application state changes, cache index should be written to disk.
+ base::android::ApplicationStatusListener::NotifyApplicationStateChange(
+ base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES);
+ base::RunLoop().RunUntilIdle();
+ content::FlushNetworkServiceInstanceForTesting();
+ disk_cache::FlushCacheThreadForTesting();
+
+ EXPECT_GT(base::ComputeDirectorySize(GetCacheIndexDirectory()),
+ directory_size);
+}
+#endif
+
class NetworkServiceInProcessBrowserTest : public ContentBrowserTest {
public:
NetworkServiceInProcessBrowserTest() {
diff --git a/chromium/content/browser/network_service_client.cc b/chromium/content/browser/network_service_client.cc
index 81a0655e94e..b27a801cc8d 100644
--- a/chromium/content/browser/network_service_client.cc
+++ b/chromium/content/browser/network_service_client.cc
@@ -6,6 +6,7 @@
#include "base/optional.h"
#include "base/task/post_task.h"
+#include "base/unguessable_token.h"
#include "content/browser/browsing_data/clear_site_data_handler.h"
#include "content/browser/devtools/devtools_url_loader_interceptor.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
@@ -13,12 +14,15 @@
#include "content/browser/ssl/ssl_error_handler.h"
#include "content/browser/ssl/ssl_manager.h"
#include "content/browser/ssl_private_key_impl.h"
+#include "content/browser/web_contents/web_contents_getter_registry.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/login_delegate.h"
+#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/resource_type.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
@@ -75,8 +79,8 @@ class SSLClientAuthDelegate : public SSLClientAuthHandler::Delegate {
web_contents->GetBrowserContext();
content::ResourceContext* resource_context =
browser_context->GetResourceContext();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SSLClientAuthDelegate::CreateSSLClientAuthHandler,
base::Unretained(this), resource_context,
web_contents_getter));
@@ -102,8 +106,8 @@ class SSLClientAuthDelegate : public SSLClientAuthHandler::Delegate {
std::move(ssl_private_key_request));
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SSLClientAuthDelegate::RunCallback,
base::Unretained(this), cert, algorithm_preferences,
std::move(ssl_private_key),
@@ -116,8 +120,8 @@ class SSLClientAuthDelegate : public SSLClientAuthHandler::Delegate {
network::mojom::SSLPrivateKeyPtr ssl_private_key;
mojo::MakeRequest(&ssl_private_key);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SSLClientAuthDelegate::RunCallback,
base::Unretained(this), nullptr, std::vector<uint16_t>(),
std::move(ssl_private_key),
@@ -185,8 +189,8 @@ class LoginHandlerDelegate {
auth_challenge_responder_.set_connection_error_handler(base::BindOnce(
&LoginHandlerDelegate::OnRequestCancelled, base::Unretained(this)));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&LoginHandlerDelegate::DispatchInterceptorHookAndStart,
base::Unretained(this), process_id, routing_id,
request_id));
@@ -198,8 +202,8 @@ class LoginHandlerDelegate {
return;
// LoginDelegate::OnRequestCancelled can only be called from the IO thread.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&LoginHandlerDelegate::OnRequestCancelledOnIOThread,
base::Unretained(this)));
}
@@ -249,8 +253,8 @@ class LoginHandlerDelegate {
void RunAuthCredentials(
const base::Optional<net::AuthCredentials>& auth_credentials) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&LoginHandlerDelegate::RunAuthCredentialsOnUI,
base::Unretained(this), auth_credentials));
}
@@ -305,11 +309,51 @@ void HandleFileUploadRequest(
std::move(files)));
}
+base::RepeatingCallback<WebContents*(void)> GetWebContentsFromRegistry(
+ const base::UnguessableToken& window_id) {
+ return WebContentsGetterRegistry::GetInstance()->Get(window_id);
+}
+
+void OnCertificateRequestedContinuation(
+ uint32_t process_id,
+ uint32_t routing_id,
+ uint32_t request_id,
+ const scoped_refptr<net::SSLCertRequestInfo>& cert_info,
+ network::mojom::NetworkServiceClient::OnCertificateRequestedCallback
+ callback,
+ base::RepeatingCallback<WebContents*(void)> web_contents_getter) {
+ if (!web_contents_getter) {
+ web_contents_getter =
+ process_id != network::mojom::kBrowserProcessId
+ ? base::BindRepeating(WebContentsImpl::FromRenderFrameHostID,
+ process_id, routing_id)
+ : base::BindRepeating(WebContents::FromFrameTreeNodeId, routing_id);
+ }
+ if (!web_contents_getter.Run()) {
+ network::mojom::SSLPrivateKeyPtr ssl_private_key;
+ mojo::MakeRequest(&ssl_private_key);
+ std::move(callback).Run(nullptr, std::vector<uint16_t>(),
+ std::move(ssl_private_key),
+ true /* cancel_certificate_selection */);
+ return;
+ }
+ new SSLClientAuthDelegate(std::move(callback), std::move(web_contents_getter),
+ cert_info); // deletes self
+}
+
} // namespace
NetworkServiceClient::NetworkServiceClient(
network::mojom::NetworkServiceClientRequest network_service_client_request)
- : binding_(this, std::move(network_service_client_request)) {}
+ : binding_(this, std::move(network_service_client_request))
+#if defined(OS_ANDROID)
+ ,
+ app_status_listener_(base::android::ApplicationStatusListener::New(
+ base::BindRepeating(&NetworkServiceClient::OnApplicationStateChange,
+ base::Unretained(this))))
+#endif
+{
+}
NetworkServiceClient::~NetworkServiceClient() = default;
@@ -330,8 +374,7 @@ void NetworkServiceClient::OnAuthRequired(
: base::Bind(WebContents::FromFrameTreeNodeId, routing_id);
if (!web_contents_getter.Run()) {
- std::move(auth_challenge_responder)
- ->OnAuthCredentials(net::AuthCredentials());
+ std::move(auth_challenge_responder)->OnAuthCredentials(base::nullopt);
return;
}
@@ -351,26 +394,27 @@ void NetworkServiceClient::OnAuthRequired(
}
void NetworkServiceClient::OnCertificateRequested(
+ const base::Optional<base::UnguessableToken>& window_id,
uint32_t process_id,
uint32_t routing_id,
uint32_t request_id,
const scoped_refptr<net::SSLCertRequestInfo>& cert_info,
network::mojom::NetworkServiceClient::OnCertificateRequestedCallback
callback) {
- base::Callback<WebContents*(void)> web_contents_getter =
- process_id ? base::Bind(WebContentsImpl::FromRenderFrameHostID,
- process_id, routing_id)
- : base::Bind(WebContents::FromFrameTreeNodeId, routing_id);
- if (!web_contents_getter.Run()) {
- network::mojom::SSLPrivateKeyPtr ssl_private_key;
- mojo::MakeRequest(&ssl_private_key);
- std::move(callback).Run(nullptr, std::vector<uint16_t>(),
- std::move(ssl_private_key),
- true /* cancel_certificate_selection */);
+ base::RepeatingCallback<WebContents*(void)> web_contents_getter;
+
+ // Use |window_id| if it's provided.
+ if (window_id) {
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&GetWebContentsFromRegistry, *window_id),
+ base::BindOnce(&OnCertificateRequestedContinuation, process_id,
+ routing_id, request_id, cert_info, std::move(callback)));
return;
}
- new SSLClientAuthDelegate(std::move(callback), std::move(web_contents_getter),
- cert_info); // deletes self
+
+ OnCertificateRequestedContinuation(process_id, routing_id, request_id,
+ cert_info, std::move(callback), {});
}
void NetworkServiceClient::OnSSLCertificateError(
@@ -473,4 +517,11 @@ void NetworkServiceClient::OnClearSiteData(int process_id,
std::move(callback));
}
+#if defined(OS_ANDROID)
+void NetworkServiceClient::OnApplicationStateChange(
+ base::android::ApplicationState state) {
+ GetNetworkService()->OnApplicationStateChange(state);
+}
+#endif
+
} // namespace content
diff --git a/chromium/content/browser/network_service_client.h b/chromium/content/browser/network_service_client.h
index 1c0edbed8db..53ed471a6e1 100644
--- a/chromium/content/browser/network_service_client.h
+++ b/chromium/content/browser/network_service_client.h
@@ -6,11 +6,16 @@
#define CONTENT_BROWSER_NETWORK_SERVICE_IMPL_H_
#include "base/macros.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "url/gurl.h"
+#if defined(OS_ANDROID)
+#include "base/android/application_status_listener.h"
+#endif
+
namespace content {
class CONTENT_EXPORT NetworkServiceClient
@@ -33,6 +38,7 @@ class CONTENT_EXPORT NetworkServiceClient
network::mojom::AuthChallengeResponderPtr
auth_challenge_responder) override;
void OnCertificateRequested(
+ const base::Optional<base::UnguessableToken>& window_id,
uint32_t process_id,
uint32_t routing_id,
uint32_t request_id,
@@ -72,9 +78,18 @@ class CONTENT_EXPORT NetworkServiceClient
int load_flags,
OnClearSiteDataCallback callback) override;
+#if defined(OS_ANDROID)
+ void OnApplicationStateChange(base::android::ApplicationState state);
+#endif
+
private:
mojo::Binding<network::mojom::NetworkServiceClient> binding_;
+#if defined(OS_ANDROID)
+ std::unique_ptr<base::android::ApplicationStatusListener>
+ app_status_listener_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(NetworkServiceClient);
};
diff --git a/chromium/content/browser/network_service_instance.cc b/chromium/content/browser/network_service_instance.cc
index 905301ab321..e2e06d84c84 100644
--- a/chromium/content/browser/network_service_instance.cc
+++ b/chromium/content/browser/network_service_instance.cc
@@ -4,8 +4,20 @@
#include "content/public/browser/network_service_instance.h"
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/environment.h"
#include "base/feature_list.h"
+#include "base/no_destructor.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
+#include "build/build_config.h"
#include "content/browser/network_service_client.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/service_manager_connection.h"
@@ -15,6 +27,7 @@
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_connection_tracker.h"
#include "services/network/public/cpp/network_switches.h"
+#include "services/network/public/mojom/net_log.mojom.h"
#include "services/network/public/mojom/network_change_manager.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
@@ -43,6 +56,24 @@ void BindNetworkChangeManagerRequest(
GetNetworkService()->GetNetworkChangeManager(std::move(request));
}
+using CrashHandlersMap =
+ std::map<NetworkServiceCrashHandlerId, base::RepeatingClosure>;
+CrashHandlersMap& GetCrashHandlersMap() {
+ static base::NoDestructor<CrashHandlersMap> s_map;
+ return *s_map;
+}
+
+void OnNetworkServiceCrash() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(g_network_service_ptr);
+ DCHECK(g_network_service_ptr->is_bound());
+ DCHECK(g_network_service_ptr->encountered_error());
+ for (const auto& it : GetCrashHandlersMap()) {
+ const base::RepeatingClosure& handler = it.second;
+ handler.Run();
+ }
+}
+
} // namespace
network::mojom::NetworkService* GetNetworkService() {
@@ -64,10 +95,12 @@ CONTENT_EXPORT network::mojom::NetworkService* GetNetworkServiceFromConnector(
if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
connector->BindInterface(mojom::kNetworkServiceName,
g_network_service_ptr);
+ g_network_service_ptr->set_connection_error_handler(
+ base::BindOnce(&OnNetworkServiceCrash));
} else {
DCHECK(!g_network_service_ptr->is_bound());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(CreateNetworkServiceOnIO,
mojo::MakeRequest(g_network_service_ptr)));
}
@@ -77,31 +110,83 @@ CONTENT_EXPORT network::mojom::NetworkService* GetNetworkServiceFromConnector(
g_client = new NetworkServiceClient(mojo::MakeRequest(&client_ptr));
(*g_network_service_ptr)->SetClient(std::move(client_ptr));
- if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(network::switches::kLogNetLog)) {
- base::FilePath log_path =
- command_line->GetSwitchValuePath(network::switches::kLogNetLog);
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ if (command_line->HasSwitch(network::switches::kLogNetLog)) {
+ base::FilePath log_path =
+ command_line->GetSwitchValuePath(network::switches::kLogNetLog);
+
+ base::DictionaryValue client_constants =
+ GetContentClient()->GetNetLogConstants();
+
+ base::File file(log_path, base::File::FLAG_CREATE_ALWAYS |
+ base::File::FLAG_WRITE);
+ LOG_IF(ERROR, !file.IsValid())
+ << "Failed opening: " << log_path.value();
+
+ // TODO(mmenke): Get capture mode from the command line.
+ (*g_network_service_ptr)
+ ->StartNetLog(std::move(file),
+ network::mojom::NetLogCaptureMode::DEFAULT,
+ std::move(client_constants));
+ }
+ }
- base::DictionaryValue client_constants =
- GetContentClient()->GetNetLogConstants();
+ if (command_line->HasSwitch(network::switches::kSSLKeyLogFile)) {
+ base::FilePath log_path =
+ command_line->GetSwitchValuePath(network::switches::kSSLKeyLogFile);
+ LOG_IF(WARNING, log_path.empty())
+ << "ssl-key-log-file argument missing";
+ if (!log_path.empty())
+ (*g_network_service_ptr)->SetSSLKeyLogFile(log_path);
+ }
- base::File file(
- log_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
- LOG_IF(ERROR, !file.IsValid())
- << "Failed opening: " << log_path.value();
- (*g_network_service_ptr)
- ->StartNetLog(std::move(file), std::move(client_constants));
+ std::unique_ptr<base::Environment> env(base::Environment::Create());
+ std::string env_str;
+ if (env->GetVar("SSLKEYLOGFILE", &env_str)) {
+#if defined(OS_WIN)
+ // base::Environment returns environment variables in UTF-8 on Windows.
+ base::FilePath log_path(base::UTF8ToUTF16(env_str));
+#else
+ base::FilePath log_path(env_str);
+#endif
+ if (!log_path.empty())
+ (*g_network_service_ptr)->SetSSLKeyLogFile(log_path);
}
- }
- GetContentClient()->browser()->OnNetworkServiceCreated(
- g_network_service_ptr->get());
+ GetContentClient()->browser()->OnNetworkServiceCreated(
+ g_network_service_ptr->get());
}
return g_network_service_ptr->get();
}
+NetworkServiceCrashHandlerId RegisterNetworkServiceCrashHandler(
+ base::RepeatingClosure handler) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!handler.is_null());
+
+ static int next_handler_id = 1;
+ NetworkServiceCrashHandlerId handler_id =
+ NetworkServiceCrashHandlerId::FromUnsafeValue(next_handler_id++);
+
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ CrashHandlersMap& map = GetCrashHandlersMap();
+ map[handler_id] = std::move(handler);
+ }
+
+ return handler_id;
+}
+
+void UnregisterNetworkServiceCrashHandler(
+ NetworkServiceCrashHandlerId handler_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ CrashHandlersMap& map = GetCrashHandlersMap();
+ map.erase(handler_id);
+ }
+}
+
network::NetworkService* GetNetworkServiceImpl() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
@@ -129,9 +214,19 @@ network::NetworkConnectionTracker* GetNetworkConnectionTracker() {
return g_network_connection_tracker;
}
+void GetNetworkConnectionTrackerFromUIThread(
+ base::OnceCallback<void(network::NetworkConnectionTracker*)> callback) {
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI, base::TaskPriority::BEST_EFFORT},
+ base::BindOnce(&GetNetworkConnectionTracker), std::move(callback));
+}
+
void SetNetworkConnectionTrackerForTesting(
network::NetworkConnectionTracker* network_connection_tracker) {
- g_network_connection_tracker = network_connection_tracker;
+ if (g_network_connection_tracker != network_connection_tracker) {
+ DCHECK(!g_network_connection_tracker || !network_connection_tracker);
+ g_network_connection_tracker = network_connection_tracker;
+ }
}
} // namespace content
diff --git a/chromium/content/browser/network_service_restart_browsertest.cc b/chromium/content/browser/network_service_restart_browsertest.cc
index a868b80d5c5..48d4220b544 100644
--- a/chromium/content/browser/network_service_restart_browsertest.cc
+++ b/chromium/content/browser/network_service_restart_browsertest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/callback.h"
+#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h"
@@ -10,6 +12,9 @@
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/frame_host/render_frame_message_filter.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/browser/service_worker/embedded_worker_instance.h"
+#include "content/browser/service_worker/embedded_worker_status.h"
+#include "content/browser/service_worker/service_worker_context_core_observer.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/url_loader_factory_getter.h"
#include "content/public/browser/browser_context.h"
@@ -32,6 +37,10 @@
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/network_service.mojom.h"
+#if BUILDFLAG(ENABLE_PLUGINS)
+#include "content/public/test/ppapi_test_utils.h"
+#endif
+
namespace content {
namespace {
@@ -100,6 +109,33 @@ void WaitForCondition(base::RepeatingCallback<bool()> condition) {
}
}
+class ServiceWorkerStatusObserver : public ServiceWorkerContextCoreObserver {
+ public:
+ void WaitForState(EmbeddedWorkerStatus expected_status) {
+ if (latest_status_ == expected_status)
+ return;
+
+ expected_status_ = expected_status;
+ base::RunLoop loop;
+ callback_ = loop.QuitClosure();
+ loop.Run();
+ }
+
+ private:
+ void OnRunningStateChanged(int64_t version_id,
+ EmbeddedWorkerStatus running_status) override {
+ latest_status_ = running_status;
+ if (expected_status_.has_value() &&
+ running_status == expected_status_.value()) {
+ std::move(callback_).Run();
+ }
+ }
+
+ base::Optional<EmbeddedWorkerStatus> expected_status_;
+ EmbeddedWorkerStatus latest_status_;
+ base::OnceClosure callback_;
+};
+
} // namespace
// This test source has been excluded from Android as Android doesn't have
@@ -111,10 +147,18 @@ class NetworkServiceRestartBrowserTest : public ContentBrowserTest {
network::features::kNetworkService);
}
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+#if BUILDFLAG(ENABLE_PLUGINS)
+ ASSERT_TRUE(ppapi::RegisterCorbTestPlugin(command_line));
+#endif
+ ContentBrowserTest::SetUpCommandLine(command_line);
+ }
+
void SetUpOnMainThread() override {
embedded_test_server()->RegisterRequestMonitor(
base::BindRepeating(&NetworkServiceRestartBrowserTest::MonitorRequest,
base::Unretained(this)));
+ host_resolver()->AddRule("*", "127.0.0.1");
EXPECT_TRUE(embedded_test_server()->Start());
ContentBrowserTest::SetUpOnMainThread();
}
@@ -279,6 +323,61 @@ IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
EXPECT_FALSE(network_context2.encountered_error());
}
+void IncrementInt(int* i) {
+ *i = *i + 1;
+}
+
+// This test verifies basic functionality of RegisterNetworkServiceCrashHandler
+// and UnregisterNetworkServiceCrashHandler.
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, CrashHandlers) {
+ network::mojom::NetworkContextPtr network_context = CreateNetworkContext();
+ EXPECT_TRUE(network_context.is_bound());
+
+ // Register 2 crash handlers.
+ int counter1 = 0;
+ int counter2 = 0;
+ NetworkServiceCrashHandlerId handler_id1 = RegisterNetworkServiceCrashHandler(
+ base::BindRepeating(&IncrementInt, base::Unretained(&counter1)));
+ NetworkServiceCrashHandlerId handler_id2 = RegisterNetworkServiceCrashHandler(
+ base::BindRepeating(&IncrementInt, base::Unretained(&counter2)));
+
+ // Crash the NetworkService process.
+ SimulateNetworkServiceCrash();
+ // |network_context| will receive an error notification, but it's not
+ // guaranteed to have arrived at this point. Flush the pointer to make sure
+ // the notification has been received.
+ network_context.FlushForTesting();
+ EXPECT_TRUE(network_context.is_bound());
+ EXPECT_TRUE(network_context.encountered_error());
+
+ // Verify the crash handlers executed.
+ EXPECT_EQ(1, counter1);
+ EXPECT_EQ(1, counter2);
+
+ // Revive the NetworkService process.
+ network_context = CreateNetworkContext();
+ EXPECT_TRUE(network_context.is_bound());
+
+ // Unregister one of the handlers.
+ UnregisterNetworkServiceCrashHandler(handler_id2);
+
+ // Crash the NetworkService process.
+ SimulateNetworkServiceCrash();
+ // |network_context| will receive an error notification, but it's not
+ // guaranteed to have arrived at this point. Flush the pointer to make sure
+ // the notification has been received.
+ network_context.FlushForTesting();
+ EXPECT_TRUE(network_context.is_bound());
+ EXPECT_TRUE(network_context.encountered_error());
+
+ // Verify only the first crash handler executed.
+ EXPECT_EQ(2, counter1);
+ EXPECT_EQ(1, counter2);
+
+ // Test cleanup.
+ UnregisterNetworkServiceCrashHandler(handler_id1);
+}
+
// Make sure |StoragePartitionImpl::GetNetworkContext()| returns valid interface
// after crash.
IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
@@ -592,6 +691,224 @@ IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, MultipleWorkerFetch) {
EXPECT_EQ(last_request_relative_url(), "/title2.html");
}
+// Flaky on Linux TSan (https://crbug.com/889855)
+#if defined(OS_LINUX) && defined(THREAD_SANITIZER)
+#define MAYBE_FetchFromServiceWorkerControlledPage_NoFetchHandler \
+ DISABLED_FetchFromServiceWorkerControlledPage_NoFetchHandler
+#else
+#define MAYBE_FetchFromServiceWorkerControlledPage_NoFetchHandler \
+ FetchFromServiceWorkerControlledPage_NoFetchHandler
+#endif
+// Make sure fetch from a page controlled by a service worker which doesn't have
+// a fetch handler works after crash.
+IN_PROC_BROWSER_TEST_F(
+ NetworkServiceRestartBrowserTest,
+ MAYBE_FetchFromServiceWorkerControlledPage_NoFetchHandler) {
+ StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+ BrowserContext::GetDefaultStoragePartition(browser_context()));
+ ServiceWorkerStatusObserver observer;
+ ServiceWorkerContextWrapper* service_worker_context =
+ partition->GetServiceWorkerContext();
+ service_worker_context->AddObserver(&observer);
+
+ // Register a service worker which controls /service_worker/.
+ EXPECT_TRUE(NavigateToURL(shell(),
+ embedded_test_server()->GetURL(
+ "/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE", EvalJs(shell(), "register('empty.js')"));
+
+ // Navigate to a controlled page.
+ EXPECT_TRUE(NavigateToURL(
+ shell(),
+ embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
+
+ // Fetch from the controlled page.
+ const std::string script = "fetch_from_page('/echo');";
+ EXPECT_EQ("Echo", EvalJs(shell(), script));
+
+ // Crash the NetworkService process. Existing interfaces should receive error
+ // notifications at some point.
+ SimulateNetworkServiceCrash();
+ // Flush the interface to make sure the error notification was received.
+ partition->FlushNetworkInterfaceForTesting();
+
+ // Service worker should be stopped when network service crashes.
+ observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
+
+ // Fetch from the controlled page again.
+ EXPECT_EQ("Echo", EvalJs(shell(), script));
+
+ service_worker_context->RemoveObserver(&observer);
+}
+
+// Flaky on Linux TSan (https://crbug.com/889855)
+#if defined(OS_LINUX) && defined(THREAD_SANITIZER)
+#define MAYBE_FetchFromServiceWorkerControlledPage_PassThrough \
+ DISABLED_FetchFromServiceWorkerControlledPage_PassThrough
+#else
+#define MAYBE_FetchFromServiceWorkerControlledPage_PassThrough \
+ FetchFromServiceWorkerControlledPage_PassThrough
+#endif
+// Make sure fetch from a page controlled by a service worker which has a fetch
+// handler but falls back to the network works after crash.
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
+ MAYBE_FetchFromServiceWorkerControlledPage_PassThrough) {
+ StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+ BrowserContext::GetDefaultStoragePartition(browser_context()));
+ ServiceWorkerStatusObserver observer;
+ ServiceWorkerContextWrapper* service_worker_context =
+ partition->GetServiceWorkerContext();
+ service_worker_context->AddObserver(&observer);
+
+ // Register a service worker which controls /service_worker/.
+ EXPECT_TRUE(NavigateToURL(shell(),
+ embedded_test_server()->GetURL(
+ "/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE", EvalJs(shell(), "register('fetch_event_pass_through.js')"));
+
+ // Navigate to a controlled page.
+ EXPECT_TRUE(NavigateToURL(
+ shell(),
+ embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
+
+ // Fetch from the controlled page.
+ const std::string script = "fetch_from_page('/echo');";
+ EXPECT_EQ("Echo", EvalJs(shell(), script));
+
+ // Crash the NetworkService process. Existing interfaces should receive error
+ // notifications at some point.
+ SimulateNetworkServiceCrash();
+ // Flush the interface to make sure the error notification was received.
+ partition->FlushNetworkInterfaceForTesting();
+
+ // Service worker should be stopped when network service crashes.
+ observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
+
+ // Fetch from the controlled page again.
+ EXPECT_EQ("Echo", EvalJs(shell(), script));
+
+ service_worker_context->RemoveObserver(&observer);
+}
+
+// Flaky on Linux TSan (https://crbug.com/889855)
+#if defined(OS_LINUX) && defined(THREAD_SANITIZER)
+#define MAYBE_FetchFromServiceWorkerControlledPage_RespondWithFetch \
+ DISABLED_FetchFromServiceWorkerControlledPage_RespondWithFetch
+#else
+#define MAYBE_FetchFromServiceWorkerControlledPage_RespondWithFetch \
+ FetchFromServiceWorkerControlledPage_RespondWithFetch
+#endif
+// Make sure fetch from a page controlled by a service worker which has a fetch
+// handler and responds with fetch() works after crash.
+IN_PROC_BROWSER_TEST_F(
+ NetworkServiceRestartBrowserTest,
+ MAYBE_FetchFromServiceWorkerControlledPage_RespondWithFetch) {
+ StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+ BrowserContext::GetDefaultStoragePartition(browser_context()));
+ ServiceWorkerStatusObserver observer;
+ ServiceWorkerContextWrapper* service_worker_context =
+ partition->GetServiceWorkerContext();
+ service_worker_context->AddObserver(&observer);
+
+ // Register a service worker which controls /service_worker/.
+ EXPECT_TRUE(NavigateToURL(shell(),
+ embedded_test_server()->GetURL(
+ "/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE",
+ EvalJs(shell(), "register('fetch_event_respond_with_fetch.js')"));
+
+ // Navigate to a controlled page.
+ EXPECT_TRUE(NavigateToURL(
+ shell(),
+ embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
+
+ // Fetch from the controlled page.
+ const std::string script = "fetch_from_page('/echo');";
+ EXPECT_EQ("Echo", EvalJs(shell(), script));
+
+ // Crash the NetworkService process. Existing interfaces should receive error
+ // notifications at some point.
+ SimulateNetworkServiceCrash();
+ // Flush the interface to make sure the error notification was received.
+ partition->FlushNetworkInterfaceForTesting();
+
+ // Service worker should be stopped when network service crashes.
+ observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
+
+ // Fetch from the controlled page again.
+ EXPECT_EQ("Echo", EvalJs(shell(), script));
+
+ service_worker_context->RemoveObserver(&observer);
+}
+
+// Make sure fetch from service worker context works after crash.
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, ServiceWorkerFetch) {
+ StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+ BrowserContext::GetDefaultStoragePartition(browser_context()));
+ ServiceWorkerStatusObserver observer;
+ ServiceWorkerContextWrapper* service_worker_context =
+ partition->GetServiceWorkerContext();
+ service_worker_context->AddObserver(&observer);
+
+ const GURL page_url = embedded_test_server()->GetURL(
+ "/service_worker/fetch_from_service_worker.html");
+ const GURL fetch_url = embedded_test_server()->GetURL("/echo");
+
+ // Navigate to the page and register a service worker.
+ EXPECT_TRUE(NavigateToURL(shell(), page_url));
+ EXPECT_EQ("ready", EvalJs(shell(), "setup();"));
+
+ // Fetch from the service worker.
+ const std::string script =
+ "fetch_from_service_worker('" + fetch_url.spec() + "');";
+ EXPECT_EQ("Echo", EvalJs(shell(), script));
+
+ // Crash the NetworkService process. Existing interfaces should receive error
+ // notifications at some point.
+ SimulateNetworkServiceCrash();
+ // Flush the interface to make sure the error notification was received.
+ partition->FlushNetworkInterfaceForTesting();
+
+ // Service worker should be stopped when network service crashes.
+ observer.WaitForState(EmbeddedWorkerStatus::STOPPED);
+
+ // Fetch from the service worker again.
+ EXPECT_EQ("Echo", EvalJs(shell(), script));
+
+ service_worker_context->RemoveObserver(&observer);
+}
+
+// Make sure shared workers terminate after crash.
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, SharedWorker) {
+ StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+ BrowserContext::GetDefaultStoragePartition(browser_context()));
+
+ const GURL page_url =
+ embedded_test_server()->GetURL("/workers/fetch_from_shared_worker.html");
+ const GURL fetch_url = embedded_test_server()->GetURL("/echo");
+
+ // Navigate to the page and prepare a shared worker.
+ EXPECT_TRUE(NavigateToURL(shell(), page_url));
+
+ // Fetch from the shared worker to ensure it has started.
+ const std::string script =
+ "fetch_from_shared_worker('" + fetch_url.spec() + "');";
+ EXPECT_EQ("Echo", EvalJs(shell(), script));
+
+ // There should be one worker host. We will later wait for it to terminate.
+ SharedWorkerServiceImpl* service = partition->GetSharedWorkerService();
+ EXPECT_EQ(1u, service->worker_hosts_.size());
+ base::RunLoop loop;
+ service->SetWorkerTerminationCallbackForTesting(loop.QuitClosure());
+
+ // Crash the NetworkService process.
+ SimulateNetworkServiceCrash();
+
+ // Wait for the worker to detect the crash and self-terminate.
+ loop.Run();
+ EXPECT_TRUE(service->worker_hosts_.empty());
+}
+
// Make sure the entry in |NetworkService::GetTotalNetworkUsages()| was cleared
// after process closed.
IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
@@ -670,7 +987,8 @@ IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest,
// Make sure cookie access doesn't hang or fail after a network process crash.
IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Cookies) {
auto* web_contents = shell()->web_contents();
- NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"));
+ ASSERT_TRUE(
+ NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
EXPECT_TRUE(ExecuteScript(web_contents, "document.cookie = 'foo=bar';"));
std::string cookie;
@@ -688,11 +1006,11 @@ IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Cookies) {
// Need to use FlushAsyncForTesting instead of FlushForTesting because the IO
// thread doesn't support nested message loops.
base::RunLoop run_loop;
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindLambdaForTesting([&]() {
- filter->GetCookieManager()->FlushAsyncForTesting(
- run_loop.QuitClosure());
- }));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindLambdaForTesting([&]() {
+ filter->GetCookieManager()->FlushAsyncForTesting(
+ run_loop.QuitClosure());
+ }));
// content_shell uses in-memory cookie database, so the value saved earlier
// won't persist across crashes. What matters is that new access works.
@@ -705,4 +1023,68 @@ IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Cookies) {
EXPECT_EQ("foo=bar", cookie);
}
+#if BUILDFLAG(ENABLE_PLUGINS)
+// Make sure that "trusted" plugins continue to be able to issue cross-origin
+// requests after a network process crash.
+IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, Plugin) {
+ auto* web_contents = shell()->web_contents();
+ ASSERT_TRUE(NavigateToURL(web_contents,
+ embedded_test_server()->GetURL("/title1.html")));
+
+ // Load the test plugin (see ppapi::RegisterFlashTestPlugin and
+ // ppapi/tests/power_saver_test_plugin.cc).
+ const char kLoadingScript[] = R"(
+ var obj = document.createElement('object');
+ obj.id = 'plugin';
+ obj.data = 'test.swf';
+ obj.type = 'application/x-shockwave-flash';
+ obj.width = 400;
+ obj.height = 400;
+
+ document.body.appendChild(obj);
+ )";
+ ASSERT_TRUE(ExecJs(web_contents, kLoadingScript));
+
+ // Ask the plugin to perform a cross-origin, CORB-eligible (i.e.
+ // application/json + nosniff) URL request. Plugins with universal access
+ // should not be subject to CORS/CORB and so the request should go through.
+ // See also https://crbug.com/874515 and https://crbug.com/846339.
+ GURL cross_origin_url = embedded_test_server()->GetURL(
+ "cross.origin.com", "/site_isolation/nosniff.json");
+ const char kFetchScriptTemplate[] = R"(
+ new Promise(function (resolve, reject) {
+ var obj = document.getElementById('plugin');
+ function callback(event) {
+ // Ignore plugin messages unrelated to requestUrl.
+ if (!event.data.startsWith('requestUrl: '))
+ return;
+
+ obj.removeEventListener('message', callback);
+ resolve('msg-from-plugin: ' + event.data);
+ };
+ obj.addEventListener('message', callback);
+ obj.postMessage('requestUrl: ' + $1);
+ });
+ )";
+ std::string fetch_script = JsReplace(kFetchScriptTemplate, cross_origin_url);
+ ASSERT_EQ(
+ "msg-from-plugin: requestUrl: RESPONSE BODY: "
+ "runMe({ \"name\" : \"chromium\" });\n",
+ EvalJs(web_contents, fetch_script));
+
+ // Crash the Network Service process and wait until host frame's
+ // URLLoaderFactory has been refreshed.
+ SimulateNetworkServiceCrash();
+ main_frame()->FlushNetworkAndNavigationInterfacesForTesting();
+
+ // Try the fetch again - it should still work (i.e. the mechanism for relaxing
+ // CORB for universal-access-plugins should be resilient to network process
+ // crashes). See also https://crbug.com/891904.
+ ASSERT_EQ(
+ "msg-from-plugin: requestUrl: RESPONSE BODY: "
+ "runMe({ \"name\" : \"chromium\" });\n",
+ EvalJs(web_contents, fetch_script));
+}
+#endif
+
} // namespace content
diff --git a/chromium/content/browser/notification_service_impl.cc b/chromium/content/browser/notification_service_impl.cc
index 9f38bb05106..12581ecdfa2 100644
--- a/chromium/content/browser/notification_service_impl.cc
+++ b/chromium/content/browser/notification_service_impl.cc
@@ -146,8 +146,7 @@ NotificationServiceImpl::~NotificationServiceImpl() {
for (int i = 0; i < static_cast<int>(observers_.size()); i++) {
NotificationSourceMap omap = observers_[i];
- for (NotificationSourceMap::iterator it = omap.begin();
- it != omap.end(); ++it)
+ for (auto it = omap.begin(); it != omap.end(); ++it)
delete it->second;
}
}
diff --git a/chromium/content/browser/notifications/blink_notification_service_impl.cc b/chromium/content/browser/notifications/blink_notification_service_impl.cc
index 73c5d6b436e..2a4592f1565 100644
--- a/chromium/content/browser/notifications/blink_notification_service_impl.cc
+++ b/chromium/content/browser/notifications/blink_notification_service_impl.cc
@@ -7,10 +7,13 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback_helpers.h"
+#include "base/feature_list.h"
#include "base/logging.h"
#include "base/strings/string16.h"
+#include "base/task/post_task.h"
#include "content/browser/notifications/notification_event_dispatcher_impl.h"
#include "content/browser/notifications/platform_notification_context_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/notification_database_data.h"
@@ -18,8 +21,9 @@
#include "content/public/browser/permission_type.h"
#include "content/public/browser/platform_notification_service.h"
#include "content/public/common/content_client.h"
-#include "content/public/common/notification_resources.h"
-#include "content/public/common/platform_notification_data.h"
+#include "content/public/common/content_features.h"
+#include "third_party/blink/public/common/notifications/notification_resources.h"
+#include "third_party/blink/public/common/notifications/platform_notification_data.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"
@@ -27,6 +31,10 @@ namespace content {
namespace {
+const char kBadMessageImproperNotificationImage[] =
+ "Received an unexpected message with image while notification images are "
+ "disabled.";
+
// Returns the implementation of the PlatformNotificationService. May be NULL.
PlatformNotificationService* GetNotificationService() {
return GetContentClient()->browser()->GetPlatformNotificationService();
@@ -79,10 +87,13 @@ void BlinkNotificationServiceImpl::OnConnectionError() {
void BlinkNotificationServiceImpl::DisplayNonPersistentNotification(
const std::string& token,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources,
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources,
blink::mojom::NonPersistentNotificationListenerPtr event_listener_ptr) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!ValidateNotificationResources(notification_resources))
+ return;
+
if (!GetNotificationService())
return;
@@ -133,12 +144,28 @@ BlinkNotificationServiceImpl::CheckPermissionStatus() {
origin_.GetURL());
}
+bool BlinkNotificationServiceImpl::ValidateNotificationResources(
+ const blink::NotificationResources& notification_resources) {
+ if (notification_resources.image.drawsNothing() ||
+ base::FeatureList::IsEnabled(features::kNotificationContentImage))
+ return true;
+ binding_.ReportBadMessage(kBadMessageImproperNotificationImage);
+ // The above ReportBadMessage() closes |binding_| but does not trigger its
+ // connection error handler, so we need to call the error handler explicitly
+ // here to do some necessary work.
+ OnConnectionError();
+ return false;
+}
+
void BlinkNotificationServiceImpl::DisplayPersistentNotification(
int64_t service_worker_registration_id,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources,
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources,
DisplayPersistentNotificationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!ValidateNotificationResources(notification_resources))
+ return;
+
if (!GetNotificationService()) {
std::move(callback).Run(PersistentNotificationError::INTERNAL_ERROR);
return;
@@ -153,8 +180,8 @@ void BlinkNotificationServiceImpl::DisplayPersistentNotification(
GetNotificationService()->ReadNextPersistentNotificationId(
browser_context_);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BlinkNotificationServiceImpl::
DisplayPersistentNotificationOnIOThread,
weak_factory_for_io_.GetWeakPtr(),
@@ -166,8 +193,8 @@ void BlinkNotificationServiceImpl::DisplayPersistentNotification(
void BlinkNotificationServiceImpl::DisplayPersistentNotificationOnIOThread(
int64_t service_worker_registration_id,
int64_t next_persistent_notification_id,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources,
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources,
DisplayPersistentNotificationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -193,15 +220,15 @@ void BlinkNotificationServiceImpl::DisplayPersistentNotificationOnIOThread(
void BlinkNotificationServiceImpl::
DisplayPersistentNotificationWithIdOnIOThread(
int64_t service_worker_registration_id,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources,
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources,
DisplayPersistentNotificationCallback callback,
bool success,
const std::string& notification_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!success) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback),
PersistentNotificationError::INTERNAL_ERROR));
return;
@@ -220,8 +247,8 @@ void BlinkNotificationServiceImpl::
void BlinkNotificationServiceImpl::
DisplayPersistentNotificationWithServiceWorkerOnIOThread(
const std::string& notification_id,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources,
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources,
DisplayPersistentNotificationCallback callback,
blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> registration) {
@@ -233,8 +260,8 @@ void BlinkNotificationServiceImpl::
// of the notification's sender.
if (service_worker_status == blink::ServiceWorkerStatusCode::kOk &&
registration->pattern().GetOrigin() == origin_.GetURL()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&PlatformNotificationService::DisplayPersistentNotification,
base::Unretained(GetNotificationService()), browser_context_,
@@ -244,8 +271,8 @@ void BlinkNotificationServiceImpl::
error = PersistentNotificationError::NONE;
}
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), error));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), error));
}
void BlinkNotificationServiceImpl::ClosePersistentNotification(
@@ -263,8 +290,8 @@ void BlinkNotificationServiceImpl::ClosePersistentNotification(
// Deleting the data associated with |notification_id| from the notification
// database has to be done on the IO thread, but there's no reason to postpone
// removing the notification from the user's display until that's done.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PlatformNotificationContextImpl::DeleteNotificationData,
notification_context_, notification_id, origin_.GetURL(),
base::DoNothing()));
@@ -281,7 +308,7 @@ void BlinkNotificationServiceImpl::GetNotifications(
// try to get notifications without permission, so return empty vectors
// indicating that no (accessible) notifications exist at this time.
std::move(callback).Run(std::vector<std::string>(),
- std::vector<PlatformNotificationData>());
+ std::vector<blink::PlatformNotificationData>());
return;
}
@@ -289,8 +316,8 @@ void BlinkNotificationServiceImpl::GetNotifications(
&BlinkNotificationServiceImpl::DidGetNotificationsOnIOThread,
weak_factory_for_io_.GetWeakPtr(), filter_tag, std::move(callback));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PlatformNotificationContextImpl::
ReadAllNotificationDataForServiceWorkerRegistration,
notification_context_, origin_.GetURL(),
@@ -307,7 +334,7 @@ void BlinkNotificationServiceImpl::DidGetNotificationsOnIOThread(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::vector<std::string> ids;
- std::vector<PlatformNotificationData> datas;
+ std::vector<blink::PlatformNotificationData> datas;
for (const NotificationDatabaseData& database_data : notifications) {
// An empty filter tag matches all, else we need an exact match.
@@ -319,8 +346,8 @@ void BlinkNotificationServiceImpl::DidGetNotificationsOnIOThread(
}
// Make sure to invoke the |callback| on the UI thread again.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback), std::move(ids), std::move(datas)));
}
diff --git a/chromium/content/browser/notifications/blink_notification_service_impl.h b/chromium/content/browser/notifications/blink_notification_service_impl.h
index 193f5d241c3..1ae12ca9550 100644
--- a/chromium/content/browser/notifications/blink_notification_service_impl.h
+++ b/chromium/content/browser/notifications/blink_notification_service_impl.h
@@ -16,11 +16,14 @@
#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
#include "url/origin.h"
+namespace blink {
+struct PlatformNotificationData;
+}
+
namespace content {
struct NotificationDatabaseData;
class PlatformNotificationContextImpl;
-struct PlatformNotificationData;
// Implementation of the NotificationService used for Web Notifications. Is
// responsible for displaying, updating and reading of both non-persistent
@@ -41,14 +44,14 @@ class CONTENT_EXPORT BlinkNotificationServiceImpl
void GetPermissionStatus(GetPermissionStatusCallback callback) override;
void DisplayNonPersistentNotification(
const std::string& token,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources,
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources,
blink::mojom::NonPersistentNotificationListenerPtr listener_ptr) override;
void CloseNonPersistentNotification(const std::string& token) override;
void DisplayPersistentNotification(
int64_t service_worker_registration_id,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources,
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources,
DisplayPersistentNotificationCallback) override;
void ClosePersistentNotification(const std::string& notification_id) override;
void GetNotifications(int64_t service_worker_registration_id,
@@ -62,25 +65,32 @@ class CONTENT_EXPORT BlinkNotificationServiceImpl
// Check the permission status for the current |origin_|.
blink::mojom::PermissionStatus CheckPermissionStatus();
+ // Validate |notification_resources| received in a Mojo IPC message.
+ // If the validation failed, we'd close the Mojo connection |binding_| and
+ // destroy |this| by calling OnConnectionError() directly, then return false.
+ // So, please do not touch |this| again after you got a false return value.
+ bool ValidateNotificationResources(
+ const blink::NotificationResources& notification_resources);
+
void DisplayPersistentNotificationOnIOThread(
int64_t service_worker_registration_id,
int64_t persistent_notification_id,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources,
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources,
DisplayPersistentNotificationCallback callback);
void DisplayPersistentNotificationWithIdOnIOThread(
int64_t service_worker_registration_id,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources,
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources,
DisplayPersistentNotificationCallback callback,
bool success,
const std::string& notification_id);
void DisplayPersistentNotificationWithServiceWorkerOnIOThread(
const std::string& notification_id,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources,
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources,
DisplayPersistentNotificationCallback callback,
blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> registration);
diff --git a/chromium/content/browser/notifications/blink_notification_service_impl_unittest.cc b/chromium/content/browser/notifications/blink_notification_service_impl_unittest.cc
index 618c7bd88cd..9985cfee820 100644
--- a/chromium/content/browser/notifications/blink_notification_service_impl_unittest.cc
+++ b/chromium/content/browser/notifications/blink_notification_service_impl_unittest.cc
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
+#include "base/test/scoped_feature_list.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/notifications/blink_notification_service_impl.h"
@@ -19,18 +20,21 @@
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/browser/permission_type.h"
+#include "content/public/common/content_features.h"
#include "content/public/test/mock_permission_manager.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "content/test/mock_platform_notification_service.h"
#include "content/test/test_content_browser_client.h"
+#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom.h"
#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
+#include "third_party/skia/include/core/SkBitmap.h"
using ::testing::Return;
using ::testing::_;
@@ -41,6 +45,16 @@ namespace {
const char kTestOrigin[] = "https://example.com";
const char kTestServiceWorkerUrl[] = "https://example.com/sw.js";
+const char kBadMessageImproperNotificationImage[] =
+ "Received an unexpected message with image while notification images are "
+ "disabled.";
+
+SkBitmap CreateBitmap(int width, int height, SkColor color) {
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(width, height);
+ bitmap.eraseColor(color);
+ return bitmap;
+}
class MockNonPersistentNotificationListener
: public blink::mojom::NonPersistentNotificationListener {
@@ -110,19 +124,25 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
// will be initialized long before it is read from so this is fine.
RunAllTasksUntilIdle();
- blink::mojom::NotificationServicePtr notification_service_ptr;
notification_service_ = std::make_unique<BlinkNotificationServiceImpl>(
notification_context_.get(), &browser_context_,
embedded_worker_helper_->context_wrapper(),
url::Origin::Create(GURL(kTestOrigin)),
- mojo::MakeRequest(&notification_service_ptr));
+ mojo::MakeRequest(&notification_service_ptr_));
// Provide a mock permission manager to the |browser_context_|.
browser_context_.SetPermissionControllerDelegate(
std::make_unique<testing::NiceMock<MockPermissionManager>>());
+
+ mojo::core::SetDefaultProcessErrorCallback(base::AdaptCallbackForRepeating(
+ base::BindOnce(&BlinkNotificationServiceImplTest::OnMojoError,
+ base::Unretained(this))));
}
void TearDown() override {
+ mojo::core::SetDefaultProcessErrorCallback(
+ mojo::core::ProcessErrorCallback());
+
embedded_worker_helper_.reset();
// Give pending shutdown operations a chance to finish.
@@ -222,7 +242,7 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
void DidGetNotifications(
base::OnceClosure quit_closure,
const std::vector<std::string>& notification_ids,
- const std::vector<PlatformNotificationData>& notification_datas) {
+ const std::vector<blink::PlatformNotificationData>& notification_datas) {
get_notifications_callback_result_ = notification_ids;
std::move(quit_closure).Run();
}
@@ -242,12 +262,29 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
std::move(quit_closure).Run();
}
+ void DisplayNonPersistentNotification(
+ const std::string& token,
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources,
+ blink::mojom::NonPersistentNotificationListenerPtr event_listener_ptr) {
+ notification_service_ptr_->DisplayNonPersistentNotification(
+ token, platform_notification_data, notification_resources,
+ std::move(event_listener_ptr));
+ // TODO(https://crbug.com/787459): Pass a callback to
+ // DisplayNonPersistentNotification instead of waiting for all tasks to run
+ // here; a callback parameter will be needed anyway to enable
+ // non-persistent notification event acknowledgements - see bug.
+ RunAllTasksUntilIdle();
+ }
+
void DisplayPersistentNotificationSync(
int64_t service_worker_registration_id,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources) {
+ const blink::PlatformNotificationData& platform_notification_data,
+ const blink::NotificationResources& notification_resources) {
base::RunLoop run_loop;
- notification_service_->DisplayPersistentNotification(
+ notification_service_ptr_.set_connection_error_handler(
+ run_loop.QuitClosure());
+ notification_service_ptr_->DisplayPersistentNotification(
service_worker_registration_id, platform_notification_data,
notification_resources,
base::BindOnce(
@@ -308,12 +345,16 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
}
protected:
+ void OnMojoError(const std::string& error) { bad_messages_.push_back(error); }
+
TestBrowserThreadBundle thread_bundle_; // Must be first member.
std::unique_ptr<EmbeddedWorkerTestHelper> embedded_worker_helper_;
std::unique_ptr<BlinkNotificationServiceImpl> notification_service_;
+ blink::mojom::NotificationServicePtr notification_service_ptr_;
+
TestBrowserContext browser_context_;
scoped_refptr<PlatformNotificationContextImpl> notification_context_;
@@ -324,6 +365,8 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
blink::mojom::PersistentNotificationError display_persistent_callback_result_;
+ std::vector<std::string> bad_messages_;
+
private:
NotificationBrowserClient notification_browser_client_;
@@ -383,16 +426,11 @@ TEST_F(BlinkNotificationServiceImplTest,
DisplayNonPersistentNotificationWithPermission) {
SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
- notification_service_->DisplayNonPersistentNotification(
- "token", PlatformNotificationData(), NotificationResources(),
+ DisplayNonPersistentNotification(
+ "token", blink::PlatformNotificationData(),
+ blink::NotificationResources(),
non_persistent_notification_listener_.GetPtr());
- // TODO(https://crbug.com/787459): Pass a callback to
- // DisplayNonPersistentNotification instead of waiting for all tasks to run
- // here; a callback parameter will be needed anyway to enable
- // non-persistent notification event acknowledgements - see bug.
- RunAllTasksUntilIdle();
-
EXPECT_EQ(1u, GetDisplayedNotifications().size());
}
@@ -400,28 +438,94 @@ TEST_F(BlinkNotificationServiceImplTest,
DisplayNonPersistentNotificationWithoutPermission) {
SetPermissionStatus(blink::mojom::PermissionStatus::DENIED);
- notification_service_->DisplayNonPersistentNotification(
- "token", PlatformNotificationData(), NotificationResources(),
+ DisplayNonPersistentNotification(
+ "token", blink::PlatformNotificationData(),
+ blink::NotificationResources(),
non_persistent_notification_listener_.GetPtr());
- // TODO(https://crbug.com/787459): Pass a callback to
- // DisplayNonPersistentNotification instead of waiting for all tasks to run
- // here; a callback parameter will be needed anyway to enable
- // non-persistent notification event acknowledgements - see bug.
+ EXPECT_EQ(0u, GetDisplayedNotifications().size());
+}
+
+TEST_F(BlinkNotificationServiceImplTest,
+ DisplayNonPersistentNotificationWithContentImageSwitchOn) {
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
+
+ blink::NotificationResources resources;
+ resources.image = CreateBitmap(200, 100, SK_ColorMAGENTA);
+ DisplayNonPersistentNotification(
+ "token", blink::PlatformNotificationData(), resources,
+ non_persistent_notification_listener_.GetPtr());
+
+ EXPECT_EQ(1u, GetDisplayedNotifications().size());
+}
+
+TEST_F(BlinkNotificationServiceImplTest,
+ DisplayNonPersistentNotificationWithContentImageSwitchOff) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndDisableFeature(
+ features::kNotificationContentImage);
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
+
+ ASSERT_TRUE(bad_messages_.empty());
+ blink::NotificationResources resources;
+ resources.image = CreateBitmap(200, 100, SK_ColorMAGENTA);
+ DisplayNonPersistentNotification(
+ "token", blink::PlatformNotificationData(), resources,
+ non_persistent_notification_listener_.GetPtr());
+ EXPECT_EQ(1u, bad_messages_.size());
+ EXPECT_EQ(kBadMessageImproperNotificationImage, bad_messages_[0]);
+}
+
+TEST_F(BlinkNotificationServiceImplTest,
+ DisplayPersistentNotificationWithContentImageSwitchOn) {
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
+
+ scoped_refptr<ServiceWorkerRegistration> registration;
+ RegisterServiceWorker(&registration);
+
+ blink::NotificationResources resources;
+ resources.image = CreateBitmap(200, 100, SK_ColorMAGENTA);
+ DisplayPersistentNotificationSync(
+ registration->id(), blink::PlatformNotificationData(), resources);
+
+ EXPECT_EQ(blink::mojom::PersistentNotificationError::NONE,
+ display_persistent_callback_result_);
+
+ // Wait for service to receive the Display call.
RunAllTasksUntilIdle();
- EXPECT_EQ(0u, GetDisplayedNotifications().size());
+ EXPECT_EQ(1u, GetDisplayedNotifications().size());
}
TEST_F(BlinkNotificationServiceImplTest,
- DisplayPersistentNotificationWithPermission) {
+ DisplayPersistentNotificationWithContentImageSwitchOff) {
+ base::test::ScopedFeatureList scoped_feature_list;
+ scoped_feature_list.InitAndDisableFeature(
+ features::kNotificationContentImage);
SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
+ ASSERT_TRUE(bad_messages_.empty());
+ blink::NotificationResources resources;
+ resources.image = CreateBitmap(200, 100, SK_ColorMAGENTA);
DisplayPersistentNotificationSync(
- registration->id(), PlatformNotificationData(), NotificationResources());
+ registration->id(), blink::PlatformNotificationData(), resources);
+ EXPECT_EQ(1u, bad_messages_.size());
+ EXPECT_EQ(kBadMessageImproperNotificationImage, bad_messages_[0]);
+}
+
+TEST_F(BlinkNotificationServiceImplTest,
+ DisplayPersistentNotificationWithPermission) {
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
+
+ scoped_refptr<ServiceWorkerRegistration> registration;
+ RegisterServiceWorker(&registration);
+
+ DisplayPersistentNotificationSync(registration->id(),
+ blink::PlatformNotificationData(),
+ blink::NotificationResources());
EXPECT_EQ(blink::mojom::PersistentNotificationError::NONE,
display_persistent_callback_result_);
@@ -438,8 +542,9 @@ TEST_F(BlinkNotificationServiceImplTest, CloseDisplayedPersistentNotification) {
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
- DisplayPersistentNotificationSync(
- registration->id(), PlatformNotificationData(), NotificationResources());
+ DisplayPersistentNotificationSync(registration->id(),
+ blink::PlatformNotificationData(),
+ blink::NotificationResources());
ASSERT_EQ(blink::mojom::PersistentNotificationError::NONE,
display_persistent_callback_result_);
@@ -465,8 +570,9 @@ TEST_F(BlinkNotificationServiceImplTest,
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
- DisplayPersistentNotificationSync(
- registration->id(), PlatformNotificationData(), NotificationResources());
+ DisplayPersistentNotificationSync(registration->id(),
+ blink::PlatformNotificationData(),
+ blink::NotificationResources());
ASSERT_EQ(blink::mojom::PersistentNotificationError::NONE,
display_persistent_callback_result_);
@@ -498,8 +604,9 @@ TEST_F(BlinkNotificationServiceImplTest,
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
- DisplayPersistentNotificationSync(
- registration->id(), PlatformNotificationData(), NotificationResources());
+ DisplayPersistentNotificationSync(registration->id(),
+ blink::PlatformNotificationData(),
+ blink::NotificationResources());
EXPECT_EQ(blink::mojom::PersistentNotificationError::PERMISSION_DENIED,
display_persistent_callback_result_);
@@ -517,11 +624,13 @@ TEST_F(BlinkNotificationServiceImplTest,
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
- DisplayPersistentNotificationSync(
- registration->id(), PlatformNotificationData(), NotificationResources());
+ DisplayPersistentNotificationSync(registration->id(),
+ blink::PlatformNotificationData(),
+ blink::NotificationResources());
- DisplayPersistentNotificationSync(
- registration->id(), PlatformNotificationData(), NotificationResources());
+ DisplayPersistentNotificationSync(registration->id(),
+ blink::PlatformNotificationData(),
+ blink::NotificationResources());
// Wait for service to receive all the Display calls.
RunAllTasksUntilIdle();
@@ -538,8 +647,9 @@ TEST_F(BlinkNotificationServiceImplTest, GetNotifications) {
EXPECT_EQ(
0u, GetNotificationsSync(registration->id(), "" /* filter_tag */).size());
- DisplayPersistentNotificationSync(
- registration->id(), PlatformNotificationData(), NotificationResources());
+ DisplayPersistentNotificationSync(registration->id(),
+ blink::PlatformNotificationData(),
+ blink::NotificationResources());
// Wait for service to receive all the Display calls.
RunAllTasksUntilIdle();
@@ -554,8 +664,9 @@ TEST_F(BlinkNotificationServiceImplTest, GetNotificationsWithoutPermission) {
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
- DisplayPersistentNotificationSync(
- registration->id(), PlatformNotificationData(), NotificationResources());
+ DisplayPersistentNotificationSync(registration->id(),
+ blink::PlatformNotificationData(),
+ blink::NotificationResources());
// Wait for service to receive all the Display calls.
RunAllTasksUntilIdle();
@@ -572,18 +683,19 @@ TEST_F(BlinkNotificationServiceImplTest, GetNotificationsWithFilter) {
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
- PlatformNotificationData platform_notification_data;
+ blink::PlatformNotificationData platform_notification_data;
platform_notification_data.tag = "tagA";
- PlatformNotificationData other_platform_notification_data;
+ blink::PlatformNotificationData other_platform_notification_data;
other_platform_notification_data.tag = "tagB";
- DisplayPersistentNotificationSync(
- registration->id(), platform_notification_data, NotificationResources());
+ DisplayPersistentNotificationSync(registration->id(),
+ platform_notification_data,
+ blink::NotificationResources());
DisplayPersistentNotificationSync(registration->id(),
other_platform_notification_data,
- NotificationResources());
+ blink::NotificationResources());
// Wait for service to receive all the Display calls.
RunAllTasksUntilIdle();
diff --git a/chromium/content/browser/notifications/notification_database.cc b/chromium/content/browser/notifications/notification_database.cc
index bc54e5a090f..85c98c8b117 100644
--- a/chromium/content/browser/notifications/notification_database.cc
+++ b/chromium/content/browser/notifications/notification_database.cc
@@ -10,8 +10,10 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "content/browser/notifications/notification_database_data_conversions.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_database_data.h"
#include "storage/common/database/database_identifier.h"
@@ -268,8 +270,8 @@ NotificationDatabase::Status NotificationDatabase::DeleteNotificationData(
NotificationDatabaseData data;
Status status = ReadNotificationData(notification_id, origin, &data);
if (status == STATUS_OK && record_notification_to_ukm_callback_) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(record_notification_to_ukm_callback_, data));
}
std::string key = CreateDataKey(origin, notification_id);
@@ -392,8 +394,8 @@ NotificationDatabase::DeleteAllNotificationDataInternal(
}
if (record_notification_to_ukm_callback_) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(record_notification_to_ukm_callback_,
notification_database_data));
}
diff --git a/chromium/content/browser/notifications/notification_database_data.proto b/chromium/content/browser/notifications/notification_database_data.proto
index 6a631180461..e521c888634 100644
--- a/chromium/content/browser/notifications/notification_database_data.proto
+++ b/chromium/content/browser/notifications/notification_database_data.proto
@@ -35,11 +35,11 @@ message NotificationDatabaseDataProto {
optional int64 time_until_close_millis = 12;
optional ClosedReason closed_reason = 13;
- // A notification action, corresponds to content::PlatformNotificationAction.
+ // A notification action, corresponds to blink::PlatformNotificationAction.
//
// Next tag: 6
message NotificationAction {
- // Corresponds to PlatformNotificationActionType.
+ // Corresponds to blink::PlatformNotificationActionType.
enum Type {
BUTTON = 0;
TEXT = 1;
@@ -53,7 +53,7 @@ message NotificationDatabaseDataProto {
}
// Actual data payload of the notification. This message is the protocol
- // buffer meant to serialize the content::PlatformNotificationData structure.
+ // buffer meant to serialize the blink::PlatformNotificationData structure.
//
// Next tag: 16
message NotificationData {
diff --git a/chromium/content/browser/notifications/notification_database_data_conversions.cc b/chromium/content/browser/notifications/notification_database_data_conversions.cc
index 904963094eb..83b0b0043fc 100644
--- a/chromium/content/browser/notifications/notification_database_data_conversions.cc
+++ b/chromium/content/browser/notifications/notification_database_data_conversions.cc
@@ -60,7 +60,8 @@ bool DeserializeNotificationDatabaseData(const std::string& input,
break;
}
- PlatformNotificationData* notification_data = &output->notification_data;
+ blink::PlatformNotificationData* notification_data =
+ &output->notification_data;
const NotificationDatabaseDataProto::NotificationData& payload =
message.notification_data();
@@ -69,14 +70,15 @@ bool DeserializeNotificationDatabaseData(const std::string& input,
switch (payload.direction()) {
case NotificationDatabaseDataProto::NotificationData::LEFT_TO_RIGHT:
notification_data->direction =
- PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT;
+ blink::PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT;
break;
case NotificationDatabaseDataProto::NotificationData::RIGHT_TO_LEFT:
notification_data->direction =
- PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT;
+ blink::PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT;
break;
case NotificationDatabaseDataProto::NotificationData::AUTO:
- notification_data->direction = PlatformNotificationData::DIRECTION_AUTO;
+ notification_data->direction =
+ blink::PlatformNotificationData::DIRECTION_AUTO;
break;
}
@@ -110,14 +112,14 @@ bool DeserializeNotificationDatabaseData(const std::string& input,
notification_data->actions.clear();
for (const auto& payload_action : payload.actions()) {
- PlatformNotificationAction action;
+ blink::PlatformNotificationAction action;
switch (payload_action.type()) {
case NotificationDatabaseDataProto::NotificationAction::BUTTON:
- action.type = PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON;
+ action.type = blink::PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON;
break;
case NotificationDatabaseDataProto::NotificationAction::TEXT:
- action.type = PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT;
+ action.type = blink::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT;
break;
default:
NOTREACHED();
@@ -143,20 +145,21 @@ bool SerializeNotificationDatabaseData(const NotificationDatabaseData& input,
std::unique_ptr<NotificationDatabaseDataProto::NotificationData> payload(
new NotificationDatabaseDataProto::NotificationData());
- const PlatformNotificationData& notification_data = input.notification_data;
+ const blink::PlatformNotificationData& notification_data =
+ input.notification_data;
payload->set_title(base::UTF16ToUTF8(notification_data.title));
switch (notification_data.direction) {
- case PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT:
+ case blink::PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT:
payload->set_direction(
NotificationDatabaseDataProto::NotificationData::LEFT_TO_RIGHT);
break;
- case PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT:
+ case blink::PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT:
payload->set_direction(
NotificationDatabaseDataProto::NotificationData::RIGHT_TO_LEFT);
break;
- case PlatformNotificationData::DIRECTION_AUTO:
+ case blink::PlatformNotificationData::DIRECTION_AUTO:
payload->set_direction(
NotificationDatabaseDataProto::NotificationData::AUTO);
break;
@@ -182,16 +185,17 @@ bool SerializeNotificationDatabaseData(const NotificationDatabaseData& input,
notification_data.data.size());
}
- for (const PlatformNotificationAction& action : notification_data.actions) {
+ for (const blink::PlatformNotificationAction& action :
+ notification_data.actions) {
NotificationDatabaseDataProto::NotificationAction* payload_action =
payload->add_actions();
switch (action.type) {
- case PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON:
+ case blink::PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON:
payload_action->set_type(
NotificationDatabaseDataProto::NotificationAction::BUTTON);
break;
- case PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT:
+ case blink::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT:
payload_action->set_type(
NotificationDatabaseDataProto::NotificationAction::TEXT);
break;
diff --git a/chromium/content/browser/notifications/notification_database_data_unittest.cc b/chromium/content/browser/notifications/notification_database_data_unittest.cc
index 9de61d52c50..db0241218f9 100644
--- a/chromium/content/browser/notifications/notification_database_data_unittest.cc
+++ b/chromium/content/browser/notifications/notification_database_data_unittest.cc
@@ -30,8 +30,8 @@ const int kTimeUntilFirstClickMillis = 11111;
const int kTimeUntilLastClickMillis = 22222;
const int kTimeUntilCloseMillis = 33333;
-const PlatformNotificationActionType kNotificationActionType =
- PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT;
+const blink::PlatformNotificationActionType kNotificationActionType =
+ blink::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT;
const char kOrigin[] = "https://example.com/";
const char kNotificationTitle[] = "My Notification";
const char kNotificationLang[] = "nl";
@@ -54,10 +54,10 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeData) {
std::vector<char> developer_data(
kNotificationData, kNotificationData + base::size(kNotificationData));
- PlatformNotificationData notification_data;
+ blink::PlatformNotificationData notification_data;
notification_data.title = base::ASCIIToUTF16(kNotificationTitle);
notification_data.direction =
- PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT;
+ blink::PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT;
notification_data.lang = kNotificationLang;
notification_data.body = base::ASCIIToUTF16(kNotificationBody);
notification_data.tag = kNotificationTag;
@@ -71,7 +71,7 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeData) {
notification_data.require_interaction = true;
notification_data.data = developer_data;
for (size_t i = 0; i < blink::kWebNotificationMaxActions; i++) {
- PlatformNotificationAction notification_action;
+ blink::PlatformNotificationAction notification_action;
notification_action.type = kNotificationActionType;
notification_action.action = base::NumberToString(i);
notification_action.title = base::NumberToString16(i);
@@ -128,7 +128,7 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeData) {
copied_data.time_until_close_millis);
EXPECT_EQ(database_data.closed_reason, copied_data.closed_reason);
- const PlatformNotificationData& copied_notification_data =
+ const blink::PlatformNotificationData& copied_notification_data =
copied_data.notification_data;
EXPECT_EQ(notification_data.title, copied_notification_data.title);
@@ -199,14 +199,14 @@ TEST(NotificationDatabaseDataTest, ActionDeserializationIsNotAdditive) {
}
TEST(NotificationDatabaseDataTest, SerializeAndDeserializeActionTypes) {
- PlatformNotificationActionType action_types[] = {
- PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON,
- PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT};
+ blink::PlatformNotificationActionType action_types[] = {
+ blink::PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON,
+ blink::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT};
- for (PlatformNotificationActionType action_type : action_types) {
- PlatformNotificationData notification_data;
+ for (blink::PlatformNotificationActionType action_type : action_types) {
+ blink::PlatformNotificationData notification_data;
- PlatformNotificationAction action;
+ blink::PlatformNotificationAction action;
action.type = action_type;
notification_data.actions.push_back(action);
@@ -226,13 +226,13 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeActionTypes) {
}
TEST(NotificationDatabaseDataTest, SerializeAndDeserializeDirections) {
- PlatformNotificationData::Direction directions[] = {
- PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT,
- PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT,
- PlatformNotificationData::DIRECTION_AUTO};
+ blink::PlatformNotificationData::Direction directions[] = {
+ blink::PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT,
+ blink::PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT,
+ blink::PlatformNotificationData::DIRECTION_AUTO};
for (size_t i = 0; i < base::size(directions); ++i) {
- PlatformNotificationData notification_data;
+ blink::PlatformNotificationData notification_data;
notification_data.direction = directions[i];
NotificationDatabaseData database_data;
@@ -273,11 +273,11 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeClosedReasons) {
}
TEST(NotificationDatabaseDataTest, SerializeAndDeserializeNullPlaceholder) {
- PlatformNotificationAction action;
+ blink::PlatformNotificationAction action;
action.type = kNotificationActionType;
action.placeholder = base::NullableString16(); // null string.
- PlatformNotificationData notification_data;
+ blink::PlatformNotificationData notification_data;
notification_data.actions.push_back(action);
NotificationDatabaseData database_data;
diff --git a/chromium/content/browser/notifications/notification_database_unittest.cc b/chromium/content/browser/notifications/notification_database_unittest.cc
index fb0d6cb80fe..8f0978c3a15 100644
--- a/chromium/content/browser/notifications/notification_database_unittest.cc
+++ b/chromium/content/browser/notifications/notification_database_unittest.cc
@@ -13,9 +13,9 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/notification_database_data.h"
-#include "content/public/common/platform_notification_data.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/notifications/platform_notification_data.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
#include "url/gurl.h"
@@ -283,10 +283,10 @@ TEST_F(NotificationDatabaseTest, ReadNotificationDataReflection) {
GURL origin("https://example.com");
- PlatformNotificationData notification_data;
+ blink::PlatformNotificationData notification_data;
notification_data.title = base::UTF8ToUTF16("My Notification");
notification_data.direction =
- PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT;
+ blink::PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT;
notification_data.lang = "nl-NL";
notification_data.body = base::UTF8ToUTF16("Hello, world!");
notification_data.tag = "replace id";
@@ -318,7 +318,7 @@ TEST_F(NotificationDatabaseTest, ReadNotificationDataReflection) {
EXPECT_EQ(database_data.service_worker_registration_id,
read_database_data.service_worker_registration_id);
- const PlatformNotificationData& read_notification_data =
+ const blink::PlatformNotificationData& read_notification_data =
read_database_data.notification_data;
EXPECT_EQ(notification_data.title, read_notification_data.title);
diff --git a/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc b/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
index d8acb3229bf..db206cc9fc7 100644
--- a/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
+++ b/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
@@ -8,17 +8,19 @@
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/optional.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/notifications/platform_notification_context_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/persistent_notification_status.h"
-#include "content/public/common/platform_notification_data.h"
+#include "third_party/blink/public/common/notifications/platform_notification_data.h"
namespace content {
namespace {
@@ -40,8 +42,8 @@ void NotificationEventFinished(
PersistentNotificationStatus status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(dispatch_complete_callback, status));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(dispatch_complete_callback, status));
}
// To be called when a notification event has finished with a
@@ -146,8 +148,8 @@ void DispatchNotificationEventOnRegistration(
break;
}
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(dispatch_error_callback, status));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(dispatch_error_callback, status));
}
// Finds the ServiceWorkerRegistration associated with the |origin| and
@@ -169,8 +171,8 @@ void FindServiceWorkerRegistration(
LOG(INFO) << "Lookup for ServiceWoker Registration: success: " << success;
#endif
if (!success) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(dispatch_error_callback,
PersistentNotificationStatus::kDatabaseError));
return;
@@ -353,8 +355,8 @@ void DispatchNotificationEvent(
scoped_refptr<PlatformNotificationContext> notification_context =
partition->GetPlatformNotificationContext();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ReadNotificationDatabaseData, notification_id, origin, interaction,
service_worker_context, notification_context,
diff --git a/chromium/content/browser/notifications/notification_id_generator.cc b/chromium/content/browser/notifications/notification_id_generator.cc
index 99fa0034c4d..9ab34c96aae 100644
--- a/chromium/content/browser/notifications/notification_id_generator.cc
+++ b/chromium/content/browser/notifications/notification_id_generator.cc
@@ -64,7 +64,7 @@ std::string NotificationIdGenerator::GenerateForPersistentNotification(
std::string NotificationIdGenerator::GenerateForNonPersistentNotification(
const url::Origin& origin,
const std::string& token) const {
- DCHECK(!origin.unique());
+ DCHECK(!origin.opaque());
DCHECK(!token.empty());
return base::StringPrintf(
"%c%c%s%c%s", kNonPersistentNotificationPrefix, kNotificationTagSeparator,
diff --git a/chromium/content/browser/notifications/platform_notification_context_impl.cc b/chromium/content/browser/notifications/platform_notification_context_impl.cc
index 13ece81608b..9b31e66db71 100644
--- a/chromium/content/browser/notifications/platform_notification_context_impl.cc
+++ b/chromium/content/browser/notifications/platform_notification_context_impl.cc
@@ -13,6 +13,7 @@
#include "content/browser/notifications/notification_database.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/notification_database_data.h"
@@ -55,8 +56,8 @@ void PlatformNotificationContextImpl::Initialize() {
GetContentClient()->browser()->GetPlatformNotificationService();
if (!service) {
auto displayed_notifications = std::make_unique<std::set<std::string>>();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PlatformNotificationContextImpl::InitializeOnIO, this,
std::move(displayed_notifications), false));
return;
@@ -76,8 +77,8 @@ void PlatformNotificationContextImpl::DidGetNotificationsOnUI(
std::unique_ptr<std::set<std::string>> displayed_notifications,
bool supports_synchronization) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PlatformNotificationContextImpl::InitializeOnIO, this,
std::move(displayed_notifications),
supports_synchronization));
@@ -112,8 +113,8 @@ void PlatformNotificationContextImpl::Shutdown() {
services_.clear();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PlatformNotificationContextImpl::ShutdownOnIO, this));
}
@@ -173,8 +174,8 @@ void PlatformNotificationContextImpl::DoReadNotificationData(
NotificationDatabase::STATUS_COUNT);
if (status == NotificationDatabase::STATUS_OK) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(callback, true /* success */, database_data));
return;
}
@@ -183,9 +184,9 @@ void PlatformNotificationContextImpl::DoReadNotificationData(
if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
DestroyDatabase();
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(callback, false /* success */,
- NotificationDatabaseData()));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(callback, false /* success */,
+ NotificationDatabaseData()));
}
void PlatformNotificationContextImpl::
@@ -197,8 +198,8 @@ void PlatformNotificationContextImpl::
bool supports_synchronization) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&PlatformNotificationContextImpl::
SynchronizeDisplayedNotificationsForServiceWorkerRegistrationOnIO,
@@ -243,8 +244,8 @@ void PlatformNotificationContextImpl::
return;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&PlatformNotificationService::GetDisplayedNotifications,
base::Unretained(service), browser_context_,
@@ -291,8 +292,8 @@ void PlatformNotificationContextImpl::
}
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(callback, true /* success */, notification_datas));
// Remove notifications that are not actually on display anymore.
@@ -305,8 +306,8 @@ void PlatformNotificationContextImpl::
if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
DestroyDatabase();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(callback, false /* success */,
std::vector<NotificationDatabaseData>()));
}
@@ -352,9 +353,9 @@ void PlatformNotificationContextImpl::DoWriteNotificationData(
if (delete_status == NotificationDatabase::STATUS_ERROR_CORRUPTED) {
DestroyDatabase();
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(callback, false /* success */,
- "" /* notification_id */));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(callback, false /* success */,
+ "" /* notification_id */));
return;
}
}
@@ -373,8 +374,8 @@ void PlatformNotificationContextImpl::DoWriteNotificationData(
NotificationDatabase::STATUS_COUNT);
if (status == NotificationDatabase::STATUS_OK) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(callback, true /* success */,
write_database_data.notification_id));
@@ -385,8 +386,8 @@ void PlatformNotificationContextImpl::DoWriteNotificationData(
if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
DestroyDatabase();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(callback, false /* success */, "" /* notification_id */));
}
@@ -424,8 +425,8 @@ void PlatformNotificationContextImpl::DoDeleteNotificationData(
success = true;
}
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(callback, success));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(callback, success));
}
void PlatformNotificationContextImpl::OnRegistrationDeleted(
@@ -536,7 +537,7 @@ void PlatformNotificationContextImpl::OpenDatabase(
database_.reset();
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, failure_closure);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO}, failure_closure);
}
bool PlatformNotificationContextImpl::DestroyDatabase() {
diff --git a/chromium/content/browser/notifications/platform_notification_context_unittest.cc b/chromium/content/browser/notifications/platform_notification_context_unittest.cc
index 1e566931611..761d302fbf3 100644
--- a/chromium/content/browser/notifications/platform_notification_context_unittest.cc
+++ b/chromium/content/browser/notifications/platform_notification_context_unittest.cc
@@ -15,12 +15,12 @@
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/browser/notification_database_data.h"
-#include "content/public/common/notification_resources.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/mock_platform_notification_service.h"
#include "content/test/test_content_browser_client.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/notifications/notification_resources.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
#include "url/gurl.h"
@@ -530,8 +530,8 @@ TEST_F(PlatformNotificationContextTest, SynchronizeNotifications) {
NotificationDatabaseData notification_database_data;
notification_database_data.service_worker_registration_id =
kFakeServiceWorkerRegistrationId;
- PlatformNotificationData notification_data;
- content::NotificationResources notification_resources;
+ blink::PlatformNotificationData notification_data;
+ blink::NotificationResources notification_resources;
context->WriteNotificationData(
next_persistent_notification_id(), kFakeServiceWorkerRegistrationId,
diff --git a/chromium/content/browser/ns_view_bridge_factory_host.mm b/chromium/content/browser/ns_view_bridge_factory_host.mm
new file mode 100644
index 00000000000..c1c59669e36
--- /dev/null
+++ b/chromium/content/browser/ns_view_bridge_factory_host.mm
@@ -0,0 +1,51 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/ns_view_bridge_factory_host.h"
+
+#include "base/no_destructor.h"
+
+namespace content {
+
+namespace {
+
+using HostIdToFactoryMap = std::map<uint64_t, NSViewBridgeFactoryHost*>;
+
+HostIdToFactoryMap* GetHostIdToFactoryMap() {
+ static base::NoDestructor<HostIdToFactoryMap> instance;
+ return instance.get();
+}
+
+} // namespace
+
+// static
+const uint64_t NSViewBridgeFactoryHost::kLocalDirectHostId = -1;
+
+// static
+NSViewBridgeFactoryHost* NSViewBridgeFactoryHost::GetFromHostId(
+ uint64_t host_id) {
+ auto found = GetHostIdToFactoryMap()->find(host_id);
+ if (found == GetHostIdToFactoryMap()->end())
+ return nullptr;
+ return found->second;
+}
+
+NSViewBridgeFactoryHost::NSViewBridgeFactoryHost(
+ mojom::NSViewBridgeFactoryAssociatedRequest* request,
+ uint64_t host_id)
+ : host_id_(host_id) {
+ *request = mojo::MakeRequest(&factory_);
+ DCHECK(!GetHostIdToFactoryMap()->count(host_id_));
+ GetHostIdToFactoryMap()->insert(std::make_pair(host_id_, this));
+}
+
+NSViewBridgeFactoryHost::~NSViewBridgeFactoryHost() {
+ GetHostIdToFactoryMap()->erase(host_id_);
+}
+
+mojom::NSViewBridgeFactory* NSViewBridgeFactoryHost::GetFactory() {
+ return factory_.get();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/ns_view_bridge_factory_impl.mm b/chromium/content/browser/ns_view_bridge_factory_impl.mm
new file mode 100644
index 00000000000..5230e9f97a0
--- /dev/null
+++ b/chromium/content/browser/ns_view_bridge_factory_impl.mm
@@ -0,0 +1,63 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/ns_view_bridge_factory_impl.h"
+
+#include <utility>
+
+#include "base/macros.h"
+#include "base/no_destructor.h"
+#include "content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h"
+#include "content/browser/web_contents/web_contents_ns_view_bridge.h"
+#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
+
+namespace content {
+
+// static
+NSViewBridgeFactoryImpl* NSViewBridgeFactoryImpl::Get() {
+ static base::NoDestructor<NSViewBridgeFactoryImpl> instance;
+ return instance.get();
+}
+
+void NSViewBridgeFactoryImpl::BindRequest(
+ mojom::NSViewBridgeFactoryAssociatedRequest request) {
+ binding_.Bind(std::move(request),
+ ui::WindowResizeHelperMac::Get()->task_runner());
+}
+
+void NSViewBridgeFactoryImpl::CreateRenderWidgetHostNSViewBridge(
+ mojom::StubInterfaceAssociatedPtrInfo stub_client,
+ mojom::StubInterfaceAssociatedRequest stub_bridge_request) {
+ // Cast from the stub interface to the mojom::RenderWidgetHostNSViewClient
+ // and mojom::RenderWidgetHostNSViewBridge private interfaces.
+ // TODO(ccameron): Remove the need for this cast.
+ // https://crbug.com/888290
+ mojom::RenderWidgetHostNSViewClientAssociatedPtr client(
+ mojo::AssociatedInterfacePtrInfo<mojom::RenderWidgetHostNSViewClient>(
+ stub_client.PassHandle(), 0));
+ mojom::RenderWidgetHostNSViewBridgeAssociatedRequest bridge_request(
+ stub_bridge_request.PassHandle());
+
+ // Create a RenderWidgetHostNSViewBridgeLocal. The resulting object will be
+ // destroyed when its underlying pipe is closed.
+ ignore_result(new RenderWidgetHostNSViewBridgeLocal(
+ std::move(client), std::move(bridge_request)));
+}
+
+void NSViewBridgeFactoryImpl::CreateWebContentsNSViewBridge(
+ uint64_t view_id,
+ mojom::WebContentsNSViewClientAssociatedPtrInfo client,
+ mojom::WebContentsNSViewBridgeAssociatedRequest bridge_request) {
+ // Note that the resulting object will be destroyed when its underlying pipe
+ // is closed.
+ ignore_result(new WebContentsNSViewBridge(
+ view_id, mojom::WebContentsNSViewClientAssociatedPtr(std::move(client)),
+ std::move(bridge_request)));
+}
+
+NSViewBridgeFactoryImpl::NSViewBridgeFactoryImpl() : binding_(this) {}
+
+NSViewBridgeFactoryImpl::~NSViewBridgeFactoryImpl() {}
+
+} // namespace content
diff --git a/chromium/content/browser/oop_browsertest.cc b/chromium/content/browser/oop_browsertest.cc
index eaf658ca213..3fcfe558d33 100644
--- a/chromium/content/browser/oop_browsertest.cc
+++ b/chromium/content/browser/oop_browsertest.cc
@@ -38,7 +38,7 @@ class OOPBrowserTest : public ContentBrowserTest {
command_line->AppendSwitch(switches::kEnablePixelOutputInTests);
command_line->AppendSwitch(switches::kEnableOopRasterization);
- const bool use_gpu_in_tests = !features::IsUsingWindowService();
+ const bool use_gpu_in_tests = !features::IsMultiProcessMash();
if (use_gpu_in_tests)
command_line->AppendSwitch(switches::kUseGpuInTests);
}
@@ -54,7 +54,13 @@ class OOPBrowserTest : public ContentBrowserTest {
// This test calls into system GL which is not instrumented with MSAN.
#if !defined(MEMORY_SANITIZER)
-IN_PROC_BROWSER_TEST_F(OOPBrowserTest, Basic) {
+// TODO(crbug.com/880948) Disabled for crashes on Linux CFI, see bug.
+#if defined(OS_LINUX)
+#define MAYBE_Basic DISABLED_Basic
+#else
+#define MAYBE_Basic Basic
+#endif
+IN_PROC_BROWSER_TEST_F(OOPBrowserTest, MAYBE_Basic) {
// Create a div to ensure we don't use solid color quads.
GURL url = GURL(
"data:text/html,"
diff --git a/chromium/content/browser/payments/payment_app_content_unittest_base.cc b/chromium/content/browser/payments/payment_app_content_unittest_base.cc
index d604c1992fa..a8d1286084b 100644
--- a/chromium/content/browser/payments/payment_app_content_unittest_base.cc
+++ b/chromium/content/browser/payments/payment_app_content_unittest_base.cc
@@ -95,7 +95,7 @@ class PaymentAppContentUnitTestBase::PaymentAppForWorkerTestHelper
} else {
pending_response_callback_ = std::move(response_callback);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
}
@@ -227,7 +227,8 @@ void PaymentAppContentUnitTestBase::SetNoPaymentRequestResponseImmediately() {
void PaymentAppContentUnitTestBase::RespondPendingPaymentRequest() {
std::move(worker_helper_->pending_response_callback_)
->OnResponseForPaymentRequest(
- payments::mojom::PaymentHandlerResponse::New(), base::Time::Now());
+ payments::mojom::PaymentHandlerResponse::New(),
+ base::TimeTicks::Now());
}
int64_t PaymentAppContentUnitTestBase::last_sw_registration_id() const {
diff --git a/chromium/content/browser/payments/payment_app_context_impl.cc b/chromium/content/browser/payments/payment_app_context_impl.cc
index f4801e11a63..f091da1820d 100644
--- a/chromium/content/browser/payments/payment_app_context_impl.cc
+++ b/chromium/content/browser/payments/payment_app_context_impl.cc
@@ -8,7 +8,9 @@
#include "base/bind.h"
#include "base/stl_util.h"
+#include "base/task/post_task.h"
#include "content/browser/payments/payment_manager.h"
+#include "content/public/browser/browser_task_traits.h"
namespace content {
@@ -23,8 +25,8 @@ void PaymentAppContextImpl::Init(
DCHECK(!did_shutdown_on_io_.IsSet());
#endif
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PaymentAppContextImpl::CreatePaymentAppDatabaseOnIO, this,
service_worker_context));
}
@@ -36,8 +38,8 @@ void PaymentAppContextImpl::Shutdown() {
// IO thread. When the last reference to |this| is released, |this| is
// automatically scheduled for deletion on the UI thread (see
// content::BrowserThread::DeleteOnUIThread in the header file).
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PaymentAppContextImpl::ShutdownOnIO, this));
}
@@ -45,8 +47,8 @@ void PaymentAppContextImpl::CreatePaymentManager(
payments::mojom::PaymentManagerRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PaymentAppContextImpl::CreatePaymentManagerOnIO, this,
std::move(request)));
}
diff --git a/chromium/content/browser/payments/payment_app_info_fetcher.cc b/chromium/content/browser/payments/payment_app_info_fetcher.cc
index c1714b4cfe6..4efac89daa1 100644
--- a/chromium/content/browser/payments/payment_app_info_fetcher.cc
+++ b/chromium/content/browser/payments/payment_app_info_fetcher.cc
@@ -8,9 +8,11 @@
#include "base/base64.h"
#include "base/bind_helpers.h"
+#include "base/task/post_task.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/manifest_icon_downloader.h"
@@ -34,8 +36,8 @@ void PaymentAppInfoFetcher::Start(
std::unique_ptr<std::vector<GlobalFrameRoutingId>> provider_hosts =
service_worker_context->GetProviderHostIds(context_url.GetOrigin());
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&PaymentAppInfoFetcher::StartOnUI, context_url,
std::move(provider_hosts), std::move(callback)));
}
@@ -122,9 +124,10 @@ void PaymentAppInfoFetcher::SelfDeleteFetcher::Start(
void PaymentAppInfoFetcher::SelfDeleteFetcher::RunCallbackAndDestroy() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(std::move(callback_),
- std::move(fetched_payment_app_info_)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(std::move(callback_),
+ std::move(fetched_payment_app_info_)));
delete this;
}
diff --git a/chromium/content/browser/payments/payment_app_installer.cc b/chromium/content/browser/payments/payment_app_installer.cc
index 6a6e31bdb07..9ec51d4332a 100644
--- a/chromium/content/browser/payments/payment_app_installer.cc
+++ b/chromium/content/browser/payments/payment_app_installer.cc
@@ -4,14 +4,18 @@
#include "content/browser/payments/payment_app_installer.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/task/post_task.h"
#include "content/browser/payments/payment_app_context_impl.h"
#include "content/browser/service_worker/service_worker_context_watcher.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
@@ -26,12 +30,10 @@ class SelfDeleteInstaller
: public WebContentsObserver,
public base::RefCountedThreadSafe<SelfDeleteInstaller> {
public:
- SelfDeleteInstaller(WebContents* web_contents,
- const std::string& app_name,
+ SelfDeleteInstaller(const std::string& app_name,
const std::string& app_icon,
const GURL& sw_url,
const GURL& scope,
- bool use_cache,
const std::string& method,
PaymentAppInstaller::InstallPaymentAppCallback callback)
: app_name_(app_name),
@@ -41,6 +43,12 @@ class SelfDeleteInstaller
method_(method),
callback_(std::move(callback)) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ }
+
+ void Init(WebContents* web_contents, bool use_cache) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ AddRef(); // Balanced by Release() in FinishInstallation.
// TODO(crbug.com/782270): Listen for web contents events to terminate
// installation early.
@@ -66,7 +74,7 @@ class SelfDeleteInstaller
blink::mojom::ServiceWorkerUpdateViaCache::kNone;
}
service_worker_context->RegisterServiceWorker(
- sw_url, option,
+ sw_url_, option,
base::BindOnce(&SelfDeleteInstaller::OnRegisterServiceWorkerResult,
this));
}
@@ -131,8 +139,8 @@ class SelfDeleteInstaller
scoped_refptr<PaymentAppContextImpl> payment_app_context =
partition->GetPaymentAppContext();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SelfDeleteInstaller::SetPaymentAppInfoOnIO, this,
payment_app_context, registration_id_, scope_.spec(),
app_name_, app_icon_, method_));
@@ -156,8 +164,8 @@ class SelfDeleteInstaller
void OnSetPaymentAppInfo(payments::mojom::PaymentHandlerStatus status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SelfDeleteInstaller::FinishInstallation, this,
status == payments::mojom::PaymentHandlerStatus::SUCCESS
? true
@@ -184,6 +192,7 @@ class SelfDeleteInstaller
}
Observe(nullptr);
+ Release(); // Balanced by AddRef() in the constructor.
}
std::string app_name_;
@@ -212,8 +221,9 @@ void PaymentAppInstaller::Install(WebContents* web_contents,
InstallPaymentAppCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- new SelfDeleteInstaller(web_contents, app_name, app_icon, sw_url, scope,
- use_cache, method, std::move(callback));
+ auto installer = base::MakeRefCounted<SelfDeleteInstaller>(
+ app_name, app_icon, sw_url, scope, method, std::move(callback));
+ installer->Init(web_contents, use_cache);
}
} // namespace content
diff --git a/chromium/content/browser/payments/payment_app_provider_impl.cc b/chromium/content/browser/payments/payment_app_provider_impl.cc
index 3cfa0bde2bc..d3042e6a2fc 100644
--- a/chromium/content/browser/payments/payment_app_provider_impl.cc
+++ b/chromium/content/browser/payments/payment_app_provider_impl.cc
@@ -6,6 +6,7 @@
#include "base/base64.h"
#include "base/strings/string_util.h"
+#include "base/task/post_task.h"
#include "content/browser/payments/payment_app_context_impl.h"
#include "content/browser/payments/payment_app_installer.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
@@ -13,6 +14,7 @@
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/permission_controller.h"
#include "content/public/browser/permission_type.h"
@@ -124,12 +126,12 @@ class RespondWithCallbacks
void OnResponseForPaymentRequest(
payments::mojom::PaymentHandlerResponsePtr response,
- base::Time dispatch_event_time) override {
+ base::TimeTicks dispatch_event_time) override {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_worker_version_->FinishRequest(request_id_, false,
std::move(dispatch_event_time));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(invoke_payment_app_callback_),
std::move(response)));
@@ -137,25 +139,26 @@ class RespondWithCallbacks
delete this;
}
- void OnResponseForCanMakePayment(bool can_make_payment,
- base::Time dispatch_event_time) override {
+ void OnResponseForCanMakePayment(
+ bool can_make_payment,
+ base::TimeTicks dispatch_event_time) override {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_worker_version_->FinishRequest(request_id_, false,
std::move(dispatch_event_time));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(payment_event_result_callback_),
can_make_payment));
delete this;
}
void OnResponseForAbortPayment(bool payment_aborted,
- base::Time dispatch_event_time) override {
+ base::TimeTicks dispatch_event_time) override {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_worker_version_->FinishRequest(request_id_, false,
std::move(dispatch_event_time));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(payment_event_result_callback_),
payment_aborted));
@@ -168,15 +171,15 @@ class RespondWithCallbacks
DCHECK(service_worker_status != blink::ServiceWorkerStatusCode::kOk);
if (event_type_ == ServiceWorkerMetrics::EventType::PAYMENT_REQUEST) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(invoke_payment_app_callback_),
payments::mojom::PaymentHandlerResponse::New()));
} else if (event_type_ ==
ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT ||
event_type_ == ServiceWorkerMetrics::EventType::ABORT_PAYMENT) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(payment_event_result_callback_), false));
}
@@ -193,7 +196,7 @@ class RespondWithCallbacks
DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_worker_version_->FinishRequest(request_id_, false,
- base::Time::Now());
+ base::TimeTicks::Now());
OnErrorStatus(blink::ServiceWorkerStatusCode::kErrorAbort);
}
@@ -205,8 +208,8 @@ class RespondWithCallbacks
InvokePaymentAppCallbackRepository::GetInstance()->RemoveCallback(
browser_context_);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&CloseClientWindowOnUIThread, browser_context_));
}
@@ -232,8 +235,9 @@ class RespondWithCallbacks
void DidGetAllPaymentAppsOnIO(
PaymentAppProvider::GetAllPaymentAppsCallback callback,
PaymentAppProvider::PaymentApps apps) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), std::move(apps)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), std::move(apps)));
}
void GetAllPaymentAppsOnIO(
@@ -253,8 +257,8 @@ void DispatchAbortPaymentEvent(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), false));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), false));
return;
}
@@ -282,8 +286,8 @@ void DispatchCanMakePaymentEvent(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), false));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), false));
return;
}
@@ -311,8 +315,8 @@ void DispatchPaymentRequestEvent(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback),
payments::mojom::PaymentHandlerResponse::New()));
return;
@@ -374,8 +378,8 @@ void StartServiceWorkerForDispatch(BrowserContext* browser_context,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
partition->GetServiceWorkerContext();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&FindRegistrationOnIO, std::move(service_worker_context),
registration_id, std::move(callback)));
}
@@ -451,8 +455,8 @@ void PaymentAppProviderImpl::GetAllPaymentApps(
scoped_refptr<PaymentAppContextImpl> payment_app_context =
partition->GetPaymentAppContext();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&GetAllPaymentAppsOnIO, payment_app_context,
base::BindOnce(&CheckPermissionForPaymentApps,
browser_context, std::move(callback))));
@@ -488,8 +492,8 @@ void PaymentAppProviderImpl::InstallAndInvokePaymentApp(
DCHECK(base::IsStringUTF8(sw_scope));
GURL scope = GURL(sw_scope);
if (!url.is_valid() || !scope.is_valid() || method.empty()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback),
payments::mojom::PaymentHandlerResponse::New()));
return;
@@ -562,8 +566,8 @@ void PaymentAppProviderImpl::OnClosingOpenedWindow(
BrowserContext* browser_context) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AbortInvokePaymentApp, browser_context));
}
diff --git a/chromium/content/browser/payments/payment_instrument_icon_fetcher.cc b/chromium/content/browser/payments/payment_instrument_icon_fetcher.cc
index 3bb8cffa724..f1481f6b37f 100644
--- a/chromium/content/browser/payments/payment_instrument_icon_fetcher.cc
+++ b/chromium/content/browser/payments/payment_instrument_icon_fetcher.cc
@@ -8,9 +8,11 @@
#include "base/base64.h"
#include "base/bind_helpers.h"
+#include "base/task/post_task.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/manifest_icon_downloader.h"
#include "third_party/blink/public/common/manifest/manifest_icon_selector.h"
@@ -42,8 +44,8 @@ void OnIconFetched(
if (bitmap.drawsNothing()) {
if (icons.empty()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), std::string()));
} else {
// If could not download or decode the chosen image(e.g. not supported,
@@ -61,8 +63,8 @@ void OnIconFetched(
base::StringPiece(reinterpret_cast<const char*>(&bitmap_data[0]),
bitmap_data.size()),
&encoded_data);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(std::move(callback), encoded_data));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(std::move(callback), encoded_data));
}
void DownloadBestMatchingIcon(
@@ -80,8 +82,9 @@ void DownloadBestMatchingIcon(
// developers in advance unlike when fetching or decoding fails. We already
// checked whether they are valid in renderer side. So, if the icon url is
// invalid, it's something wrong.
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(std::move(callback), std::string()));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(std::move(callback), std::string()));
return;
}
@@ -146,8 +149,8 @@ void PaymentInstrumentIconFetcher::Start(
PaymentInstrumentIconFetcherCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&StartOnUI, scope, std::move(provider_hosts), icons,
std::move(callback)));
}
diff --git a/chromium/content/browser/permissions/permission_service_impl.cc b/chromium/content/browser/permissions/permission_service_impl.cc
index f84599df41c..064107bb019 100644
--- a/chromium/content/browser/permissions/permission_service_impl.cc
+++ b/chromium/content/browser/permissions/permission_service_impl.cc
@@ -82,6 +82,9 @@ bool PermissionDescriptorToPermissionType(
case PermissionName::PAYMENT_HANDLER:
*permission_type = PermissionType::PAYMENT_HANDLER;
return true;
+ case PermissionName::BACKGROUND_FETCH:
+ *permission_type = PermissionType::BACKGROUND_FETCH;
+ return true;
}
NOTREACHED();
diff --git a/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
index ba0270dd8d3..d0758e65cb4 100644
--- a/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
+++ b/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -71,16 +71,6 @@ gfx::Size PictureInPictureWindowControllerImpl::Show() {
return window_->GetBounds().size();
}
-void PictureInPictureWindowControllerImpl::ClickCustomControl(
- const std::string& control_id) {
- DCHECK(window_);
-
- media_player_id_->render_frame_host->Send(
- new MediaPlayerDelegateMsg_ClickPictureInPictureControl(
- media_player_id_->render_frame_host->GetRoutingID(),
- media_player_id_->delegate_id, control_id));
-}
-
void PictureInPictureWindowControllerImpl::SetPictureInPictureCustomControls(
const std::vector<blink::PictureInPictureControlInfo>& controls) {
DCHECK(window_);
@@ -189,6 +179,24 @@ bool PictureInPictureWindowControllerImpl::TogglePlayPause() {
return true;
}
+void PictureInPictureWindowControllerImpl::CustomControlPressed(
+ const std::string& control_id) {
+ DCHECK(window_);
+
+ media_player_id_->render_frame_host->Send(
+ new MediaPlayerDelegateMsg_ClickPictureInPictureControl(
+ media_player_id_->render_frame_host->GetRoutingID(),
+ media_player_id_->delegate_id, control_id));
+}
+
+void PictureInPictureWindowControllerImpl::SetAlwaysHidePlayPauseButton(
+ bool is_visible) {
+ if (!window_)
+ return;
+
+ window_->SetAlwaysHidePlayPauseButton(is_visible);
+}
+
void PictureInPictureWindowControllerImpl::OnLeavingPictureInPicture(
bool should_pause_video,
bool should_reset_pip_player) {
diff --git a/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h b/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h
index a5c6499509e..17fb5e892e7 100644
--- a/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h
+++ b/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h
@@ -38,8 +38,6 @@ class PictureInPictureWindowControllerImpl
CONTENT_EXPORT void Close(bool should_pause_video,
bool should_reset_pip_player) override;
CONTENT_EXPORT void OnWindowDestroyed() override;
- CONTENT_EXPORT void ClickCustomControl(
- const std::string& control_id) override;
CONTENT_EXPORT void SetPictureInPictureCustomControls(
const std::vector<blink::PictureInPictureControlInfo>& controls) override;
CONTENT_EXPORT void EmbedSurface(const viz::SurfaceId& surface_id,
@@ -49,8 +47,11 @@ class PictureInPictureWindowControllerImpl
CONTENT_EXPORT bool IsPlayerActive() override;
CONTENT_EXPORT WebContents* GetInitiatorWebContents() override;
CONTENT_EXPORT bool TogglePlayPause() override;
+ CONTENT_EXPORT void CustomControlPressed(
+ const std::string& control_id) override;
CONTENT_EXPORT void UpdatePlaybackState(bool is_playing,
bool reached_end_of_stream) override;
+ CONTENT_EXPORT void SetAlwaysHidePlayPauseButton(bool is_visible) override;
private:
friend class WebContentsUserData<PictureInPictureWindowControllerImpl>;
diff --git a/chromium/content/browser/plugin_data_remover_impl.cc b/chromium/content/browser/plugin_data_remover_impl.cc
index fefc248ddbb..43ec1a50e93 100644
--- a/chromium/content/browser/plugin_data_remover_impl.cc
+++ b/chromium/content/browser/plugin_data_remover_impl.cc
@@ -12,12 +12,14 @@
#include "base/sequenced_task_runner_helpers.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
#include "base/version.h"
#include "build/build_config.h"
#include "content/browser/plugin_service_impl.h"
#include "content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h"
#include "content/common/child_process_host_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/content_constants.h"
@@ -48,8 +50,7 @@ void PluginDataRemover::GetSupportedPlugins(
PluginService::GetInstance()->GetPluginInfoArray(
GURL(), kFlashPluginSwfMimeType, allow_wildcard, &plugins, nullptr);
base::Version min_version(kMinFlashVersion);
- for (std::vector<WebPluginInfo>::iterator it = plugins.begin();
- it != plugins.end(); ++it) {
+ for (auto it = plugins.begin(); it != plugins.end(); ++it) {
base::Version version;
WebPluginInfo::CreateVersionFromString(it->version, &version);
if (version.IsValid() && min_version.CompareTo(version) == -1)
@@ -74,11 +75,12 @@ class PluginDataRemoverImpl::Context
}
void Init(const std::string& mime_type) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&Context::InitOnIOThread, this, mime_type));
- BrowserThread::PostDelayedTask(
- BrowserThread::IO, FROM_HERE, base::BindOnce(&Context::OnTimeout, this),
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&Context::OnTimeout, this),
base::TimeDelta::FromMilliseconds(kRemovalTimeoutMs));
}
diff --git a/chromium/content/browser/plugin_private_storage_helper.cc b/chromium/content/browser/plugin_private_storage_helper.cc
index 60fa438616b..57f5b7e0bef 100644
--- a/chromium/content/browser/plugin_private_storage_helper.cc
+++ b/chromium/content/browser/plugin_private_storage_helper.cc
@@ -21,6 +21,8 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "ppapi/shared_impl/ppapi_constants.h"
#include "storage/browser/fileapi/async_file_util.h"
@@ -308,11 +310,12 @@ void PluginPrivateDataDeletionHelper::CheckOriginsOnFileTaskRunner(
}
// Currently the plugin private filesystem is only used by Encrypted
- // Media Content Decryption Modules, which are treated as pepper plugins.
- // Each CDM gets a directory based on the mimetype (e.g. plugin
- // application/x-ppapi-widevine-cdm uses directory
- // application_x-ppapi-widevine-cdm). Enumerate through the set of
- // directories so that data from any CDM used by this origin is deleted.
+ // Media Content Decryption Modules (CDM), which used to be hosted as pepper
+ // plugins. Each CDM gets a directory based on the CdmInfo::file_system_id,
+ // e.g. application/x-ppapi-widevine-cdm (same as previous plugin mimetypes
+ // to avoid data migration). See https://crbug.com/479923 for the history.
+ // Enumerate through the set of directories so that data from any CDM used
+ // by this origin is deleted.
base::FileEnumerator file_enumerator(path, false,
base::FileEnumerator::DIRECTORIES);
for (base::FilePath plugin_path = file_enumerator.Next();
@@ -323,8 +326,8 @@ void PluginPrivateDataDeletionHelper::CheckOriginsOnFileTaskRunner(
filesystem_context_.get(), origin.GetOrigin(),
plugin_path.BaseName().MaybeAsASCII(), begin_, end_,
decrement_callback);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&PluginPrivateDataByOriginChecker::CheckFilesOnIOThread,
base::Unretained(helper)));
diff --git a/chromium/content/browser/plugin_service_impl.cc b/chromium/content/browser/plugin_service_impl.cc
index 3a6480c7177..7834d3d1843 100644
--- a/chromium/content/browser/plugin_service_impl.cc
+++ b/chromium/content/browser/plugin_service_impl.cc
@@ -31,6 +31,7 @@
#include "content/common/pepper_plugin_list.h"
#include "content/common/plugin_list.h"
#include "content/common/view_messages.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/plugin_service_filter.h"
@@ -272,9 +273,9 @@ void PluginServiceImpl::OpenChannelToPpapiBroker(
int render_frame_id,
const base::FilePath& path,
PpapiPluginProcessHost::BrokerClient* client) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&PluginServiceImpl::RecordBrokerUsage,
- render_process_id, render_frame_id));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&PluginServiceImpl::RecordBrokerUsage,
+ render_process_id, render_frame_id));
PpapiPluginProcessHost* plugin_host = FindOrStartPpapiBrokerProcess(
render_process_id, path);
@@ -414,8 +415,7 @@ static const unsigned int kCrashesInterval = 120;
void PluginServiceImpl::RegisterPluginCrash(const base::FilePath& path) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- std::map<base::FilePath, std::vector<base::Time> >::iterator i =
- crash_times_.find(path);
+ auto i = crash_times_.find(path);
if (i == crash_times_.end()) {
crash_times_[path] = std::vector<base::Time>();
i = crash_times_.find(path);
diff --git a/chromium/content/browser/plugin_service_impl_browsertest.cc b/chromium/content/browser/plugin_service_impl_browsertest.cc
index 1dfaa4d45c8..23fc78b5b5d 100644
--- a/chromium/content/browser/plugin_service_impl_browsertest.cc
+++ b/chromium/content/browser/plugin_service_impl_browsertest.cc
@@ -11,8 +11,10 @@
#include "base/optional.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/ppapi_plugin_process_host.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/content_browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -82,8 +84,8 @@ class PluginServiceImplBrowserTest : public ContentBrowserTest {
client->SetRunLoop(&run_loop);
PluginServiceImpl* service = PluginServiceImpl::GetInstance();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PluginServiceImpl::OpenChannelToPpapiPlugin,
base::Unretained(service), 0, plugin_path_, profile_dir_,
origin, base::Unretained(client)));
diff --git a/chromium/content/browser/pointer_lock_browsertest.cc b/chromium/content/browser/pointer_lock_browsertest.cc
index d6eaf149a84..05b56a7255e 100644
--- a/chromium/content/browser/pointer_lock_browsertest.cc
+++ b/chromium/content/browser/pointer_lock_browsertest.cc
@@ -319,6 +319,55 @@ IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest,
root->current_frame_host()->GetRenderWidgetHost()));
}
+IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockOopifCrashes) {
+ // This test runs three times, testing a crash at each level of the frametree.
+ for (int crash_depth = 0; crash_depth < 3; crash_depth++) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b(c))"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+ FrameTreeNode* lock_node = root->child_at(0)->child_at(0);
+
+ // Pick which node to crash.
+ FrameTreeNode* crash_node = root;
+ for (int i = 0; i < crash_depth; i++)
+ crash_node = crash_node->child_at(0);
+
+ // Request a pointer lock to |lock_node|'s document.body.
+ EXPECT_EQ("success", EvalJs(lock_node, R"(
+ new Promise((resolve, reject) => {
+ document.addEventListener('pointerlockchange', resolve);
+ document.addEventListener('pointerlockerror', reject);
+ document.body.requestPointerLock();
+ }).then(() => 'success');
+ )"));
+
+ // Root (platform) RenderWidgetHostView should have the pointer locked.
+ EXPECT_TRUE(root->current_frame_host()->GetView()->IsMouseLocked());
+ EXPECT_EQ(lock_node->current_frame_host()->GetRenderWidgetHost(),
+ web_contents()->GetMouseLockWidget());
+
+ // Crash the process of |crash_node|.
+ RenderProcessHost* crash_process =
+ crash_node->current_frame_host()->GetProcess();
+ RenderProcessHostWatcher crash_observer(
+ crash_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ crash_process->Shutdown(0);
+ crash_observer.Wait();
+
+ // This should cancel the pointer lock.
+ EXPECT_EQ(nullptr, web_contents()->GetMouseLockWidget());
+ EXPECT_EQ(nullptr, web_contents()->mouse_lock_widget_);
+ EXPECT_FALSE(web_contents()->HasMouseLock(
+ root->current_frame_host()->GetRenderWidgetHost()));
+ if (crash_depth != 0)
+ EXPECT_FALSE(root->current_frame_host()->GetView()->IsMouseLocked());
+ else
+ EXPECT_EQ(nullptr, root->current_frame_host()->GetView());
+ }
+}
+
IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWheelEventRouting) {
GURL main_url(embedded_test_server()->GetURL(
"a.com", "/cross_site_iframe_factory.html?a(b)"));
diff --git a/chromium/content/browser/portal/portal.cc b/chromium/content/browser/portal/portal.cc
index 14430222d47..ff5a59c41d0 100644
--- a/chromium/content/browser/portal/portal.cc
+++ b/chromium/content/browser/portal/portal.cc
@@ -9,6 +9,7 @@
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/content_switches.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "third_party/blink/public/common/features.h"
@@ -53,6 +54,9 @@ void Portal::Init(
WebContents::FromRenderFrameHost(owner_render_frame_host_)
->GetBrowserContext());
portal_contents_ = WebContents::Create(params);
+ WebContents::FromRenderFrameHost(owner_render_frame_host_)
+ ->GetDelegate()
+ ->PortalWebContentsCreated(portal_contents_.get());
}
void Portal::Navigate(const GURL& url) {
@@ -60,6 +64,34 @@ void Portal::Navigate(const GURL& url) {
portal_contents_->GetController().LoadURLWithParams(load_url_params);
}
+void Portal::Activate(
+ base::OnceCallback<void(blink::mojom::PortalActivationStatus)> callback) {
+ WebContents* outer_contents =
+ WebContents::FromRenderFrameHost(owner_render_frame_host_);
+ WebContentsDelegate* delegate = outer_contents->GetDelegate();
+ if (delegate) {
+ bool is_loading = portal_contents_->IsLoading();
+ WebContents* portal_contents = portal_contents_.get();
+ std::unique_ptr<WebContents> contents = delegate->SwapWebContents(
+ outer_contents, std::move(portal_contents_), true, is_loading);
+
+ if (contents.get() == outer_contents) {
+ // TODO(lfg): The old WebContents is currently discarded, but should be
+ // kept and passed to the new page.
+ std::move(callback).Run(blink::mojom::PortalActivationStatus::kSuccess);
+ } else {
+ DCHECK_EQ(portal_contents, contents.get());
+ portal_contents_ = std::move(contents);
+ std::move(callback).Run(
+ blink::mojom::PortalActivationStatus::kNotSupported);
+ }
+
+ return;
+ }
+
+ std::move(callback).Run(blink::mojom::PortalActivationStatus::kNotSupported);
+}
+
void Portal::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
if (render_frame_host == owner_render_frame_host_)
binding_->Close(); // Also deletes |this|.
diff --git a/chromium/content/browser/portal/portal.h b/chromium/content/browser/portal/portal.h
index f894cb7d65c..c6cd4896127 100644
--- a/chromium/content/browser/portal/portal.h
+++ b/chromium/content/browser/portal/portal.h
@@ -44,6 +44,8 @@ class CONTENT_EXPORT Portal : public blink::mojom::Portal,
void Init(base::OnceCallback<void(const base::UnguessableToken&)> callback)
override;
void Navigate(const GURL& url) override;
+ void Activate(base::OnceCallback<void(blink::mojom::PortalActivationStatus)>
+ callback) override;
// WebContentsObserver overrides.
void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
diff --git a/chromium/content/browser/portal/portal_browsertest.cc b/chromium/content/browser/portal/portal_browsertest.cc
index a9a661e8b7b..82fdddf230d 100644
--- a/chromium/content/browser/portal/portal_browsertest.cc
+++ b/chromium/content/browser/portal/portal_browsertest.cc
@@ -5,9 +5,11 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/portal/portal.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/web_contents_delegate.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
@@ -16,9 +18,12 @@
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/portal/portal.mojom.h"
#include "url/url_constants.h"
+using testing::_;
namespace content {
@@ -38,8 +43,23 @@ class PortalInterceptorForTesting final
ASSERT_FALSE(portal_initialized_);
portal_initialized_ = true;
- if (run_loop_)
+ if (run_loop_) {
run_loop_->Quit();
+ run_loop_ = nullptr;
+ }
+ }
+
+ void Activate(base::OnceCallback<void(blink::mojom::PortalActivationStatus)>
+ callback) override {
+ portal_activated_ = true;
+
+ if (run_loop_) {
+ run_loop_->Quit();
+ run_loop_ = nullptr;
+ }
+
+ // |this| can be destroyed after Activate() is called.
+ portal_->Activate(std::move(callback));
}
void WaitForInit() {
@@ -49,7 +69,15 @@ class PortalInterceptorForTesting final
base::RunLoop run_loop;
run_loop_ = &run_loop;
run_loop.Run();
- run_loop_ = nullptr;
+ }
+
+ void WaitForActivate() {
+ if (portal_activated_)
+ return;
+
+ base::RunLoop run_loop;
+ run_loop_ = &run_loop;
+ run_loop.Run();
}
// Test getters.
@@ -66,6 +94,7 @@ class PortalInterceptorForTesting final
std::unique_ptr<content::Portal> portal_;
bool portal_initialized_ = false;
+ bool portal_activated_ = false;
base::RunLoop* run_loop_ = nullptr;
};
@@ -91,6 +120,25 @@ PortalInterceptorForTesting* PortalInterceptorForTesting::From(
return interceptor;
}
+class MockPortalWebContentsDelegate : public WebContentsDelegate {
+ public:
+ MockPortalWebContentsDelegate() {}
+ ~MockPortalWebContentsDelegate() override {}
+
+ MOCK_METHOD4(
+ DoSwapWebContents,
+ std::unique_ptr<WebContents>(WebContents*, WebContents*, bool, bool));
+ std::unique_ptr<WebContents> SwapWebContents(
+ WebContents* old_contents,
+ std::unique_ptr<WebContents> new_contents,
+ bool did_start_load,
+ bool did_finish_load) override {
+ DoSwapWebContents(old_contents, new_contents.get(), did_start_load,
+ did_finish_load);
+ return new_contents;
+ }
+};
+
// The PortalCreatedObserver observes portal creations on
// |render_frame_host_impl|. This observer can be used to monitor for multiple
// Portal creations on the same RenderFrameHost, by repeatedly calling
@@ -252,4 +300,91 @@ IN_PROC_BROWSER_TEST_F(PortalBrowserTest, NavigatePortal) {
}
}
+// Tests that the WebContentsDelegate will receive a request to swap the
+// WebContents when a portal is activated.
+// Disabled due to flakiness on Android. See https://crbug.com/892669.
+#if defined(OS_ANDROID)
+#define MAYBE_ActivatePortal DISABLED_ActivatePortal
+#else
+#define MAYBE_ActivatePortal ActivatePortal
+#endif
+
+IN_PROC_BROWSER_TEST_F(PortalBrowserTest, MAYBE_ActivatePortal) {
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL("portal.test", "/title1.html")));
+ WebContentsImpl* web_contents_impl =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ RenderFrameHostImpl* main_frame = web_contents_impl->GetMainFrame();
+
+ PortalCreatedObserver portal_created_observer(main_frame);
+ GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ EXPECT_TRUE(ExecJs(main_frame,
+ JsReplace("var portal = document.createElement('portal');"
+ "portal.src = $1;"
+ "document.body.appendChild(portal);",
+ a_url)));
+ Portal* portal = portal_created_observer.WaitUntilPortalCreated();
+ PortalInterceptorForTesting* portal_interceptor =
+ PortalInterceptorForTesting::From(portal);
+ portal_interceptor->WaitForInit();
+
+ MockPortalWebContentsDelegate mock_delegate;
+ shell()->web_contents()->SetDelegate(&mock_delegate);
+
+ base::RunLoop run_loop;
+ EXPECT_CALL(mock_delegate,
+ DoSwapWebContents(shell()->web_contents(),
+ portal->GetPortalContents(), _, _))
+ .WillOnce(testing::DoAll(
+ testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
+ testing::ReturnNull()));
+ EXPECT_TRUE(
+ ExecJs(main_frame, "document.querySelector('portal').activate();"));
+ run_loop.Run();
+}
+
+// Tests that a portal can be activated in content_shell.
+// Disabled due to flakiness on Android. See https://crbug.com/892669.
+#if defined(OS_ANDROID)
+#define MAYBE_ActivatePortalInShell DISABLED_ActivatePortalInShell
+#else
+#define MAYBE_ActivatePortalInShell ActivatePortalInShell
+#endif
+IN_PROC_BROWSER_TEST_F(PortalBrowserTest, MAYBE_ActivatePortalInShell) {
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL("portal.test", "/title1.html")));
+ WebContentsImpl* web_contents_impl =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ RenderFrameHostImpl* main_frame = web_contents_impl->GetMainFrame();
+
+ Portal* portal = nullptr;
+ {
+ PortalCreatedObserver portal_created_observer(main_frame);
+ GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ EXPECT_TRUE(ExecJs(
+ main_frame, JsReplace("var portal = document.createElement('portal');"
+ "portal.src = $1;"
+ "document.body.appendChild(portal);",
+ a_url)));
+ portal = portal_created_observer.WaitUntilPortalCreated();
+ }
+ PortalInterceptorForTesting* portal_interceptor =
+ PortalInterceptorForTesting::From(portal);
+ portal_interceptor->WaitForInit();
+
+ // Ensure that the portal WebContents exists and is different from the tab's
+ // WebContents.
+ WebContents* portal_contents = portal->GetPortalContents();
+ EXPECT_NE(nullptr, portal_contents);
+ EXPECT_NE(portal_contents, shell()->web_contents());
+
+ ExecuteScriptAsync(main_frame,
+ "document.querySelector('portal').activate();");
+ portal_interceptor->WaitForActivate();
+
+ // After activation, the shell's WebContents should be the previous portal's
+ // WebContents.
+ EXPECT_EQ(portal_contents, shell()->web_contents());
+}
+
} // namespace content
diff --git a/chromium/content/browser/power_monitor_browsertest.cc b/chromium/content/browser/power_monitor_browsertest.cc
index ffd7190d197..19fa617b74c 100644
--- a/chromium/content/browser/power_monitor_browsertest.cc
+++ b/chromium/content/browser/power_monitor_browsertest.cc
@@ -6,9 +6,11 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/utility_process_host.h"
#include "content/browser/utility_process_host_client.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/gpu_service_registry.h"
#include "content/public/browser/render_frame_host.h"
@@ -150,8 +152,8 @@ class PowerMonitorTest : public ContentBrowserTest {
void StartUtilityProcess(mojom::PowerMonitorTestPtr* power_monitor_test,
base::Closure utility_bound_closure) {
utility_bound_closure_ = std::move(utility_bound_closure);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&StartUtilityProcessOnIOThread,
mojo::MakeRequest(power_monitor_test)));
}
@@ -240,8 +242,8 @@ IN_PROC_BROWSER_TEST_F(PowerMonitorTest, TestGpuProcess) {
EXPECT_EQ(1, request_count_from_gpu());
mojom::PowerMonitorTestPtr power_monitor_gpu;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BindInterfaceForGpuOnIOThread,
mojo::MakeRequest(&power_monitor_gpu)));
diff --git a/chromium/content/browser/ppapi_plugin_process_host.cc b/chromium/content/browser/ppapi_plugin_process_host.cc
index 1df1149921b..3c2cf89aa1f 100644
--- a/chromium/content/browser/ppapi_plugin_process_host.cc
+++ b/chromium/content/browser/ppapi_plugin_process_host.cc
@@ -23,14 +23,15 @@
#include "content/common/child_process_host_impl.h"
#include "content/common/content_switches_internal.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/pepper_plugin_info.h"
#include "content/public/common/process_type.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/common/service_names.mojom.h"
-#include "net/base/network_change_notifier.h"
#include "ppapi/proxy/ppapi_messages.h"
+#include "services/network/public/cpp/network_connection_tracker.h"
#include "services/service_manager/sandbox/sandbox_type.h"
#include "services/service_manager/sandbox/switches.h"
#include "services/service_manager/zygote/common/zygote_buildflags.h"
@@ -129,25 +130,38 @@ class PpapiPluginSandboxedProcessLauncherDelegate
};
class PpapiPluginProcessHost::PluginNetworkObserver
- : public net::NetworkChangeNotifier::NetworkChangeObserver {
+ : public network::NetworkConnectionTracker::NetworkConnectionObserver {
public:
explicit PluginNetworkObserver(PpapiPluginProcessHost* process_host)
- : process_host_(process_host) {
- net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
+ : process_host_(process_host),
+ network_connection_tracker_(nullptr),
+ weak_factory_(this) {
+ GetNetworkConnectionTrackerFromUIThread(
+ base::BindOnce(&PluginNetworkObserver::SetNetworkConnectionTracker,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ void SetNetworkConnectionTracker(
+ network::NetworkConnectionTracker* network_connection_tracker) {
+ DCHECK(network_connection_tracker);
+ network_connection_tracker_ = network_connection_tracker;
+ network_connection_tracker_->AddNetworkConnectionObserver(this);
}
~PluginNetworkObserver() override {
- net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
+ if (network_connection_tracker_)
+ network_connection_tracker_->RemoveNetworkConnectionObserver(this);
}
- void OnNetworkChanged(
- net::NetworkChangeNotifier::ConnectionType type) override {
+ void OnConnectionChanged(network::mojom::ConnectionType type) override {
process_host_->Send(new PpapiMsg_SetNetworkState(
- type != net::NetworkChangeNotifier::CONNECTION_NONE));
+ type != network::mojom::ConnectionType::CONNECTION_NONE));
}
private:
PpapiPluginProcessHost* const process_host_;
+ network::NetworkConnectionTracker* network_connection_tracker_;
+ base::WeakPtrFactory<PluginNetworkObserver> weak_factory_;
};
PpapiPluginProcessHost::~PpapiPluginProcessHost() {
diff --git a/chromium/content/browser/presentation/presentation_service_impl_unittest.cc b/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
index 51fd39f10ab..c8abad15dfb 100644
--- a/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
+++ b/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
@@ -175,11 +175,9 @@ class MockReceiverPresentationServiceDelegate
class MockPresentationConnection : public PresentationConnection {
public:
- MOCK_METHOD2(OnMessage,
- void(PresentationConnectionMessagePtr message,
- base::OnceCallback<void(bool)> send_message_cb));
+ MOCK_METHOD1(OnMessage, void(PresentationConnectionMessagePtr message));
MOCK_METHOD1(DidChangeState, void(PresentationConnectionState state));
- MOCK_METHOD0(RequestClose, void());
+ MOCK_METHOD1(DidClose, void(blink::mojom::PresentationConnectionCloseReason));
};
class MockPresentationController : public blink::mojom::PresentationController {
diff --git a/chromium/content/browser/process_internals/BUILD.gn b/chromium/content/browser/process_internals/BUILD.gn
index fedd9d9609b..a85f61cf4a0 100644
--- a/chromium/content/browser/process_internals/BUILD.gn
+++ b/chromium/content/browser/process_internals/BUILD.gn
@@ -8,4 +8,8 @@ mojom("mojo_bindings") {
sources = [
"process_internals.mojom",
]
+
+ deps = [
+ "//url/mojom:url_mojom_gurl",
+ ]
}
diff --git a/chromium/content/browser/process_internals/process_internals.mojom b/chromium/content/browser/process_internals/process_internals.mojom
index d8fe8594f2d..fe11eebcb85 100644
--- a/chromium/content/browser/process_internals/process_internals.mojom
+++ b/chromium/content/browser/process_internals/process_internals.mojom
@@ -4,6 +4,37 @@
module mojom;
+import "url/mojom/url.mojom";
+
+// Basic information describing a SiteInstance.
+struct SiteInstanceInfo {
+ int32 id;
+
+ // Boolean indicating whether the SiteInstance is locked to a specific URL.
+ // It does not indicate the granularity of the lock URL.
+ bool locked;
+
+ url.mojom.Url? site_url;
+};
+
+// Basic information describing a frame and all of its subframes.
+struct FrameInfo {
+ int32 routing_id;
+ int32 process_id;
+
+ SiteInstanceInfo site_instance;
+ url.mojom.Url? last_committed_url;
+
+ array<FrameInfo> subframes;
+};
+
+// Basic information describing a WebContents object and all frames that are
+// in it.
+struct WebContentsInfo {
+ string title;
+ FrameInfo root_frame;
+};
+
// Interface used by chrome://process-internals to query data from the
// browser process.
interface ProcessInternalsHandler {
@@ -13,4 +44,8 @@ interface ProcessInternalsHandler {
// Returns the number of isolated origins.
GetIsolatedOriginsSize() => (uint32 size);
+
+ // Returns an array of WebContentsInfo structs for all WebContents
+ // associated with the profile in which this call is made.
+ GetAllWebContentsInfo() => (array<WebContentsInfo> infos);
};
diff --git a/chromium/content/browser/process_internals/process_internals_handler_impl.cc b/chromium/content/browser/process_internals/process_internals_handler_impl.cc
index dbd0e5792b1..2011f1b54d2 100644
--- a/chromium/content/browser/process_internals/process_internals_handler_impl.cc
+++ b/chromium/content/browser/process_internals/process_internals_handler_impl.cc
@@ -4,15 +4,53 @@
#include "content/browser/process_internals/process_internals_handler_impl.h"
+#include <utility>
+#include <vector>
+
+#include "base/strings/string_piece.h"
#include "content/browser/process_internals/process_internals.mojom.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/web_contents.h"
namespace content {
+namespace {
+
+::mojom::FrameInfoPtr FrameTreeNodeToFrameInfo(FrameTreeNode* ftn) {
+ RenderFrameHost* frame = ftn->current_frame_host();
+ auto frame_info = ::mojom::FrameInfo::New();
+
+ frame_info->routing_id = frame->GetRoutingID();
+ frame_info->process_id = frame->GetProcess()->GetID();
+ frame_info->last_committed_url =
+ frame->GetLastCommittedURL().is_valid()
+ ? base::make_optional(frame->GetLastCommittedURL())
+ : base::nullopt;
+
+ SiteInstanceImpl* site_instance =
+ static_cast<SiteInstanceImpl*>(frame->GetSiteInstance());
+ frame_info->site_instance = ::mojom::SiteInstanceInfo::New();
+ frame_info->site_instance->id = site_instance->GetId();
+ frame_info->site_instance->locked = site_instance->lock_url().is_valid();
+ frame_info->site_instance->site_url =
+ site_instance->HasSite()
+ ? base::make_optional(site_instance->GetSiteURL())
+ : base::nullopt;
+
+ for (size_t i = 0; i < ftn->child_count(); ++i) {
+ frame_info->subframes.push_back(FrameTreeNodeToFrameInfo(ftn->child_at(i)));
+ }
+
+ return frame_info;
+}
+
+} // namespace
+
ProcessInternalsHandlerImpl::ProcessInternalsHandlerImpl(
+ BrowserContext* browser_context,
mojo::InterfaceRequest<::mojom::ProcessInternalsHandler> request)
- : binding_(this, std::move(request)) {}
+ : browser_context_(browser_context), binding_(this, std::move(request)) {}
ProcessInternalsHandlerImpl::~ProcessInternalsHandlerImpl() = default;
@@ -21,8 +59,6 @@ void ProcessInternalsHandlerImpl::GetIsolationMode(
std::vector<base::StringPiece> modes;
if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites())
modes.push_back("Site Per Process");
- if (SiteIsolationPolicy::IsTopDocumentIsolationEnabled())
- modes.push_back("Top Document Isolation");
if (SiteIsolationPolicy::AreIsolatedOriginsEnabled())
modes.push_back("Isolate Origins");
@@ -36,4 +72,26 @@ void ProcessInternalsHandlerImpl::GetIsolatedOriginsSize(
std::move(callback).Run(size);
}
+void ProcessInternalsHandlerImpl::GetAllWebContentsInfo(
+ GetAllWebContentsInfoCallback callback) {
+ std::vector<::mojom::WebContentsInfoPtr> infos;
+ std::vector<WebContentsImpl*> all_contents =
+ WebContentsImpl::GetAllWebContents();
+
+ for (WebContentsImpl* web_contents : all_contents) {
+ // Do not return WebContents that don't belong to the current
+ // BrowserContext to avoid leaking data between contexts.
+ if (web_contents->GetBrowserContext() != browser_context_)
+ continue;
+
+ auto info = ::mojom::WebContentsInfo::New();
+ info->title = base::UTF16ToUTF8(web_contents->GetTitle());
+ info->root_frame =
+ FrameTreeNodeToFrameInfo(web_contents->GetFrameTree()->root());
+ infos.push_back(std::move(info));
+ }
+
+ std::move(callback).Run(std::move(infos));
+}
+
} // namespace content
diff --git a/chromium/content/browser/process_internals/process_internals_handler_impl.h b/chromium/content/browser/process_internals/process_internals_handler_impl.h
index 54b7def12f9..4d75ba9c131 100644
--- a/chromium/content/browser/process_internals/process_internals_handler_impl.h
+++ b/chromium/content/browser/process_internals/process_internals_handler_impl.h
@@ -17,14 +17,17 @@ namespace content {
class ProcessInternalsHandlerImpl : public ::mojom::ProcessInternalsHandler {
public:
ProcessInternalsHandlerImpl(
+ BrowserContext* browser_context,
mojo::InterfaceRequest<::mojom::ProcessInternalsHandler> request);
~ProcessInternalsHandlerImpl() override;
// mojom::ProcessInternalsHandler overrides:
void GetIsolationMode(GetIsolationModeCallback callback) override;
void GetIsolatedOriginsSize(GetIsolatedOriginsSizeCallback callback) override;
+ void GetAllWebContentsInfo(GetAllWebContentsInfoCallback callback) override;
private:
+ BrowserContext* browser_context_;
mojo::Binding<::mojom::ProcessInternalsHandler> binding_;
DISALLOW_COPY_AND_ASSIGN(ProcessInternalsHandlerImpl);
diff --git a/chromium/content/browser/process_internals/process_internals_ui.cc b/chromium/content/browser/process_internals/process_internals_ui.cc
index 8c3558c5b61..0c3ea14ce1d 100644
--- a/chromium/content/browser/process_internals/process_internals_ui.cc
+++ b/chromium/content/browser/process_internals/process_internals_ui.cc
@@ -34,7 +34,9 @@ ProcessInternalsUI::ProcessInternalsUI(WebUI* web_ui)
WebUIDataSource* source =
WebUIDataSource::Create(kChromeUIProcessInternalsHost);
+ source->AddResourcePath("url.mojom.js", IDR_URL_MOJO_JS);
source->AddResourcePath("process_internals.js", IDR_PROCESS_INTERNALS_JS);
+ source->AddResourcePath("process_internals.css", IDR_PROCESS_INTERNALS_CSS);
source->AddResourcePath("process_internals.mojom.js",
IDR_PROCESS_INTERNALS_MOJO_JS);
source->SetDefaultResource(IDR_PROCESS_INTERNALS_HTML);
@@ -50,13 +52,15 @@ ProcessInternalsUI::ProcessInternalsUI(WebUI* web_ui)
ProcessInternalsUI::~ProcessInternalsUI() = default;
void ProcessInternalsUI::BindProcessInternalsHandler(
- ::mojom::ProcessInternalsHandlerRequest request) {
- ui_handler_ =
- std::make_unique<ProcessInternalsHandlerImpl>(std::move(request));
+ ::mojom::ProcessInternalsHandlerRequest request,
+ RenderFrameHost* render_frame_host) {
+ ui_handler_ = std::make_unique<ProcessInternalsHandlerImpl>(
+ render_frame_host->GetSiteInstance()->GetBrowserContext(),
+ std::move(request));
}
void ProcessInternalsUI::OnInterfaceRequestFromFrame(
- content::RenderFrameHost* render_frame_host,
+ RenderFrameHost* render_frame_host,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle* interface_pipe) {
// This should not be requested by subframes, so terminate the renderer if
@@ -67,7 +71,7 @@ void ProcessInternalsUI::OnInterfaceRequestFromFrame(
return;
}
- registry_.TryBindInterface(interface_name, interface_pipe);
+ registry_.TryBindInterface(interface_name, interface_pipe, render_frame_host);
}
} // namespace content
diff --git a/chromium/content/browser/process_internals/process_internals_ui.h b/chromium/content/browser/process_internals/process_internals_ui.h
index 8c760bcf5f8..bd2bdc6f0d3 100644
--- a/chromium/content/browser/process_internals/process_internals_ui.h
+++ b/chromium/content/browser/process_internals/process_internals_ui.h
@@ -32,11 +32,12 @@ class ProcessInternalsUI : public WebUIController, public WebContentsObserver {
registry_.AddInterface(std::move(binder));
}
void BindProcessInternalsHandler(
- ::mojom::ProcessInternalsHandlerRequest request);
+ ::mojom::ProcessInternalsHandlerRequest request,
+ RenderFrameHost* render_frame_host);
private:
std::unique_ptr<::mojom::ProcessInternalsHandler> ui_handler_;
- service_manager::BinderRegistry registry_;
+ service_manager::BinderRegistryWithArgs<content::RenderFrameHost*> registry_;
DISALLOW_COPY_AND_ASSIGN(ProcessInternalsUI);
};
diff --git a/chromium/content/browser/push_messaging/push_messaging_manager.cc b/chromium/content/browser/push_messaging/push_messaging_manager.cc
index 91018ad3310..267d942e20b 100644
--- a/chromium/content/browser/push_messaging/push_messaging_manager.cc
+++ b/chromium/content/browser/push_messaging/push_messaging_manager.cc
@@ -15,6 +15,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "base/strings/string_number_conversions.h"
+#include "base/task/post_task.h"
#include "content/browser/permissions/permission_controller_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/service_worker/service_worker_context_core.h"
@@ -22,6 +23,7 @@
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/common/push_messaging.mojom.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/push_messaging_service.h"
#include "content/public/browser/render_frame_host.h"
@@ -369,8 +371,8 @@ void PushMessagingManager::DidCheckForExistingRegistration(
// the subscription algorithm instead of trying to subscribe.
if (!data.options.sender_info.empty()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Core::RegisterOnUI, base::Unretained(ui_core_.get()),
std::move(data)));
} else {
@@ -405,8 +407,8 @@ void PushMessagingManager::DidGetSenderIdFromStorage(
return;
}
data.options.sender_info = fixed_sender_id;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Core::RegisterOnUI, base::Unretained(ui_core_.get()),
std::move(data)));
}
@@ -419,8 +421,8 @@ void PushMessagingManager::Core::RegisterOnUI(
if (!is_incognito()) {
// This might happen if InstanceIDProfileService::IsInstanceIDEnabled
// returns false because the Instance ID kill switch was enabled.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PushMessagingManager::SendSubscriptionError,
io_parent_, std::move(data),
mojom::PushRegistrationStatus::SERVICE_NOT_AVAILABLE));
@@ -429,8 +431,8 @@ void PushMessagingManager::Core::RegisterOnUI(
// have happened if we had a PushMessagingService available.
if (!data.FromDocument() || !data.options.user_visible_only) {
// Throw a permission denied error under the same circumstances.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&PushMessagingManager::SendSubscriptionError, io_parent_,
std::move(data),
@@ -487,8 +489,8 @@ void PushMessagingManager::Core::DidRequestPermissionInIncognito(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Notification permission should always be denied in incognito.
DCHECK_EQ(blink::mojom::PermissionStatus::DENIED, status);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&PushMessagingManager::SendSubscriptionError, io_parent_,
std::move(data),
@@ -511,8 +513,8 @@ void PushMessagingManager::Core::DidRegister(
data.existing_subscription_id.value() != push_subscription_id;
if (status == mojom::PushRegistrationStatus::SUCCESS_FROM_PUSH_SERVICE) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&PushMessagingManager::PersistRegistrationOnIO, io_parent_,
std::move(data), push_subscription_id, p256dh, auth,
@@ -521,8 +523,8 @@ void PushMessagingManager::Core::DidRegister(
SUCCESS_NEW_SUBSCRIPTION_FROM_PUSH_SERVICE
: mojom::PushRegistrationStatus::SUCCESS_FROM_PUSH_SERVICE));
} else {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PushMessagingManager::SendSubscriptionError, io_parent_,
std::move(data), status));
}
@@ -637,8 +639,8 @@ void PushMessagingManager::UnsubscribeHavingGottenSenderId(
DCHECK_EQ(1u, sender_ids.size());
sender_id = sender_ids[0];
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Core::UnregisterFromService,
base::Unretained(ui_core_.get()), std::move(callback),
service_worker_registration_id, requesting_origin,
@@ -656,8 +658,8 @@ void PushMessagingManager::Core::UnregisterFromService(
// This shouldn't be possible in incognito mode, since we've already checked
// that we have an existing registration. Hence it's ok to throw an error.
DCHECK(!is_incognito());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PushMessagingManager::DidUnregister, io_parent_,
std::move(callback),
mojom::PushUnregistrationStatus::SERVICE_NOT_AVAILABLE));
@@ -678,8 +680,8 @@ void PushMessagingManager::Core::DidUnregisterFromService(
mojom::PushUnregistrationStatus unregistration_status) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PushMessagingManager::DidUnregister, io_parent_,
std::move(callback), unregistration_status));
}
@@ -772,8 +774,8 @@ void PushMessagingManager::DidGetSubscription(
const GURL endpoint =
CreateEndpoint(uses_standard_protocol, push_subscription_id);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Core::GetSubscriptionInfoOnUI,
base::Unretained(ui_core_.get()), origin,
service_worker_registration_id, sender_info,
@@ -845,9 +847,9 @@ void PushMessagingManager::Core::GetSubscriptionDidGetInfoOnUI(
mojom::PushGetRegistrationStatus status =
mojom::PushGetRegistrationStatus::SUCCESS;
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(std::move(callback), status,
- endpoint, options, p256dh, auth));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(std::move(callback), status,
+ endpoint, options, p256dh, auth));
RecordGetRegistrationStatus(status);
} else {
@@ -856,8 +858,8 @@ void PushMessagingManager::Core::GetSubscriptionDidGetInfoOnUI(
// Shouldn't be possible to have a stored push subscription in a profile
// with no push service, but this case can occur when the renderer is
// shutting down.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback),
mojom::PushGetRegistrationStatus::RENDERER_SHUTDOWN,
base::nullopt /* endpoint */,
@@ -889,8 +891,8 @@ void PushMessagingManager::Core::GetSubscriptionDidUnsubscribe(
mojom::PushGetRegistrationStatus get_status,
mojom::PushUnregistrationStatus unsubscribe_status) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), get_status,
base::nullopt /* endpoint */, base::nullopt /* options */,
base::nullopt /* p256dh */, base::nullopt /* auth */));
diff --git a/chromium/content/browser/push_messaging/push_messaging_router.cc b/chromium/content/browser/push_messaging/push_messaging_router.cc
index 697ca1fabf8..5734e177333 100644
--- a/chromium/content/browser/push_messaging/push_messaging_router.cc
+++ b/chromium/content/browser/push_messaging/push_messaging_router.cc
@@ -8,10 +8,12 @@
#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
+#include "base/task/post_task.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/push_messaging_status.mojom.h"
@@ -25,8 +27,8 @@ void RunDeliverCallback(
const PushMessagingRouter::DeliverMessageCallback& deliver_message_callback,
mojom::PushDeliveryStatus delivery_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(deliver_message_callback, delivery_status));
}
@@ -45,8 +47,8 @@ void PushMessagingRouter::DeliverMessage(
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
static_cast<ServiceWorkerContextWrapper*>(
partition->GetServiceWorkerContext());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PushMessagingRouter::FindServiceWorkerRegistration,
origin, service_worker_registration_id, std::move(payload),
deliver_message_callback, service_worker_context));
diff --git a/chromium/content/browser/quota_dispatcher_host.cc b/chromium/content/browser/quota_dispatcher_host.cc
index c32742729ad..350bdf3b32f 100644
--- a/chromium/content/browser/quota_dispatcher_host.cc
+++ b/chromium/content/browser/quota_dispatcher_host.cc
@@ -11,6 +11,8 @@
#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/numerics/safe_conversions.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_process_host.h"
@@ -51,8 +53,8 @@ void QuotaDispatcherHost::CreateForWorker(
// one provided by QuotaDispatcher.
// Bind on the IO thread.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&BindConnectorOnIOThread, host->GetID(), MSG_ROUTING_NONE,
base::RetainedRef(host->GetStoragePartition()->GetQuotaManager()),
@@ -65,8 +67,8 @@ void QuotaDispatcherHost::CreateForFrame(
int render_frame_id,
blink::mojom::QuotaDispatcherHostRequest request) {
// Bind on the IO thread.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&BindConnectorOnIOThread, host->GetID(), render_frame_id,
base::RetainedRef(host->GetStoragePartition()->GetQuotaManager()),
@@ -93,7 +95,7 @@ void QuotaDispatcherHost::QueryStorageUsageAndQuota(
StorageType storage_type,
QueryStorageUsageAndQuotaCallback callback) {
quota_manager_->GetUsageAndQuotaForWebApps(
- origin.GetURL(), storage_type,
+ origin, storage_type,
base::BindOnce(&QuotaDispatcherHost::DidQueryStorageUsageAndQuota,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
@@ -115,7 +117,7 @@ void QuotaDispatcherHost::RequestStorageQuota(
return;
}
- if (origin.unique()) {
+ if (origin.opaque()) {
mojo::ReportBadMessage("Unique origins may not request storage quota.");
return;
}
@@ -124,13 +126,13 @@ void QuotaDispatcherHost::RequestStorageQuota(
storage_type == StorageType::kPersistent);
if (storage_type == StorageType::kPersistent) {
quota_manager_->GetUsageAndQuotaForWebApps(
- origin.GetURL(), storage_type,
+ origin, storage_type,
base::BindOnce(&QuotaDispatcherHost::DidGetPersistentUsageAndQuota,
weak_factory_.GetWeakPtr(), origin, storage_type,
requested_size, std::move(callback)));
} else {
quota_manager_->GetUsageAndQuotaForWebApps(
- origin.GetURL(), storage_type,
+ origin, storage_type,
base::BindOnce(&QuotaDispatcherHost::DidGetTemporaryUsageAndQuota,
weak_factory_.GetWeakPtr(), requested_size,
std::move(callback)));
@@ -164,7 +166,7 @@ void QuotaDispatcherHost::DidGetPersistentUsageAndQuota(
// TODO(nhiroki): The backend should accept uint64_t values.
int64_t requested_quota_signed =
base::saturated_cast<int64_t>(requested_quota);
- if (quota_manager_->IsStorageUnlimited(origin.GetURL(), storage_type) ||
+ if (quota_manager_->IsStorageUnlimited(origin, storage_type) ||
requested_quota_signed <= current_quota) {
std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk, current_usage,
requested_quota);
diff --git a/chromium/content/browser/renderer_host/browser_compositor_view_mac.h b/chromium/content/browser/renderer_host/browser_compositor_view_mac.h
index 7dc490ea560..71a9e1024b6 100644
--- a/chromium/content/browser/renderer_host/browser_compositor_view_mac.h
+++ b/chromium/content/browser/renderer_host/browser_compositor_view_mac.h
@@ -137,6 +137,7 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient,
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
void OnBeginFrame(base::TimeTicks frame_time) override;
void OnFrameTokenChanged(uint32_t frame_token) override;
+ float GetDeviceScaleFactor() const override;
base::WeakPtr<BrowserCompositorMac> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
diff --git a/chromium/content/browser/renderer_host/browser_compositor_view_mac.mm b/chromium/content/browser/renderer_host/browser_compositor_view_mac.mm
index fb23caccdd1..65670cccb50 100644
--- a/chromium/content/browser/renderer_host/browser_compositor_view_mac.mm
+++ b/chromium/content/browser/renderer_host/browser_compositor_view_mac.mm
@@ -401,6 +401,10 @@ void BrowserCompositorMac::OnFrameTokenChanged(uint32_t frame_token) {
client_->OnFrameTokenChanged(frame_token);
}
+float BrowserCompositorMac::GetDeviceScaleFactor() const {
+ return dfh_display_.device_scale_factor();
+}
+
void BrowserCompositorMac::DidNavigate() {
// The first navigation does not need a new LocalSurfaceID. The renderer can
// use the ID that was already provided.
diff --git a/chromium/content/browser/renderer_host/clipboard_host_impl.cc b/chromium/content/browser/renderer_host/clipboard_host_impl.cc
index 60928166661..0b8dc1505a6 100644
--- a/chromium/content/browser/renderer_host/clipboard_host_impl.cc
+++ b/chromium/content/browser/renderer_host/clipboard_host_impl.cc
@@ -6,11 +6,13 @@
#include <utility>
+#include "base/location.h"
#include "base/macros.h"
#include "base/pickle.h"
+#include "base/sequenced_task_runner.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/threading/sequenced_task_runner_handle.h"
#include "build/build_config.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard.h"
@@ -20,15 +22,23 @@
namespace content {
-ClipboardHostImpl::ClipboardHostImpl()
- : clipboard_(ui::Clipboard::GetForCurrentThread()),
+ClipboardHostImpl::ClipboardHostImpl(blink::mojom::ClipboardHostRequest request)
+ : binding_(this, std::move(request)),
+ clipboard_(ui::Clipboard::GetForCurrentThread()),
clipboard_writer_(
new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE)) {}
void ClipboardHostImpl::Create(blink::mojom::ClipboardHostRequest request) {
- mojo::MakeStrongBinding(
- base::WrapUnique<ClipboardHostImpl>(new ClipboardHostImpl()),
- std::move(request));
+ // Clipboard implementations do interesting things, like run nested message
+ // loops. Since StrongBinding<T> synchronously destroys on failure, that can
+ // result in some unfortunate use-after-frees after the nested message loops
+ // exit.
+ auto* host = new ClipboardHostImpl(std::move(request));
+ host->binding_.set_connection_error_handler(base::BindOnce(
+ [](ClipboardHostImpl* host) {
+ base::SequencedTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, host);
+ },
+ host));
}
ClipboardHostImpl::~ClipboardHostImpl() {
diff --git a/chromium/content/browser/renderer_host/clipboard_host_impl.h b/chromium/content/browser/renderer_host/clipboard_host_impl.h
index f9c6a3db4af..82a0d6be9de 100644
--- a/chromium/content/browser/renderer_host/clipboard_host_impl.h
+++ b/chromium/content/browser/renderer_host/clipboard_host_impl.h
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "third_party/blink/public/mojom/clipboard/clipboard.mojom.h"
#include "ui/base/clipboard/clipboard.h"
@@ -33,7 +34,7 @@ class CONTENT_EXPORT ClipboardHostImpl : public blink::mojom::ClipboardHost {
private:
friend class ClipboardHostImplTest;
- ClipboardHostImpl();
+ explicit ClipboardHostImpl(blink::mojom::ClipboardHostRequest request);
// content::mojom::ClipboardHost
void GetSequenceNumber(ui::ClipboardType clipboard_type,
@@ -73,7 +74,8 @@ class CONTENT_EXPORT ClipboardHostImpl : public blink::mojom::ClipboardHost {
void WriteStringToFindPboard(const base::string16& text) override;
#endif
- ui::Clipboard* clipboard_; // Not owned
+ mojo::Binding<blink::mojom::ClipboardHost> binding_;
+ ui::Clipboard* const clipboard_; // Not owned
std::unique_ptr<ui::ScopedClipboardWriter> clipboard_writer_;
};
diff --git a/chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc b/chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc
index a3a0e92ec35..50b866d09b6 100644
--- a/chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc
+++ b/chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc
@@ -7,8 +7,12 @@
#include <stddef.h>
#include <stdint.h>
+#include "base/callback_helpers.h"
#include "base/run_loop.h"
+#include "base/strings/string16.h"
+#include "base/test/bind_test_util.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "mojo/public/cpp/system/message_pipe.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/test/test_clipboard.h"
@@ -19,26 +23,21 @@ namespace content {
class ClipboardHostImplTest : public ::testing::Test {
protected:
ClipboardHostImplTest()
- : clipboard_(ui::TestClipboard::CreateForCurrentThread()) {}
+ : clipboard_(ui::TestClipboard::CreateForCurrentThread()) {
+ ClipboardHostImpl::Create(mojo::MakeRequest(&ptr_));
+ }
~ClipboardHostImplTest() override {
ui::Clipboard::DestroyClipboardForCurrentThread();
}
- void CallWriteImage(const SkBitmap& bitmap) {
- host_.WriteImage(ui::CLIPBOARD_TYPE_COPY_PASTE, bitmap);
- }
+ blink::mojom::ClipboardHostPtr& mojo_clipboard() { return ptr_; }
- void CallCommitWrite() {
- host_.CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
- base::RunLoop().RunUntilIdle();
- }
-
- ui::Clipboard* clipboard() { return clipboard_; }
+ ui::Clipboard* system_clipboard() { return clipboard_; }
private:
const TestBrowserThreadBundle thread_bundle_;
- ClipboardHostImpl host_;
+ blink::mojom::ClipboardHostPtr ptr_;
ui::Clipboard* const clipboard_;
};
@@ -47,20 +46,48 @@ TEST_F(ClipboardHostImplTest, SimpleImage) {
SkBitmap bitmap;
bitmap.allocN32Pixels(3, 2);
bitmap.eraseARGB(255, 0, 255, 0);
- CallWriteImage(bitmap);
+ mojo_clipboard()->WriteImage(ui::CLIPBOARD_TYPE_COPY_PASTE, bitmap);
uint64_t sequence_number =
- clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE);
- CallCommitWrite();
+ system_clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ mojo_clipboard()->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ base::RunLoop().RunUntilIdle();
- EXPECT_NE(sequence_number,
- clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE));
- EXPECT_FALSE(clipboard()->IsFormatAvailable(
+ EXPECT_NE(sequence_number, system_clipboard()->GetSequenceNumber(
+ ui::CLIPBOARD_TYPE_COPY_PASTE));
+ EXPECT_FALSE(system_clipboard()->IsFormatAvailable(
ui::Clipboard::GetPlainTextFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
- EXPECT_TRUE(clipboard()->IsFormatAvailable(
+ EXPECT_TRUE(system_clipboard()->IsFormatAvailable(
ui::Clipboard::GetBitmapFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
- SkBitmap actual = clipboard()->ReadImage(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ SkBitmap actual =
+ system_clipboard()->ReadImage(ui::CLIPBOARD_TYPE_COPY_PASTE);
EXPECT_TRUE(gfx::BitmapsAreEqual(bitmap, actual));
}
+TEST_F(ClipboardHostImplTest, ReentrancyInSyncCall) {
+ // Due to the nature of this test, it's somewhat racy. On some platforms
+ // (currently Linux), reading the clipboard requires running a nested message
+ // loop. During that time, it's possible to send a bad message that causes the
+ // message pipe to be closed. Make sure ClipboardHostImpl doesn't UaF |this|
+ // after exiting the nested message loop.
+
+ // ReadText() is a sync method, so normally, one wouldn't call this method
+ // directly. These are not normal times though...
+ base::RunLoop run_loop;
+ mojo_clipboard()->ReadText(
+ ui::CLIPBOARD_TYPE_COPY_PASTE,
+ base::BindLambdaForTesting(
+ [&run_loop](const base::string16& ignored) { run_loop.Quit(); }));
+
+ // Now purposely write a raw message which (hopefully) won't deserialize to
+ // anything valid. The receiver side should still be in the midst of
+ // dispatching ReadText() when Mojo attempts to deserialize this message,
+ // which should cause a validation failure that signals a connection error.
+ mojo::WriteMessageRaw(mojo_clipboard().internal_state()->handle(), "moo", 3,
+ nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE);
+ run_loop.Run();
+
+ EXPECT_TRUE(mojo_clipboard().encountered_error());
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/code_cache_host_impl.cc b/chromium/content/browser/renderer_host/code_cache_host_impl.cc
new file mode 100644
index 00000000000..17dcbed2857
--- /dev/null
+++ b/chromium/content/browser/renderer_host/code_cache_host_impl.cc
@@ -0,0 +1,239 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/code_cache_host_impl.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/task/post_task.h"
+#include "base/threading/thread.h"
+#include "build/build_config.h"
+#include "content/browser/cache_storage/cache_storage_cache.h"
+#include "content/browser/cache_storage/cache_storage_cache_handle.h"
+#include "content/browser/cache_storage/cache_storage_context_impl.h"
+#include "content/browser/cache_storage/cache_storage_manager.h"
+#include "content/browser/child_process_security_policy_impl.h"
+#include "content/browser/code_cache/generated_code_cache.h"
+#include "content/browser/code_cache/generated_code_cache_context.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/public/browser/resource_context.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/common/content_features.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "net/base/features.h"
+#include "net/base/io_buffer.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+using blink::mojom::CacheStorageError;
+
+namespace content {
+
+namespace {
+
+void NoOpCacheStorageErrorCallback(CacheStorageCacheHandle cache_handle,
+ CacheStorageError error) {}
+
+base::Optional<url::Origin> GetRendererOrigin(const GURL& url,
+ int render_process_id) {
+ GURL requesting_url =
+ ChildProcessSecurityPolicyImpl::GetInstance()->GetOriginLock(
+ render_process_id);
+
+ if (!requesting_url.is_valid() || !url.is_valid())
+ return base::nullopt;
+
+ url::Origin origin = url::Origin::Create(requesting_url);
+
+ // Don't cache the code corresponding to unique origins. The same-origin
+ // checks should always fail for unique origins but the serialized value of
+ // unique origins does not ensure this.
+ if (origin.opaque())
+ return base::nullopt;
+
+ return origin;
+}
+
+} // namespace
+
+CodeCacheHostImpl::CodeCacheHostImpl(
+ int render_process_id,
+ scoped_refptr<CacheStorageContextImpl> cache_storage_context,
+ scoped_refptr<GeneratedCodeCacheContext> generated_code_cache_context)
+ : render_process_id_(render_process_id),
+ cache_storage_context_(std::move(cache_storage_context)),
+ generated_code_cache_context_(std::move(generated_code_cache_context)),
+ weak_ptr_factory_(this) {}
+
+CodeCacheHostImpl::~CodeCacheHostImpl() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+}
+
+// static
+void CodeCacheHostImpl::Create(
+ int render_process_id,
+ scoped_refptr<CacheStorageContextImpl> cache_storage_context,
+ scoped_refptr<GeneratedCodeCacheContext> generated_code_cache_context,
+ blink::mojom::CodeCacheHostRequest request) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ mojo::MakeStrongBinding(
+ std::make_unique<CodeCacheHostImpl>(
+ render_process_id, std::move(cache_storage_context),
+ std::move(generated_code_cache_context)),
+ std::move(request));
+}
+
+void CodeCacheHostImpl::DidGenerateCacheableMetadata(
+ blink::mojom::CodeCacheType cache_type,
+ const GURL& url,
+ base::Time expected_response_time,
+ const std::vector<uint8_t>& data) {
+ if (!url.SchemeIsHTTPOrHTTPS()) {
+ mojo::ReportBadMessage("Invalid URL scheme for code cache.");
+ return;
+ }
+
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ if (!base::FeatureList::IsEnabled(net::features::kIsolatedCodeCache)) {
+ // Only store Javascript (not WebAssembly) code in the single-keyed cache.
+ if (cache_type == blink::mojom::CodeCacheType::kJavascript) {
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&CodeCacheHostImpl::DidGenerateCacheableMetadataOnUI,
+ render_process_id_, url, expected_response_time,
+ data));
+ } else {
+ mojo::ReportBadMessage("Single-keyed code cache is Javascript only.");
+ return;
+ }
+ } else {
+ GeneratedCodeCache* code_cache = GetCodeCache(cache_type);
+ if (!code_cache)
+ return;
+
+ base::Optional<url::Origin> requesting_origin =
+ GetRendererOrigin(url, render_process_id_);
+ if (!requesting_origin)
+ return;
+
+ code_cache->WriteData(url, *requesting_origin, expected_response_time,
+ data);
+ }
+}
+
+void CodeCacheHostImpl::FetchCachedCode(blink::mojom::CodeCacheType cache_type,
+ const GURL& url,
+ FetchCachedCodeCallback callback) {
+ GeneratedCodeCache* code_cache = GetCodeCache(cache_type);
+ if (!code_cache) {
+ std::move(callback).Run(base::Time(), std::vector<uint8_t>());
+ return;
+ }
+
+ base::Optional<url::Origin> requesting_origin =
+ GetRendererOrigin(url, render_process_id_);
+ if (!requesting_origin) {
+ std::move(callback).Run(base::Time(), std::vector<uint8_t>());
+ return;
+ }
+
+ auto read_callback = base::BindRepeating(
+ &CodeCacheHostImpl::OnReceiveCachedCode, weak_ptr_factory_.GetWeakPtr(),
+ base::Passed(&callback));
+ code_cache->FetchEntry(url, *requesting_origin, read_callback);
+}
+
+void CodeCacheHostImpl::ClearCodeCacheEntry(
+ blink::mojom::CodeCacheType cache_type,
+ const GURL& url) {
+ GeneratedCodeCache* code_cache = GetCodeCache(cache_type);
+ if (!code_cache)
+ return;
+
+ base::Optional<url::Origin> requesting_origin =
+ GetRendererOrigin(url, render_process_id_);
+ if (!requesting_origin)
+ return;
+
+ code_cache->DeleteEntry(url, *requesting_origin);
+}
+
+void CodeCacheHostImpl::DidGenerateCacheableMetadataInCacheStorage(
+ const GURL& url,
+ base::Time expected_response_time,
+ const std::vector<uint8_t>& data,
+ const url::Origin& cache_storage_origin,
+ const std::string& cache_storage_cache_name) {
+ scoped_refptr<net::IOBuffer> buf =
+ base::MakeRefCounted<net::IOBuffer>(data.size());
+ if (!data.empty())
+ memcpy(buf->data(), &data.front(), data.size());
+
+ cache_storage_context_->cache_manager()->OpenCache(
+ cache_storage_origin, CacheStorageOwner::kCacheAPI,
+ cache_storage_cache_name,
+ base::BindOnce(&CodeCacheHostImpl::OnCacheStorageOpenCallback,
+ weak_ptr_factory_.GetWeakPtr(), url,
+ expected_response_time, buf, data.size()));
+}
+
+GeneratedCodeCache* CodeCacheHostImpl::GetCodeCache(
+ blink::mojom::CodeCacheType cache_type) {
+ if (!generated_code_cache_context_)
+ return nullptr;
+
+ if (cache_type == blink::mojom::CodeCacheType::kJavascript)
+ return generated_code_cache_context_->generated_js_code_cache();
+
+ DCHECK_EQ(blink::mojom::CodeCacheType::kWebAssembly, cache_type);
+ return generated_code_cache_context_->generated_wasm_code_cache();
+}
+
+void CodeCacheHostImpl::OnReceiveCachedCode(FetchCachedCodeCallback callback,
+ const base::Time& response_time,
+ const std::vector<uint8_t>& data) {
+ // TODO(crbug.com/867848): Pass the data as a mojo data pipe instead
+ // of vector<uint8>
+ std::move(callback).Run(response_time, data);
+}
+
+void CodeCacheHostImpl::OnCacheStorageOpenCallback(
+ const GURL& url,
+ base::Time expected_response_time,
+ scoped_refptr<net::IOBuffer> buf,
+ int buf_len,
+ CacheStorageCacheHandle cache_handle,
+ CacheStorageError error) {
+ if (error != CacheStorageError::kSuccess || !cache_handle.value())
+ return;
+ CacheStorageCache* cache = cache_handle.value();
+ cache->WriteSideData(
+ base::BindOnce(&NoOpCacheStorageErrorCallback, std::move(cache_handle)),
+ url, expected_response_time, buf, buf_len);
+}
+
+// static
+void CodeCacheHostImpl::DidGenerateCacheableMetadataOnUI(
+ int render_process_id,
+ const GURL& url,
+ base::Time expected_response_time,
+ const std::vector<uint8_t>& data) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RenderProcessHost* host = RenderProcessHost::FromID(render_process_id);
+ if (!host)
+ return;
+
+ // Use the same priority for the metadata write as for script
+ // resources (see defaultPriorityForResourceType() in WebKit's
+ // CachedResource.cpp). Note that WebURLRequest::PriorityMedium
+ // corresponds to net::LOW (see ConvertWebKitPriorityToNetPriority()
+ // in weburlloader_impl.cc).
+ const net::RequestPriority kPriority = net::LOW;
+ host->GetStoragePartition()->GetNetworkContext()->WriteCacheMetadata(
+ url, kPriority, expected_response_time, data);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/code_cache_host_impl.h b/chromium/content/browser/renderer_host/code_cache_host_impl.h
new file mode 100644
index 00000000000..4e0844adaad
--- /dev/null
+++ b/chromium/content/browser/renderer_host/code_cache_host_impl.h
@@ -0,0 +1,104 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_CODE_CACHE_HOST_IMPL_H_
+#define CONTENT_BROWSER_RENDERER_HOST_CODE_CACHE_HOST_IMPL_H_
+
+#include <string>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/strings/string16.h"
+#include "build/build_config.h"
+#include "content/common/content_export.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "third_party/blink/public/mojom/loader/code_cache.mojom.h"
+#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h"
+
+class GURL;
+
+namespace net {
+class IOBuffer;
+}
+
+namespace url {
+class Origin;
+}
+
+namespace content {
+
+class CacheStorageContextImpl;
+class CacheStorageCacheHandle;
+class GeneratedCodeCache;
+class GeneratedCodeCacheContext;
+
+// The implementation of a CodeCacheHost, which stores and retrieves resource
+// metadata, either bytecode or native code, generated by a renderer process.
+// Instances of this class are owned by by the Mojo pipe that's passed to the
+// renderer process via StrongBinding.
+// Instances of this class must be created and used on the IO thread.
+class CONTENT_EXPORT CodeCacheHostImpl : public blink::mojom::CodeCacheHost {
+ public:
+ CodeCacheHostImpl(
+ int render_process_id,
+ scoped_refptr<CacheStorageContextImpl> cache_storage_context,
+ scoped_refptr<GeneratedCodeCacheContext> generated_code_cache_context);
+ ~CodeCacheHostImpl() override;
+
+ static void Create(
+ int render_process_id,
+ scoped_refptr<CacheStorageContextImpl> cache_storage_context,
+ scoped_refptr<GeneratedCodeCacheContext> generated_code_cache_context,
+ blink::mojom::CodeCacheHostRequest request);
+
+ private:
+ // blink::mojom::CodeCacheHost implementation.
+ void DidGenerateCacheableMetadata(blink::mojom::CodeCacheType cache_type,
+ const GURL& url,
+ base::Time expected_response_time,
+ const std::vector<uint8_t>& data) override;
+ void FetchCachedCode(blink::mojom::CodeCacheType cache_type,
+ const GURL& url,
+ FetchCachedCodeCallback) override;
+ void ClearCodeCacheEntry(blink::mojom::CodeCacheType cache_type,
+ const GURL& url) override;
+ void DidGenerateCacheableMetadataInCacheStorage(
+ const GURL& url,
+ base::Time expected_response_time,
+ const std::vector<uint8_t>& data,
+ const url::Origin& cache_storage_origin,
+ const std::string& cache_storage_cache_name) override;
+
+ // Helpers.
+ GeneratedCodeCache* GetCodeCache(blink::mojom::CodeCacheType cache_type);
+ void OnReceiveCachedCode(FetchCachedCodeCallback callback,
+ const base::Time& response_time,
+ const std::vector<uint8_t>& data);
+ void OnCacheStorageOpenCallback(const GURL& url,
+ base::Time expected_response_time,
+ scoped_refptr<net::IOBuffer> buf,
+ int buf_len,
+ CacheStorageCacheHandle cache_handle,
+ blink::mojom::CacheStorageError error);
+ static void DidGenerateCacheableMetadataOnUI(
+ int render_process_id,
+ const GURL& url,
+ base::Time expected_response_time,
+ const std::vector<uint8_t>& data);
+
+ // Our render process host ID, used to bind to the correct render process.
+ const int render_process_id_;
+
+ scoped_refptr<CacheStorageContextImpl> cache_storage_context_;
+
+ scoped_refptr<GeneratedCodeCacheContext> generated_code_cache_context_;
+
+ base::WeakPtrFactory<CodeCacheHostImpl> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(CodeCacheHostImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_CODE_CACHE_HOST_IMPL_H_
diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.cc b/chromium/content/browser/renderer_host/compositor_impl_android.cc
index ebfb4c19fb0..7e99e812763 100644
--- a/chromium/content/browser/renderer_host/compositor_impl_android.cc
+++ b/chromium/content/browser/renderer_host/compositor_impl_android.cc
@@ -27,6 +27,7 @@
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/sys_info.h"
+#include "base/task/post_task.h"
#include "base/threading/simple_thread.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
@@ -61,15 +62,17 @@
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/compositor/surface_utils.h"
+#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
-#include "content/common/gpu_stream_constants.h"
#include "content/public/browser/android/compositor.h"
#include "content/public/browser/android/compositor_client.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_stream_constants.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/common/swap_buffers_complete_params.h"
@@ -78,9 +81,11 @@
#include "gpu/ipc/client/gpu_channel_host.h"
#include "gpu/ipc/common/gpu_surface_tracker.h"
#include "gpu/vulkan/buildflags.h"
+#if BUILDFLAG(ENABLE_VULKAN)
#include "gpu/vulkan/init/vulkan_factory.h"
#include "gpu/vulkan/vulkan_implementation.h"
#include "gpu/vulkan/vulkan_surface.h"
+#endif
#include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
#include "services/ws/public/cpp/gpu/context_provider_command_buffer.h"
@@ -104,6 +109,8 @@ namespace content {
namespace {
+static const char* kBrowser = "Browser";
+
// These functions are called based on application visibility status.
void SendOnBackgroundedToGpuService() {
content::GpuProcessHost::CallOnIO(
@@ -127,6 +134,14 @@ void SendOnForegroundedToGpuService() {
}));
}
+void BrowserGpuChannelHostFactorySetApplicationVisible(bool is_visible) {
+ // This code relies on the browser's GpuChannelEstablishFactory being the
+ // BrowserGpuChannelHostFactory.
+ DCHECK_EQ(BrowserMainLoop::GetInstance()->gpu_channel_establish_factory(),
+ BrowserGpuChannelHostFactory::instance());
+ BrowserGpuChannelHostFactory::instance()->SetApplicationVisible(is_visible);
+}
+
// The client_id used here should not conflict with the client_id generated
// from RenderWidgetHostImpl.
constexpr uint32_t kDefaultClientId = 0u;
@@ -144,18 +159,28 @@ class SingleThreadTaskGraphRunner : public cc::SingleThreadTaskGraphRunner {
class AndroidHostDisplayClient : public viz::HostDisplayClient {
public:
explicit AndroidHostDisplayClient(
- base::RepeatingCallback<void(const gfx::Size&)> on_swap)
+ base::RepeatingCallback<void(const gfx::Size&)> on_swap,
+ base::RepeatingCallback<void(gpu::ContextResult)>
+ on_context_creation_failure)
: HostDisplayClient(gfx::kNullAcceleratedWidget),
- on_swap_(std::move(on_swap)) {}
+ on_swap_(std::move(on_swap)),
+ on_context_creation_failure_(std::move(on_context_creation_failure)) {}
// viz::mojom::DisplayClient implementation:
void DidCompleteSwapWithSize(const gfx::Size& pixel_size) override {
if (on_swap_)
on_swap_.Run(pixel_size);
}
+ void OnFatalOrSurfaceContextCreationFailure(
+ gpu::ContextResult context_result) override {
+ if (on_context_creation_failure_)
+ on_context_creation_failure_.Run(context_result);
+ }
private:
base::RepeatingCallback<void(const gfx::Size&)> on_swap_;
+ base::RepeatingCallback<void(gpu::ContextResult)>
+ on_context_creation_failure_;
};
class CompositorDependencies {
@@ -184,14 +209,19 @@ class CompositorDependencies {
host_frame_sink_manager.SetConnectionLostCallback(base::BindRepeating(
[]() { CompositorDependencies::Get().CreateVizFrameSinkManager(); }));
- pending_connect_viz_on_main_thread_ = base::BindOnce(
- &CompositorDependencies::
- OnReadyToConnectVizFrameSinkManagerOnMainThread,
- base::Unretained(this), std::move(frame_sink_manager_request),
+ // Set up a pending request which will be run once we've successfully
+ // connected to the GPU process.
+ pending_connect_viz_on_io_thread_ = base::BindOnce(
+ &CompositorDependencies::ConnectVizFrameSinkManagerOnIOThread,
+ std::move(frame_sink_manager_request),
frame_sink_manager_client.PassInterface());
+ }
- // Will connect using the above callback if we are foreground.
- TryEstablishVizConnectionIfNeeded();
+ void TryEstablishVizConnectionIfNeeded() {
+ if (!pending_connect_viz_on_io_thread_)
+ return;
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ std::move(pending_connect_viz_on_io_thread_));
}
SingleThreadTaskGraphRunner task_graph_runner;
@@ -216,11 +246,15 @@ class CompositorDependencies {
CompositorDependencies()
: frame_sink_id_allocator(kDefaultClientId),
- app_listener_(base::BindRepeating(
- &CompositorDependencies::OnApplicationStateChange,
- base::Unretained(this))) {
+ app_listener_(
+ base::android::ApplicationStatusListener::New(base::BindRepeating(
+ &CompositorDependencies::OnApplicationStateChange,
+ base::Unretained(this)))) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Ensure we're in the correct state at start up.
+ OnApplicationStateChange(app_listener_->GetState());
+
bool enable_viz =
base::FeatureList::IsEnabled(features::kVizDisplayCompositor);
if (!enable_viz) {
@@ -233,54 +267,20 @@ class CompositorDependencies {
} else {
CreateVizFrameSinkManager();
}
-
- // Ensure we're in the correct state at start up.
- OnApplicationStateChange(app_listener_.GetState());
- }
-
- void OnReadyToConnectVizFrameSinkManagerOnMainThread(
- viz::mojom::FrameSinkManagerRequest request,
- viz::mojom::FrameSinkManagerClientPtrInfo client,
- scoped_refptr<gpu::GpuChannelHost> host) {
- if (!host) {
- // If host creation failed, try again. We have no software fallback on
- // Android. This must succeed.
- CreateVizFrameSinkManager();
- return;
- }
-
- // Forward |connect_on_io| to the IO thread to run.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CompositorDependencies::
- OnReadyToConnectVizFrameSinkManagerOnIOThread,
- base::Unretained(this), std::move(request),
- std::move(client)));
}
- void OnReadyToConnectVizFrameSinkManagerOnIOThread(
+ // Called on IO thread, after a GPU connection has already been established.
+ // |gpu_process_host| should only be invalid if a channel has been
+ // established and lost. In this case the ConnectionLost callback will be
+ // re-run when the request is deleted (goes out of scope).
+ static void ConnectVizFrameSinkManagerOnIOThread(
viz::mojom::FrameSinkManagerRequest request,
viz::mojom::FrameSinkManagerClientPtrInfo client) {
- // There should always be a GpuProcessHost instance, and GPU
- // process at this point. The exception is
- // during shutdown the GPU process won't be restarted and
- // GpuProcessHost::Get() can return null.
auto* gpu_process_host = GpuProcessHost::Get();
- if (gpu_process_host) {
- gpu_process_host->gpu_host()->ConnectFrameSinkManager(std::move(request),
- std::move(client));
- }
- }
-
- void TryEstablishVizConnectionIfNeeded() {
- // We don't connect to the viz process if backgrounded, as the OS may
- // repeatedly kill the resulting process. Instead wait until we come to the
- // foreground.
- if (pending_connect_viz_on_main_thread_ && application_is_foreground_) {
- BrowserMainLoop::GetInstance()
- ->gpu_channel_establish_factory()
- ->EstablishGpuChannel(std::move(pending_connect_viz_on_main_thread_));
- }
+ if (!gpu_process_host)
+ return;
+ gpu_process_host->gpu_host()->ConnectFrameSinkManager(std::move(request),
+ std::move(client));
}
void EnqueueLowEndBackgroundCleanup() {
@@ -323,18 +323,23 @@ class CompositorDependencies {
case base::android::APPLICATION_STATE_UNKNOWN:
case base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES:
case base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES:
+ if (application_is_foreground_)
+ return;
+ application_is_foreground_ = true;
GpuDataManagerImpl::GetInstance()->SetApplicationVisible(true);
+ BrowserGpuChannelHostFactorySetApplicationVisible(true);
SendOnForegroundedToGpuService();
low_end_background_cleanup_task_.Cancel();
- application_is_foreground_ = true;
- TryEstablishVizConnectionIfNeeded();
break;
case base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES:
case base::android::APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES:
+ if (!application_is_foreground_)
+ return;
+ application_is_foreground_ = false;
GpuDataManagerImpl::GetInstance()->SetApplicationVisible(false);
+ BrowserGpuChannelHostFactorySetApplicationVisible(false);
SendOnBackgroundedToGpuService();
EnqueueLowEndBackgroundCleanup();
- application_is_foreground_ = false;
}
}
@@ -343,9 +348,11 @@ class CompositorDependencies {
base::CancelableOnceClosure low_end_background_cleanup_task_;
// An instance of Android AppListener.
- base::android::ApplicationStatusListener app_listener_;
+ std::unique_ptr<base::android::ApplicationStatusListener> app_listener_;
bool application_is_foreground_ = true;
- gpu::GpuChannelEstablishedCallback pending_connect_viz_on_main_thread_;
+
+ // A callback which connects to the viz service on the IO thread.
+ base::OnceClosure pending_connect_viz_on_io_thread_;
};
const unsigned int kMaxDisplaySwapBuffers = 1U;
@@ -372,28 +379,10 @@ scoped_refptr<viz::VulkanContextProvider> GetSharedVulkanContextProvider() {
gpu::SharedMemoryLimits GetCompositorContextSharedMemoryLimits(
gfx::NativeWindow window) {
- constexpr size_t kBytesPerPixel = 4;
- const gfx::Size size = display::Screen::GetScreen()
- ->GetDisplayNearestWindow(window)
- .GetSizeInPixel();
- const size_t full_screen_texture_size_in_bytes =
- size.width() * size.height() * kBytesPerPixel;
-
- gpu::SharedMemoryLimits limits;
- // This limit is meant to hold the contents of the display compositor
- // drawing the scene. See discussion here:
- // https://codereview.chromium.org/1900993002/diff/90001/content/browser/renderer_host/compositor_impl_android.cc?context=3&column_width=80&tab_spaces=8
- limits.command_buffer_size = 64 * 1024;
- // These limits are meant to hold the uploads for the browser UI without
- // any excess space.
- limits.start_transfer_buffer_size = 64 * 1024;
- limits.min_transfer_buffer_size = 64 * 1024;
- limits.max_transfer_buffer_size = full_screen_texture_size_in_bytes;
- // Texture uploads may use mapped memory so give a reasonable limit for
- // them.
- limits.mapped_memory_reclaim_limit = full_screen_texture_size_in_bytes;
-
- return limits;
+ const gfx::Size screen_size = display::Screen::GetScreen()
+ ->GetDisplayNearestWindow(window)
+ .GetSizeInPixel();
+ return gpu::SharedMemoryLimits::ForDisplayCompositor(screen_size);
}
gpu::ContextCreationAttribs GetCompositorContextAttributes(
@@ -778,7 +767,7 @@ CompositorImpl::CompositorImpl(CompositorClient* client,
needs_animate_(false),
pending_frames_(0U),
layer_tree_frame_sink_request_pending_(false),
- lock_manager_(base::ThreadTaskRunnerHandle::Get(), this),
+ lock_manager_(base::ThreadTaskRunnerHandle::Get()),
enable_surface_synchronization_(
features::IsSurfaceSynchronizationEnabled()),
enable_viz_(
@@ -924,7 +913,7 @@ void CompositorImpl::CreateLayerTreeHost() {
params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
params.settings = &settings;
params.mutator_host = animation_host_.get();
- host_ = cc::LayerTreeHost::CreateSingleThreaded(this, &params);
+ host_ = cc::LayerTreeHost::CreateSingleThreaded(this, std::move(params));
DCHECK(!host_->IsVisible());
host_->SetViewportSizeAndScale(size_, root_window_->GetDipScale(),
GenerateLocalSurfaceId());
@@ -1026,9 +1015,7 @@ void CompositorImpl::SetNeedsComposite() {
host_->SetNeedsAnimate();
}
-void CompositorImpl::UpdateLayerTreeHost(VisualStateUpdate requested_update) {
- if (requested_update == VisualStateUpdate::kPrePaint)
- return;
+void CompositorImpl::UpdateLayerTreeHost() {
client_->UpdateLayerTreeHost();
if (needs_animate_) {
needs_animate_ = false;
@@ -1104,6 +1091,10 @@ bool CompositorImpl::CreateVulkanOutputSurface() {
void CompositorImpl::OnGpuChannelEstablished(
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
+ // At this point we know we have a valid GPU process, establish our viz
+ // connection if needed.
+ CompositorDependencies::Get().TryEstablishVizConnectionIfNeeded();
+
// We might end up queing multiple GpuChannel requests for the same
// LayerTreeFrameSink request as the visibility of the compositor changes, so
// the LayerTreeFrameSink request could have been handled already.
@@ -1149,9 +1140,9 @@ void CompositorImpl::OnGpuChannelEstablished(
requires_alpha_channel_),
ws::command_buffer_metrics::ContextType::BROWSER_COMPOSITOR);
auto result = context_provider->BindToCurrentThread();
- LOG_IF(FATAL, result == gpu::ContextResult::kFatalFailure)
- << "Fatal error making Gpu context";
if (result != gpu::ContextResult::kSuccess) {
+ if (gpu::IsFatalOrSurfaceFailure(result))
+ OnFatalOrSurfaceContextCreationFailure(result);
HandlePendingLayerTreeFrameSinkRequest();
return;
}
@@ -1192,6 +1183,10 @@ void CompositorImpl::InitializeDisplay(
renderer_settings.allow_antialiasing = false;
renderer_settings.highp_threshold_min = 2048;
renderer_settings.auto_resize_output_surface = false;
+ renderer_settings.initial_screen_size =
+ display::Screen::GetScreen()
+ ->GetDisplayNearestWindow(root_window_)
+ .GetSizeInPixel();
auto* gpu_memory_buffer_manager = BrowserMainLoop::GetInstance()
->gpu_channel_establish_factory()
->GetGpuMemoryBufferManager();
@@ -1327,7 +1322,10 @@ bool CompositorImpl::HavePendingReadbacks() {
std::unique_ptr<ui::CompositorLock> CompositorImpl::GetCompositorLock(
ui::CompositorLockClient* client,
base::TimeDelta timeout) {
- return lock_manager_.GetCompositorLock(client, timeout);
+ std::unique_ptr<cc::ScopedDeferCommits> scoped_defer_commits =
+ host_ ? host_->DeferCommits() : nullptr;
+ return lock_manager_.GetCompositorLock(client, timeout,
+ std::move(scoped_defer_commits));
}
bool CompositorImpl::IsDrawingFirstVisibleFrame() const {
@@ -1347,11 +1345,6 @@ void CompositorImpl::SetVSyncPaused(bool paused) {
display_private_->SetVSyncPaused(paused);
}
-void CompositorImpl::OnCompositorLockStateChanged(bool locked) {
- if (host_)
- host_->SetDeferCommits(locked);
-}
-
void CompositorImpl::InitializeVizLayerTreeFrameSink(
scoped_refptr<ws::ContextProviderCommandBuffer> context_provider) {
DCHECK(enable_viz_);
@@ -1372,9 +1365,12 @@ void CompositorImpl::InitializeVizLayerTreeFrameSink(
viz::mojom::CompositorFrameSinkClientRequest client_request =
mojo::MakeRequest(&root_params->compositor_frame_sink_client);
root_params->display_private = mojo::MakeRequest(&display_private_);
- display_client_ =
- std::make_unique<AndroidHostDisplayClient>(base::BindRepeating(
- &CompositorImpl::DidSwapBuffers, weak_factory_.GetWeakPtr()));
+ display_client_ = std::make_unique<AndroidHostDisplayClient>(
+ base::BindRepeating(&CompositorImpl::DidSwapBuffers,
+ weak_factory_.GetWeakPtr()),
+ base::BindRepeating(
+ &CompositorImpl::OnFatalOrSurfaceContextCreationFailure,
+ weak_factory_.GetWeakPtr()));
root_params->display_client =
display_client_->GetBoundPtr(task_runner).PassInterface();
@@ -1382,6 +1378,10 @@ void CompositorImpl::InitializeVizLayerTreeFrameSink(
renderer_settings.allow_antialiasing = false;
renderer_settings.highp_threshold_min = 2048;
renderer_settings.requires_alpha_channel = requires_alpha_channel_;
+ renderer_settings.initial_screen_size =
+ display::Screen::GetScreen()
+ ->GetDisplayNearestWindow(root_window_)
+ .GetSizeInPixel();
root_params->frame_sink_id = frame_sink_id_;
root_params->widget = surface_handle_;
root_params->gpu_compositing = true;
@@ -1403,7 +1403,9 @@ void CompositorImpl::InitializeVizLayerTreeFrameSink(
params.enable_surface_synchronization = true;
params.hit_test_data_provider =
std::make_unique<viz::HitTestDataProviderDrawQuad>(
- /*should_ask_for_child_region=*/false);
+ false /* should_ask_for_child_region */,
+ true /* root_accepts_events */);
+ params.client_name = kBrowser;
auto layer_tree_frame_sink =
std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>(
std::move(context_provider), nullptr, &params);
@@ -1420,4 +1422,16 @@ viz::LocalSurfaceId CompositorImpl::GenerateLocalSurfaceId() const {
return viz::LocalSurfaceId();
}
+void CompositorImpl::OnFatalOrSurfaceContextCreationFailure(
+ gpu::ContextResult context_result) {
+ DCHECK(gpu::IsFatalOrSurfaceFailure(context_result));
+ LOG_IF(FATAL, context_result == gpu::ContextResult::kFatalFailure)
+ << "Fatal error making Gpu context";
+
+ if (context_result == gpu::ContextResult::kSurfaceFailure) {
+ SetSurface(nullptr);
+ client_->RecreateSurface();
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.h b/chromium/content/browser/renderer_host/compositor_impl_android.h
index 465dee6734a..7190d3c5139 100644
--- a/chromium/content/browser/renderer_host/compositor_impl_android.h
+++ b/chromium/content/browser/renderer_host/compositor_impl_android.h
@@ -66,7 +66,6 @@ class CONTENT_EXPORT CompositorImpl
: public Compositor,
public cc::LayerTreeHostClient,
public cc::LayerTreeHostSingleThreadClient,
- public ui::CompositorLockManagerClient,
public ui::UIResourceProvider,
public ui::WindowAndroidCompositor,
public viz::HostFrameSinkClient,
@@ -112,12 +111,9 @@ class CONTENT_EXPORT CompositorImpl
void BeginMainFrame(const viz::BeginFrameArgs& args) override {}
void BeginMainFrameNotExpectedSoon() override {}
void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override {}
- void UpdateLayerTreeHost(VisualStateUpdate requested_update) override;
- void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
- const gfx::Vector2dF& outer_delta,
- const gfx::Vector2dF& elastic_overscroll_delta,
- float page_scale,
- float top_controls_delta) override {}
+ void UpdateLayerTreeHost() override;
+ void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) override {
+ }
void RecordWheelAndTouchScrollingCount(bool has_scrolled_by_wheel,
bool has_scrolled_by_touch) override {}
void RequestNewLayerTreeFrameSink() override;
@@ -131,6 +127,7 @@ class CONTENT_EXPORT CompositorImpl
void DidPresentCompositorFrame(
uint32_t frame_token,
const gfx::PresentationFeedback& feedback) override {}
+ void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override {}
// LayerTreeHostSingleThreadClient implementation.
void DidSubmitCompositorFrame() override;
@@ -159,9 +156,6 @@ class CONTENT_EXPORT CompositorImpl
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override;
- // ui::CompositorLockManagerClient implementation.
- void OnCompositorLockStateChanged(bool locked) override;
-
void SetVisible(bool visible);
void CreateLayerTreeHost();
@@ -197,6 +191,10 @@ class CONTENT_EXPORT CompositorImpl
// Registers the root frame sink ID.
void RegisterRootFrameSink();
+ // Called when we fail to create the context for the root frame sink.
+ void OnFatalOrSurfaceContextCreationFailure(
+ gpu::ContextResult context_result);
+
// Viz specific functions:
void InitializeVizLayerTreeFrameSink(
scoped_refptr<ws::ContextProviderCommandBuffer> context_provider);
diff --git a/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc b/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc
index 207c42dd823..e2b2f8a6159 100644
--- a/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc
+++ b/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc
@@ -11,8 +11,8 @@
#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/common/gpu_stream_constants.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_stream_constants.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
diff --git a/chromium/content/browser/renderer_host/delegated_frame_host.cc b/chromium/content/browser/renderer_host/delegated_frame_host.cc
index 995ba36a5e1..36f068e3361 100644
--- a/chromium/content/browser/renderer_host/delegated_frame_host.cc
+++ b/chromium/content/browser/renderer_host/delegated_frame_host.cc
@@ -45,7 +45,8 @@ DelegatedFrameHost::DelegatedFrameHost(const viz::FrameSinkId& frame_sink_id,
base::FeatureList::IsEnabled(features::kVizDisplayCompositor)),
should_register_frame_sink_id_(should_register_frame_sink_id),
host_frame_sink_manager_(GetHostFrameSinkManager()),
- frame_evictor_(std::make_unique<viz::FrameEvictor>(this)) {
+ frame_evictor_(std::make_unique<viz::FrameEvictor>(this)),
+ weak_factory_(this) {
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
factory->GetContextFactory()->AddObserver(this);
DCHECK(host_frame_sink_manager_);
@@ -95,6 +96,8 @@ void DelegatedFrameHost::CopyFromCompositingSurface(
const gfx::Rect& src_subrect,
const gfx::Size& output_size,
base::OnceCallback<void(const SkBitmap&)> callback) {
+ DCHECK(CanCopyFromCompositingSurface());
+
std::unique_ptr<viz::CopyOutputRequest> request =
std::make_unique<viz::CopyOutputRequest>(
viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
@@ -110,23 +113,11 @@ void DelegatedFrameHost::CopyFromCompositingSurface(
if (!output_size.IsEmpty())
request->set_result_selection(gfx::Rect(output_size));
- // If there is enough information to populate the copy output request fields,
- // then process it now. Otherwise, wait until the information becomes
- // available.
- if (CanCopyFromCompositingSurface() &&
- active_local_surface_id_ == pending_local_surface_id_)
- ProcessCopyOutputRequest(std::move(request));
- else
- pending_first_frame_requests_.push_back(std::move(request));
-}
-
-void DelegatedFrameHost::ProcessCopyOutputRequest(
- std::unique_ptr<viz::CopyOutputRequest> request) {
if (!request->has_area())
request->set_area(gfx::Rect(pending_surface_dip_size_));
- request->set_area(
- gfx::ScaleToRoundedRect(request->area(), active_device_scale_factor_));
+ request->set_area(gfx::ScaleToRoundedRect(request->area(),
+ client_->GetDeviceScaleFactor()));
if (request->has_result_selection()) {
const gfx::Rect& area = request->area();
@@ -148,7 +139,7 @@ void DelegatedFrameHost::ProcessCopyOutputRequest(
}
bool DelegatedFrameHost::CanCopyFromCompositingSurface() const {
- return HasFallbackSurface() && active_device_scale_factor_ != 0.f;
+ return pending_local_surface_id_.is_valid();
}
bool DelegatedFrameHost::TransformPointToLocalCoordSpaceLegacy(
@@ -219,15 +210,18 @@ void DelegatedFrameHost::EmbedSurface(
pending_local_surface_id_ = new_pending_local_surface_id;
pending_surface_dip_size_ = new_pending_dip_size;
+ viz::SurfaceId new_primary_surface_id(frame_sink_id_,
+ pending_local_surface_id_);
+
if (!client_->DelegatedFrameHostIsVisible()) {
- // If the tab is resized while hidden, reset the fallback so that the next
+ // If the tab is resized while hidden, advance the fallback so that the next
// time user switches back to it the page is blank. This is preferred to
// showing contents of old size. Don't call EvictDelegatedFrame to avoid
// races when dragging tabs across displays. See https://crbug.com/813157.
if (pending_surface_dip_size_ != current_frame_size_in_dip_ &&
- HasFallbackSurface()) {
+ HasPrimarySurface()) {
client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
- viz::SurfaceId());
+ new_primary_surface_id);
}
// Don't update the SurfaceLayer when invisible to avoid blocking on
// renderers that do not submit CompositorFrames. Next time the renderer
@@ -237,7 +231,6 @@ void DelegatedFrameHost::EmbedSurface(
if (!primary_surface_id ||
primary_surface_id->local_surface_id() != pending_local_surface_id_) {
- viz::SurfaceId surface_id(frame_sink_id_, pending_local_surface_id_);
#if defined(OS_WIN) || defined(USE_X11)
// On Windows and Linux, we would like to produce new content as soon as
// possible or the OS will create an additional black gutter. Until we can
@@ -254,7 +247,7 @@ void DelegatedFrameHost::EmbedSurface(
#endif
current_frame_size_in_dip_ = pending_surface_dip_size_;
client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface(
- surface_id, current_frame_size_in_dip_, GetGutterColor(),
+ new_primary_surface_id, current_frame_size_in_dip_, GetGutterColor(),
deadline_policy, false /* stretch_content_to_fill_bounds */);
if (compositor_ && !base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableResizeLock)) {
@@ -319,33 +312,13 @@ void DelegatedFrameHost::OnBeginFramePausedChanged(bool paused) {
void DelegatedFrameHost::OnFirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) {
- // If there's no primary surface, then we don't wish to display content at
- // this time (e.g. the view is hidden) and so we don't need a fallback
- // surface either. Since we won't use the fallback surface, we drop the
- // temporary reference here to save resources.
- if (!HasPrimarySurface()) {
- DCHECK(host_frame_sink_manager_);
- host_frame_sink_manager_->DropTemporaryReference(surface_info.id());
- return;
- }
-
- client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
- surface_info.id());
active_local_surface_id_ = surface_info.id().local_surface_id();
- active_device_scale_factor_ = surface_info.device_scale_factor();
// This is used by macOS' unique resize path.
client_->OnFirstSurfaceActivation(surface_info);
frame_evictor_->SwappedFrame(client_->DelegatedFrameHostIsVisible());
// Note: the frame may have been evicted immediately.
-
- if (!pending_first_frame_requests_.empty()) {
- DCHECK(CanCopyFromCompositingSurface());
- for (auto& request : pending_first_frame_requests_)
- ProcessCopyOutputRequest(std::move(request));
- pending_first_frame_requests_.clear();
- }
}
void DelegatedFrameHost::OnFrameTokenChanged(uint32_t frame_token) {
@@ -359,18 +332,27 @@ void DelegatedFrameHost::OnBeginFrame(const viz::BeginFrameArgs& args) {
}
void DelegatedFrameHost::ResetFallbackToFirstNavigationSurface() {
- if (HasFallbackSurface()) {
- client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(viz::SurfaceId(
- frame_sink_id_, first_local_surface_id_after_navigation_));
+ if (!HasPrimarySurface())
+ return;
+
+ const viz::SurfaceId* fallback_surface_id =
+ client_->DelegatedFrameHostGetLayer()->GetFallbackSurfaceId();
+
+ // Don't update the fallback if it's already newer than the first id after
+ // navigation.
+ if (fallback_surface_id &&
+ fallback_surface_id->frame_sink_id() == frame_sink_id_ &&
+ fallback_surface_id->local_surface_id().IsSameOrNewerThan(
+ first_local_surface_id_after_navigation_)) {
+ return;
}
+
+ client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
+ viz::SurfaceId(frame_sink_id_, first_local_surface_id_after_navigation_));
}
void DelegatedFrameHost::EvictDelegatedFrame() {
- // Reset fallback and primary surfaces.
- if (HasFallbackSurface()) {
- client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
- viz::SurfaceId());
- }
+ // Reset primary surface.
if (HasPrimarySurface()) {
client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface(
viz::SurfaceId(), current_frame_size_in_dip_, GetGutterColor(),
@@ -411,14 +393,6 @@ void DelegatedFrameHost::OnCompositingShuttingDown(ui::Compositor* compositor) {
void DelegatedFrameHost::OnLostSharedContext() {}
void DelegatedFrameHost::OnLostVizProcess() {
- // With OOP-D renderer surface was destroyed if the GPU process crashed. Reset
- // the fallback Surface but leave the primary so we embed the renderer surface
- // again.
- if (HasFallbackSurface()) {
- client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
- viz::SurfaceId());
- }
-
if (HasSavedFrame())
frame_evictor_->DiscardedFrame();
}
@@ -482,7 +456,6 @@ void DelegatedFrameHost::ResetCompositorFrameSinkSupport() {
void DelegatedFrameHost::DidNavigate() {
first_local_surface_id_after_navigation_ = pending_local_surface_id_;
- received_frame_after_navigation_ = false;
}
bool DelegatedFrameHost::IsPrimarySurfaceEvicted() const {
@@ -496,20 +469,45 @@ void DelegatedFrameHost::WindowTitleChanged(const std::string& title) {
}
void DelegatedFrameHost::TakeFallbackContentFrom(DelegatedFrameHost* other) {
- if (!other->HasFallbackSurface() || HasFallbackSurface())
+ // If the other view is not showing anything, we can't obtain a fallback.
+ if (!other->HasPrimarySurface())
+ return;
+
+ // This method should not overwrite the existing fallback. This method is only
+ // supposed to be called when the view was just created and there is no
+ // existing fallback.
+ if (HasFallbackSurface())
return;
+ const viz::SurfaceId* other_primary =
+ other->client_->DelegatedFrameHostGetLayer()->GetPrimarySurfaceId();
+
+ const viz::SurfaceId* other_fallback =
+ other->client_->DelegatedFrameHostGetLayer()->GetFallbackSurfaceId();
+
+ // In two cases we need to obtain a new fallback from the primary id of the
+ // other view instead of using its fallback:
+ // - When the other view has no fallback,
+ // - When a fallback exists but has a different FrameSinkId or embed token
+ // than the primary. If we use the fallback, then the resulting SurfaceRange
+ // in this view will not cover any surface with the FrameSinkId / embed token
+ // of the old view's primary.
+ viz::SurfaceId desired_fallback;
+ if (!other_fallback || !other_primary->IsSameOrNewerThan(*other_fallback)) {
+ desired_fallback = other_primary->ToSmallestId();
+ } else {
+ desired_fallback = *other_fallback;
+ }
+
if (!HasPrimarySurface()) {
client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface(
- *other->client_->DelegatedFrameHostGetLayer()->GetFallbackSurfaceId(),
- other->client_->DelegatedFrameHostGetLayer()->size(),
+ desired_fallback, other->client_->DelegatedFrameHostGetLayer()->size(),
other->client_->DelegatedFrameHostGetLayer()->background_color(),
cc::DeadlinePolicy::UseDefaultDeadline(),
false /* stretch_content_to_fill_bounds */);
}
- client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
- *other->client_->DelegatedFrameHostGetLayer()->GetFallbackSurfaceId());
+ client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(desired_fallback);
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/delegated_frame_host.h b/chromium/content/browser/renderer_host/delegated_frame_host.h
index b223d4708b3..b5492e018ec 100644
--- a/chromium/content/browser/renderer_host/delegated_frame_host.h
+++ b/chromium/content/browser/renderer_host/delegated_frame_host.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/gtest_prod_util.h"
+#include "base/memory/weak_ptr.h"
#include "components/viz/client/frame_evictor.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
@@ -43,14 +44,13 @@ class CONTENT_EXPORT DelegatedFrameHostClient {
virtual ui::Layer* DelegatedFrameHostGetLayer() const = 0;
virtual bool DelegatedFrameHostIsVisible() const = 0;
-
// Returns the color that the resize gutters should be drawn with.
virtual SkColor DelegatedFrameHostGetGutterColor() const = 0;
-
virtual void OnFirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) = 0;
virtual void OnBeginFrame(base::TimeTicks frame_time) = 0;
virtual void OnFrameTokenChanged(uint32_t frame_token) = 0;
+ virtual float GetDeviceScaleFactor() const = 0;
};
// The DelegatedFrameHost is used to host all of the RenderWidgetHostView state
@@ -179,6 +179,10 @@ class CONTENT_EXPORT DelegatedFrameHost
// |other|.
void TakeFallbackContentFrom(DelegatedFrameHost* other);
+ base::WeakPtr<DelegatedFrameHost> GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+ }
+
private:
friend class DelegatedFrameHostClient;
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
@@ -194,9 +198,6 @@ class CONTENT_EXPORT DelegatedFrameHost
void CreateCompositorFrameSinkSupport();
void ResetCompositorFrameSinkSupport();
- void ProcessCopyOutputRequest(
- std::unique_ptr<viz::CopyOutputRequest> request);
-
const viz::FrameSinkId frame_sink_id_;
DelegatedFrameHostClient* const client_;
const bool enable_viz_;
@@ -206,8 +207,6 @@ class CONTENT_EXPORT DelegatedFrameHost
// The surface id that was most recently activated by
// OnFirstSurfaceActivation.
viz::LocalSurfaceId active_local_surface_id_;
- // The scale factor of the above surface.
- float active_device_scale_factor_ = 0.f;
// The local surface id as of the most recent call to
// EmbedSurface or WasShown. This is the surface that we expect
@@ -238,10 +237,8 @@ class CONTENT_EXPORT DelegatedFrameHost
std::unique_ptr<viz::FrameEvictor> frame_evictor_;
viz::LocalSurfaceId first_local_surface_id_after_navigation_;
- bool received_frame_after_navigation_ = false;
- std::vector<std::unique_ptr<viz::CopyOutputRequest>>
- pending_first_frame_requests_;
+ base::WeakPtrFactory<DelegatedFrameHost> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DelegatedFrameHost);
};
diff --git a/chromium/content/browser/renderer_host/delegated_frame_host_client_aura.cc b/chromium/content/browser/renderer_host/delegated_frame_host_client_aura.cc
index b3dc666da0f..f1714b9fd2d 100644
--- a/chromium/content/browser/renderer_host/delegated_frame_host_client_aura.cc
+++ b/chromium/content/browser/renderer_host/delegated_frame_host_client_aura.cc
@@ -54,4 +54,8 @@ void DelegatedFrameHostClientAura::OnFrameTokenChanged(uint32_t frame_token) {
render_widget_host_view_->OnFrameTokenChangedForView(frame_token);
}
+float DelegatedFrameHostClientAura::GetDeviceScaleFactor() const {
+ return render_widget_host_view_->device_scale_factor_;
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/delegated_frame_host_client_aura.h b/chromium/content/browser/renderer_host/delegated_frame_host_client_aura.h
index 3df3bbb637d..30858853177 100644
--- a/chromium/content/browser/renderer_host/delegated_frame_host_client_aura.h
+++ b/chromium/content/browser/renderer_host/delegated_frame_host_client_aura.h
@@ -33,6 +33,7 @@ class CONTENT_EXPORT DelegatedFrameHostClientAura
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
void OnBeginFrame(base::TimeTicks frame_time) override;
void OnFrameTokenChanged(uint32_t frame_token) override;
+ float GetDeviceScaleFactor() const override;
private:
RenderWidgetHostViewAura* render_widget_host_view_;
diff --git a/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win_unittest.cc b/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win_unittest.cc
index 78db7022f9c..c06c66a2b6b 100644
--- a/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win_unittest.cc
+++ b/chromium/content/browser/renderer_host/dwrite_font_proxy_message_filter_win_unittest.cc
@@ -19,9 +19,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "services/service_manager/public/cpp/bind_source_info.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/win/direct_write.h"
-
-namespace mswr = Microsoft::WRL;
+#include "third_party/blink/public/common/dwrite_rasterizer_support/dwrite_rasterizer_support.h"
namespace content {
@@ -32,18 +30,6 @@ class DWriteFontProxyImplUnitTest : public testing::Test {
DWriteFontProxyImplUnitTest()
: binding_(&impl_, mojo::MakeRequest(&dwrite_font_proxy_)) {}
- bool IsDWrite2Available() {
- mswr::ComPtr<IDWriteFactory> factory;
- gfx::win::CreateDWriteFactory(&factory);
- mswr::ComPtr<IDWriteFactory2> factory2;
- factory.As<IDWriteFactory2>(&factory2);
-
- if (!factory2.Get()) {
- // IDWriteFactory2 is expected to not be available before Win8.1
- EXPECT_LT(base::win::GetVersion(), base::win::VERSION_WIN8_1);
- }
- return factory2.Get();
- }
mojom::DWriteFontProxy& dwrite_font_proxy() { return *dwrite_font_proxy_; }
base::test::ScopedTaskEnvironment scoped_task_environment_;
@@ -119,7 +105,7 @@ TEST_F(DWriteFontProxyImplUnitTest, GetFontFilesIndexOutOfBounds) {
}
TEST_F(DWriteFontProxyImplUnitTest, MapCharacter) {
- if (!IsDWrite2Available())
+ if (!blink::DWriteRasterizerSupport::IsDWriteFactory2Available())
return;
mojom::MapCharactersResultPtr result;
@@ -140,7 +126,7 @@ TEST_F(DWriteFontProxyImplUnitTest, MapCharacter) {
}
TEST_F(DWriteFontProxyImplUnitTest, MapCharacterInvalidCharacter) {
- if (!IsDWrite2Available())
+ if (!blink::DWriteRasterizerSupport::IsDWriteFactory2Available())
return;
mojom::MapCharactersResultPtr result;
@@ -157,7 +143,7 @@ TEST_F(DWriteFontProxyImplUnitTest, MapCharacterInvalidCharacter) {
}
TEST_F(DWriteFontProxyImplUnitTest, MapCharacterInvalidAfterValid) {
- if (!IsDWrite2Available())
+ if (!blink::DWriteRasterizerSupport::IsDWriteFactory2Available())
return;
mojom::MapCharactersResultPtr result;
diff --git a/chromium/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc b/chromium/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc
index 71073a5ff02..045779e38bd 100644
--- a/chromium/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc
+++ b/chromium/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc
@@ -8,8 +8,8 @@
#include <utility>
#include <vector>
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/host/host_frame_sink_manager.h"
@@ -141,7 +141,7 @@ class EmbeddedFrameSinkProviderImplTest : public testing::Test {
private:
// A MessageLoop is required for mojo bindings which are used to
// connect to graphics services.
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
viz::ServerSharedBitmapManager shared_bitmap_manager_;
viz::FakeHostFrameSinkClient host_frame_sink_client_;
std::unique_ptr<viz::HostFrameSinkManager> host_frame_sink_manager_;
diff --git a/chromium/content/browser/renderer_host/hit_test_debug_key_event_observer.cc b/chromium/content/browser/renderer_host/hit_test_debug_key_event_observer.cc
new file mode 100644
index 00000000000..ee542014434
--- /dev/null
+++ b/chromium/content/browser/renderer_host/hit_test_debug_key_event_observer.cc
@@ -0,0 +1,76 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/hit_test_debug_key_event_observer.h"
+
+#include "components/viz/common/hit_test/hit_test_region_list.h"
+#include "components/viz/host/host_frame_sink_manager.h"
+#include "content/browser/compositor/surface_utils.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
+#include "ui/events/keycodes/keyboard_codes.h"
+
+typedef blink::WebInputEvent::Type Type;
+typedef blink::WebInputEvent::Modifiers Modifiers;
+
+namespace {
+
+viz::HitTestQuery* GetHitTestQuery(
+ viz::HostFrameSinkManager* host_frame_sink_manager,
+ const viz::FrameSinkId& frame_sink_id) {
+ if (!frame_sink_id.is_valid())
+ return nullptr;
+ const auto& display_hit_test_query_map =
+ host_frame_sink_manager->display_hit_test_query();
+ const auto iter = display_hit_test_query_map.find(frame_sink_id);
+ if (iter == display_hit_test_query_map.end())
+ return nullptr;
+ return iter->second.get();
+}
+
+} // namespace
+
+namespace content {
+
+HitTestDebugKeyEventObserver::HitTestDebugKeyEventObserver(
+ RenderWidgetHostImpl* host)
+ : host_(host), hit_test_query_(nullptr) {
+ host_->AddInputEventObserver(this);
+}
+
+HitTestDebugKeyEventObserver::~HitTestDebugKeyEventObserver() {
+ host_->RemoveInputEventObserver(this);
+}
+
+void HitTestDebugKeyEventObserver::OnInputEventAck(
+ InputEventAckSource source,
+ InputEventAckState state,
+ const blink::WebInputEvent& event) {
+ if (INPUT_EVENT_ACK_STATE_CONSUMED == state ||
+ (event.GetType() != Type::kRawKeyDown &&
+ event.GetType() != Type::kKeyDown)) {
+ return;
+ }
+
+ const blink::WebKeyboardEvent& key_event =
+ static_cast<const blink::WebKeyboardEvent&>(event);
+
+ if (key_event.windows_key_code != ui::VKEY_H ||
+ key_event.GetModifiers() !=
+ (Modifiers::kControlKey | Modifiers::kShiftKey)) {
+ return;
+ }
+
+ if (!hit_test_query_) {
+ hit_test_query_ = GetHitTestQuery(GetHostFrameSinkManager(),
+ host_->GetView()->GetRootFrameSinkId());
+ }
+ if (hit_test_query_) {
+ std::string printed_hit_test_data = hit_test_query_->PrintHitTestData();
+ VLOG(1) << (printed_hit_test_data.empty() ? "No hit-test data."
+ : printed_hit_test_data);
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/hit_test_debug_key_event_observer.h b/chromium/content/browser/renderer_host/hit_test_debug_key_event_observer.h
new file mode 100644
index 00000000000..90e20efba0d
--- /dev/null
+++ b/chromium/content/browser/renderer_host/hit_test_debug_key_event_observer.h
@@ -0,0 +1,40 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_HIT_TEST_DEBUG_KEY_EVENT_OBSERVER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_HIT_TEST_DEBUG_KEY_EVENT_OBSERVER_H_
+
+#include "content/public/browser/render_widget_host.h"
+
+namespace viz {
+
+class HitTestQuery;
+
+} // namespace viz
+
+namespace content {
+
+class RenderWidgetHostImpl;
+
+// Implements the RenderWidgetHost::InputEventObserver interface, and acts on
+// keyboard input events to print hit-test data.
+class HitTestDebugKeyEventObserver
+ : public RenderWidgetHost::InputEventObserver {
+ public:
+ explicit HitTestDebugKeyEventObserver(RenderWidgetHostImpl* host);
+ ~HitTestDebugKeyEventObserver() override;
+
+ // RenderWidgetHost::InputEventObserver:
+ void OnInputEventAck(InputEventAckSource source,
+ InputEventAckState state,
+ const blink::WebInputEvent&) override;
+
+ private:
+ RenderWidgetHostImpl* host_;
+ viz::HitTestQuery* hit_test_query_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_HIT_TEST_DEBUG_KEY_EVENT_OBSERVER_H_
diff --git a/chromium/content/browser/renderer_host/input/OWNERS b/chromium/content/browser/renderer_host/input/OWNERS
index 86bfa17ec3d..e6d74ae941f 100644
--- a/chromium/content/browser/renderer_host/input/OWNERS
+++ b/chromium/content/browser/renderer_host/input/OWNERS
@@ -1,5 +1,6 @@
dtapuska@chromium.org
tdresser@chromium.org
+nzolghadr@chromium.org
# TEAM: input-dev@chromium.org
diff --git a/chromium/content/browser/renderer_host/input/autoscroll_browsertest.cc b/chromium/content/browser/renderer_host/input/autoscroll_browsertest.cc
index 0b662c1fd05..731d4cca767 100644
--- a/chromium/content/browser/renderer_host/input/autoscroll_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/autoscroll_browsertest.cc
@@ -33,6 +33,52 @@ const std::string kAutoscrollDataURL = R"HTML(
namespace content {
+// Waits for a GSB ack and checks that the acked event has none zero scroll
+// delta hints.
+class GestureScrollBeginWatcher : public RenderWidgetHost::InputEventObserver {
+ public:
+ GestureScrollBeginWatcher(RenderWidgetHost* rwh)
+ : rwh_(static_cast<RenderWidgetHostImpl*>(rwh)->GetWeakPtr()) {
+ rwh->AddInputEventObserver(this);
+ Reset();
+ }
+ ~GestureScrollBeginWatcher() override {
+ if (rwh_)
+ rwh_->RemoveInputEventObserver(this);
+ }
+
+ void OnInputEventAck(InputEventAckSource,
+ InputEventAckState,
+ const blink::WebInputEvent& event) override {
+ if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
+ blink::WebGestureEvent received_begin =
+ *static_cast<const blink::WebGestureEvent*>(&event);
+ DCHECK(received_begin.data.scroll_begin.delta_x_hint ||
+ received_begin.data.scroll_begin.delta_y_hint);
+ if (run_loop_)
+ run_loop_->Quit();
+ gesture_scroll_begin_seen_ = true;
+ }
+ }
+
+ void Wait() {
+ if (gesture_scroll_begin_seen_)
+ return;
+ DCHECK(run_loop_);
+ run_loop_->Run();
+ }
+
+ void Reset() {
+ gesture_scroll_begin_seen_ = false;
+ run_loop_ = std::make_unique<base::RunLoop>();
+ }
+
+ private:
+ base::WeakPtr<RenderWidgetHostImpl> rwh_;
+ std::unique_ptr<base::RunLoop> run_loop_;
+ bool gesture_scroll_begin_seen_;
+};
+
class AutoscrollBrowserTest : public ContentBrowserTest {
public:
AutoscrollBrowserTest() {}
@@ -82,60 +128,75 @@ class AutoscrollBrowserTest : public ContentBrowserTest {
GetWidgetHost()->ForwardMouseEvent(up_event);
}
+ void WaitForScroll(RenderFrameSubmissionObserver& observer) {
+ gfx::Vector2dF default_scroll_offset;
+ while (observer.LastRenderFrameMetadata()
+ .root_scroll_offset.value_or(default_scroll_offset)
+ .y() <= 0) {
+ observer.WaitForMetadataChange();
+ }
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(AutoscrollBrowserTest);
};
+// We don't plan on supporting middle click autoscroll on Android.
+// See https://crbug.com/686223
+#if !defined(OS_ANDROID)
// TODO(sahel): This test is flaky https://crbug.com/838769
IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest, DISABLED_AutoscrollFling) {
LoadURL(kAutoscrollDataURL);
// Start autoscroll with middle click.
- auto input_msg_watcher = std::make_unique<InputMsgWatcher>(
- GetWidgetHost(), blink::WebInputEvent::kGestureScrollBegin);
+ auto scroll_begin_watcher =
+ std::make_unique<GestureScrollBeginWatcher>(GetWidgetHost());
SimulateMiddleClick(10, 10, blink::WebInputEvent::kNoModifiers);
- input_msg_watcher->WaitForAck();
// The page should start scrolling with mouse move.
RenderFrameSubmissionObserver observer(
GetWidgetHost()->render_frame_metadata_provider());
blink::WebMouseEvent move_event = SyntheticWebMouseEventBuilder::Build(
- blink::WebInputEvent::kMouseMove, 30, 30,
+ blink::WebInputEvent::kMouseMove, 50, 50,
blink::WebInputEvent::kNoModifiers);
move_event.SetTimeStamp(ui::EventTimeForNow());
- move_event.SetPositionInScreen(30, 30);
+ move_event.SetPositionInScreen(50, 50);
GetWidgetHost()->ForwardMouseEvent(move_event);
- gfx::Vector2dF default_scroll_offset;
- while (observer.LastRenderFrameMetadata()
- .root_scroll_offset.value_or(default_scroll_offset)
- .y() <= 0) {
- observer.WaitForMetadataChange();
- }
+ scroll_begin_watcher->Wait();
+ WaitForScroll(observer);
+}
+
+// Tests that the GSB sent in the beginning of a middle click autoscroll has
+// none-zero delta hints.
+IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest, AutoscrollFlingGSBDeltaHints) {
+ LoadURL(kAutoscrollDataURL);
+
+ // Start autoscroll with middle click.
+ auto scroll_begin_watcher =
+ std::make_unique<GestureScrollBeginWatcher>(GetWidgetHost());
+ SimulateMiddleClick(10, 10, blink::WebInputEvent::kNoModifiers);
+
+ // A GSB will be sent on first mouse move.
+ blink::WebMouseEvent move_event = SyntheticWebMouseEventBuilder::Build(
+ blink::WebInputEvent::kMouseMove, 50, 50,
+ blink::WebInputEvent::kNoModifiers);
+ move_event.SetTimeStamp(ui::EventTimeForNow());
+ move_event.SetPositionInScreen(50, 50);
+ GetWidgetHost()->ForwardMouseEvent(move_event);
+ // The test crashes if the received GSB has zero delta hints.
+ scroll_begin_watcher->Wait();
}
-#if !defined(OS_ANDROID)
-#define MAYBE_WheelScrollingWorksAfterAutoscrollCancel \
- WheelScrollingWorksAfterAutoscrollCancel
-#else
-#define MAYBE_WheelScrollingWorksAfterAutoscrollCancel \
- DISABLED_WheelScrollingWorksAfterAutoscrollCancel
-#endif
// Checks that wheel scrolling works after autoscroll cancelation.
IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest,
- MAYBE_WheelScrollingWorksAfterAutoscrollCancel) {
+ WheelScrollingWorksAfterAutoscrollCancel) {
LoadURL(kAutoscrollDataURL);
// Start autoscroll with middle click.
- auto input_msg_watcher = std::make_unique<InputMsgWatcher>(
- GetWidgetHost(), blink::WebInputEvent::kGestureScrollBegin);
SimulateMiddleClick(10, 10, blink::WebInputEvent::kNoModifiers);
- input_msg_watcher->WaitForAck();
// Without moving the mouse cancel the autoscroll fling with another click.
- input_msg_watcher = std::make_unique<InputMsgWatcher>(
- GetWidgetHost(), blink::WebInputEvent::kGestureScrollEnd);
SimulateMiddleClick(10, 10, blink::WebInputEvent::kNoModifiers);
- input_msg_watcher->WaitForAck();
// The mouse wheel scrolling must work after autoscroll cancellation.
RenderFrameSubmissionObserver observer(
@@ -144,12 +205,52 @@ IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest,
SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, -53, 0, true);
wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
GetWidgetHost()->ForwardWheelEvent(wheel_event);
- gfx::Vector2dF default_scroll_offset;
- while (observer.LastRenderFrameMetadata()
- .root_scroll_offset.value_or(default_scroll_offset)
- .y() <= 0) {
- observer.WaitForMetadataChange();
- }
+ WaitForScroll(observer);
+}
+
+// Checks that autoscrolling still works after changing the scroll direction
+// when the element is fully scrolled.
+IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest,
+ AutoscrollDirectionChangeAfterFullyScrolled) {
+ LoadURL(kAutoscrollDataURL);
+
+ // Start autoscroll with middle click.
+ auto scroll_begin_watcher =
+ std::make_unique<GestureScrollBeginWatcher>(GetWidgetHost());
+ SimulateMiddleClick(100, 100, blink::WebInputEvent::kNoModifiers);
+
+ // Move the mouse up, no scrolling happens since the page is at its extent.
+ auto scroll_update_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kGestureScrollUpdate);
+ blink::WebMouseEvent move_up = SyntheticWebMouseEventBuilder::Build(
+ blink::WebInputEvent::kMouseMove, 20, 20,
+ blink::WebInputEvent::kNoModifiers);
+ move_up.SetTimeStamp(ui::EventTimeForNow());
+ move_up.SetPositionInScreen(20, 20);
+ GetWidgetHost()->ForwardMouseEvent(move_up);
+ scroll_begin_watcher->Wait();
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
+ scroll_update_watcher->WaitForAck());
+
+ // Wait for 300ms before changing the scroll direction.
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(),
+ base::TimeDelta::FromMillisecondsD(300));
+ run_loop.Run();
+
+ // Now move the mouse down and wait for the page to scroll. The test will
+ // timeout if autoscrolling does not work after direction change.
+ RenderFrameSubmissionObserver observer(
+ GetWidgetHost()->render_frame_metadata_provider());
+ blink::WebMouseEvent move_down = SyntheticWebMouseEventBuilder::Build(
+ blink::WebInputEvent::kMouseMove, 180, 180,
+ blink::WebInputEvent::kNoModifiers);
+ move_down.SetTimeStamp(ui::EventTimeForNow());
+ move_down.SetPositionInScreen(180, 180);
+ GetWidgetHost()->ForwardMouseEvent(move_down);
+ WaitForScroll(observer);
}
+#endif // !defined(OS_ANDROID)
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc b/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc
index 835b21e194f..dda80454bdd 100644
--- a/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc
@@ -13,6 +13,7 @@
#include "build/build_config.h"
#include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
@@ -245,12 +246,17 @@ IN_PROC_BROWSER_TEST_F(CompositorEventAckBrowserTest,
MAYBE_TouchStartDuringFling) {
LoadURL(kBlockingTouchStartDataURL);
+ // Send the touch events via routing since they need to be registered by the
+ // TouchEventAckQueue.
+ auto* root_view = GetWidgetHost()->GetView();
+ auto* input_event_router = GetWidgetHost()->delegate()->GetInputEventRouter();
+
// Send a TouchStart so that we can set allowed touch action to Auto.
SyntheticWebTouchEvent touch_event;
touch_event.PressPoint(50, 50);
touch_event.SetTimeStamp(ui::EventTimeForNow());
- GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch_event,
- ui::LatencyInfo());
+ input_event_router->RouteTouchEvent(root_view, &touch_event,
+ ui::LatencyInfo());
GetWidgetHost()->input_router()->OnSetTouchAction(cc::kTouchActionAuto);
// Send GSB to start scrolling sequence.
@@ -282,8 +288,12 @@ IN_PROC_BROWSER_TEST_F(CompositorEventAckBrowserTest,
observer.WaitForMetadataChange();
touch_event.ReleasePoint(0);
- GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch_event,
- ui::LatencyInfo());
+ // TODO(wjmaclean): Figure out why we can send two touch events with the same
+ // id, and not only does it work, it fails to work if we give the second
+ // event a unique id!
+ // touch_event.unique_touch_event_id = ui::GetNextTouchEventId();
+ input_event_router->RouteTouchEvent(root_view, &touch_event,
+ ui::LatencyInfo());
touch_event.ResetPoints();
// Send a touch start event and wait for its ack. The touch start must be
@@ -294,8 +304,8 @@ IN_PROC_BROWSER_TEST_F(CompositorEventAckBrowserTest,
WebInputEvent::kTouchStart);
touch_event.PressPoint(50, 50);
touch_event.SetTimeStamp(ui::EventTimeForNow());
- GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch_event,
- ui::LatencyInfo());
+ input_event_router->RouteTouchEvent(root_view, &touch_event,
+ ui::LatencyInfo());
touch_start_ack_observer.Wait();
}
diff --git a/chromium/content/browser/renderer_host/input/fling_browsertest.cc b/chromium/content/browser/renderer_host/input/fling_browsertest.cc
index cba336b610d..14afc422dcc 100644
--- a/chromium/content/browser/renderer_host/input/fling_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/fling_browsertest.cc
@@ -204,11 +204,11 @@ class BrowserSideFlingBrowserTest : public ContentBrowserTest {
}
}
- void GiveItSomeTime() {
+ void GiveItSomeTime(int64_t time_delta_ms = 10) {
base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, run_loop.QuitClosure(),
- base::TimeDelta::FromMilliseconds(10));
+ base::TimeDelta::FromMilliseconds(time_delta_ms));
run_loop.Run();
}
@@ -250,6 +250,34 @@ IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchpadFling) {
WaitForScroll();
}
+// Tests that flinging does not continue after navigating to a page that uses
+// the same renderer.
+IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest,
+ FlingingStopsAfterNavigation) {
+ GURL first_url(embedded_test_server()->GetURL(
+ "b.a.com", "/scrollable_page_with_iframe.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), first_url));
+ MainThreadFrameObserver main_thread_sync1(GetWidgetHost());
+ main_thread_sync1.Wait();
+ SimulateTouchscreenFling(GetWidgetHost());
+ WaitForScroll();
+
+ // Navigate to a second page with the same domain.
+ GURL second_url(
+ embedded_test_server()->GetURL("a.com", "/scrollable_page.html"));
+ NavigateToURL(shell(), second_url);
+ MainThreadFrameObserver main_thread_sync2(GetWidgetHost());
+ main_thread_sync2.Wait();
+
+ // Wait for 100ms. Then check that the second page has not scrolled.
+ GiveItSomeTime(100);
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ EXPECT_EQ(
+ 0, EvalJs(root->current_frame_host(), "window.scrollY").ExtractDouble());
+}
+
IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchscreenFlingInOOPIF) {
LoadPageWithOOPIF();
SimulateTouchscreenFling(child_view_->host());
diff --git a/chromium/content/browser/renderer_host/input/fling_controller.cc b/chromium/content/browser/renderer_host/input/fling_controller.cc
index a82ea976947..c09268dd6f2 100644
--- a/chromium/content/browser/renderer_host/input/fling_controller.cc
+++ b/chromium/content/browser/renderer_host/input/fling_controller.cc
@@ -4,6 +4,7 @@
#include "content/browser/renderer_host/input/fling_controller.h"
+#include "base/time/default_tick_clock.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/renderer_host/input/gesture_event_queue.h"
#include "content/public/browser/content_browser_client.h"
@@ -54,6 +55,7 @@ FlingController::FlingController(
touchscreen_tap_suppression_controller_(
config.touchscreen_tap_suppression_config),
fling_in_progress_(false),
+ clock_(base::DefaultTickClock::GetInstance()),
weak_ptr_factory_(this) {
DCHECK(gesture_event_queue);
DCHECK(event_sender_client);
@@ -188,14 +190,13 @@ void FlingController::ProcessGestureFlingStart(
current_fling_parameters_.velocity,
current_fling_parameters_.source_device,
current_fling_parameters_.modifiers);
-
// Wait for BeginFrame to call ProgressFling when
// SetNeedsBeginFrameForFlingProgress is used to progress flings instead of
// compositor animation observer (happens on Android WebView).
if (scheduler_client_->NeedsBeginFrameForFlingProgress())
ScheduleFlingProgress();
else
- ProgressFling(base::TimeTicks::Now());
+ ProgressFling(clock_->NowTicks());
}
void FlingController::ScheduleFlingProgress() {
@@ -288,7 +289,7 @@ void FlingController::GenerateAndSendWheelEvents(
blink::WebMouseWheelEvent::Phase phase) {
MouseWheelEventWithLatencyInfo synthetic_wheel(
WebInputEvent::kMouseWheel, current_fling_parameters_.modifiers,
- base::TimeTicks::Now(), ui::LatencyInfo(ui::SourceEventType::WHEEL));
+ clock_->NowTicks(), ui::LatencyInfo(ui::SourceEventType::WHEEL));
synthetic_wheel.event.delta_x = delta.x();
synthetic_wheel.event.delta_y = delta.y();
synthetic_wheel.event.has_precise_scrolling_deltas = true;
@@ -307,7 +308,7 @@ void FlingController::GenerateAndSendGestureScrollEvents(
WebInputEvent::Type type,
const gfx::Vector2dF& delta /* = gfx::Vector2dF() */) {
GestureEventWithLatencyInfo synthetic_gesture(
- type, current_fling_parameters_.modifiers, base::TimeTicks::Now(),
+ type, current_fling_parameters_.modifiers, clock_->NowTicks(),
ui::LatencyInfo(ui::SourceEventType::INERTIAL));
synthetic_gesture.event.SetPositionInWidget(current_fling_parameters_.point);
synthetic_gesture.event.SetPositionInScreen(
diff --git a/chromium/content/browser/renderer_host/input/fling_controller.h b/chromium/content/browser/renderer_host/input/fling_controller.h
index 56e997187ca..3f02f832422 100644
--- a/chromium/content/browser/renderer_host/input/fling_controller.h
+++ b/chromium/content/browser/renderer_host/input/fling_controller.h
@@ -106,6 +106,8 @@ class CONTENT_EXPORT FlingController {
// Returns the |TouchpadTapSuppressionController| instance.
TouchpadTapSuppressionController* GetTouchpadTapSuppressionController();
+ void set_clock_for_testing(const base::TickClock* clock) { clock_ = clock; }
+
protected:
std::unique_ptr<ui::FlingBooster> fling_booster_;
@@ -178,6 +180,9 @@ class CONTENT_EXPORT FlingController {
// for determining if the fling start time should be re-initialized.
bool has_fling_animation_started_;
+ // The clock used; overridable for tests.
+ const base::TickClock* clock_;
+
base::WeakPtrFactory<FlingController> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(FlingController);
diff --git a/chromium/content/browser/renderer_host/input/fling_controller_unittest.cc b/chromium/content/browser/renderer_host/input/fling_controller_unittest.cc
index 3478d4eb08e..51e37f88793 100644
--- a/chromium/content/browser/renderer_host/input/fling_controller_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/fling_controller_unittest.cc
@@ -4,8 +4,10 @@
#include "content/browser/renderer_host/input/fling_controller.h"
+#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
+#include "base/test/simple_test_tick_clock.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/input/gesture_event_queue.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -16,6 +18,10 @@ using blink::WebGestureEvent;
using blink::WebInputEvent;
using blink::WebMouseWheelEvent;
+namespace {
+constexpr double kFrameDelta = 1000.0 / 60.0;
+} // namespace
+
namespace content {
class FakeFlingController : public FlingController {
@@ -51,6 +57,8 @@ class FlingControllerTest : public GestureEventQueueClient,
GestureEventQueue::Config());
fling_controller_ = std::make_unique<FakeFlingController>(
queue_.get(), this, this, FlingController::Config());
+ fling_controller_->set_clock_for_testing(&mock_clock_);
+ AdvanceTime();
}
// GestureEventQueueClient
@@ -90,14 +98,19 @@ class FlingControllerTest : public GestureEventQueueClient,
}
void SimulateFlingStart(blink::WebGestureDevice source_device,
- const gfx::Vector2dF& velocity) {
+ const gfx::Vector2dF& velocity,
+ bool wait_before_processing = true) {
scheduled_next_fling_progress_ = false;
sent_scroll_gesture_count_ = 0;
WebGestureEvent fling_start(WebInputEvent::kGestureFlingStart, 0,
- base::TimeTicks::Now(), source_device);
+ NowTicks(), source_device);
fling_start.data.fling_start.velocity_x = velocity.x();
fling_start.data.fling_start.velocity_y = velocity.y();
GestureEventWithLatencyInfo fling_start_with_latency(fling_start);
+ if (wait_before_processing) {
+ // Wait for up to one frame before processing the event.
+ AdvanceTime(base::RandInt(0, static_cast<int>(kFrameDelta)));
+ }
if (!fling_controller_->FilterGestureEvent(fling_start_with_latency))
fling_controller_->ProcessGestureFlingStart(fling_start_with_latency);
}
@@ -105,7 +118,7 @@ class FlingControllerTest : public GestureEventQueueClient,
void SimulateFlingCancel(blink::WebGestureDevice source_device) {
notified_client_after_fling_stop_ = false;
WebGestureEvent fling_cancel(WebInputEvent::kGestureFlingCancel, 0,
- base::TimeTicks::Now(), source_device);
+ NowTicks(), source_device);
// autoscroll fling cancel doesn't allow fling boosting.
if (source_device == blink::kWebGestureDeviceSyntheticAutoscroll)
fling_cancel.data.fling_cancel.prevent_boosting = true;
@@ -125,6 +138,12 @@ class FlingControllerTest : public GestureEventQueueClient,
bool FlingInProgress() { return fling_controller_->fling_in_progress(); }
bool FlingBoosted() { return fling_controller_->FlingBoosted(); }
+ void AdvanceTime(double time_delta_ms = kFrameDelta) {
+ mock_clock_.Advance(base::TimeDelta::FromMillisecondsD(time_delta_ms));
+ }
+
+ base::TimeTicks NowTicks() const { return mock_clock_.NowTicks(); }
+
protected:
std::unique_ptr<FakeFlingController> fling_controller_;
WebMouseWheelEvent last_sent_wheel_;
@@ -136,6 +155,8 @@ class FlingControllerTest : public GestureEventQueueClient,
int sent_scroll_gesture_count_ = 0;
private:
+ base::SimpleTestTickClock mock_clock_;
+
bool needs_begin_frame_for_fling_progress_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<GestureEventQueue> queue_;
@@ -163,9 +184,7 @@ TEST_P(FlingControllerTest,
EXPECT_EQ(WebInputEvent::kGestureScrollEnd, last_sent_gesture_.GetType());
}
-// TODO(https://crbug.com/836996): Timing-dependent flakes on some platforms.
-TEST_P(FlingControllerTest, DISABLED_ControllerHandlesTouchpadGestureFling) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
+TEST_P(FlingControllerTest, ControllerHandlesTouchpadGestureFling) {
SimulateFlingStart(blink::kWebGestureDeviceTouchpad, gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
// Processing GFS will send the first fling prgoress event if the time delta
@@ -173,8 +192,8 @@ TEST_P(FlingControllerTest, DISABLED_ControllerHandlesTouchpadGestureFling) {
// is called is large enough.
bool process_GFS_sent_first_event = first_wheel_event_sent_;
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
if (!process_GFS_sent_first_event) {
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, last_sent_wheel_.momentum_phase);
@@ -185,8 +204,8 @@ TEST_P(FlingControllerTest, DISABLED_ControllerHandlesTouchpadGestureFling) {
EXPECT_GT(last_sent_wheel_.delta_x, 0.f);
// The rest of the wheel events must have momentum_phase == KPhaseChanged.
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, last_sent_wheel_.momentum_phase);
EXPECT_GT(last_sent_wheel_.delta_x, 0.f);
@@ -196,24 +215,22 @@ TEST_P(FlingControllerTest, DISABLED_ControllerHandlesTouchpadGestureFling) {
EXPECT_TRUE(FlingInProgress());
// Wait for the boosting timer to expire. The delayed cancelation must work.
- progress_time += base::TimeDelta::FromMilliseconds(500);
- ProgressFling(progress_time);
+ AdvanceTime(500);
+ ProgressFling(NowTicks());
EXPECT_FALSE(FlingInProgress());
EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, last_sent_wheel_.momentum_phase);
EXPECT_EQ(0.f, last_sent_wheel_.delta_x);
EXPECT_EQ(0.f, last_sent_wheel_.delta_y);
}
-// TODO(https://crbug.com/836996): Timing-dependent flakes on some platforms.
-TEST_P(FlingControllerTest, DISABLED_ControllerHandlesTouchscreenGestureFling) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
+TEST_P(FlingControllerTest, ControllerHandlesTouchscreenGestureFling) {
SimulateFlingStart(blink::kWebGestureDeviceTouchscreen,
gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
// The fling progress will generate and send GSU events with inertial state.
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate, last_sent_gesture_.GetType());
EXPECT_EQ(WebGestureEvent::kMomentumPhase,
last_sent_gesture_.data.scroll_update.inertial_phase);
@@ -225,16 +242,13 @@ TEST_P(FlingControllerTest, DISABLED_ControllerHandlesTouchscreenGestureFling) {
EXPECT_TRUE(FlingInProgress());
// Wait for the boosting timer to expire. The delayed cancelation must work.
- progress_time += base::TimeDelta::FromMilliseconds(500);
- ProgressFling(progress_time);
+ AdvanceTime(500);
+ ProgressFling(NowTicks());
EXPECT_FALSE(FlingInProgress());
EXPECT_EQ(WebInputEvent::kGestureScrollEnd, last_sent_gesture_.GetType());
}
-// TODO(https://crbug.com/836996): Timing-dependent flakes on some platforms.
-TEST_P(FlingControllerTest,
- DISABLED_ControllerSendsWheelEndWhenTouchpadFlingIsOver) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
+TEST_P(FlingControllerTest, ControllerSendsWheelEndWhenTouchpadFlingIsOver) {
SimulateFlingStart(blink::kWebGestureDeviceTouchpad, gfx::Vector2dF(100, 0));
EXPECT_TRUE(FlingInProgress());
// Processing GFS will send the first fling prgoress event if the time delta
@@ -242,8 +256,8 @@ TEST_P(FlingControllerTest,
// is called is large enough.
bool process_GFS_sent_first_event = first_wheel_event_sent_;
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
if (!process_GFS_sent_first_event) {
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, last_sent_wheel_.momentum_phase);
} else {
@@ -252,14 +266,14 @@ TEST_P(FlingControllerTest,
}
EXPECT_GT(last_sent_wheel_.delta_x, 0.f);
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
while (FlingInProgress()) {
EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged,
last_sent_wheel_.momentum_phase);
EXPECT_GT(last_sent_wheel_.delta_x, 0.f);
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
}
EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, last_sent_wheel_.momentum_phase);
@@ -267,33 +281,28 @@ TEST_P(FlingControllerTest,
EXPECT_EQ(0.f, last_sent_wheel_.delta_y);
}
-// TODO(https://crbug.com/836996): Timing-dependent flakes on some platforms.
-TEST_P(FlingControllerTest,
- DISABLED_ControllerSendsGSEWhenTouchscreenFlingIsOver) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
+TEST_P(FlingControllerTest, ControllerSendsGSEWhenTouchscreenFlingIsOver) {
SimulateFlingStart(blink::kWebGestureDeviceTouchscreen,
gfx::Vector2dF(100, 0));
EXPECT_TRUE(FlingInProgress());
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
while (FlingInProgress()) {
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate,
last_sent_gesture_.GetType());
EXPECT_EQ(WebGestureEvent::kMomentumPhase,
last_sent_gesture_.data.scroll_update.inertial_phase);
EXPECT_GT(last_sent_gesture_.data.scroll_update.delta_x, 0.f);
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
}
EXPECT_EQ(WebInputEvent::kGestureScrollEnd, last_sent_gesture_.GetType());
}
-// TODO(https://crbug.com/836996): Timing-dependent flakes on some platforms.
TEST_P(FlingControllerTest,
- DISABLED_EarlyTouchpadFlingCancelationOnInertialGSUAckNotConsumed) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
+ EarlyTouchpadFlingCancelationOnInertialGSUAckNotConsumed) {
SimulateFlingStart(blink::kWebGestureDeviceTouchpad, gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
// Processing GFS will send the first fling prgoress event if the time delta
@@ -301,8 +310,8 @@ TEST_P(FlingControllerTest,
// is called is large enough.
bool process_GFS_sent_first_event = first_wheel_event_sent_;
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
if (!process_GFS_sent_first_event) {
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, last_sent_wheel_.momentum_phase);
} else {
@@ -313,7 +322,7 @@ TEST_P(FlingControllerTest,
// A non-consumed GSU ack in inertial state cancels out the rest of the fling.
WebGestureEvent scroll_update(WebInputEvent::kGestureScrollUpdate, 0,
- base::TimeTicks::Now());
+ NowTicks());
scroll_update.data.scroll_update.inertial_phase =
WebGestureEvent::kMomentumPhase;
@@ -326,15 +335,13 @@ TEST_P(FlingControllerTest,
EXPECT_EQ(0.f, last_sent_wheel_.delta_y);
}
-// TODO(https://crbug.com/836996): Timing-dependent flakes on some platforms.
TEST_P(FlingControllerTest,
- DISABLED_EarlyTouchscreenFlingCancelationOnInertialGSUAckNotConsumed) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
+ EarlyTouchscreenFlingCancelationOnInertialGSUAckNotConsumed) {
SimulateFlingStart(blink::kWebGestureDeviceTouchscreen,
gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate, last_sent_gesture_.GetType());
EXPECT_EQ(WebGestureEvent::kMomentumPhase,
last_sent_gesture_.data.scroll_update.inertial_phase);
@@ -342,7 +349,7 @@ TEST_P(FlingControllerTest,
// A non-consumed GSU ack in inertial state cancels out the rest of the fling.
WebGestureEvent scroll_update(WebInputEvent::kGestureScrollUpdate, 0,
- base::TimeTicks::Now());
+ NowTicks());
scroll_update.data.scroll_update.inertial_phase =
WebGestureEvent::kMomentumPhase;
@@ -353,9 +360,7 @@ TEST_P(FlingControllerTest,
EXPECT_EQ(WebInputEvent::kGestureScrollEnd, last_sent_gesture_.GetType());
}
-// Flaky. https://crbug.com/836996.
-TEST_P(FlingControllerTest, DISABLED_EarlyTouchpadFlingCancelationOnFlingStop) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
+TEST_P(FlingControllerTest, EarlyTouchpadFlingCancelationOnFlingStop) {
SimulateFlingStart(blink::kWebGestureDeviceTouchpad, gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
// Processing GFS will send the first fling prgoress event if the time delta
@@ -363,8 +368,8 @@ TEST_P(FlingControllerTest, DISABLED_EarlyTouchpadFlingCancelationOnFlingStop) {
// is called is large enough.
bool process_GFS_sent_first_event = first_wheel_event_sent_;
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
if (!process_GFS_sent_first_event) {
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, last_sent_wheel_.momentum_phase);
} else {
@@ -381,14 +386,13 @@ TEST_P(FlingControllerTest, DISABLED_EarlyTouchpadFlingCancelationOnFlingStop) {
}
TEST_P(FlingControllerTest, EarlyTouchscreenFlingCancelationOnFlingStop) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
SimulateFlingStart(blink::kWebGestureDeviceTouchscreen,
gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
// progress fling must send GSU events.
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate, last_sent_gesture_.GetType());
EXPECT_EQ(WebGestureEvent::kMomentumPhase,
last_sent_gesture_.data.scroll_update.inertial_phase);
@@ -417,24 +421,21 @@ TEST_P(FlingControllerTest, GestureFlingCancelsFiltered) {
EXPECT_TRUE(last_fling_cancel_filtered_);
}
-// Flaky. https://crbug.com/836996.
-TEST_P(FlingControllerTest, DISABLED_GestureFlingNotCancelledBySmallTimeDelta) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
+TEST_P(FlingControllerTest, GestureFlingNotCancelledBySmallTimeDelta) {
SimulateFlingStart(blink::kWebGestureDeviceTouchscreen,
- gfx::Vector2dF(1000, 0));
+ gfx::Vector2dF(1000, 0), false);
EXPECT_TRUE(FlingInProgress());
+ int current_sent_scroll_gesture_count = sent_scroll_gesture_count_;
// If we the first progress tick happens too close to the fling_start time,
// the controller won't send any GSU events, but the fling is still active.
- // progress_time += base::TimeDelta::FromMilliseconds(1);
- ProgressFling(progress_time);
- EXPECT_EQ(blink::kWebGestureDeviceUninitialized,
- last_sent_gesture_.SourceDevice());
+ ProgressFling(NowTicks());
+ EXPECT_EQ(current_sent_scroll_gesture_count, sent_scroll_gesture_count_);
EXPECT_TRUE(FlingInProgress());
// The rest of the progress flings must advance the fling normally.
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
EXPECT_EQ(blink::kWebGestureDeviceTouchscreen,
last_sent_gesture_.SourceDevice());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate, last_sent_gesture_.GetType());
@@ -443,9 +444,9 @@ TEST_P(FlingControllerTest, DISABLED_GestureFlingNotCancelledBySmallTimeDelta) {
EXPECT_GT(last_sent_gesture_.data.scroll_update.delta_x, 0.f);
}
-// TODO(https://crbug.com/836996): Timing-dependent flakes on some platforms.
-TEST_P(FlingControllerTest, DISABLED_GestureFlingWithNegativeTimeDelta) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
+TEST_P(FlingControllerTest, GestureFlingWithNegativeTimeDelta) {
+ base::TimeTicks initial_time = NowTicks();
+ AdvanceTime();
SimulateFlingStart(blink::kWebGestureDeviceTouchscreen,
gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
@@ -454,13 +455,12 @@ TEST_P(FlingControllerTest, DISABLED_GestureFlingWithNegativeTimeDelta) {
// If we get a negative time delta, that is, the Progress tick time happens
// before the fling's start time then we should *not* try progressing the
// fling.
- progress_time -= base::TimeDelta::FromMilliseconds(5);
- ProgressFling(progress_time);
+ ProgressFling(initial_time);
EXPECT_EQ(current_sent_scroll_gesture_count, sent_scroll_gesture_count_);
// The rest of the progress flings must advance the fling normally.
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
EXPECT_EQ(blink::kWebGestureDeviceTouchscreen,
last_sent_gesture_.SourceDevice());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate, last_sent_gesture_.GetType());
@@ -476,7 +476,6 @@ TEST_P(FlingControllerTest, DISABLED_GestureFlingWithNegativeTimeDelta) {
#define MAYBE_ControllerBoostsTouchpadFling ControllerBoostsTouchpadFling
#endif
TEST_P(FlingControllerTest, MAYBE_ControllerBoostsTouchpadFling) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
SimulateFlingStart(blink::kWebGestureDeviceTouchpad, gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
// Processing GFS will send the first fling prgoress event if the time delta
@@ -484,8 +483,8 @@ TEST_P(FlingControllerTest, MAYBE_ControllerBoostsTouchpadFling) {
// is called is large enough.
bool process_GFS_sent_first_event = first_wheel_event_sent_;
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
if (!process_GFS_sent_first_event) {
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, last_sent_wheel_.momentum_phase);
} else {
@@ -495,8 +494,8 @@ TEST_P(FlingControllerTest, MAYBE_ControllerBoostsTouchpadFling) {
EXPECT_GT(last_sent_wheel_.delta_x, 0.f);
// The rest of the wheel events must have momentum_phase == KPhaseChanged.
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, last_sent_wheel_.momentum_phase);
EXPECT_GT(last_sent_wheel_.delta_x, 0.f);
@@ -512,14 +511,12 @@ TEST_P(FlingControllerTest, MAYBE_ControllerBoostsTouchpadFling) {
}
TEST_P(FlingControllerTest, ControllerBoostsTouchscreenFling) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
SimulateFlingStart(blink::kWebGestureDeviceTouchscreen,
gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
-
// Fling progress must send GSU events.
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate, last_sent_gesture_.GetType());
EXPECT_EQ(WebGestureEvent::kMomentumPhase,
last_sent_gesture_.data.scroll_update.inertial_phase);
@@ -538,7 +535,6 @@ TEST_P(FlingControllerTest, ControllerBoostsTouchscreenFling) {
}
TEST_P(FlingControllerTest, ControllerNotifiesTheClientAfterFlingStart) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
SimulateFlingStart(blink::kWebGestureDeviceTouchscreen,
gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
@@ -550,21 +546,20 @@ TEST_P(FlingControllerTest, ControllerNotifiesTheClientAfterFlingStart) {
// Wait for the boosting timer to expire. The delayed cancelation must work
// and the client must be notified after fling cancelation.
- progress_time += base::TimeDelta::FromMilliseconds(500);
- ProgressFling(progress_time);
+ AdvanceTime(500);
+ ProgressFling(NowTicks());
EXPECT_FALSE(FlingInProgress());
EXPECT_EQ(WebInputEvent::kGestureScrollEnd, last_sent_gesture_.GetType());
EXPECT_TRUE(notified_client_after_fling_stop_);
}
TEST_P(FlingControllerTest, MiddleClickAutoScrollFling) {
- base::TimeTicks progress_time = base::TimeTicks::Now();
SimulateFlingStart(blink::kWebGestureDeviceSyntheticAutoscroll,
gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
- progress_time += base::TimeDelta::FromMilliseconds(17);
- ProgressFling(progress_time);
+ AdvanceTime();
+ ProgressFling(NowTicks());
ASSERT_EQ(WebInputEvent::kGestureScrollUpdate, last_sent_gesture_.GetType());
EXPECT_EQ(WebGestureEvent::kMomentumPhase,
last_sent_gesture_.data.scroll_update.inertial_phase);
diff --git a/chromium/content/browser/renderer_host/input/input_router_impl.cc b/chromium/content/browser/renderer_host/input/input_router_impl.cc
index 582b96fb30c..d50dbf0156c 100644
--- a/chromium/content/browser/renderer_host/input/input_router_impl.cc
+++ b/chromium/content/browser/renderer_host/input/input_router_impl.cc
@@ -33,9 +33,6 @@
namespace content {
-using base::Time;
-using base::TimeDelta;
-using base::TimeTicks;
using blink::WebGestureEvent;
using blink::WebInputEvent;
using blink::WebKeyboardEvent;
@@ -185,10 +182,10 @@ void InputRouterImpl::SendGestureEvent(
void InputRouterImpl::SendTouchEvent(
const TouchEventWithLatencyInfo& touch_event) {
- TouchEventWithLatencyInfo updatd_touch_event = touch_event;
- SetMovementXYForTouchPoints(&updatd_touch_event.event);
- input_stream_validator_.Validate(updatd_touch_event.event);
- touch_event_queue_.QueueEvent(updatd_touch_event);
+ TouchEventWithLatencyInfo updated_touch_event = touch_event;
+ SetMovementXYForTouchPoints(&updated_touch_event.event);
+ input_stream_validator_.Validate(updated_touch_event.event);
+ touch_event_queue_.QueueEvent(updated_touch_event);
}
void InputRouterImpl::NotifySiteIsMobileOptimized(bool is_mobile_optimized) {
@@ -335,21 +332,30 @@ void InputRouterImpl::SendTouchEventImmediately(
void InputRouterImpl::OnTouchEventAck(const TouchEventWithLatencyInfo& event,
InputEventAckSource ack_source,
InputEventAckState ack_result) {
- // Touchstart events sent to the renderer indicate a new touch sequence, but
- // in some cases we may filter out sending the touchstart - catch those here.
- if (WebTouchEventTraits::IsTouchSequenceStart(event.event) &&
- ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) {
+ if (WebTouchEventTraits::IsTouchSequenceStart(event.event)) {
touch_action_filter_.AppendToGestureSequenceForDebugging("T");
- // Touch action must be auto when there is no consumer
- touch_action_filter_.OnSetTouchAction(cc::kTouchActionAuto);
- touch_action_filter_.SetActiveTouchInProgress(true);
- UpdateTouchAckTimeoutEnabled();
+ touch_action_filter_.AppendToGestureSequenceForDebugging(
+ base::NumberToString(ack_result).c_str());
+ touch_action_filter_.AppendToGestureSequenceForDebugging(
+ base::NumberToString(event.event.unique_touch_event_id).c_str());
+ touch_action_filter_.IncreaseActiveTouches();
+ // There are some cases the touch action may not have value when receiving
+ // the ACK for the touch start, such as input ack state is
+ // NO_CONSUMER_EXISTS, or the renderer has swapped out. In these cases, set
+ // touch action Auto.
+ if (!touch_action_filter_.allowed_touch_action().has_value()) {
+ touch_action_filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ UpdateTouchAckTimeoutEnabled();
+ }
}
disposition_handler_->OnTouchEventAck(event, ack_source, ack_result);
if (WebTouchEventTraits::IsTouchSequenceEnd(event.event)) {
+ touch_action_filter_.AppendToGestureSequenceForDebugging("E");
+ touch_action_filter_.AppendToGestureSequenceForDebugging(
+ base::NumberToString(event.event.unique_touch_event_id).c_str());
+ touch_action_filter_.DecreaseActiveTouches();
touch_action_filter_.ReportAndResetTouchAction();
- touch_action_filter_.SetActiveTouchInProgress(false);
UpdateTouchAckTimeoutEnabled();
}
}
@@ -596,7 +602,6 @@ void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) {
void InputRouterImpl::ForceSetTouchActionAuto() {
touch_action_filter_.AppendToGestureSequenceForDebugging("F");
touch_action_filter_.OnSetTouchAction(cc::kTouchActionAuto);
- touch_action_filter_.SetActiveTouchInProgress(true);
}
void InputRouterImpl::OnHasTouchEventHandlersForTest(bool has_handlers) {
@@ -614,9 +619,8 @@ void InputRouterImpl::OnSetTouchAction(cc::TouchAction touch_action) {
touch_action_filter_.AppendToGestureSequenceForDebugging("S");
touch_action_filter_.AppendToGestureSequenceForDebugging(
- std::to_string(touch_action).c_str());
+ base::NumberToString(touch_action).c_str());
touch_action_filter_.OnSetTouchAction(touch_action);
- touch_action_filter_.SetActiveTouchInProgress(true);
// kTouchActionNone should disable the touch ack timeout.
UpdateTouchAckTimeoutEnabled();
diff --git a/chromium/content/browser/renderer_host/input/input_router_impl.h b/chromium/content/browser/renderer_host/input/input_router_impl.h
index 9f2862155d0..5aa7c74e123 100644
--- a/chromium/content/browser/renderer_host/input/input_router_impl.h
+++ b/chromium/content/browser/renderer_host/input/input_router_impl.h
@@ -114,7 +114,8 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter,
private:
friend class InputRouterImplTest;
friend class MockRenderWidgetHost;
- friend class RenderWidgetHostBrowserTest;
+ friend class RenderWidgetHostSitePerProcessTest;
+ friend class SitePerProcessBrowserTouchActionTest;
// Keeps track of last position of touch points and sets MovementXY for them.
void SetMovementXYForTouchPoints(blink::WebTouchEvent* event);
diff --git a/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc b/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc
index e06e5c15acb..18f0cbce82b 100644
--- a/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc
@@ -255,12 +255,12 @@ class InputRouterImplTest : public testing::Test {
}
void SimulateWheelEvent(float x,
- float y,
- float dX,
- float dY,
- int modifiers,
- bool precise,
- WebMouseWheelEvent::Phase phase) {
+ float y,
+ float dX,
+ float dY,
+ int modifiers,
+ bool precise,
+ WebMouseWheelEvent::Phase phase) {
WebMouseWheelEvent wheel_event = SyntheticWebMouseWheelEventBuilder::Build(
x, y, dX, dY, modifiers, precise);
wheel_event.phase = phase;
@@ -424,6 +424,33 @@ class InputRouterImplTest : public testing::Test {
disposition_handler_->GetAndResetAckCount();
}
+ void ActiveTouchSequenceCountTest(
+ const base::Optional<cc::TouchAction>& touch_action,
+ InputEventAckState state) {
+ PressTouchPoint(1, 1);
+ base::Optional<ui::DidOverscrollParams> overscroll;
+ input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch_event_));
+ input_router_->TouchEventHandled(
+ TouchEventWithLatencyInfo(touch_event_), InputEventAckSource::BROWSER,
+ ui::LatencyInfo(), state, overscroll, touch_action);
+ EXPECT_EQ(input_router_->touch_action_filter_.num_of_active_touches_, 1);
+ ReleaseTouchPoint(0);
+ input_router_->OnTouchEventAck(TouchEventWithLatencyInfo(touch_event_),
+ InputEventAckSource::BROWSER, state);
+ EXPECT_EQ(input_router_->touch_action_filter_.num_of_active_touches_, 0);
+ }
+
+ void OnTouchEventAckWithAckState(InputEventAckState ack_state) {
+ input_router_->OnHasTouchEventHandlers(true);
+ EXPECT_FALSE(input_router_->AllowedTouchAction().has_value());
+ PressTouchPoint(1, 1);
+ input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch_event_));
+ input_router_->OnTouchEventAck(TouchEventWithLatencyInfo(touch_event_),
+ InputEventAckSource::BROWSER, ack_state);
+ EXPECT_EQ(input_router_->AllowedTouchAction().value(),
+ cc::kTouchActionAuto);
+ }
+
InputRouter::Config config_;
std::unique_ptr<MockInputRouterImplClient> client_;
std::unique_ptr<InputRouterImpl> input_router_;
@@ -592,6 +619,64 @@ TEST_F(InputRouterImplTest, CoalescesWheelEvents) {
EXPECT_EQ(0u, dispatched_messages.size());
}
+// Test that the active touch sequence count increment when the touch start is
+// not ACKed from the main thread.
+TEST_F(InputRouterImplTest, ActiveTouchSequenceCountWithoutTouchAction) {
+ base::Optional<cc::TouchAction> touch_action;
+ ActiveTouchSequenceCountTest(touch_action,
+ INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+}
+
+TEST_F(InputRouterImplTest,
+ ActiveTouchSequenceCountWithoutTouchActionNoConsumer) {
+ base::Optional<cc::TouchAction> touch_action;
+ ActiveTouchSequenceCountTest(touch_action,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+}
+
+// Test that the active touch sequence count increment when the touch start is
+// ACKed from the main thread.
+TEST_F(InputRouterImplTest, ActiveTouchSequenceCountWithTouchAction) {
+ base::Optional<cc::TouchAction> touch_action(cc::kTouchActionPanY);
+ ActiveTouchSequenceCountTest(touch_action,
+ INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+}
+
+TEST_F(InputRouterImplTest, ActiveTouchSequenceCountWithTouchActionNoConsumer) {
+ base::Optional<cc::TouchAction> touch_action(cc::kTouchActionPanY);
+ ActiveTouchSequenceCountTest(touch_action,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+}
+
+TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateConsumed) {
+ OnTouchEventAckWithAckState(INPUT_EVENT_ACK_STATE_CONSUMED);
+}
+
+TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateNotConsumed) {
+ OnTouchEventAckWithAckState(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+}
+
+TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateConsumedShouldBubble) {
+ OnTouchEventAckWithAckState(INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE);
+}
+
+TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateNoConsumerExists) {
+ OnTouchEventAckWithAckState(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+}
+
+TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateIgnored) {
+ OnTouchEventAckWithAckState(INPUT_EVENT_ACK_STATE_IGNORED);
+}
+
+TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateNonBlocking) {
+ OnTouchEventAckWithAckState(INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+}
+
+TEST_F(InputRouterImplTest, TouchActionAutoWithAckStateNonBlockingDueToFling) {
+ OnTouchEventAckWithAckState(
+ INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING_DUE_TO_FLING);
+}
+
// Tests that touch-events are sent properly.
TEST_F(InputRouterImplTest, TouchEventQueue) {
OnHasTouchEventHandlers(true);
diff --git a/chromium/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc b/chromium/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc
index 3b1595d2e49..a26f229afa3 100644
--- a/chromium/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/main_thread_event_queue_browsertest.cc
@@ -13,6 +13,7 @@
#include "build/build_config.h"
#include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
@@ -141,14 +142,14 @@ class MainThreadEventQueueBrowserTest : public ContentBrowserTest {
}
void DoTouchMove() {
- SyntheticWebTouchEvent kEvents[4];
- kEvents[0].PressPoint(10, 10);
- kEvents[1].PressPoint(10, 10);
- kEvents[1].MovePoint(0, 20, 20);
- kEvents[2].PressPoint(10, 10);
- kEvents[2].MovePoint(0, 30, 30);
- kEvents[3].PressPoint(10, 10);
- kEvents[3].MovePoint(0, 35, 40);
+ SyntheticWebTouchEvent events[4];
+ events[0].PressPoint(10, 10);
+ events[1].PressPoint(10, 10);
+ events[1].MovePoint(0, 20, 20);
+ events[2].PressPoint(10, 10);
+ events[2].MovePoint(0, 30, 30);
+ events[3].PressPoint(10, 10);
+ events[3].MovePoint(0, 35, 40);
// Send a click event to cause some jankiness. This is done via a click
// event as ExecuteScript is synchronous.
@@ -157,8 +158,11 @@ class MainThreadEventQueueBrowserTest : public ContentBrowserTest {
auto input_msg_watcher = std::make_unique<InputMsgWatcher>(
GetWidgetHost(), blink::WebInputEvent::kTouchMove);
- for (const auto& event : kEvents)
- GetWidgetHost()->ForwardEmulatedTouchEvent(event, nullptr);
+ auto* root_view = GetWidgetHost()->GetView();
+ auto* input_event_router =
+ GetWidgetHost()->delegate()->GetInputEventRouter();
+ for (auto& event : events)
+ input_event_router->RouteTouchEvent(root_view, &event, ui::LatencyInfo());
// Runs until we get the InputMsgAck callback.
EXPECT_EQ(INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING,
diff --git a/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc b/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc
index a7c0c6dca37..b784cb04a90 100644
--- a/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc
@@ -151,7 +151,7 @@ class TracingRenderWidgetHostFactory : public RenderWidgetHostFactory {
class MouseLatencyBrowserTest : public ContentBrowserTest {
public:
- MouseLatencyBrowserTest() : loop_(base::MessageLoop::TYPE_UI) {}
+ MouseLatencyBrowserTest() {}
~MouseLatencyBrowserTest() override {}
RenderWidgetHostImpl* GetWidgetHost() {
@@ -306,7 +306,6 @@ class MouseLatencyBrowserTest : public ContentBrowserTest {
}
private:
- base::MessageLoop loop_;
std::unique_ptr<base::RunLoop> runner_;
base::Value trace_data_;
TracingRenderWidgetHostFactory widget_factory_;
diff --git a/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.cc b/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
index db69b0d9fb3..52f29658403 100644
--- a/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
+++ b/chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
@@ -8,6 +8,7 @@
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "content/common/input/input_event_dispatch_type.h"
+#include "content/common/input/web_mouse_wheel_event_traits.h"
#include "content/public/common/content_features.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/web_input_event_traits.h"
@@ -57,6 +58,10 @@ void MouseWheelEventQueue::QueueEvent(
event.latency.Terminate();
last_event->CoalesceWith(event);
+ // The deltas for the coalesced event change; the corresponding action
+ // might be different now.
+ last_event->event.event_action =
+ WebMouseWheelEventTraits::GetEventAction(last_event->event);
TRACE_EVENT_INSTANT2("input", "MouseWheelEventQueue::CoalescedWheelEvent",
TRACE_EVENT_SCOPE_THREAD, "total_dx",
last_event->event.delta_x, "total_dy",
@@ -65,7 +70,13 @@ void MouseWheelEventQueue::QueueEvent(
}
}
- wheel_queue_.push_back(std::make_unique<QueuedWebMouseWheelEvent>(event));
+ MouseWheelEventWithLatencyInfo event_with_action(event.event, event.latency);
+ event_with_action.event.event_action =
+ WebMouseWheelEventTraits::GetEventAction(event.event);
+ // Update the expected event action before queuing the event. From this point
+ // on, the action should not change.
+ wheel_queue_.push_back(
+ std::make_unique<QueuedWebMouseWheelEvent>(event_with_action));
TryForwardNextEventToRenderer();
LOCAL_HISTOGRAM_COUNTS_100("Renderer.WheelQueueSize", wheel_queue_.size());
}
@@ -78,8 +89,8 @@ bool MouseWheelEventQueue::CanGenerateGestureScroll(
return false;
}
- if (!ui::WebInputEventTraits::CanCauseScroll(
- event_sent_for_gesture_ack_->event)) {
+ if (event_sent_for_gesture_ack_->event.event_action ==
+ blink::WebMouseWheelEvent::EventAction::kPageZoom) {
TRACE_EVENT_INSTANT0("input", "Wheel Event Cannot Cause Scroll",
TRACE_EVENT_SCOPE_THREAD);
return false;
@@ -129,8 +140,8 @@ void MouseWheelEventQueue::ProcessMouseWheelAck(
#if !defined(OS_MACOSX)
// Swap X & Y if Shift is down and when there is no horizontal movement.
- if ((event_sent_for_gesture_ack_->event.GetModifiers() &
- WebInputEvent::kShiftKey) != 0 &&
+ if (event_sent_for_gesture_ack_->event.event_action ==
+ blink::WebMouseWheelEvent::EventAction::kScrollHorizontal &&
event_sent_for_gesture_ack_->event.delta_x == 0) {
scroll_update.data.scroll_update.delta_x =
event_sent_for_gesture_ack_->event.delta_y;
diff --git a/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc b/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
index 718e02bf755..a7b9c1d78df 100644
--- a/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc
@@ -14,6 +14,7 @@
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/stl_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/renderer_host/input/timeout_monitor.h"
@@ -155,9 +156,7 @@ class PassthroughTouchEventQueueTest : public testing::Test,
int unique_event_id) {
queue_->ProcessTouchAck(InputEventAckSource::COMPOSITOR_THREAD, ack_result,
ui::LatencyInfo(), unique_event_id);
- sent_events_ids_.erase(std::remove(sent_events_ids_.begin(),
- sent_events_ids_.end(), unique_event_id),
- sent_events_ids_.end());
+ base::Erase(sent_events_ids_, unique_event_id);
}
void SendGestureEventAck(WebInputEvent::Type type,
diff --git a/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc b/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc
index 2d8e33bd72a..ad008cb8313 100644
--- a/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc
@@ -62,7 +62,7 @@ namespace content {
class ScrollLatencyBrowserTest : public ContentBrowserTest {
public:
- ScrollLatencyBrowserTest() : loop_(base::MessageLoop::TYPE_UI) {}
+ ScrollLatencyBrowserTest() {}
~ScrollLatencyBrowserTest() override {}
RenderWidgetHostImpl* GetWidgetHost() {
@@ -140,7 +140,6 @@ class ScrollLatencyBrowserTest : public ContentBrowserTest {
private:
base::HistogramTester histogram_tester_;
- base::MessageLoop loop_;
std::unique_ptr<MainThreadFrameObserver> frame_observer_;
DISALLOW_COPY_AND_ASSIGN(ScrollLatencyBrowserTest);
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture.cc
index fd09c2ab43d..f5ba649b1b1 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture.cc
@@ -52,4 +52,8 @@ std::unique_ptr<SyntheticGesture> SyntheticGesture::Create(
}
}
+bool SyntheticGesture::AllowHighFrequencyDispatch() const {
+ return true;
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture.h b/chromium/content/browser/renderer_host/input/synthetic_gesture.h
index 90d49902470..6f5d330575d 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture.h
@@ -51,6 +51,12 @@ class CONTENT_EXPORT SyntheticGesture {
virtual Result ForwardInputEvents(
const base::TimeTicks& timestamp, SyntheticGestureTarget* target) = 0;
+ // Returns whether the gesture events can be dispatched at high frequency
+ // (e.g. at 120Hz), instead of the regular frequence (at 60Hz). Some gesture
+ // interact differently depending on how long they take (e.g. the TAP gesture
+ // generates a click only if its duration is longer than a threshold).
+ virtual bool AllowHighFrequencyDispatch() const;
+
protected:
DISALLOW_COPY_AND_ASSIGN(SyntheticGesture);
};
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.cc
index 44308e011ed..eef8cd03df4 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.cc
@@ -40,11 +40,10 @@ void SyntheticGestureController::QueueSyntheticGesture(
StartGesture(*pending_gesture_queue_.FrontGesture());
}
-void SyntheticGestureController::StartTimer() {
- // TODO(sad): Change the interval to allow sending multiple events per begin
- // frame.
+void SyntheticGestureController::StartTimer(bool high_frequency) {
dispatch_timer_.Start(
- FROM_HERE, base::TimeDelta::FromMicroseconds(16666),
+ FROM_HERE,
+ base::TimeDelta::FromMicroseconds(high_frequency ? 8333 : 16666),
base::BindRepeating(
[](base::WeakPtr<SyntheticGestureController> weak_ptr) {
if (weak_ptr)
@@ -90,7 +89,7 @@ void SyntheticGestureController::StartGesture(const SyntheticGesture& gesture) {
"SyntheticGestureController::running",
&gesture);
if (!dispatch_timer_.IsRunning())
- StartTimer();
+ StartTimer(gesture.AllowHighFrequencyDispatch());
}
void SyntheticGestureController::StopGesture(
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.h b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.h
index 085fdc353ff..dcc3b8ebcfb 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller.h
@@ -52,7 +52,7 @@ class CONTENT_EXPORT SyntheticGestureController {
private:
friend class SyntheticGestureControllerTestBase;
- void StartTimer();
+ void StartTimer(bool high_frequency);
void StartGesture(const SyntheticGesture& gesture);
void StopGesture(const SyntheticGesture& gesture,
OnGestureCompleteCallback completion_callback,
diff --git a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
index 74d0eb047d9..82e72f820ae 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc
@@ -676,7 +676,9 @@ class MockSyntheticPointerMouseActionTarget
testing::AssertionResult SyntheticMouseActionDispatchedCorrectly(
const SyntheticPointerActionParams& param,
- int click_count) {
+ int click_count,
+ SyntheticPointerActionParams::Button button =
+ SyntheticPointerActionParams::Button::NO_BUTTON) {
if (type_ != ToWebMouseEventType(param.pointer_action_type())) {
return testing::AssertionFailure()
<< "Pointer type was " << WebInputEvent::GetName(type_)
@@ -690,16 +692,31 @@ class MockSyntheticPointerMouseActionTarget
<< click_count << ".";
}
- if (clickCount_ == 1 && button_ != WebMouseEvent::Button::kLeft) {
- return testing::AssertionFailure()
- << "Pointer button was " << (int)button_ << ", expected "
- << (int)WebMouseEvent::Button::kLeft << ".";
- }
+ if (button_ != WebMouseEvent::Button::kNoButton) {
+ if (param.pointer_action_type() ==
+ SyntheticPointerActionParams::PointerActionType::PRESS ||
+ param.pointer_action_type() ==
+ SyntheticPointerActionParams::PointerActionType::RELEASE) {
+ if (clickCount_ != 1) {
+ return testing::AssertionFailure() << "Pointer click count was "
+ << clickCount_ << ", expected 1.";
+ }
+ }
- if (clickCount_ == 0 && button_ != WebMouseEvent::Button::kNoButton) {
- return testing::AssertionFailure()
- << "Pointer button was " << (int)button_ << ", expected "
- << (int)WebMouseEvent::Button::kNoButton << ".";
+ if (param.pointer_action_type() ==
+ SyntheticPointerActionParams::PointerActionType::MOVE) {
+ if (clickCount_ != 0) {
+ return testing::AssertionFailure() << "Pointer click count was "
+ << clickCount_ << ", expected 0.";
+ }
+ }
+
+ if (button_ !=
+ SyntheticPointerActionParams::GetWebMouseEventButton(button)) {
+ return testing::AssertionFailure()
+ << "Pointer button was " << static_cast<int>(button_)
+ << ", expected " << static_cast<int>(button) << ".";
+ }
}
if ((param.pointer_action_type() ==
@@ -1760,9 +1777,9 @@ TEST_F(SyntheticGestureControllerTest, PointerTouchAction) {
SyntheticPointerActionParams param1 = SyntheticPointerActionParams(
SyntheticPointerActionParams::PointerActionType::PRESS);
param0.set_position(gfx::PointF(54, 89));
- param0.set_index(0);
+ param0.set_pointer_id(0);
param1.set_position(gfx::PointF(79, 132));
- param1.set_index(1);
+ param1.set_pointer_id(1);
param_list.push_back(param0);
param_list.push_back(param1);
SyntheticPointerActionListParams params(param_list);
@@ -1859,8 +1876,8 @@ TEST_F(SyntheticGestureControllerTest, PointerMouseAction) {
EXPECT_EQ(2, num_success_);
EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pointer_mouse_target->num_dispatched_pointer_actions(), 2);
- EXPECT_TRUE(
- pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(param, 1));
+ EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
+ param, 1, SyntheticPointerActionParams::Button::LEFT));
// Third, send a mouse move.
param.set_pointer_action_type(
@@ -1875,8 +1892,8 @@ TEST_F(SyntheticGestureControllerTest, PointerMouseAction) {
EXPECT_EQ(3, num_success_);
EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pointer_mouse_target->num_dispatched_pointer_actions(), 3);
- EXPECT_TRUE(
- pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(param, 1));
+ EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
+ param, 0, SyntheticPointerActionParams::Button::LEFT));
// Fourth, send a mouse release.
param.set_pointer_action_type(
@@ -1890,8 +1907,8 @@ TEST_F(SyntheticGestureControllerTest, PointerMouseAction) {
EXPECT_EQ(4, num_success_);
EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pointer_mouse_target->num_dispatched_pointer_actions(), 4);
- EXPECT_TRUE(
- pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(param, 1));
+ EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
+ param, 1, SyntheticPointerActionParams::Button::LEFT));
}
TEST_F(SyntheticGestureControllerTest, PointerPenAction) {
@@ -1932,8 +1949,8 @@ TEST_F(SyntheticGestureControllerTest, PointerPenAction) {
EXPECT_EQ(2, num_success_);
EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pointer_pen_target->num_dispatched_pointer_actions(), 2);
- EXPECT_TRUE(
- pointer_pen_target->SyntheticMouseActionDispatchedCorrectly(param, 1));
+ EXPECT_TRUE(pointer_pen_target->SyntheticMouseActionDispatchedCorrectly(
+ param, 1, SyntheticPointerActionParams::Button::LEFT));
// Third, send a pen move.
param.set_pointer_action_type(
@@ -1948,8 +1965,8 @@ TEST_F(SyntheticGestureControllerTest, PointerPenAction) {
EXPECT_EQ(3, num_success_);
EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pointer_pen_target->num_dispatched_pointer_actions(), 3);
- EXPECT_TRUE(
- pointer_pen_target->SyntheticMouseActionDispatchedCorrectly(param, 1));
+ EXPECT_TRUE(pointer_pen_target->SyntheticMouseActionDispatchedCorrectly(
+ param, 0, SyntheticPointerActionParams::Button::LEFT));
// Fourth, send a pen release.
param.set_pointer_action_type(
@@ -1963,8 +1980,8 @@ TEST_F(SyntheticGestureControllerTest, PointerPenAction) {
EXPECT_EQ(4, num_success_);
EXPECT_EQ(0, num_failure_);
EXPECT_EQ(pointer_pen_target->num_dispatched_pointer_actions(), 4);
- EXPECT_TRUE(
- pointer_pen_target->SyntheticMouseActionDispatchedCorrectly(param, 1));
+ EXPECT_TRUE(pointer_pen_target->SyntheticMouseActionDispatchedCorrectly(
+ param, 1, SyntheticPointerActionParams::Button::LEFT));
// Fifth, send a pen leave.
param.set_pointer_action_type(
diff --git a/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.cc b/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.cc
index 4a48a9684bc..3ae84c103c5 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_mouse_driver.cc
@@ -41,13 +41,13 @@ void SyntheticMouseDriver::Press(float x,
void SyntheticMouseDriver::Move(float x, float y, int index) {
DCHECK_EQ(index, 0);
- blink::WebMouseEvent::Button button = mouse_event_.button;
- int click_count = mouse_event_.click_count;
mouse_event_ = SyntheticWebMouseEventBuilder::Build(
blink::WebInputEvent::kMouseMove, x, y, last_modifiers_,
mouse_event_.pointer_type);
- mouse_event_.button = button;
- mouse_event_.click_count = click_count;
+ mouse_event_.button =
+ SyntheticPointerActionParams::GetWebMouseEventButtonFromModifier(
+ last_modifiers_);
+ mouse_event_.click_count = 0;
}
void SyntheticMouseDriver::Release(
@@ -72,9 +72,6 @@ void SyntheticMouseDriver::Leave(int index) {
bool SyntheticMouseDriver::UserInputCheck(
const SyntheticPointerActionParams& params) const {
- if (params.index() != 0)
- return false;
-
if (params.pointer_action_type() ==
SyntheticPointerActionParams::PointerActionType::NOT_INITIALIZED) {
return false;
@@ -90,9 +87,6 @@ bool SyntheticMouseDriver::UserInputCheck(
if (params.pointer_action_type() ==
SyntheticPointerActionParams::PointerActionType::RELEASE) {
- if (mouse_event_.click_count <= 0)
- return false;
-
int modifiers =
SyntheticPointerActionParams::GetWebMouseEventModifier(params.button());
if (!(last_modifiers_ & modifiers))
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc b/chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc
index 65dccb01a30..9e889dabb22 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc
@@ -47,6 +47,10 @@ SyntheticGesture::Result SyntheticPointerAction::ForwardInputEvents(
: SyntheticGesture::GESTURE_RUNNING;
}
+bool SyntheticPointerAction::AllowHighFrequencyDispatch() const {
+ return false;
+}
+
SyntheticPointerAction::GestureState
SyntheticPointerAction::ForwardTouchOrMouseInputEvents(
const base::TimeTicks& timestamp,
@@ -64,18 +68,18 @@ SyntheticPointerAction::ForwardTouchOrMouseInputEvents(
switch (param.pointer_action_type()) {
case SyntheticPointerActionParams::PointerActionType::PRESS:
synthetic_pointer_driver_->Press(param.position().x(),
- param.position().y(), param.index(),
- param.button());
+ param.position().y(),
+ param.pointer_id(), param.button());
break;
case SyntheticPointerActionParams::PointerActionType::MOVE:
- synthetic_pointer_driver_->Move(param.position().x(),
- param.position().y(), param.index());
+ synthetic_pointer_driver_->Move(
+ param.position().x(), param.position().y(), param.pointer_id());
break;
case SyntheticPointerActionParams::PointerActionType::RELEASE:
- synthetic_pointer_driver_->Release(param.index(), param.button());
+ synthetic_pointer_driver_->Release(param.pointer_id(), param.button());
break;
case SyntheticPointerActionParams::PointerActionType::LEAVE:
- synthetic_pointer_driver_->Leave(param.index());
+ synthetic_pointer_driver_->Leave(param.pointer_id());
break;
case SyntheticPointerActionParams::PointerActionType::IDLE:
break;
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pointer_action.h b/chromium/content/browser/renderer_host/input/synthetic_pointer_action.h
index 39b3656d7c5..e836a08de98 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_pointer_action.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_pointer_action.h
@@ -24,6 +24,7 @@ class CONTENT_EXPORT SyntheticPointerAction : public SyntheticGesture {
SyntheticGesture::Result ForwardInputEvents(
const base::TimeTicks& timestamp,
SyntheticGestureTarget* target) override;
+ bool AllowHighFrequencyDispatch() const override;
private:
enum GestureState { UNINITIALIZED, RUNNING, INVALID, DONE };
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pointer_action_unittest.cc b/chromium/content/browser/renderer_host/input/synthetic_pointer_action_unittest.cc
index 8f480dd77dc..7b66c3bff07 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_pointer_action_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_pointer_action_unittest.cc
@@ -145,10 +145,10 @@ class MockSyntheticPointerTouchActionTarget
SyntheticPointerActionParams::PointerActionType::PRESS ||
param.pointer_action_type() ==
SyntheticPointerActionParams::PointerActionType::MOVE) {
- if (indexes_[index] != param.index()) {
+ if (indexes_[index] != param.pointer_id()) {
return testing::AssertionFailure()
<< "Pointer index at index " << index << " was "
- << indexes_[index] << ", expected " << param.index() << ".";
+ << indexes_[index] << ", expected " << param.pointer_id() << ".";
}
if (positions_[index] != param.position()) {
@@ -193,7 +193,7 @@ class MockSyntheticPointerTouchActionTarget
private:
int num_dispatched_pointer_actions_;
gfx::PointF positions_[WebTouchEvent::kTouchesLengthCap];
- int indexes_[WebTouchEvent::kTouchesLengthCap];
+ uint32_t indexes_[WebTouchEvent::kTouchesLengthCap];
WebTouchPoint::State states_[WebTouchEvent::kTouchesLengthCap];
};
@@ -217,6 +217,8 @@ class MockSyntheticPointerMouseActionTarget
const SyntheticPointerActionParams& param,
int click_count,
std::vector<SyntheticPointerActionParams::Button> buttons,
+ SyntheticPointerActionParams::Button button =
+ SyntheticPointerActionParams::Button::NO_BUTTON,
SyntheticGestureParams::GestureSourceType source_type =
SyntheticGestureParams::MOUSE_INPUT) {
if (GetDefaultSyntheticGestureSourceType() != source_type) {
@@ -239,9 +241,25 @@ class MockSyntheticPointerMouseActionTarget
<< click_count << ".";
}
- if (click_count_ == 1) {
- DCHECK_GT(buttons.size(), 0U);
- SyntheticPointerActionParams::Button button = buttons[buttons.size() - 1];
+ if (button_ != WebMouseEvent::Button::kNoButton) {
+ if (param.pointer_action_type() ==
+ SyntheticPointerActionParams::PointerActionType::PRESS ||
+ param.pointer_action_type() ==
+ SyntheticPointerActionParams::PointerActionType::RELEASE) {
+ if (click_count_ != 1) {
+ return testing::AssertionFailure() << "Pointer click count was "
+ << click_count_ << ", expected 1.";
+ }
+ }
+
+ if (param.pointer_action_type() ==
+ SyntheticPointerActionParams::PointerActionType::MOVE) {
+ if (click_count_ != 0) {
+ return testing::AssertionFailure() << "Pointer click count was "
+ << click_count_ << ", expected 0.";
+ }
+ }
+
if (button_ !=
SyntheticPointerActionParams::GetWebMouseEventButton(button)) {
return testing::AssertionFailure()
@@ -250,14 +268,6 @@ class MockSyntheticPointerMouseActionTarget
}
}
- if (click_count_ == 0 && button_ != WebMouseEvent::Button::kNoButton) {
- DCHECK_EQ(buttons.size(), 0U);
- return testing::AssertionFailure()
- << "Pointer button was " << static_cast<int>(button_)
- << ", expected "
- << static_cast<int>(WebMouseEvent::Button::kNoButton) << ".";
- }
-
int modifiers = 0;
for (size_t index = 0; index < buttons.size(); ++index)
modifiers |= SyntheticPointerActionParams::GetWebMouseEventModifier(
@@ -346,7 +356,7 @@ TEST_F(SyntheticPointerActionTest, PointerTouchAction) {
// Send a touch press for one finger.
SyntheticPointerActionParams param1 = SyntheticPointerActionParams(
SyntheticPointerActionParams::PointerActionType::PRESS);
- param1.set_index(0);
+ param1.set_pointer_id(0);
param1.set_position(gfx::PointF(54, 89));
SyntheticPointerActionListParams::ParamList param_list1;
param_list1.push_back(param1);
@@ -359,7 +369,7 @@ TEST_F(SyntheticPointerActionTest, PointerTouchAction) {
param1.set_position(gfx::PointF(133, 156));
SyntheticPointerActionParams param2 = SyntheticPointerActionParams(
SyntheticPointerActionParams::PointerActionType::PRESS);
- param2.set_index(1);
+ param2.set_pointer_id(1);
param2.set_position(gfx::PointF(79, 132));
SyntheticPointerActionListParams::ParamList param_list2;
param_list2.push_back(param1);
@@ -429,7 +439,7 @@ TEST_F(SyntheticPointerActionTest, PointerTouchActionsMultiPressRelease) {
// Send a touch press for one finger.
SyntheticPointerActionParams param1 = SyntheticPointerActionParams(
SyntheticPointerActionParams::PointerActionType::PRESS);
- param1.set_index(0);
+ param1.set_pointer_id(0);
param1.set_position(gfx::PointF(54, 89));
SyntheticPointerActionListParams::ParamList param_list1;
param_list1.push_back(param1);
@@ -437,7 +447,7 @@ TEST_F(SyntheticPointerActionTest, PointerTouchActionsMultiPressRelease) {
SyntheticPointerActionParams param2 = SyntheticPointerActionParams(
SyntheticPointerActionParams::PointerActionType::PRESS);
- param2.set_index(1);
+ param2.set_pointer_id(1);
param2.set_position(gfx::PointF(123, 69));
param1.set_pointer_action_type(
SyntheticPointerActionParams::PointerActionType::IDLE);
@@ -497,7 +507,7 @@ TEST_F(SyntheticPointerActionTest, PointerTouchActionTypeInvalid) {
// first.
SyntheticPointerActionParams param = SyntheticPointerActionParams(
SyntheticPointerActionParams::PointerActionType::MOVE);
- param.set_index(0);
+ param.set_pointer_id(0);
param.set_position(gfx::PointF(54, 89));
params_.PushPointerActionParams(param);
pointer_action_.reset(new SyntheticPointerAction(params_));
@@ -580,19 +590,19 @@ TEST_F(SyntheticPointerActionTest, PointerMouseAction) {
EXPECT_EQ(0, num_failure_);
buttons.push_back(SyntheticPointerActionParams::Button::LEFT);
EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
- param2, 1, buttons));
+ param2, 1, buttons, SyntheticPointerActionParams::Button::LEFT));
ForwardSyntheticPointerAction();
EXPECT_EQ(3, num_success_);
EXPECT_EQ(0, num_failure_);
EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
- param3, 1, buttons));
+ param3, 0, buttons, SyntheticPointerActionParams::Button::LEFT));
ForwardSyntheticPointerAction();
EXPECT_EQ(4, num_success_);
EXPECT_EQ(0, num_failure_);
EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
- param4, 1, buttons));
+ param4, 1, buttons, SyntheticPointerActionParams::Button::LEFT));
}
TEST_F(SyntheticPointerActionTest, PointerMouseActionMultiPress) {
@@ -605,25 +615,36 @@ TEST_F(SyntheticPointerActionTest, PointerMouseActionMultiPress) {
param1.set_button(SyntheticPointerActionParams::Button::LEFT);
params_.PushPointerActionParams(param1);
- // Press a mouse's middle button.
+ // Move the mouse while left button is pressed.
SyntheticPointerActionParams param2 = SyntheticPointerActionParams(
- SyntheticPointerActionParams::PointerActionType::PRESS);
- param2.set_position(gfx::PointF(189, 62));
- param2.set_button(SyntheticPointerActionParams::Button::MIDDLE);
+ SyntheticPointerActionParams::PointerActionType::MOVE);
+ param2.set_position(gfx::PointF(139, 98));
params_.PushPointerActionParams(param2);
- // Release a mouse's middle button.
+ // Press the mouse's middle button.
SyntheticPointerActionParams param3 = SyntheticPointerActionParams(
- SyntheticPointerActionParams::PointerActionType::RELEASE);
+ SyntheticPointerActionParams::PointerActionType::PRESS);
+ param3.set_position(gfx::PointF(139, 98));
param3.set_button(SyntheticPointerActionParams::Button::MIDDLE);
params_.PushPointerActionParams(param3);
- pointer_action_.reset(new SyntheticPointerAction(params_));
- // Release a mouse's middle button.
+ // Move the mouse while left and middle buttons are pressed.
SyntheticPointerActionParams param4 = SyntheticPointerActionParams(
- SyntheticPointerActionParams::PointerActionType::RELEASE);
- param4.set_button(SyntheticPointerActionParams::Button::LEFT);
+ SyntheticPointerActionParams::PointerActionType::MOVE);
+ param4.set_position(gfx::PointF(86, 69));
params_.PushPointerActionParams(param4);
+
+ // Release a mouse's middle button.
+ SyntheticPointerActionParams param5 = SyntheticPointerActionParams(
+ SyntheticPointerActionParams::PointerActionType::RELEASE);
+ param5.set_button(SyntheticPointerActionParams::Button::MIDDLE);
+ params_.PushPointerActionParams(param5);
+
+ // Release a mouse's left button.
+ SyntheticPointerActionParams param6 = SyntheticPointerActionParams(
+ SyntheticPointerActionParams::PointerActionType::RELEASE);
+ param6.set_button(SyntheticPointerActionParams::Button::LEFT);
+ params_.PushPointerActionParams(param6);
pointer_action_.reset(new SyntheticPointerAction(params_));
ForwardSyntheticPointerAction();
@@ -634,27 +655,41 @@ TEST_F(SyntheticPointerActionTest, PointerMouseActionMultiPress) {
std::vector<SyntheticPointerActionParams::Button> buttons(
1, SyntheticPointerActionParams::Button::LEFT);
EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
- param1, 1, buttons));
+ param1, 1, buttons, SyntheticPointerActionParams::Button::LEFT));
ForwardSyntheticPointerAction();
EXPECT_EQ(2, num_success_);
EXPECT_EQ(0, num_failure_);
- buttons.push_back(SyntheticPointerActionParams::Button::MIDDLE);
+ buttons.push_back(SyntheticPointerActionParams::Button::LEFT);
EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
- param2, 1, buttons));
+ param2, 0, buttons, SyntheticPointerActionParams::Button::LEFT));
ForwardSyntheticPointerAction();
EXPECT_EQ(3, num_success_);
EXPECT_EQ(0, num_failure_);
+ buttons.push_back(SyntheticPointerActionParams::Button::MIDDLE);
EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
- param3, 1, buttons));
+ param3, 1, buttons, SyntheticPointerActionParams::Button::MIDDLE));
ForwardSyntheticPointerAction();
EXPECT_EQ(4, num_success_);
EXPECT_EQ(0, num_failure_);
+ EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
+ param4, 0, buttons, SyntheticPointerActionParams::Button::MIDDLE));
+
+ ForwardSyntheticPointerAction();
+ EXPECT_EQ(5, num_success_);
+ EXPECT_EQ(0, num_failure_);
+ EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
+ param5, 1, buttons, SyntheticPointerActionParams::Button::MIDDLE));
buttons.pop_back();
+
+ ForwardSyntheticPointerAction();
+ EXPECT_EQ(6, num_success_);
+ EXPECT_EQ(0, num_failure_);
EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
- param4, 1, buttons));
+ param6, 1, buttons, SyntheticPointerActionParams::Button::LEFT));
+ buttons.pop_back();
}
TEST_F(SyntheticPointerActionTest, PointerMouseActionTypeInvalid) {
@@ -689,7 +724,7 @@ TEST_F(SyntheticPointerActionTest, PointerMouseActionTypeInvalid) {
std::vector<SyntheticPointerActionParams::Button> buttons(
1, SyntheticPointerActionParams::Button::LEFT);
EXPECT_TRUE(pointer_mouse_target->SyntheticMouseActionDispatchedCorrectly(
- param, 1, buttons));
+ param, 1, buttons, SyntheticPointerActionParams::Button::LEFT));
ForwardSyntheticPointerAction();
EXPECT_EQ(1, num_success_);
@@ -729,27 +764,31 @@ TEST_F(SyntheticPointerActionTest, PointerPenAction) {
EXPECT_EQ(0, num_failure_);
std::vector<SyntheticPointerActionParams::Button> buttons;
EXPECT_TRUE(pointer_pen_target->SyntheticMouseActionDispatchedCorrectly(
- param1, 0, buttons, SyntheticGestureParams::PEN_INPUT));
+ param1, 0, buttons, SyntheticPointerActionParams::Button::NO_BUTTON,
+ SyntheticGestureParams::PEN_INPUT));
ForwardSyntheticPointerAction();
EXPECT_EQ(2, num_success_);
EXPECT_EQ(0, num_failure_);
buttons.push_back(SyntheticPointerActionParams::Button::LEFT);
EXPECT_TRUE(pointer_pen_target->SyntheticMouseActionDispatchedCorrectly(
- param2, 1, buttons, SyntheticGestureParams::PEN_INPUT));
+ param2, 1, buttons, SyntheticPointerActionParams::Button::LEFT,
+ SyntheticGestureParams::PEN_INPUT));
ForwardSyntheticPointerAction();
EXPECT_EQ(3, num_success_);
EXPECT_EQ(0, num_failure_);
EXPECT_TRUE(pointer_pen_target->SyntheticMouseActionDispatchedCorrectly(
- param3, 1, buttons, SyntheticGestureParams::PEN_INPUT));
+ param3, 1, buttons, SyntheticPointerActionParams::Button::LEFT,
+ SyntheticGestureParams::PEN_INPUT));
ForwardSyntheticPointerAction();
EXPECT_EQ(4, num_success_);
EXPECT_EQ(0, num_failure_);
buttons.pop_back();
EXPECT_TRUE(pointer_pen_target->SyntheticMouseActionDispatchedCorrectly(
- param4, 0, buttons, SyntheticGestureParams::PEN_INPUT));
+ param4, 0, buttons, SyntheticPointerActionParams::Button::NO_BUTTON,
+ SyntheticGestureParams::PEN_INPUT));
}
TEST_F(SyntheticPointerActionTest, EmptyParams) {
diff --git a/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc b/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc
index 80503e564d7..54b70a02bb2 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.cc
@@ -46,6 +46,10 @@ SyntheticGesture::Result SyntheticTapGesture::ForwardInputEvents(
: SyntheticGesture::GESTURE_RUNNING;
}
+bool SyntheticTapGesture::AllowHighFrequencyDispatch() const {
+ return false;
+}
+
void SyntheticTapGesture::ForwardTouchOrMouseInputEvents(
const base::TimeTicks& timestamp, SyntheticGestureTarget* target) {
switch (state_) {
diff --git a/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.h b/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.h
index 03d4f470f26..b3d2bfc5ee8 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_tap_gesture.h
@@ -22,6 +22,7 @@ class CONTENT_EXPORT SyntheticTapGesture : public SyntheticGesture {
SyntheticGesture::Result ForwardInputEvents(
const base::TimeTicks& timestamp,
SyntheticGestureTarget* target) override;
+ bool AllowHighFrequencyDispatch() const override;
private:
enum GestureState {
diff --git a/chromium/content/browser/renderer_host/input/synthetic_touch_driver.cc b/chromium/content/browser/renderer_host/input/synthetic_touch_driver.cc
index c16c6e00c9c..e4b16def1f7 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_touch_driver.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_touch_driver.cc
@@ -8,14 +8,10 @@
namespace content {
-SyntheticTouchDriver::SyntheticTouchDriver() {
- std::fill(index_map_.begin(), index_map_.end(), -1);
-}
+SyntheticTouchDriver::SyntheticTouchDriver() {}
SyntheticTouchDriver::SyntheticTouchDriver(SyntheticWebTouchEvent touch_event)
- : touch_event_(touch_event) {
- std::fill(index_map_.begin(), index_map_.end(), -1);
-}
+ : touch_event_(touch_event) {}
SyntheticTouchDriver::~SyntheticTouchDriver() {}
@@ -25,7 +21,7 @@ void SyntheticTouchDriver::DispatchEvent(SyntheticGestureTarget* target,
if (touch_event_.GetType() != blink::WebInputEvent::kUndefined)
target->DispatchInputEventToPlatform(touch_event_);
touch_event_.ResetPoints();
- ResetIndexMap();
+ ResetPointerIdIndexMap();
}
void SyntheticTouchDriver::Press(float x,
@@ -33,24 +29,25 @@ void SyntheticTouchDriver::Press(float x,
int index,
SyntheticPointerActionParams::Button button) {
DCHECK_GE(index, 0);
- DCHECK_LT(index, blink::WebTouchEvent::kTouchesLengthCap);
+ DCHECK(pointer_id_map_.find(index) == pointer_id_map_.end());
int touch_index = touch_event_.PressPoint(x, y);
- index_map_[index] = touch_index;
+ touch_event_.touches[touch_index].id = index;
+ pointer_id_map_[index] = touch_index;
}
void SyntheticTouchDriver::Move(float x, float y, int index) {
DCHECK_GE(index, 0);
- DCHECK_LT(index, blink::WebTouchEvent::kTouchesLengthCap);
- touch_event_.MovePoint(index_map_[index], x, y);
+ DCHECK(pointer_id_map_.find(index) != pointer_id_map_.end());
+ touch_event_.MovePoint(pointer_id_map_[index], x, y);
}
void SyntheticTouchDriver::Release(
int index,
SyntheticPointerActionParams::Button button) {
DCHECK_GE(index, 0);
- DCHECK_LT(index, blink::WebTouchEvent::kTouchesLengthCap);
- touch_event_.ReleasePoint(index_map_[index]);
- index_map_[index] = -1;
+ DCHECK(pointer_id_map_.find(index) != pointer_id_map_.end());
+ touch_event_.ReleasePoint(pointer_id_map_[index]);
+ pointer_id_map_.erase(index);
}
void SyntheticTouchDriver::Leave(int index) {
@@ -59,10 +56,6 @@ void SyntheticTouchDriver::Leave(int index) {
bool SyntheticTouchDriver::UserInputCheck(
const SyntheticPointerActionParams& params) const {
- if (params.index() < 0 ||
- params.index() >= blink::WebTouchEvent::kTouchesLengthCap)
- return false;
-
if (params.pointer_action_type() ==
SyntheticPointerActionParams::PointerActionType::NOT_INITIALIZED) {
return false;
@@ -70,26 +63,26 @@ bool SyntheticTouchDriver::UserInputCheck(
if (params.pointer_action_type() ==
SyntheticPointerActionParams::PointerActionType::PRESS &&
- index_map_[params.index()] >= 0) {
+ pointer_id_map_.find(params.pointer_id()) != pointer_id_map_.end()) {
return false;
}
if (params.pointer_action_type() ==
SyntheticPointerActionParams::PointerActionType::MOVE &&
- index_map_[params.index()] == -1) {
+ pointer_id_map_.find(params.pointer_id()) == pointer_id_map_.end()) {
return false;
}
if (params.pointer_action_type() ==
SyntheticPointerActionParams::PointerActionType::RELEASE &&
- index_map_[params.index()] == -1) {
+ pointer_id_map_.find(params.pointer_id()) == pointer_id_map_.end()) {
return false;
}
return true;
}
-void SyntheticTouchDriver::ResetIndexMap() {
+void SyntheticTouchDriver::ResetPointerIdIndexMap() {
unsigned free_index = 0;
for (unsigned int i = 0; i < blink::WebTouchEvent::kTouchesLengthCap; ++i) {
if (free_index >= touch_event_.touches_length)
@@ -97,18 +90,22 @@ void SyntheticTouchDriver::ResetIndexMap() {
if (touch_event_.touches[i].state !=
blink::WebTouchPoint::kStateUndefined) {
touch_event_.touches[free_index] = touch_event_.touches[i];
- int index = GetIndexFromMap(i);
- index_map_[index] = free_index;
+ int pointer_id = GetIndexFromMap(i);
+ pointer_id_map_[pointer_id] = free_index;
free_index++;
}
}
}
int SyntheticTouchDriver::GetIndexFromMap(int value) const {
- int index = std::find(index_map_.begin(), index_map_.end(), value) -
- index_map_.begin();
- DCHECK(index >= 0 && index < blink::WebTouchEvent::kTouchesLengthCap);
- return index;
+ PointerIdIndexMap::const_iterator it;
+ for (it = pointer_id_map_.begin(); it != pointer_id_map_.end(); ++it) {
+ if (it->second == value) {
+ return it->first;
+ }
+ }
+ NOTREACHED() << "Failed to find the value.";
+ return -1;
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/synthetic_touch_driver.h b/chromium/content/browser/renderer_host/input/synthetic_touch_driver.h
index 3f8102a212d..bd2e8ececbc 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_touch_driver.h
+++ b/chromium/content/browser/renderer_host/input/synthetic_touch_driver.h
@@ -37,13 +37,13 @@ class CONTENT_EXPORT SyntheticTouchDriver : public SyntheticPointerDriver {
const SyntheticPointerActionParams& params) const override;
private:
- using IndexMap = std::array<int, blink::WebTouchEvent::kTouchesLengthCap>;
+ using PointerIdIndexMap = std::map<int, int>;
- void ResetIndexMap();
+ void ResetPointerIdIndexMap();
int GetIndexFromMap(int value) const;
SyntheticWebTouchEvent touch_event_;
- IndexMap index_map_;
+ PointerIdIndexMap pointer_id_map_;
DISALLOW_COPY_AND_ASSIGN(SyntheticTouchDriver);
};
diff --git a/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc b/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc
index 41c2c94fe34..835b0d6c7f0 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -7,6 +7,7 @@
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
@@ -18,7 +19,9 @@
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/input/actions_parser.h"
#include "content/common/input/synthetic_gesture_params.h"
+#include "content/common/input/synthetic_pointer_action_list_params.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
#include "content/common/input_messages.h"
#include "content/public/browser/render_view_host.h"
@@ -168,9 +171,6 @@ class TouchActionBrowserTest : public ContentBrowserTest {
void SetUpCommandLine(base::CommandLine* cmd) override {
cmd->AppendSwitchASCII(switches::kTouchEventFeatureDetection,
switches::kTouchEventFeatureDetectionEnabled);
- // TODO(rbyers): Remove this switch once touch-action ships.
- // http://crbug.com/241964
- cmd->AppendSwitch(switches::kEnableExperimentalWebPlatformFeatures);
}
// ContentBrowserTest:
@@ -319,6 +319,45 @@ class TouchActionBrowserTest : public ContentBrowserTest {
expected_scroll_position_after_scroll);
}
+ // Generate touch events for a double tap and drag zoom gesture at
+ // coordinates (50, 50).
+ void DoDoubleTapDragZoom() {
+ DCHECK(URLLoaded());
+
+ const std::string pointer_actions_json = R"HTML(
+ [{
+ "source": "touch",
+ "actions": [
+ { "name": "pointerDown", "x": 50, "y": 50 },
+ { "name": "pointerUp" },
+ { "name": "pause", "duration": 0.05 },
+ { "name": "pointerDown", "x": 50, "y": 50 },
+ { "name": "pointerMove", "x": 50, "y": 150 },
+ { "name": "pointerUp" }
+ ]
+ }]
+ )HTML";
+
+ base::JSONReader json_reader;
+ std::unique_ptr<base::Value> params =
+ json_reader.ReadToValue(pointer_actions_json);
+ ASSERT_TRUE(params.get()) << json_reader.GetErrorMessage();
+ ActionsParser actions_parser(params.get());
+
+ ASSERT_TRUE(actions_parser.ParsePointerActionSequence());
+
+ run_loop_ = std::make_unique<base::RunLoop>();
+
+ GetWidgetHost()->QueueSyntheticGesture(
+ SyntheticGesture::Create(actions_parser.gesture_params()),
+ base::BindOnce(&TouchActionBrowserTest::OnSyntheticGestureCompleted,
+ base::Unretained(this)));
+
+ // Runs until we get the OnSyntheticGestureCompleted callback
+ run_loop_->Run();
+ run_loop_.reset();
+ }
+
private:
void CheckScrollOffset(
bool wait_until_scrolled,
@@ -535,4 +574,43 @@ IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest,
gfx::Vector2d(45, 0), kShortJankTime);
}
+namespace {
+
+const std::string kDoubleTapZoomDataURL = R"HTML(
+ data:text/html,<!DOCTYPE html>
+ <meta name='viewport' content='width=device-width'/>
+ <style>
+ html, body {
+ margin: 0;
+ }
+ .spacer { height: 10000px; }
+ .touchaction { width: 75px; height: 75px; touch-action: none; }
+ </style>
+ <div class="touchaction"></div>
+ <div class=spacer></div>
+ <script>
+ document.title='ready';
+ </script>)HTML";
+
+} // namespace
+
+// Test that |touch-action: none| correctly blocks a double-tap and drag zoom
+// gesture.
+IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest, BlockDoubleTapDragZoom) {
+ LoadURL(kDoubleTapZoomDataURL.c_str());
+
+ ASSERT_EQ(1, ExecuteScriptAndExtractDouble("window.visualViewport.scale"));
+
+ DoDoubleTapDragZoom();
+
+ // Since we don't expect anything to change, we don't know how long to wait
+ // before we're sure the zoom was blocked. Do a scroll so that we can wait
+ // until the offset changes. At that point, we know the zoom should have
+ // taken effect if it wasn't blocked by touch-action.
+ DoTouchScroll(gfx::Point(300, 300), gfx::Vector2d(0, 200), true, 10075,
+ gfx::Vector2d(0, 200), kNoJankTime);
+
+ EXPECT_EQ(1, ExecuteScriptAndExtractDouble("window.visualViewport.scale"));
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter.cc b/chromium/content/browser/renderer_host/input/touch_action_filter.cc
index 8a35a81229d..c420cf79179 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_filter.cc
+++ b/chromium/content/browser/renderer_host/input/touch_action_filter.cc
@@ -9,6 +9,7 @@
#include "base/debug/crash_logging.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/strings/string_number_conversions.h"
#include "third_party/blink/public/platform/web_gesture_event.h"
using blink::WebInputEvent;
@@ -62,14 +63,13 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
if (!scrolling_touch_action_.has_value())
SetTouchAction(cc::kTouchActionAuto);
}
+ gesture_scroll_in_progress_ = true;
gesture_sequence_.append("B");
if (!scrolling_touch_action_.has_value()) {
static auto* crash_key = base::debug::AllocateCrashKeyString(
"scrollbegin-gestures", base::debug::CrashKeySize::Size256);
base::debug::SetCrashKeyString(crash_key, gesture_sequence_);
gesture_sequence_.clear();
- // https://crbug.com/869375, temporary fix to prevent crash.
- SetTouchAction(cc::kTouchActionAuto);
}
suppress_manipulation_events_ =
ShouldSuppressManipulation(*gesture_event);
@@ -96,8 +96,6 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
"scrollupdate-gestures", base::debug::CrashKeySize::Size256);
base::debug::SetCrashKeyString(crash_key, gesture_sequence_);
gesture_sequence_.clear();
- // https://crbug.com/869375, temporary fix to prevent crash.
- SetTouchAction(cc::kTouchActionAuto);
}
if (IsYAxisActionDisallowed(scrolling_touch_action_.value())) {
gesture_event->data.scroll_update.delta_y = 0;
@@ -117,6 +115,7 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
case WebInputEvent::kGestureScrollEnd:
gesture_sequence_.clear();
+ gesture_scroll_in_progress_ = false;
gesture_sequence_in_progress_ = false;
ReportGestureEventFiltered(suppress_manipulation_events_);
return FilterManipulationEventAndResetState()
@@ -124,22 +123,50 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
: FilterGestureEventResult::kFilterGestureEventAllowed;
case WebInputEvent::kGesturePinchBegin:
+ if (!gesture_scroll_in_progress_) {
+ suppress_manipulation_events_ =
+ ShouldSuppressManipulation(*gesture_event);
+ }
+ FALLTHROUGH;
case WebInputEvent::kGesturePinchUpdate:
- case WebInputEvent::kGesturePinchEnd:
gesture_sequence_.append("P");
ReportGestureEventFiltered(suppress_manipulation_events_);
return suppress_manipulation_events_
? FilterGestureEventResult::kFilterGestureEventFiltered
: FilterGestureEventResult::kFilterGestureEventAllowed;
+ case WebInputEvent::kGesturePinchEnd:
+ ReportGestureEventFiltered(suppress_manipulation_events_);
+ // If we're in a double-tap and drag zoom, we won't be bracketed between
+ // a GSB/GSE pair so end the sequence now. Otherwise this will happen
+ // when we get the GSE.
+ if (!gesture_scroll_in_progress_) {
+ gesture_sequence_.clear();
+ gesture_sequence_in_progress_ = false;
+ return FilterManipulationEventAndResetState()
+ ? FilterGestureEventResult::kFilterGestureEventFiltered
+ : FilterGestureEventResult::kFilterGestureEventAllowed;
+ }
+ return suppress_manipulation_events_
+ ? FilterGestureEventResult::kFilterGestureEventFiltered
+ : FilterGestureEventResult::kFilterGestureEventAllowed;
- // The double tap gesture is a tap ending event. If a double tap gesture is
- // filtered out, replace it with a tap event.
+ // The double tap gesture is a tap ending event. If a double-tap gesture is
+ // filtered out, replace it with a tap event but preserve the tap-count to
+ // allow firing dblclick event in Blink.
+ //
+ // TODO(mustaq): This replacement of a double-tap gesture with a tap seems
+ // buggy, it produces an inconsistent gesture event stream: GestureTapCancel
+ // followed by GestureTap. See crbug.com/874474#c47 for a repro. We don't
+ // know of any bug resulting from it, but it's better to fix the broken
+ // assumption here at least to avoid introducing new bugs in future.
case WebInputEvent::kGestureDoubleTap:
gesture_sequence_in_progress_ = false;
gesture_sequence_.append("D");
DCHECK_EQ(1, gesture_event->data.tap.tap_count);
- if (!allow_current_double_tap_event_)
+ if (!allow_current_double_tap_event_) {
gesture_event->SetType(WebInputEvent::kGestureTap);
+ gesture_event->data.tap.tap_count = 2;
+ }
allow_current_double_tap_event_ = true;
break;
@@ -152,8 +179,6 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
"tapunconfirmed-gestures", base::debug::CrashKeySize::Size256);
base::debug::SetCrashKeyString(crash_key, gesture_sequence_);
gesture_sequence_.clear();
- // https://crbug.com/869375, temporary fix to prevent crash.
- SetTouchAction(cc::kTouchActionAuto);
}
allow_current_double_tap_event_ = (scrolling_touch_action_.value() &
cc::kTouchActionDoubleTapZoom) != 0;
@@ -185,13 +210,18 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
gesture_sequence_in_progress_ = true;
// If the gesture is hitting a region that has a non-blocking (such as a
// passive) event listener.
- if (gesture_event->is_source_touch_event_set_non_blocking)
+ // In theory, the num_of_active_touches_ should be > 0 at this point. But
+ // crash reports suggest otherwise.
+ if (gesture_event->is_source_touch_event_set_non_blocking ||
+ num_of_active_touches_ <= 0)
SetTouchAction(cc::kTouchActionAuto);
scrolling_touch_action_ = allowed_touch_action_;
if (scrolling_touch_action_.has_value())
- gesture_sequence_.append("O1");
+ gesture_sequence_.append("OY");
else
- gesture_sequence_.append("O2");
+ gesture_sequence_.append("ON");
+ gesture_sequence_.append(
+ base::NumberToString(gesture_event->unique_touch_event_id));
DCHECK(!drop_current_tap_ending_event_);
break;
@@ -248,24 +278,25 @@ void TouchActionFilter::OnSetTouchAction(cc::TouchAction touch_action) {
scrolling_touch_action_ = allowed_touch_action_;
}
-void TouchActionFilter::SetActiveTouchInProgress(
- bool active_touch_in_progress) {
- active_touch_in_progress_ = active_touch_in_progress;
+void TouchActionFilter::IncreaseActiveTouches() {
+ num_of_active_touches_++;
+}
+
+void TouchActionFilter::DecreaseActiveTouches() {
+ num_of_active_touches_--;
}
void TouchActionFilter::ReportAndResetTouchAction() {
if (has_touch_event_handler_)
- gesture_sequence_.append("R1");
+ gesture_sequence_.append("RY");
else
- gesture_sequence_.append("R0");
+ gesture_sequence_.append("RN");
ReportTouchAction();
- ResetTouchAction();
+ if (num_of_active_touches_ <= 0)
+ ResetTouchAction();
}
void TouchActionFilter::ReportTouchAction() {
- // https://crbug.com/869375, temporary fix to prevent crash.
- if (!scrolling_touch_action_.has_value())
- SetTouchAction(cc::kTouchActionAuto);
// Report the effective touch action computed by blink such as
// kTouchActionNone, kTouchActionPanX, etc.
// Since |cc::kTouchActionAuto| is equivalent to |cc::kTouchActionMax|, we
@@ -324,7 +355,12 @@ void TouchActionFilter::OnSetWhiteListedTouchAction(
bool TouchActionFilter::ShouldSuppressManipulation(
const blink::WebGestureEvent& gesture_event) {
- DCHECK_EQ(gesture_event.GetType(), WebInputEvent::kGestureScrollBegin);
+ DCHECK(gesture_event.GetType() == WebInputEvent::kGestureScrollBegin ||
+ WebInputEvent::IsPinchGestureEventType(gesture_event.GetType()));
+
+ if (WebInputEvent::IsPinchGestureEventType(gesture_event.GetType())) {
+ return (scrolling_touch_action_.value() & cc::kTouchActionPinchZoom) == 0;
+ }
if (gesture_event.data.scroll_begin.pointer_count >= 2) {
// Any GestureScrollBegin with more than one fingers is like a pinch-zoom
@@ -369,13 +405,13 @@ void TouchActionFilter::OnHasTouchEventHandlers(bool has_handlers) {
return;
has_touch_event_handler_ = has_handlers;
if (has_touch_event_handler_)
- gesture_sequence_.append("L1");
+ gesture_sequence_.append("LY");
else
- gesture_sequence_.append("L0");
+ gesture_sequence_.append("LN");
// We have set the associated touch action if the touch start already happened
// or there is a gesture in progress. In these cases, we should not reset the
// associated touch action.
- if (!gesture_sequence_in_progress_ && !active_touch_in_progress_) {
+ if (!gesture_sequence_in_progress_ && num_of_active_touches_ <= 0) {
ResetTouchAction();
if (has_touch_event_handler_)
scrolling_touch_action_.reset();
diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter.h b/chromium/content/browser/renderer_host/input/touch_action_filter.h
index 2d157fbebe9..d28115dc2ab 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_filter.h
+++ b/chromium/content/browser/renderer_host/input/touch_action_filter.h
@@ -9,7 +9,6 @@
#include "base/optional.h"
#include "cc/input/touch_action.h"
#include "content/common/content_export.h"
-#include "third_party/blink/public/platform/web_input_event.h"
namespace blink {
class WebGestureEvent;
@@ -67,14 +66,17 @@ class CONTENT_EXPORT TouchActionFilter {
void OnHasTouchEventHandlers(bool has_handlers);
- void SetActiveTouchInProgress(bool active_touch_in_progress);
+ void IncreaseActiveTouches();
+ void DecreaseActiveTouches();
// Debugging only.
void AppendToGestureSequenceForDebugging(const char* str);
private:
+ friend class InputRouterImplTest;
friend class MockRenderWidgetHost;
friend class TouchActionFilterTest;
+ friend class SitePerProcessBrowserTouchActionTest;
bool ShouldSuppressManipulation(const blink::WebGestureEvent&);
bool FilterManipulationEventAndResetState();
@@ -107,8 +109,11 @@ class CONTENT_EXPORT TouchActionFilter {
// before GSE.
bool gesture_sequence_in_progress_ = false;
- // True at touch start and false at touch end.
- bool active_touch_in_progress_ = false;
+ // True if we're between a GSB and a GSE.
+ bool gesture_scroll_in_progress_ = false;
+
+ // Increment at receiving ACK for touch start and decrement at touch end.
+ int num_of_active_touches_ = 0;
// What touch actions are currently permitted.
base::Optional<cc::TouchAction> allowed_touch_action_;
diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc b/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc
index 95d48e39153..caef54592cb 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc
@@ -45,6 +45,7 @@ class TouchActionFilterTest : public testing::Test {
// Scrolls with no direction hint are permitted in the |action| direction.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(action);
+ filter_.IncreaseActiveTouches();
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(0, 0,
@@ -64,12 +65,14 @@ class TouchActionFilterTest : public testing::Test {
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
}
{
// Scrolls biased towards the touch-action axis are permitted.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(action);
+ filter_.IncreaseActiveTouches();
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(scroll_x, scroll_y,
kSourceDevice);
@@ -100,6 +103,7 @@ class TouchActionFilterTest : public testing::Test {
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
}
{
@@ -107,6 +111,7 @@ class TouchActionFilterTest : public testing::Test {
// suppressed entirely.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(action);
+ filter_.IncreaseActiveTouches();
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(scroll_y, scroll_x,
kSourceDevice);
@@ -125,6 +130,7 @@ class TouchActionFilterTest : public testing::Test {
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
}
}
@@ -140,6 +146,7 @@ class TouchActionFilterTest : public testing::Test {
// Scrolls towards the touch-action direction are permitted.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(action);
+ filter_.IncreaseActiveTouches();
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(scroll_x, scroll_y,
kSourceDevice);
@@ -155,6 +162,7 @@ class TouchActionFilterTest : public testing::Test {
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
}
{
@@ -162,6 +170,7 @@ class TouchActionFilterTest : public testing::Test {
// suppressed entirely.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(action);
+ filter_.IncreaseActiveTouches();
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(
-scroll_x, -scroll_y, kSourceDevice);
@@ -177,6 +186,7 @@ class TouchActionFilterTest : public testing::Test {
FilterGestureEventResult::kFilterGestureEventFiltered);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
}
{
@@ -184,6 +194,7 @@ class TouchActionFilterTest : public testing::Test {
// suppressed entirely.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(action);
+ filter_.IncreaseActiveTouches();
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(
-scroll_x - scroll_y, -scroll_x - scroll_y, kSourceDevice);
@@ -199,6 +210,7 @@ class TouchActionFilterTest : public testing::Test {
FilterGestureEventResult::kFilterGestureEventFiltered);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
}
}
TouchActionFilter filter_;
@@ -220,6 +232,7 @@ TEST_F(TouchActionFilterTest, SimpleFilter) {
// cc::kTouchActionAuto doesn't cause any filtering.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -230,10 +243,12 @@ TEST_F(TouchActionFilterTest, SimpleFilter) {
EXPECT_EQ(kDeltaY, scroll_update.data.scroll_update.delta_y);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
// cc::kTouchActionNone filters out all scroll events, but no other events.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionNone);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -246,10 +261,12 @@ TEST_F(TouchActionFilterTest, SimpleFilter) {
EXPECT_EQ(kDeltaY, scroll_update.data.scroll_update.delta_y);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
// When a new touch sequence begins, the state is reset.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -258,10 +275,12 @@ TEST_F(TouchActionFilterTest, SimpleFilter) {
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
// Setting touch action doesn't impact any in-progress gestures.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -271,20 +290,24 @@ TEST_F(TouchActionFilterTest, SimpleFilter) {
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
// And the state is still cleared for the next gesture.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
// Changing the touch action during a gesture has no effect.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionNone);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -298,6 +321,7 @@ TEST_F(TouchActionFilterTest, SimpleFilter) {
EXPECT_EQ(kDeltaY, scroll_update.data.scroll_update.delta_y);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
}
TEST_F(TouchActionFilterTest, PanLeft) {
@@ -370,6 +394,7 @@ TEST_F(TouchActionFilterTest, PanXY) {
// Scrolls hinted in the X axis are permitted and unmodified.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionPan);
+ filter_.IncreaseActiveTouches();
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(-7, 6, kSourceDevice);
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
@@ -387,12 +412,14 @@ TEST_F(TouchActionFilterTest, PanXY) {
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
}
{
// Scrolls hinted in the Y axis are permitted and unmodified.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionPan);
+ filter_.IncreaseActiveTouches();
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7, kSourceDevice);
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
@@ -410,12 +437,14 @@ TEST_F(TouchActionFilterTest, PanXY) {
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
}
{
// A two-finger gesture is not allowed.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionPan);
+ filter_.IncreaseActiveTouches();
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7, kSourceDevice,
2);
@@ -432,6 +461,7 @@ TEST_F(TouchActionFilterTest, PanXY) {
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
}
}
@@ -466,6 +496,7 @@ TEST_F(TouchActionFilterTest, MultiTouch) {
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionNone);
filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -478,12 +509,14 @@ TEST_F(TouchActionFilterTest, MultiTouch) {
EXPECT_EQ(kDeltaY, scroll_update.data.scroll_update.delta_y);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
// Intersection of PAN_X and PAN_Y is NONE.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionPanX);
filter_.OnSetTouchAction(cc::kTouchActionPanY);
filter_.OnSetTouchAction(cc::kTouchActionPan);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -492,6 +525,7 @@ TEST_F(TouchActionFilterTest, MultiTouch) {
FilterGestureEventResult::kFilterGestureEventFiltered);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
}
class TouchActionFilterPinchTest : public testing::Test {
@@ -518,6 +552,7 @@ class TouchActionFilterPinchTest : public testing::Test {
// Pinch is allowed with touch-action: auto.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -530,10 +565,12 @@ class TouchActionFilterPinchTest : public testing::Test {
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
// Pinch is not allowed with touch-action: none.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionNone);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -552,11 +589,13 @@ class TouchActionFilterPinchTest : public testing::Test {
FilterGestureEventResult::kFilterGestureEventFiltered);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
// Pinch is not allowed with touch-action: pan-x pan-y except for force
// enable zoom.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionPan);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_NE(filter_.FilterGestureEvent(&scroll_begin),
@@ -579,10 +618,12 @@ class TouchActionFilterPinchTest : public testing::Test {
force_enable_zoom
? FilterGestureEventResult::kFilterGestureEventFiltered
: FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
// Pinch is allowed with touch-action: manipulation.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionManipulation);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -595,10 +636,12 @@ class TouchActionFilterPinchTest : public testing::Test {
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
// Pinch state is automatically reset at the end of a scroll.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -611,10 +654,12 @@ class TouchActionFilterPinchTest : public testing::Test {
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
// Pinching is only computed at GestureScrollBegin time.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -641,11 +686,13 @@ class TouchActionFilterPinchTest : public testing::Test {
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
// Once a pinch has started, any change in state won't affect the pinch
// gestures since it is computed in GestureScrollBegin.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -665,10 +712,12 @@ class TouchActionFilterPinchTest : public testing::Test {
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
// Scrolling is allowed when two fingers are down.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionPinchZoom);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -681,12 +730,14 @@ class TouchActionFilterPinchTest : public testing::Test {
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
// A pinch event sequence with only one pointer is equivalent to a scroll
// gesture, so disallowed as a pinch gesture.
scroll_begin.data.scroll_begin.pointer_count = 1;
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionPinchZoom);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -699,6 +750,7 @@ class TouchActionFilterPinchTest : public testing::Test {
FilterGestureEventResult::kFilterGestureEventFiltered);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
}
private:
@@ -759,6 +811,7 @@ TEST_F(TouchActionFilterTest, DoubleTap) {
// Double tap is disabled with any touch action other than auto.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionManipulation);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&unconfirmed_tap),
@@ -775,6 +828,8 @@ TEST_F(TouchActionFilterTest, DoubleTap) {
EXPECT_EQ(filter_.FilterGestureEvent(&double_tap),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(WebInputEvent::kGestureTap, double_tap.GetType());
+ EXPECT_EQ(2, double_tap.data.tap.tap_count);
+ filter_.DecreaseActiveTouches();
}
TEST_F(TouchActionFilterTest, SingleTapWithTouchActionAuto) {
@@ -808,6 +863,7 @@ TEST_F(TouchActionFilterTest, SingleTap) {
// With touch action other than auto, tap unconfirmed is turned into tap.
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionNone);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&unconfirmed_tap1),
@@ -815,6 +871,7 @@ TEST_F(TouchActionFilterTest, SingleTap) {
EXPECT_EQ(WebInputEvent::kGestureTap, unconfirmed_tap1.GetType());
EXPECT_EQ(filter_.FilterGestureEvent(&tap),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
}
TEST_F(TouchActionFilterTest, TouchActionResetsOnResetTouchAction) {
@@ -829,26 +886,32 @@ TEST_F(TouchActionFilterTest, TouchActionResetsOnResetTouchAction) {
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionNone);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionNone);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&tap),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
filter_.ResetTouchAction();
filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
}
TEST_F(TouchActionFilterTest, TouchActionResetMidSequence) {
@@ -868,6 +931,7 @@ TEST_F(TouchActionFilterTest, TouchActionResetMidSequence) {
WebInputEvent::kGestureScrollEnd, kSourceDevice);
filter_.OnSetTouchAction(cc::kTouchActionNone);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
@@ -887,9 +951,11 @@ TEST_F(TouchActionFilterTest, TouchActionResetMidSequence) {
FilterGestureEventResult::kFilterGestureEventFiltered);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
+ filter_.DecreaseActiveTouches();
// A new scroll and pinch sequence should be allowed.
filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
@@ -906,6 +972,7 @@ TEST_F(TouchActionFilterTest, TouchActionResetMidSequence) {
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
}
// This test makes sure that we do not reset scrolling touch action in the
@@ -925,6 +992,7 @@ TEST_F(TouchActionFilterTest, TouchActionNotResetWithinGestureSequence) {
WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureScrollEnd, kSourceDevice);
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(cc::kTouchActionPanY, ScrollingTouchAction().value());
@@ -934,6 +1002,7 @@ TEST_F(TouchActionFilterTest, TouchActionNotResetWithinGestureSequence) {
EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
// Simulate a touch sequence end by calling ReportAndResetTouchAction.
+ filter_.DecreaseActiveTouches();
filter_.ReportAndResetTouchAction();
EXPECT_FALSE(filter_.allowed_touch_action().has_value());
EXPECT_EQ(cc::kTouchActionPanY, ScrollingTouchAction().value());
@@ -985,6 +1054,7 @@ TEST_F(TouchActionFilterTest, OnHasTouchEventHandlersReceivedDuringDoubleTap) {
WebInputEvent::kGestureDoubleTap, kSourceDevice);
// Simulate a double tap gesture: GTD-->GTC-->GTD-->GTC-->GDT.
+ filter_.IncreaseActiveTouches();
EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(ScrollingTouchAction().value(), cc::kTouchActionAuto);
@@ -1000,6 +1070,7 @@ TEST_F(TouchActionFilterTest, OnHasTouchEventHandlersReceivedDuringDoubleTap) {
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(filter_.FilterGestureEvent(&double_tap),
FilterGestureEventResult::kFilterGestureEventAllowed);
+ filter_.DecreaseActiveTouches();
}
TEST_F(TouchActionFilterTest, OnHasTouchEventHandlersReceivedDuringScroll) {
@@ -1079,7 +1150,7 @@ TEST_F(TouchActionFilterTest, OnHasTouchEventHandlersReceivedAfterTouchStart) {
// Receive a touch start ack, set the touch action.
filter_.OnSetTouchAction(cc::kTouchActionPanY);
- filter_.SetActiveTouchInProgress(true);
+ filter_.IncreaseActiveTouches();
filter_.OnHasTouchEventHandlers(false);
EXPECT_EQ(ScrollingTouchAction().value(), cc::kTouchActionPanY);
EXPECT_EQ(filter_.allowed_touch_action().value(), cc::kTouchActionPanY);
@@ -1088,6 +1159,33 @@ TEST_F(TouchActionFilterTest, OnHasTouchEventHandlersReceivedAfterTouchStart) {
EXPECT_EQ(filter_.allowed_touch_action().value(), cc::kTouchActionPanY);
}
+TEST_F(TouchActionFilterTest, ResetTouchActionWithActiveTouch) {
+ filter_.OnHasTouchEventHandlers(true);
+ EXPECT_FALSE(ScrollingTouchAction().has_value());
+ EXPECT_FALSE(filter_.allowed_touch_action().has_value());
+
+ // Receive a touch start ack, set the touch action.
+ filter_.OnSetTouchAction(cc::kTouchActionPanY);
+ filter_.IncreaseActiveTouches();
+
+ // Somehow we get the ACK for the second touch start before the ACK for the
+ // first touch end.
+ filter_.OnSetTouchAction(cc::kTouchActionPan);
+ filter_.IncreaseActiveTouches();
+
+ // The first touch end comes, we report and reset touch action. The touch
+ // actions should still have value.
+ filter_.DecreaseActiveTouches();
+ filter_.ReportAndResetTouchAction();
+ EXPECT_EQ(ScrollingTouchAction().value(), cc::kTouchActionPanY);
+ EXPECT_EQ(filter_.allowed_touch_action().value(), cc::kTouchActionPanY);
+
+ // The ack for the second touch end comes, the touch actions will be reset.
+ filter_.DecreaseActiveTouches();
+ filter_.ReportAndResetTouchAction();
+ EXPECT_FALSE(filter_.allowed_touch_action().has_value());
+}
+
// If the renderer is busy, the gesture event might have come before the
// OnHasTouchEventHanlders IPC is received. In this case, we should allow all
// the gestures.
@@ -1122,6 +1220,20 @@ TEST_F(TouchActionFilterTest, ScrollBeginWithoutTapDown) {
EXPECT_EQ(filter_.allowed_touch_action().value(), cc::kTouchActionAuto);
}
+// This tests a gesture tap down with |num_of_active_touches_| == 0
+TEST_F(TouchActionFilterTest, TapDownWithZeroNumOfActiveTouches) {
+ filter_.OnHasTouchEventHandlers(true);
+ EXPECT_FALSE(ScrollingTouchAction().has_value());
+ EXPECT_FALSE(filter_.allowed_touch_action().has_value());
+
+ WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::kGestureTapDown, kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_TRUE(ScrollingTouchAction().has_value());
+ EXPECT_EQ(ScrollingTouchAction().value(), cc::kTouchActionAuto);
+}
+
TEST_F(TouchActionFilterTest, ScrollBeginWithoutTapDownWithKnownTouchAction) {
filter_.OnHasTouchEventHandlers(true);
EXPECT_FALSE(ScrollingTouchAction().has_value());
diff --git a/chromium/content/browser/renderer_host/input/touch_emulator.cc b/chromium/content/browser/renderer_host/input/touch_emulator.cc
index e5cfa600cf5..ab7c6f7f23a 100644
--- a/chromium/content/browser/renderer_host/input/touch_emulator.cc
+++ b/chromium/content/browser/renderer_host/input/touch_emulator.cc
@@ -71,6 +71,7 @@ TouchEmulator::TouchEmulator(TouchEmulatorClient* client,
ui::GestureProviderConfigType::CURRENT_PLATFORM),
double_tap_enabled_(true),
use_2x_cursors_(false),
+ pinch_gesture_mode_for_testing_(false),
emulated_stream_active_sequence_count_(0),
native_stream_active_sequence_count_(0),
last_emulated_start_target_(nullptr),
@@ -516,6 +517,7 @@ void TouchEmulator::ScrollEnd(const WebGestureEvent& event) {
WebGestureEvent scroll_event(
WebInputEvent::kGestureScrollEnd, ModifiersWithoutMouseButtons(event),
event.TimeStamp(), blink::kWebGestureDeviceTouchscreen);
+ scroll_event.unique_touch_event_id = event.unique_touch_event_id;
client_->ForwardEmulatedGestureEvent(scroll_event);
}
@@ -571,7 +573,11 @@ void TouchEmulator::FillTouchEventAndPoint(const WebMouseEvent& mouse_event,
}
bool TouchEmulator::InPinchGestureMode() const {
- return shift_pressed_;
+ return shift_pressed_ || pinch_gesture_mode_for_testing_;
+}
+
+void TouchEmulator::SetPinchGestureModeForTesting(bool pinch_gesture_mode) {
+ pinch_gesture_mode_for_testing_ = pinch_gesture_mode;
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/touch_emulator.h b/chromium/content/browser/renderer_host/input/touch_emulator.h
index 55fabad3b55..20d2656e513 100644
--- a/chromium/content/browser/renderer_host/input/touch_emulator.h
+++ b/chromium/content/browser/renderer_host/input/touch_emulator.h
@@ -85,6 +85,14 @@ class CONTENT_EXPORT TouchEmulator : public ui::GestureProviderClient {
// Cancel any touches, for example, when focus is lost.
void CancelTouch();
+ // This is needed because SyntheticGestureSmoothDrag doesn't support setting
+ // key-modifiers on the drag sequence.
+ // https://crbug.com/901374.
+ void SetPinchGestureModeForTesting(bool pinch_gesture_mode);
+ bool suppress_next_fling_cancel_for_testing() const {
+ return suppress_next_fling_cancel_;
+ }
+
private:
// ui::GestureProviderClient implementation.
void OnGestureEvent(const ui::GestureEventData& gesture) override;
@@ -147,6 +155,7 @@ class CONTENT_EXPORT TouchEmulator : public ui::GestureProviderClient {
bool mouse_pressed_;
bool shift_pressed_;
+ bool pinch_gesture_mode_for_testing_;
blink::WebTouchEvent touch_event_;
int emulated_stream_active_sequence_count_;
diff --git a/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc b/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc
index ddab75b7c0a..181dcb75270 100644
--- a/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_input_browsertest.cc
@@ -12,7 +12,9 @@
#include "build/build_config.h"
#include "components/viz/common/features.h"
#include "content/browser/gpu/compositor_util.h"
+#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/common/input_messages.h"
@@ -99,8 +101,11 @@ class TouchInputBrowserTest : public ContentBrowserTest {
protected:
void SendTouchEvent(SyntheticWebTouchEvent* event) {
- GetWidgetHost()->ForwardTouchEventWithLatencyInfo(*event,
- ui::LatencyInfo());
+ auto* root_view = GetWidgetHost()->GetView();
+ auto* input_event_router =
+ GetWidgetHost()->delegate()->GetInputEventRouter();
+ input_event_router->RouteTouchEvent(root_view, event, ui::LatencyInfo());
+
event->ResetPoints();
}
void LoadURL() {
diff --git a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
index 86f8645c735..11af0a042d0 100644
--- a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc
@@ -30,6 +30,7 @@
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/display/display_switches.h"
+#include "ui/events/event_sink.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
#include "ui/touch_selection/touch_selection_controller_test_api.h"
@@ -178,10 +179,8 @@ class TouchSelectionControllerClientAuraTest : public ContentBrowserTest {
new TestTouchSelectionControllerClientAura(rwhva);
rwhva->SetSelectionControllerClientForTest(
base::WrapUnique(selection_controller_client_));
- rwhva->event_handler()->disable_input_event_router_for_testing();
}
- protected:
void SetUpOnMainThread() override {
ContentBrowserTest::SetUpOnMainThread();
if (!ui::TouchSelectionMenuRunner::GetInstance())
@@ -235,30 +234,49 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraTest, BasicSelection) {
EXPECT_TRUE(ui::TouchSelectionMenuRunner::GetInstance()->IsRunning());
}
-class GestureLongPressWaiter : public RenderWidgetHost::InputEventObserver {
+class GestureEventWaiter : public RenderWidgetHost::InputEventObserver {
public:
- GestureLongPressWaiter(RenderWidgetHost* rwh)
+ explicit GestureEventWaiter(RenderWidgetHost* rwh,
+ blink::WebInputEvent::Type target_event_type)
: rwh_(static_cast<RenderWidgetHostImpl*>(rwh)->GetWeakPtr()),
- gesture_long_press_seen_(false) {
+ target_event_type_(target_event_type),
+ gesture_event_type_seen_(false),
+ gesture_event_type_ack_seen_(false) {
rwh->AddInputEventObserver(this);
}
- ~GestureLongPressWaiter() override {
+ ~GestureEventWaiter() override {
if (rwh_)
rwh_->RemoveInputEventObserver(this);
}
+ void OnInputEvent(const blink::WebInputEvent& event) override {
+ if (event.GetType() == target_event_type_) {
+ gesture_event_type_seen_ = true;
+ if (run_loop_)
+ run_loop_->Quit();
+ }
+ }
+
void OnInputEventAck(InputEventAckSource,
InputEventAckState,
const blink::WebInputEvent& event) override {
- if (event.GetType() == blink::WebInputEvent::kGestureLongPress) {
- gesture_long_press_seen_ = true;
+ if (event.GetType() == target_event_type_) {
+ gesture_event_type_ack_seen_ = true;
if (run_loop_)
run_loop_->Quit();
}
}
void Wait() {
- if (gesture_long_press_seen_)
+ if (gesture_event_type_seen_)
+ return;
+ run_loop_.reset(new base::RunLoop);
+ run_loop_->Run();
+ run_loop_.reset();
+ }
+
+ void WaitForAck() {
+ if (gesture_event_type_ack_seen_)
return;
run_loop_.reset(new base::RunLoop);
run_loop_->Run();
@@ -268,7 +286,9 @@ class GestureLongPressWaiter : public RenderWidgetHost::InputEventObserver {
private:
base::WeakPtr<RenderWidgetHostImpl> rwh_;
std::unique_ptr<base::RunLoop> run_loop_;
- bool gesture_long_press_seen_;
+ blink::WebInputEvent::Type target_event_type_;
+ bool gesture_event_type_seen_;
+ bool gesture_event_type_ack_seen_;
};
class TouchSelectionControllerClientAuraSiteIsolationTest
@@ -291,25 +311,32 @@ class TouchSelectionControllerClientAuraSiteIsolationTest
// Get main frame view for event insertion.
RenderWidgetHostViewAura* main_view = GetRenderWidgetHostViewAura();
+ GestureEventWaiter long_press_waiter(
+ expected_target->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureLongPress);
SendTouch(main_view, ui::ET_TOUCH_PRESSED, point);
- SendTouch(main_view, ui::ET_TOUCH_RELEASED, point);
- SendGestureTap(main_view, point);
-
- // Since our hit-testing is now asynchronous, wait for the Ack to come
- // back before proceeding.
- GestureLongPressWaiter long_press_waiter(
- expected_target->GetRenderWidgetHost());
- SendGestureLongPress(main_view, point);
+ // Wait until we see the out-bound LongPress on its way to the renderer, so
+ // we know it's ok to send the TOUCH_RELEASED to end the sequence.
long_press_waiter.Wait();
+ SendTouch(main_view, ui::ET_TOUCH_RELEASED, point);
+ // Now wait for the LongPress ack to return from the renderer, so our caller
+ // knows the LongPress event has been consumed and any relevant selection
+ // performed.
+ long_press_waiter.WaitForAck();
}
- void SimpleTap(gfx::Point point) {
+ void SimpleTap(gfx::Point point, RenderWidgetHostViewBase* expected_target) {
// Get main frame view for event insertion.
RenderWidgetHostViewAura* main_view = GetRenderWidgetHostViewAura();
+ GestureEventWaiter tap_down_waiter(expected_target->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureTapDown);
+ GestureEventWaiter tap_waiter(expected_target->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureTap);
SendTouch(main_view, ui::ET_TOUCH_PRESSED, point);
+ tap_down_waiter.Wait();
SendTouch(main_view, ui::ET_TOUCH_RELEASED, point);
- SendGestureTap(main_view, point);
+ tap_waiter.WaitForAck();
}
private:
@@ -317,33 +344,18 @@ class TouchSelectionControllerClientAuraSiteIsolationTest
ui::EventType type,
gfx::Point point) {
DCHECK(type >= ui::ET_TOUCH_RELEASED && type << ui::ET_TOUCH_CANCELLED);
+ // If we want the GestureRecognizer to create the gestures for us, we must
+ // register the outgoing touch event with it by sending it through the
+ // window's event dispatching system.
+ aura::Window* shell_window = shell()->window();
+ aura::Window* content_window = view->GetNativeView();
+ aura::Window::ConvertPointToTarget(content_window, shell_window, &point);
+ ui::EventSink* sink = content_window->GetHost()->event_sink();
ui::TouchEvent touch(
type, point, ui::EventTimeForNow(),
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
- view->OnTouchEvent(&touch);
- }
-
- void SendGestureTap(RenderWidgetHostViewAura* view, gfx::Point point) {
- ui::GestureEventDetails tap_down_details(ui::ET_GESTURE_TAP_DOWN);
- tap_down_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHSCREEN);
- ui::GestureEvent gesture_tap_down(point.x(), point.y(), 0,
- ui::EventTimeForNow(), tap_down_details);
- view->OnGestureEvent(&gesture_tap_down);
- ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP);
- tap_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHSCREEN);
- tap_details.set_tap_count(1);
- ui::GestureEvent gesture_tap(point.x(), point.y(), 0, ui::EventTimeForNow(),
- tap_details);
- view->OnGestureEvent(&gesture_tap);
- }
-
- void SendGestureLongPress(RenderWidgetHostViewAura* view, gfx::Point point) {
- ui::GestureEventDetails long_press_details(ui::ET_GESTURE_LONG_PRESS);
- long_press_details.set_device_type(
- ui::GestureDeviceType::DEVICE_TOUCHSCREEN);
- ui::GestureEvent gesture_long_press(
- point.x(), point.y(), 0, ui::EventTimeForNow(), long_press_details);
- view->OnGestureEvent(&gesture_long_press);
+ ui::EventDispatchDetails details = sink->OnEventFromSource(&touch);
+ ASSERT_FALSE(details.dispatcher_destroyed);
}
};
@@ -466,11 +478,13 @@ IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAuraSiteIsolationTest,
if (GetParam()) {
gfx::PointF point_outside_iframe =
child_view->TransformPointToRootCoordSpaceF(gfx::PointF(-1.f, -1.f));
- SimpleTap(gfx::Point(point_outside_iframe.x(), point_outside_iframe.y()));
+ SimpleTap(gfx::Point(point_outside_iframe.x(), point_outside_iframe.y()),
+ parent_view);
} else {
gfx::PointF point_inside_iframe =
child_view->TransformPointToRootCoordSpaceF(gfx::PointF(+1.f, +1.f));
- SimpleTap(gfx::Point(point_inside_iframe.x(), point_inside_iframe.y()));
+ SimpleTap(gfx::Point(point_inside_iframe.x(), point_inside_iframe.y()),
+ child_view);
}
parent_selection_controller_client->Wait();
diff --git a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc
index e419b3fbed8..08acc8569f2 100644
--- a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc
+++ b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_child_frame.cc
@@ -7,7 +7,7 @@
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/browser/touch_selection_controller_client_manager.h"
#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "ui/base/clipboard/clipboard.h"
@@ -206,9 +206,9 @@ void TouchSelectionControllerClientChildFrame::RunContextMenu() {
gfx::PointF origin = rwhv_->TransformPointToRootCoordSpaceF(gfx::PointF());
anchor_point.Offset(-origin.x(), -origin.y());
RenderWidgetHostImpl* host = rwhv_->host();
- host->Send(new ViewMsg_ShowContextMenu(host->GetRoutingID(),
- ui::MENU_SOURCE_TOUCH_EDIT_MENU,
- gfx::ToRoundedPoint(anchor_point)));
+ host->Send(new WidgetMsg_ShowContextMenu(host->GetRoutingID(),
+ ui::MENU_SOURCE_TOUCH_EDIT_MENU,
+ gfx::ToRoundedPoint(anchor_point)));
// Hide selection handles after getting rect-between-bounds from touch
// selection controller; otherwise, rect would be empty and the above
diff --git a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_manager_android.cc b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_manager_android.cc
index fc968742ec8..d34a19317a6 100644
--- a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_manager_android.cc
+++ b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_manager_android.cc
@@ -11,7 +11,7 @@ namespace content {
TouchSelectionControllerClientManagerAndroid::
TouchSelectionControllerClientManagerAndroid(
RenderWidgetHostViewAndroid* rwhv)
- : rwhv_(rwhv), active_client_(rwhv), page_scale_factor_(1.f) {
+ : rwhv_(rwhv), active_client_(rwhv) {
DCHECK(rwhv_);
}
@@ -21,27 +21,6 @@ TouchSelectionControllerClientManagerAndroid::
observer.OnManagerWillDestroy(this);
}
-void TouchSelectionControllerClientManagerAndroid::SetPageScaleFactor(
- float page_scale_factor) {
- page_scale_factor_ = page_scale_factor;
-}
-
-namespace {
-
-gfx::SelectionBound ScaleSelectionBound(const gfx::SelectionBound& bound,
- float scale) {
- gfx::SelectionBound scaled_bound;
- gfx::PointF scaled_top = bound.edge_top();
- scaled_top.Scale(scale);
- gfx::PointF scaled_bottom = bound.edge_bottom();
- scaled_bottom.Scale(scale);
- scaled_bound.SetEdge(scaled_top, scaled_bottom);
- scaled_bound.set_type(bound.type());
- scaled_bound.set_visible(bound.visible());
- return scaled_bound;
-}
-} // namespace
-
// TouchSelectionControllerClientManager implementation.
void TouchSelectionControllerClientManagerAndroid::DidStopFlinging() {
// TODO(wjmaclean): determine what, if anything, needs to happen here.
@@ -61,13 +40,9 @@ void TouchSelectionControllerClientManagerAndroid::UpdateClientSelectionBounds(
}
active_client_ = client;
- if (active_client_ != rwhv_) {
- manager_selection_start_ = ScaleSelectionBound(start, page_scale_factor_);
- manager_selection_end_ = ScaleSelectionBound(end, page_scale_factor_);
- } else {
- manager_selection_start_ = start;
- manager_selection_end_ = end;
- }
+ manager_selection_start_ = start;
+ manager_selection_end_ = end;
+
// Notify TouchSelectionController if anything should change here. Only
// update if the client is different and not making a change to empty, or
// is the same client.
@@ -109,30 +84,18 @@ void TouchSelectionControllerClientManagerAndroid::SetNeedsAnimate() {
void TouchSelectionControllerClientManagerAndroid::MoveCaret(
const gfx::PointF& position) {
- gfx::PointF scaled_position = position;
- if (active_client_ != rwhv_)
- scaled_position.Scale(1 / page_scale_factor_);
- active_client_->MoveCaret(scaled_position);
+ active_client_->MoveCaret(position);
}
void TouchSelectionControllerClientManagerAndroid::MoveRangeSelectionExtent(
const gfx::PointF& extent) {
- gfx::PointF scaled_extent = extent;
- if (active_client_ != rwhv_)
- scaled_extent.Scale(1 / page_scale_factor_);
- active_client_->MoveRangeSelectionExtent(scaled_extent);
+ active_client_->MoveRangeSelectionExtent(extent);
}
void TouchSelectionControllerClientManagerAndroid::SelectBetweenCoordinates(
const gfx::PointF& base,
const gfx::PointF& extent) {
- gfx::PointF scaled_extent = extent;
- gfx::PointF scaled_base = base;
- if (active_client_ != rwhv_) {
- scaled_extent.Scale(1 / page_scale_factor_);
- scaled_base.Scale(1 / page_scale_factor_);
- }
- active_client_->SelectBetweenCoordinates(scaled_base, scaled_extent);
+ active_client_->SelectBetweenCoordinates(base, extent);
}
void TouchSelectionControllerClientManagerAndroid::OnSelectionEvent(
diff --git a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_manager_android.h b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_manager_android.h
index b839bddccbf..d3f3fb19515 100644
--- a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_manager_android.h
+++ b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_manager_android.h
@@ -21,8 +21,6 @@ class TouchSelectionControllerClientManagerAndroid
explicit TouchSelectionControllerClientManagerAndroid(
RenderWidgetHostViewAndroid* rwhv);
~TouchSelectionControllerClientManagerAndroid() override;
- void SetPageScaleFactor(float page_scale_factor);
- float page_scale_factor() { return page_scale_factor_; }
// TouchSelectionControllerClientManager implementation.
void DidStopFlinging() override;
@@ -52,7 +50,6 @@ class TouchSelectionControllerClientManagerAndroid
private:
RenderWidgetHostViewAndroid* rwhv_;
TouchSelectionControllerClient* active_client_;
- float page_scale_factor_;
gfx::SelectionBound manager_selection_start_;
gfx::SelectionBound manager_selection_end_;
base::ObserverList<TouchSelectionControllerClientManager::Observer>::Unchecked
diff --git a/chromium/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm b/chromium/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
index bad84541740..b0a397f10d1 100644
--- a/chromium/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
+++ b/chromium/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
@@ -434,7 +434,7 @@ TEST(WebInputEventBuilderMacTest, USDvorakQWERTYCommand) {
}
// Test conversion from key combination with Control to DomKey.
-// TODO(chongz): Move DomKey tests for all platforms into one place.
+// TODO(input-dev): Move DomKey tests for all platforms into one place.
// http://crbug.com/587589
// This test case only works for U.S. layout.
TEST(WebInputEventBuilderMacTest, DomKeyCtrlShift) {
@@ -781,4 +781,4 @@ TEST(WebInputEventBuilderMacTest, BuildWebTouchEvents) {
EXPECT_EQ(60, touch_event.touches[0].twist);
EXPECT_FLOAT_EQ(60.0, touch_event.touches[0].rotation_angle);
}
-#endif // MAC_OS_X_VERSION_10_12 \ No newline at end of file
+#endif // MAC_OS_X_VERSION_10_12
diff --git a/chromium/content/browser/renderer_host/media/audio_input_delegate_impl.cc b/chromium/content/browser/renderer_host/media/audio_input_delegate_impl.cc
index 718bb1a6e5a..4706dac9f7f 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_delegate_impl.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_delegate_impl.cc
@@ -14,11 +14,13 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "content/browser/media/capture/desktop_capture_device_uma_types.h"
#include "content/browser/media/capture/web_contents_audio_input_stream.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents_media_capture_id.h"
@@ -65,8 +67,8 @@ class AudioInputDelegateImpl::ControllerEventHandler
: stream_id_(stream_id), weak_delegate_(std::move(weak_delegate)) {}
void OnCreated(bool initially_muted) override {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioInputDelegateImpl::SendCreatedNotification,
weak_delegate_, initially_muted));
}
@@ -76,8 +78,8 @@ class AudioInputDelegateImpl::ControllerEventHandler
// we log it here.
LogMessage(stream_id_,
base::StringPrintf("AIC reports error_code=%d", error_code));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioInputDelegateImpl::OnError, weak_delegate_));
}
@@ -88,9 +90,9 @@ class AudioInputDelegateImpl::ControllerEventHandler
void OnMuted(bool is_muted) override {
LogMessage(stream_id_, is_muted ? "OnMuted: State changed to muted"
: "OnMuted: State changed to not muted");
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AudioInputDelegateImpl::OnMuted,
- weak_delegate_, is_muted));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&AudioInputDelegateImpl::OnMuted,
+ weak_delegate_, is_muted));
}
private:
@@ -182,8 +184,8 @@ AudioInputDelegateImpl::AudioInputDelegateImpl(
render_process_id_(render_process_id),
weak_factory_(this) {
// Prevent process backgrounding while audio input is active:
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NotifyProcessHostStreamAdded, render_process_id_));
controller_event_handler_ = std::make_unique<ControllerEventHandler>(
@@ -231,8 +233,8 @@ AudioInputDelegateImpl::~AudioInputDelegateImpl() {
audio_log_->OnClosed();
LogMessage(stream_id_, "Closing stream");
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&NotifyProcessHostStreamRemoved, render_process_id_));
// We pass |controller_event_handler_| and |writer_| in here to make sure they
diff --git a/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc b/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc
index 2e72505f818..26172e5ae38 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_device_manager.cc
@@ -11,7 +11,9 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/metrics/histogram_macros.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/media_stream_request.h"
#include "media/audio/audio_input_ipc.h"
@@ -57,7 +59,7 @@ AudioInputDeviceManager::~AudioInputDeviceManager() {
const MediaStreamDevice* AudioInputDeviceManager::GetOpenedDeviceById(
int session_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- MediaStreamDevices::iterator device = GetDevice(session_id);
+ auto device = GetDevice(session_id);
if (device == devices_.end())
return nullptr;
@@ -115,7 +117,7 @@ int AudioInputDeviceManager::Open(const MediaStreamDevice& device) {
void AudioInputDeviceManager::Close(int session_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- MediaStreamDevices::iterator device = GetDevice(session_id);
+ auto device = GetDevice(session_id);
if (device == devices_.end())
return;
const MediaStreamType stream_type = device->type;
@@ -124,8 +126,8 @@ void AudioInputDeviceManager::Close(int session_id) {
// Post a callback through the listener on IO thread since
// MediaStreamManager is expecting the callback asynchronously.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioInputDeviceManager::ClosedOnIOThread, this,
stream_type, session_id));
}
@@ -155,8 +157,8 @@ void AudioInputDeviceManager::KeyboardMicRegistration::DeregisterIfNeeded() {
--*shared_registration_count_;
DCHECK_GE(*shared_registration_count_, 0);
if (*shared_registration_count_ == 0) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SetKeyboardMicStreamActiveOnUIThread, false));
}
}
@@ -172,8 +174,8 @@ void AudioInputDeviceManager::RegisterKeyboardMicStream(
++keyboard_mic_streams_count_;
if (keyboard_mic_streams_count_ == 1) {
- BrowserThread::PostTaskAndReply(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SetKeyboardMicStreamActiveOnUIThread, true),
base::BindOnce(std::move(callback),
KeyboardMicRegistration(&keyboard_mic_streams_count_)));
@@ -221,8 +223,7 @@ void AudioInputDeviceManager::ClosedOnIOThread(MediaStreamType stream_type,
MediaStreamDevices::iterator AudioInputDeviceManager::GetDevice(
int session_id) {
- for (MediaStreamDevices::iterator it = devices_.begin(); it != devices_.end();
- ++it) {
+ for (auto it = devices_.begin(); it != devices_.end(); ++it) {
if (it->session_id == session_id)
return it;
}
diff --git a/chromium/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc b/chromium/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc
index a843d538ebf..2f09cdb7cbb 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc
@@ -9,10 +9,10 @@
#include "base/bind.h"
#include "base/memory/read_only_shared_memory_region.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/sync_socket.h"
#include "base/test/mock_callback.h"
+#include "base/test/scoped_task_environment.h"
#include "media/audio/audio_input_delegate.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -122,7 +122,7 @@ class AudioInputStreamHandleTest : public Test {
}
private:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
StrictMock<MockRendererAudioInputStreamFactoryClient> client_;
mojom::RendererAudioInputStreamFactoryClientPtr client_ptr_;
mojo::Binding<mojom::RendererAudioInputStreamFactoryClient> client_binding_;
diff --git a/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.cc b/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.cc
index 5d888b45bed..c890bb8df13 100644
--- a/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.cc
+++ b/chromium/content/browser/renderer_host/media/audio_output_authorization_handler.cc
@@ -6,11 +6,13 @@
#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
+#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/media/media_devices_permission_checker.h"
#include "content/browser/media/media_devices_util.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/media_device_id.h"
#include "content/public/browser/render_frame_host.h"
@@ -168,8 +170,8 @@ void AudioOutputAuthorizationHandler::RequestDeviceAuthorization(
trace_scope->UsingSessionId(session_id, device->id);
// We don't need the origin for authorization in this case, but it's used
// for hashing the device id before sending it back to the renderer.
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&GetMediaDeviceSaltAndOrigin, render_process_id_,
render_frame_id),
base::BindOnce(&AudioOutputAuthorizationHandler::HashDeviceId,
@@ -189,8 +191,8 @@ void AudioOutputAuthorizationHandler::RequestDeviceAuthorization(
trace_scope->CheckAccessStart(device_id);
// Check device permissions if nondefault device is requested.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&CheckAccessOnUIThread, render_process_id_,
render_frame_id, override_permissions_,
permissions_override_value_,
diff --git a/chromium/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc b/chromium/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc
index 15a70a66df8..fc657650af9 100644
--- a/chromium/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_output_authorization_handler_unittest.cc
@@ -9,7 +9,9 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "base/test/mock_callback.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread.h"
@@ -54,7 +56,7 @@ class TestBrowserContextWithRealURLRequestContextGetter
public:
TestBrowserContextWithRealURLRequestContextGetter() {
request_context_ = base::MakeRefCounted<net::TestURLRequestContextGetter>(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
salt_ = TestBrowserContext::GetMediaDeviceIDSalt();
}
@@ -132,15 +134,16 @@ class AudioOutputAuthorizationHandlerTest : public RenderViewHostTestHarness {
// enough for our code.
for (int i = 0; i < 20; ++i) {
base::RunLoop().RunUntilIdle();
- SyncWith(BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ SyncWith(
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
SyncWith(audio_manager_->GetWorkerTaskRunner());
}
}
std::string GetRawNondefaultId() {
std::string id;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandlerTest::GetRawNondefaultIdOnIOThread,
base::Unretained(this), base::Unretained(&id)));
@@ -198,8 +201,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest, AuthorizeDefaultDevice_Ok) {
std::make_unique<AudioOutputAuthorizationHandler>(
GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
base::Unretained(handler.get()), main_rfh()->GetRoutingID(), 0,
@@ -220,8 +223,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
std::make_unique<AudioOutputAuthorizationHandler>(
GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
base::Unretained(handler.get()), main_rfh()->GetRoutingID(), 0,
@@ -243,8 +246,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
std::unique_ptr<AudioOutputAuthorizationHandler> handler =
std::make_unique<AudioOutputAuthorizationHandler>(
GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::OverridePermissionsForTesting,
base::Unretained(handler.get()), false));
@@ -254,8 +257,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
std::string(), std::string()))
.Times(1);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
base::Unretained(handler.get()), main_rfh()->GetRoutingID(), 0,
@@ -276,8 +279,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
std::unique_ptr<AudioOutputAuthorizationHandler> handler =
std::make_unique<AudioOutputAuthorizationHandler>(
GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::OverridePermissionsForTesting,
base::Unretained(handler.get()), true));
@@ -286,8 +289,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
raw_nondefault_id, std::string()))
.Times(1);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
base::Unretained(handler.get()), main_rfh()->GetRoutingID(), 0,
@@ -308,8 +311,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest, AuthorizeInvalidDeviceId_NotFound) {
std::string(), std::string()))
.Times(1);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
base::Unretained(handler.get()), main_rfh()->GetRoutingID(), 0,
@@ -343,8 +346,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
std::string(), std::string()))
.Times(1);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
base::Unretained(handler.get()), main_rfh()->GetRoutingID(), 0,
@@ -367,8 +370,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
std::string()))
.Times(1);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
base::Unretained(handler.get()), main_rfh()->GetRoutingID(),
@@ -389,16 +392,16 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
std::unique_ptr<AudioOutputAuthorizationHandler> handler =
std::make_unique<AudioOutputAuthorizationHandler>(
GetAudioSystem(), GetMediaStreamManager(), process()->GetID());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::OverridePermissionsForTesting,
base::Unretained(handler.get()), true));
EXPECT_CALL(listener, Run(media::OUTPUT_DEVICE_STATUS_OK, _,
raw_nondefault_id, std::string()));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
base::Unretained(handler.get()), main_rfh()->GetRoutingID(), 0,
@@ -413,8 +416,8 @@ TEST_F(AudioOutputAuthorizationHandlerTest,
context->set_media_device_id_salt("new salt");
EXPECT_CALL(listener, Run(media::OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND, _, _,
std::string()));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
base::Unretained(handler.get()), main_rfh()->GetRoutingID(), 0,
diff --git a/chromium/content/browser/renderer_host/media/audio_output_delegate_impl.cc b/chromium/content/browser/renderer_host/media/audio_output_delegate_impl.cc
index 81cd7e4f1f4..aa87128fe0b 100644
--- a/chromium/content/browser/renderer_host/media/audio_output_delegate_impl.cc
+++ b/chromium/content/browser/renderer_host/media/audio_output_delegate_impl.cc
@@ -9,10 +9,12 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "content/browser/media/audio_stream_monitor.h"
#include "content/browser/media/capture/audio_mirroring_manager.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/media_observer.h"
#include "media/audio/audio_output_controller.h"
@@ -64,29 +66,29 @@ AudioOutputDelegateImpl::ControllerEventHandler::ControllerEventHandler(
: delegate_(std::move(delegate)), stream_id_(stream_id) {}
void AudioOutputDelegateImpl::ControllerEventHandler::OnControllerCreated() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateImpl::SendCreatedNotification,
delegate_));
}
void AudioOutputDelegateImpl::ControllerEventHandler::OnControllerPlaying() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateImpl::UpdatePlayingState, delegate_,
true));
}
void AudioOutputDelegateImpl::ControllerEventHandler::OnControllerPaused() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateImpl::UpdatePlayingState, delegate_,
false));
}
void AudioOutputDelegateImpl::ControllerEventHandler::OnControllerError() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateImpl::OnError, delegate_));
}
diff --git a/chromium/content/browser/renderer_host/media/audio_output_delegate_impl_unittest.cc b/chromium/content/browser/renderer_host/media/audio_output_delegate_impl_unittest.cc
index ac462bdb117..83bca5dac78 100644
--- a/chromium/content/browser/renderer_host/media/audio_output_delegate_impl_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_output_delegate_impl_unittest.cc
@@ -13,7 +13,9 @@
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/sync_socket.h"
+#include "base/task/post_task.h"
#include "content/browser/media/capture/audio_mirroring_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/media_observer.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -206,7 +208,7 @@ class AudioOutputDelegateTest : public testing::Test {
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
}
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
void PlayTest(base::Closure done, bool use_bound_observer) {
@@ -252,7 +254,7 @@ class AudioOutputDelegateTest : public testing::Test {
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
}
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
void PauseTest(base::Closure done) {
@@ -283,7 +285,7 @@ class AudioOutputDelegateTest : public testing::Test {
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
}
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
void PlayPausePlayTest(base::Closure done) {
@@ -320,7 +322,7 @@ class AudioOutputDelegateTest : public testing::Test {
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
}
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
void PlayPlayTest(base::Closure done) {
@@ -354,7 +356,7 @@ class AudioOutputDelegateTest : public testing::Test {
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
}
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
void CreateDivertTest(base::Closure done) {
@@ -386,7 +388,7 @@ class AudioOutputDelegateTest : public testing::Test {
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
}
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
void CreateDivertPauseTest(base::Closure done) {
@@ -417,7 +419,7 @@ class AudioOutputDelegateTest : public testing::Test {
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
}
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
void PlayDivertTest(base::Closure done) {
@@ -451,7 +453,7 @@ class AudioOutputDelegateTest : public testing::Test {
EXPECT_CALL(mirroring_manager_, RemoveDiverter(NotNull()));
}
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
void TrampolineToUI(base::Closure done,
@@ -459,7 +461,7 @@ class AudioOutputDelegateTest : public testing::Test {
// Destruct and then sync since destruction will post some tasks.
delegate.reset();
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
void ErrorTest(base::Closure done) {
@@ -517,7 +519,7 @@ class AudioOutputDelegateTest : public testing::Test {
std::move(observer_ptr), kDefaultDeviceId);
}
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
void PlayAndDestroyTest(base::Closure done) {
@@ -547,7 +549,7 @@ class AudioOutputDelegateTest : public testing::Test {
delegate.OnPlayStream();
}
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
void ErrorAndDestroyTest(base::Closure done) {
@@ -576,7 +578,7 @@ class AudioOutputDelegateTest : public testing::Test {
delegate.GetControllerForTesting()->OnError();
}
SyncWithAllThreads();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(done));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
protected:
@@ -594,7 +596,8 @@ class AudioOutputDelegateTest : public testing::Test {
// least one task will be run. 20 iterations should be enough for our code.
for (int i = 0; i < 20; ++i) {
base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle();
- SyncWith(BrowserThread::GetTaskRunnerForThread(BrowserThread::UI));
+ SyncWith(
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}));
SyncWith(audio_manager_->GetWorkerTaskRunner());
}
}
@@ -615,8 +618,8 @@ class AudioOutputDelegateTest : public testing::Test {
TEST_F(AudioOutputDelegateTest, Create) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::CreateTest,
base::Unretained(this), l.QuitClosure()));
l.Run();
@@ -624,8 +627,8 @@ TEST_F(AudioOutputDelegateTest, Create) {
TEST_F(AudioOutputDelegateTest, Play) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::PlayTest, base::Unretained(this),
l.QuitClosure(), true /* use_bound_observer */));
l.Run();
@@ -633,8 +636,8 @@ TEST_F(AudioOutputDelegateTest, Play) {
TEST_F(AudioOutputDelegateTest, PlayWithUnboundObserver) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::PlayTest, base::Unretained(this),
l.QuitClosure(), false /* use_bound_observer */));
l.Run();
@@ -642,8 +645,8 @@ TEST_F(AudioOutputDelegateTest, PlayWithUnboundObserver) {
TEST_F(AudioOutputDelegateTest, Pause) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::PauseTest,
base::Unretained(this), l.QuitClosure()));
l.Run();
@@ -651,8 +654,8 @@ TEST_F(AudioOutputDelegateTest, Pause) {
TEST_F(AudioOutputDelegateTest, PlayPausePlay) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::PlayPausePlayTest,
base::Unretained(this), l.QuitClosure()));
l.Run();
@@ -660,8 +663,8 @@ TEST_F(AudioOutputDelegateTest, PlayPausePlay) {
TEST_F(AudioOutputDelegateTest, PlayPlay) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::PlayPlayTest,
base::Unretained(this), l.QuitClosure()));
l.Run();
@@ -669,8 +672,8 @@ TEST_F(AudioOutputDelegateTest, PlayPlay) {
TEST_F(AudioOutputDelegateTest, PlayDivert) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::PlayDivertTest,
base::Unretained(this), l.QuitClosure()));
l.Run();
@@ -678,8 +681,8 @@ TEST_F(AudioOutputDelegateTest, PlayDivert) {
TEST_F(AudioOutputDelegateTest, CreateDivert) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::CreateDivertTest,
base::Unretained(this), l.QuitClosure()));
l.Run();
@@ -687,8 +690,8 @@ TEST_F(AudioOutputDelegateTest, CreateDivert) {
TEST_F(AudioOutputDelegateTest, Error) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::ErrorTest,
base::Unretained(this), l.QuitClosure()));
l.Run();
@@ -696,8 +699,8 @@ TEST_F(AudioOutputDelegateTest, Error) {
TEST_F(AudioOutputDelegateTest, CreateAndDestroy) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::CreateAndDestroyTest,
base::Unretained(this), l.QuitClosure()));
l.Run();
@@ -705,8 +708,8 @@ TEST_F(AudioOutputDelegateTest, CreateAndDestroy) {
TEST_F(AudioOutputDelegateTest, PlayAndDestroy) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::PlayAndDestroyTest,
base::Unretained(this), l.QuitClosure()));
l.Run();
@@ -714,8 +717,8 @@ TEST_F(AudioOutputDelegateTest, PlayAndDestroy) {
TEST_F(AudioOutputDelegateTest, ErrorAndDestroy) {
base::RunLoop l;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AudioOutputDelegateTest::PlayAndDestroyTest,
base::Unretained(this), l.QuitClosure()));
l.Run();
diff --git a/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc b/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
index ffa3e8c0062..d70bb7c1fa2 100644
--- a/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
+++ b/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
@@ -10,10 +10,12 @@
#include "base/command_line.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
+#include "content/browser/gpu/video_capture_dependencies.h"
#include "content/browser/renderer_host/media/in_process_launched_video_capture_device.h"
#include "content/browser/renderer_host/media/video_capture_controller.h"
-#include "content/browser/renderer_host/media/video_capture_dependencies.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "content/public/common/media_stream_request.h"
@@ -49,8 +51,8 @@ std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
return std::make_unique<media::VideoCaptureJpegDecoderImpl>(
base::BindRepeating(
&content::VideoCaptureDependencies::CreateJpegDecodeAccelerator),
- content::BrowserThread::GetTaskRunnerForThread(
- content::BrowserThread::IO),
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {content::BrowserThread::IO}),
std::move(decode_done_cb), std::move(send_log_message_cb));
}
@@ -99,7 +101,7 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
// to the IO thread.
auto receiver = std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
receiver_on_io_thread,
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
base::OnceClosure start_capture_closure;
// Use of Unretained |this| is safe, because |done_cb| guarantees that |this|
diff --git a/chromium/content/browser/renderer_host/media/media_capture_devices_impl.cc b/chromium/content/browser/renderer_host/media/media_capture_devices_impl.cc
index 9a8444f1392..02f6e4e6501 100644
--- a/chromium/content/browser/renderer_host/media/media_capture_devices_impl.cc
+++ b/chromium/content/browser/renderer_host/media/media_capture_devices_impl.cc
@@ -4,8 +4,10 @@
#include "content/browser/renderer_host/media/media_capture_devices_impl.h"
+#include "base/task/post_task.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@@ -14,8 +16,8 @@ namespace {
void EnsureMonitorCaptureDevices() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&MediaStreamManager::EnsureDeviceMonitorStarted,
base::Unretained(
@@ -57,8 +59,8 @@ void MediaCaptureDevicesImpl::AddVideoCaptureObserver(
MediaStreamManager* media_stream_manager =
BrowserMainLoop::GetInstance()->media_stream_manager();
if (media_stream_manager != nullptr) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&MediaStreamManager::AddVideoCaptureObserver,
base::Unretained(media_stream_manager), observer));
} else {
@@ -70,8 +72,8 @@ void MediaCaptureDevicesImpl::RemoveAllVideoCaptureObservers() {
MediaStreamManager* media_stream_manager =
BrowserMainLoop::GetInstance()->media_stream_manager();
if (media_stream_manager != nullptr) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&MediaStreamManager::RemoveAllVideoCaptureObservers,
base::Unretained(media_stream_manager)));
} else {
@@ -84,8 +86,8 @@ void MediaCaptureDevicesImpl::OnAudioCaptureDevicesChanged(
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
UpdateAudioDevicesOnUIThread(devices);
} else {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&MediaCaptureDevicesImpl::UpdateAudioDevicesOnUIThread,
base::Unretained(this), devices));
}
@@ -96,8 +98,8 @@ void MediaCaptureDevicesImpl::OnVideoCaptureDevicesChanged(
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
UpdateVideoDevicesOnUIThread(devices);
} else {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&MediaCaptureDevicesImpl::UpdateVideoDevicesOnUIThread,
base::Unretained(this), devices));
}
diff --git a/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.cc b/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
index 1812e217cec..6f3fe56d91c 100644
--- a/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
+++ b/chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.cc
@@ -10,6 +10,7 @@
#include "base/bind_helpers.h"
#include "base/command_line.h"
+#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "content/browser/bad_message.h"
#include "content/browser/media/media_devices_permission_checker.h"
@@ -17,6 +18,7 @@
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/common/media/media_devices.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/media_device_id.h"
#include "content/public/browser/render_frame_host.h"
@@ -122,7 +124,8 @@ void MediaDevicesDispatcherHost::GetVideoInputCapabilities(
GetVideoInputCapabilitiesCallback client_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::PostTaskAndReplyWithResult(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}).get(),
+ FROM_HERE,
base::BindOnce(media_stream_manager_->media_devices_manager()
->salt_and_origin_callback(),
render_process_id_, render_frame_id_),
@@ -149,7 +152,8 @@ void MediaDevicesDispatcherHost::GetAvailableVideoInputDeviceFormats(
void MediaDevicesDispatcherHost::GetAudioInputCapabilities(
GetAudioInputCapabilitiesCallback client_callback) {
base::PostTaskAndReplyWithResult(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}).get(),
+ FROM_HERE,
base::BindOnce(media_stream_manager_->media_devices_manager()
->salt_and_origin_callback(),
render_process_id_, render_frame_id_),
@@ -251,7 +255,8 @@ void MediaDevicesDispatcherHost::GetVideoInputDeviceFormats(
GetVideoInputDeviceFormatsCallback client_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::PostTaskAndReplyWithResult(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}).get(),
+ FROM_HERE,
base::BindOnce(media_stream_manager_->media_devices_manager()
->salt_and_origin_callback(),
render_process_id_, render_frame_id_),
@@ -267,11 +272,12 @@ void MediaDevicesDispatcherHost::EnumerateVideoDevicesForFormats(
bool try_in_use_first,
const MediaDeviceSaltAndOrigin& salt_and_origin) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- media_stream_manager_->video_capture_manager()->EnumerateDevices(base::Bind(
- &MediaDevicesDispatcherHost::FinalizeGetVideoInputDeviceFormats,
- weak_factory_.GetWeakPtr(), base::Passed(&client_callback), device_id,
- try_in_use_first, salt_and_origin.device_id_salt,
- salt_and_origin.origin));
+ media_stream_manager_->video_capture_manager()->EnumerateDevices(
+ base::BindOnce(
+ &MediaDevicesDispatcherHost::FinalizeGetVideoInputDeviceFormats,
+ weak_factory_.GetWeakPtr(), base::Passed(&client_callback), device_id,
+ try_in_use_first, salt_and_origin.device_id_salt,
+ salt_and_origin.origin));
}
void MediaDevicesDispatcherHost::FinalizeGetVideoInputDeviceFormats(
diff --git a/chromium/content/browser/renderer_host/media/media_devices_manager.cc b/chromium/content/browser/renderer_host/media/media_devices_manager.cc
index 307115c6d57..d79886ff495 100644
--- a/chromium/content/browser/renderer_host/media/media_devices_manager.cc
+++ b/chromium/content/browser/renderer_host/media/media_devices_manager.cc
@@ -14,7 +14,9 @@
#include "base/command_line.h"
#include "base/location.h"
#include "base/sequence_checker.h"
+#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -23,6 +25,7 @@
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/browser/service_manager/service_manager_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
#include "media/audio/audio_device_description.h"
@@ -422,7 +425,8 @@ void MediaDevicesManager::EnumerateDevices(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::PostTaskAndReplyWithResult(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}).get(),
+ FROM_HERE,
base::BindOnce(salt_and_origin_callback_, render_process_id,
render_frame_id),
base::BindOnce(&MediaDevicesManager::CheckPermissionsForEnumerateDevices,
@@ -515,8 +519,8 @@ void MediaDevicesManager::StartMonitoring() {
}
#if defined(OS_MACOSX)
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&MediaDevicesManager::StartMonitoringOnUIThread,
base::Unretained(this)));
#endif
@@ -584,11 +588,9 @@ media::VideoCaptureFormats MediaDevicesManager::GetVideoInputFormats(
video_capture_manager_->GetDeviceSupportedFormats(device_id, &formats);
ReplaceInvalidFrameRatesWithFallback(&formats);
// Remove formats that have zero resolution.
- formats.erase(std::remove_if(formats.begin(), formats.end(),
- [](const media::VideoCaptureFormat& format) {
- return format.frame_size.GetArea() <= 0;
- }),
- formats.end());
+ base::EraseIf(formats, [](const media::VideoCaptureFormat& format) {
+ return format.frame_size.GetArea() <= 0;
+ });
// If the device does not report any valid format, use a fallback list of
// standard formats.
@@ -733,8 +735,8 @@ void MediaDevicesManager::DoEnumerateDevices(MediaDeviceType type) {
break;
case MEDIA_DEVICE_TYPE_VIDEO_INPUT:
video_capture_manager_->EnumerateDevices(
- base::Bind(&MediaDevicesManager::VideoInputDevicesEnumerated,
- weak_factory_.GetWeakPtr()));
+ base::BindOnce(&MediaDevicesManager::VideoInputDevicesEnumerated,
+ weak_factory_.GetWeakPtr()));
break;
case MEDIA_DEVICE_TYPE_AUDIO_OUTPUT:
EnumerateAudioDevices(false /* is_input */);
@@ -946,7 +948,8 @@ void MediaDevicesManager::NotifyDeviceChangeSubscribers(
const SubscriptionRequest& request = subscription.second;
if (request.subscribe_types[type]) {
base::PostTaskAndReplyWithResult(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})
+ .get(),
FROM_HERE,
base::BindOnce(salt_and_origin_callback_, request.render_process_id,
request.render_frame_id),
diff --git a/chromium/content/browser/renderer_host/media/media_devices_manager.h b/chromium/content/browser/renderer_host/media/media_devices_manager.h
index 7ba5aff3293..2a4b6cfecf4 100644
--- a/chromium/content/browser/renderer_host/media/media_devices_manager.h
+++ b/chromium/content/browser/renderer_host/media/media_devices_manager.h
@@ -15,7 +15,7 @@
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/system_monitor/system_monitor.h"
+#include "base/system/system_monitor.h"
#include "content/browser/media/media_devices_util.h"
#include "content/common/content_export.h"
#include "content/common/media/media_devices.h"
diff --git a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
index 9f623c4c883..8a7be0e38d2 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host.cc
@@ -7,8 +7,10 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
+#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "services/service_manager/public/cpp/interface_provider.h"
@@ -83,8 +85,8 @@ MediaStreamDispatcherHost::GetMediaStreamDeviceObserver() {
observer.set_connection_error_handler(base::BindOnce(
&MediaStreamDispatcherHost::OnMediaStreamDeviceObserverConnectionError,
weak_factory_.GetWeakPtr()));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&BindMediaStreamDeviceObserverRequest, render_process_id_,
render_frame_id_, std::move(dispatcher_request)));
media_stream_device_observer_ = std::move(observer);
@@ -113,7 +115,8 @@ void MediaStreamDispatcherHost::GenerateStream(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::PostTaskAndReplyWithResult(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}).get(),
+ FROM_HERE,
base::BindOnce(salt_and_origin_callback_, render_process_id_,
render_frame_id_),
base::BindOnce(&MediaStreamDispatcherHost::DoGenerateStream,
@@ -164,7 +167,8 @@ void MediaStreamDispatcherHost::OpenDevice(int32_t page_request_id,
DCHECK_CURRENTLY_ON(BrowserThread::IO);
base::PostTaskAndReplyWithResult(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI).get(), FROM_HERE,
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}).get(),
+ FROM_HERE,
base::BindOnce(salt_and_origin_callback_, render_process_id_,
render_frame_id_),
base::BindOnce(&MediaStreamDispatcherHost::DoOpenDevice,
diff --git a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
index a1cd9c20c51..a9677e7bb22 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc
@@ -16,7 +16,7 @@
#include "base/containers/queue.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
-#include "base/system_monitor/system_monitor.h"
+#include "base/system/system_monitor.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
diff --git a/chromium/content/browser/renderer_host/media/media_stream_manager.cc b/chromium/content/browser/renderer_host/media/media_stream_manager.cc
index a154e72ac00..280d5f2319b 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_manager.cc
@@ -23,12 +23,14 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "base/threading/thread.h"
#include "base/threading/thread_local.h"
#include "build/build_config.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
+#include "content/browser/gpu/video_capture_dependencies.h"
#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/audio_service_listener.h"
#include "content/browser/renderer_host/media/in_process_video_capture_provider.h"
@@ -36,10 +38,11 @@
#include "content/browser/renderer_host/media/media_devices_manager.h"
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "content/browser/renderer_host/media/service_video_capture_provider.h"
-#include "content/browser/renderer_host/media/video_capture_dependencies.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/browser/renderer_host/media/video_capture_provider_switcher.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/browser/screenlock_monitor/screenlock_monitor.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/desktop_media_id.h"
@@ -60,6 +63,7 @@
#include "media/capture/video/fake_video_capture_device.h"
#include "media/capture/video/fake_video_capture_device_factory.h"
#include "media/capture/video/video_capture_system_impl.h"
+#include "media/mojo/interfaces/display_media_information.mojom.h"
#include "services/video_capture/public/uma/video_capture_service_event.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -190,14 +194,20 @@ MediaStreamType AdjustAudioStreamTypeBasedOnCommandLineSwitches(
: MEDIA_NO_SERVICE;
}
-// Returns DesktopMediaID with fake initializers if
-// |kUseFakeDeviceForMediaStream| is set. Returns the default DesktopMediaID
-// otherwise.
-DesktopMediaID FindDesktopMediaIDFromFakeDeviceConfig() {
+// Returns MediaStreamDevice built with DesktopMediaID with fake
+// initializers if |kUseFakeDeviceForMediaStream| is set. Returns a
+// MediaStreamDevice with default DesktopMediaID otherwise.
+MediaStreamDevice MediaStreamDeviceFromFakeDeviceConfig() {
// TODO(emircan): When getDisplayMedia() accepts constraints, pick
// the corresponding type.
- DesktopMediaID media_id =
- DesktopMediaID(DesktopMediaID::TYPE_SCREEN, DesktopMediaID::kNullId);
+ DesktopMediaID media_id(DesktopMediaID::TYPE_SCREEN, DesktopMediaID::kNullId);
+
+ MediaStreamDevice device(MEDIA_DISPLAY_VIDEO_CAPTURE, media_id.ToString(),
+ media_id.ToString());
+ media::mojom::DisplayCaptureSurfaceType display_surface =
+ media::mojom::DisplayCaptureSurfaceType::MONITOR;
+ device.display_media_info = media::mojom::DisplayMediaInformation::New(
+ display_surface, true, media::mojom::CursorCaptureType::NEVER);
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
@@ -210,26 +220,31 @@ DesktopMediaID FindDesktopMediaIDFromFakeDeviceConfig() {
switches::kUseFakeDeviceForMediaStream),
&config);
if (config.empty())
- return media_id;
+ return device;
DesktopMediaID::Type desktop_media_type = DesktopMediaID::TYPE_NONE;
switch (config[0].display_media_type) {
case media::FakeVideoCaptureDevice::DisplayMediaType::ANY:
- desktop_media_type = DesktopMediaID::TYPE_SCREEN;
- break;
case media::FakeVideoCaptureDevice::DisplayMediaType::MONITOR:
desktop_media_type = DesktopMediaID::TYPE_SCREEN;
+ display_surface = media::mojom::DisplayCaptureSurfaceType::MONITOR;
break;
case media::FakeVideoCaptureDevice::DisplayMediaType::WINDOW:
desktop_media_type = DesktopMediaID::TYPE_WINDOW;
+ display_surface = media::mojom::DisplayCaptureSurfaceType::WINDOW;
break;
case media::FakeVideoCaptureDevice::DisplayMediaType::BROWSER:
desktop_media_type = DesktopMediaID::TYPE_WEB_CONTENTS;
+ display_surface = media::mojom::DisplayCaptureSurfaceType::BROWSER;
break;
}
media_id = DesktopMediaID(desktop_media_type, DesktopMediaID::kFakeId);
}
- return media_id;
+ device = MediaStreamDevice(MEDIA_DISPLAY_VIDEO_CAPTURE, media_id.ToString(),
+ media_id.ToString());
+ device.display_media_info = media::mojom::DisplayMediaInformation::New(
+ display_surface, true, media::mojom::CursorCaptureType::NEVER);
+ return device;
}
} // namespace
@@ -422,8 +437,8 @@ class MediaStreamManager::DeviceRequest {
// static
void MediaStreamManager::SendMessageToNativeLog(const std::string& message) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&MediaStreamManager::SendMessageToNativeLog, message));
return;
}
@@ -504,7 +519,8 @@ MediaStreamManager::MediaStreamManager(
video_capture_provider = InProcessVideoCaptureProvider::CreateInstance(
std::make_unique<media::VideoCaptureSystemImpl>(
media::CreateVideoCaptureDeviceFactory(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))),
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {BrowserThread::UI}))),
std::move(device_task_runner),
base::BindRepeating(&SendVideoCaptureLogMessage));
}
@@ -603,9 +619,9 @@ std::string MediaStreamManager::MakeMediaAccessRequest(
// and thus can not handle a response. Using base::Unretained is safe since
// MediaStreamManager is deleted on the UI thread, after the IO thread has
// been stopped.
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&MediaStreamManager::SetUpRequest,
- base::Unretained(this), label));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&MediaStreamManager::SetUpRequest,
+ base::Unretained(this), label));
return label;
}
@@ -647,9 +663,9 @@ void MediaStreamManager::GenerateStream(
// and thus can not handle a response. Using base::Unretained is safe since
// MediaStreamManager is deleted on the UI thread, after the IO thread has
// been stopped.
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&MediaStreamManager::SetUpRequest,
- base::Unretained(this), label));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&MediaStreamManager::SetUpRequest,
+ base::Unretained(this), label));
}
void MediaStreamManager::CancelRequest(int render_process_id,
@@ -697,7 +713,7 @@ void MediaStreamManager::CancelRequest(const std::string& label) {
void MediaStreamManager::CancelAllRequests(int render_process_id,
int render_frame_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DeviceRequests::iterator request_it = requests_.begin();
+ auto request_it = requests_.begin();
while (request_it != requests_.end()) {
if (request_it->second->requesting_process_id != render_process_id ||
request_it->second->requesting_frame_id != render_frame_id) {
@@ -757,7 +773,7 @@ void MediaStreamManager::StopDevice(MediaStreamType type, int session_id) {
DVLOG(1) << "StopDevice"
<< "{type = " << type << "}"
<< "{session_id = " << session_id << "}";
- DeviceRequests::iterator request_it = requests_.begin();
+ auto request_it = requests_.begin();
while (request_it != requests_.end()) {
DeviceRequest* request = request_it->second;
MediaStreamDevices* devices = &request->devices;
@@ -766,7 +782,7 @@ void MediaStreamManager::StopDevice(MediaStreamType type, int session_id) {
++request_it;
continue;
}
- MediaStreamDevices::iterator device_it = devices->begin();
+ auto device_it = devices->begin();
while (device_it != devices->end()) {
if (device_it->type != type || device_it->session_id != session_id) {
++device_it;
@@ -847,9 +863,9 @@ void MediaStreamManager::OpenDevice(int render_process_id,
// and thus can not handle a response. Using base::Unretained is safe since
// MediaStreamManager is deleted on the UI thread, after the IO thread has
// been stopped.
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&MediaStreamManager::SetUpRequest,
- base::Unretained(this), label));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&MediaStreamManager::SetUpRequest,
+ base::Unretained(this), label));
}
bool MediaStreamManager::TranslateSourceIdToDeviceId(
@@ -1018,8 +1034,8 @@ MediaStreamManager::DeviceRequest* MediaStreamManager::FindRequest(
void MediaStreamManager::DeleteRequest(const std::string& label) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DVLOG(1) << "DeleteRequest({label= " << label << "})";
- for (DeviceRequests::iterator request_it = requests_.begin();
- request_it != requests_.end(); ++request_it) {
+ for (auto request_it = requests_.begin(); request_it != requests_.end();
+ ++request_it) {
if (request_it->first == label) {
std::unique_ptr<DeviceRequest> request(request_it->second);
requests_.erase(request_it);
@@ -1089,10 +1105,7 @@ void MediaStreamManager::PostRequestToUI(
if (request->video_type() == MEDIA_DISPLAY_VIDEO_CAPTURE) {
DCHECK(devices.empty());
- DesktopMediaID media_id = FindDesktopMediaIDFromFakeDeviceConfig();
- devices.push_back(MediaStreamDevice(MEDIA_DISPLAY_VIDEO_CAPTURE,
- media_id.ToString(),
- media_id.ToString()));
+ devices.push_back(MediaStreamDeviceFromFakeDeviceConfig());
}
std::unique_ptr<FakeMediaStreamUIProxy> fake_ui = fake_ui_factory_.Run();
fake_ui->SetAvailableDevices(devices);
@@ -1233,8 +1246,8 @@ bool MediaStreamManager::SetUpTabCaptureRequest(DeviceRequest* request,
return false;
}
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&MediaStreamManager::ResolveTabCaptureDeviceIdOnUIThread,
base::Unretained(this), capture_device_id,
request->requesting_process_id,
@@ -1450,8 +1463,8 @@ void MediaStreamManager::InitializeMaybeAsync(
// initialization is done synchronously. Other clients call this from a
// different thread and expect initialization to run asynchronously.
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&MediaStreamManager::InitializeMaybeAsync,
base::Unretained(this),
std::move(video_capture_provider)));
@@ -1474,7 +1487,8 @@ void MediaStreamManager::InitializeMaybeAsync(
video_capture_manager_ =
new VideoCaptureManager(std::move(video_capture_provider),
- base::BindRepeating(&SendVideoCaptureLogMessage));
+ base::BindRepeating(&SendVideoCaptureLogMessage),
+ ScreenlockMonitor::Get());
video_capture_manager_->RegisterListener(this);
// Using base::Unretained(this) is safe because |this| owns and therefore
diff --git a/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc
index fae5c3ca81c..f8ac784541f 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_manager_unittest.cc
@@ -436,6 +436,7 @@ TEST_F(MediaStreamManagerTest, GetDisplayMediaRequest) {
run_loop_.Run();
EXPECT_EQ(MEDIA_DISPLAY_VIDEO_CAPTURE, video_device.type);
+ EXPECT_TRUE(video_device.display_media_info.has_value());
EXPECT_CALL(*media_observer_, OnMediaRequestStateChanged(
_, _, _, _, MEDIA_DISPLAY_VIDEO_CAPTURE,
MEDIA_REQUEST_STATE_CLOSING));
diff --git a/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.cc b/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.cc
index 4d22fb1c51a..120bc443e69 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_track_metrics_host.cc
@@ -21,9 +21,7 @@ MediaStreamTrackMetricsHost::MediaStreamTrackMetricsHost() {}
MediaStreamTrackMetricsHost::~MediaStreamTrackMetricsHost() {
// Our render process has exited. We won't receive any more IPC
// messages from it. Assume all tracks ended now.
- for (TrackMap::iterator it = tracks_.begin();
- it != tracks_.end();
- ++it) {
+ for (auto it = tracks_.begin(); it != tracks_.end(); ++it) {
TrackInfo& info = it->second;
ReportDuration(info);
}
diff --git a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc
index 43c3b83d83d..4db595a7b34 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy.cc
@@ -8,9 +8,11 @@
#include "base/command_line.h"
#include "base/macros.h"
+#include "base/task/post_task.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "media/capture/video/fake_video_capture_device.h"
@@ -163,8 +165,8 @@ void MediaStreamUIProxy::Core::ProcessAccessRequestResponse(
result = MEDIA_DEVICE_PERMISSION_DENIED;
ui_ = std::move(stream_ui);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&MediaStreamUIProxy::ProcessAccessRequestResponse, proxy_,
filtered_devices, result));
}
@@ -172,8 +174,8 @@ void MediaStreamUIProxy::Core::ProcessAccessRequestResponse(
void MediaStreamUIProxy::Core::ProcessStopRequestFromUI() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&MediaStreamUIProxy::ProcessStopRequestFromUI, proxy_));
}
@@ -216,8 +218,8 @@ void MediaStreamUIProxy::RequestAccess(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
response_callback_ = std::move(response_callback);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Core::RequestAccess, base::Unretained(core_.get()),
std::move(request)));
}
@@ -231,8 +233,8 @@ void MediaStreamUIProxy::OnStarted(base::OnceClosure stop_callback,
// Owned by the PostTaskAndReply callback.
gfx::NativeViewId* window_id = new gfx::NativeViewId(0);
- BrowserThread::PostTaskAndReply(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&Core::OnStarted, base::Unretained(core_.get()),
window_id),
base::BindOnce(&MediaStreamUIProxy::OnWindowId,
@@ -294,8 +296,8 @@ void FakeMediaStreamUIProxy::RequestAccess(
if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kUseFakeUIForMediaStream) == "deny") {
// Immediately deny the request.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&MediaStreamUIProxy::Core::ProcessAccessRequestResponse,
base::Unretained(core_.get()),
request->render_process_id, request->render_frame_id,
@@ -334,8 +336,8 @@ void FakeMediaStreamUIProxy::RequestAccess(
devices_to_use.clear();
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&MediaStreamUIProxy::Core::ProcessAccessRequestResponse,
base::Unretained(core_.get()), request->render_process_id,
diff --git a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
index 54c050bceba..73cdee45f57 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc
@@ -7,11 +7,12 @@
#include <string>
#include <utility>
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/frame_host/render_frame_host_delegate.h"
-#include "content/public/test/test_browser_thread.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/test_render_frame_host.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -65,9 +66,7 @@ class MockStopStreamHandler {
class MediaStreamUIProxyTest : public testing::Test {
public:
- MediaStreamUIProxyTest()
- : ui_thread_(BrowserThread::UI, &message_loop_),
- io_thread_(BrowserThread::IO, &message_loop_) {
+ MediaStreamUIProxyTest() {
proxy_ = MediaStreamUIProxy::CreateForTests(&delegate_);
}
@@ -77,9 +76,7 @@ class MediaStreamUIProxyTest : public testing::Test {
}
protected:
- base::MessageLoop message_loop_;
- TestBrowserThread ui_thread_;
- TestBrowserThread io_thread_;
+ TestBrowserThreadBundle thread_bundle_;
MockRenderFrameHostDelegate delegate_;
MockResponseCallback response_callback_;
@@ -324,8 +321,8 @@ class MediaStreamUIProxyFeaturePolicyTest
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::RunLoop run_loop;
quit_closure_ = run_loop.QuitClosure();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&MediaStreamUIProxyFeaturePolicyTest::GetResultForRequestOnIOThread,
base::Unretained(this), std::move(request)));
@@ -376,8 +373,8 @@ class MediaStreamUIProxyFeaturePolicyTest
MediaStreamRequestResult result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
proxy_.reset();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&MediaStreamUIProxyFeaturePolicyTest::FinishedGetResult,
base::Unretained(this), devices, result));
}
diff --git a/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.cc b/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.cc
index 5093cee0282..a84a59521eb 100644
--- a/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.cc
+++ b/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.cc
@@ -7,10 +7,12 @@
#include <utility>
#include "base/feature_list.h"
+#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "content/browser/media/media_devices_permission_checker.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/media_device_id.h"
#include "content/public/common/content_features.h"
#include "media/base/audio_parameters.h"
@@ -33,8 +35,8 @@ void CheckPermissionAndGetSaltAndOrigin(
// If we're not allowed to use the device, don't call |cb|.
return;
}
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(std::move(cb), salt_and_origin));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(std::move(cb), salt_and_origin));
}
void OldEnumerateOutputDevices(
@@ -69,8 +71,8 @@ RenderFrameAudioInputStreamFactoryHandle::CreateFactory(
render_process_id, render_frame_id));
// Unretained is safe since |*handle| must be posted to the IO thread prior to
// deletion.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&RenderFrameAudioInputStreamFactoryHandle::Init,
base::Unretained(handle.get()), std::move(request)));
return handle;
@@ -191,8 +193,8 @@ void OldRenderFrameAudioInputStreamFactory::AssociateInputAndOutputForAec(
}
}
} else {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
CheckPermissionAndGetSaltAndOrigin, output_device_id,
render_process_id_, render_frame_id_,
diff --git a/chromium/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory.cc b/chromium/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory.cc
index df02e54c4e6..e323b9c5f9c 100644
--- a/chromium/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory.cc
+++ b/chromium/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory.cc
@@ -8,10 +8,12 @@
#include <utility>
#include "base/metrics/histogram_macros.h"
+#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "content/browser/renderer_host/media/audio_output_authorization_handler.h"
#include "content/browser/renderer_host/media/audio_output_stream_observer_impl.h"
#include "content/browser/renderer_host/media/renderer_audio_output_stream_factory_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/render_frame_host.h"
#include "media/base/audio_parameters.h"
#include "media/mojo/services/mojo_audio_output_stream_provider.h"
@@ -32,8 +34,8 @@ RenderFrameAudioOutputStreamFactoryHandle::CreateFactory(
render_frame_id));
// Unretained is safe since |*handle| must be posted to the IO thread prior to
// deletion.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&RenderFrameAudioOutputStreamFactoryHandle::Init,
base::Unretained(handle.get()), std::move(request)));
return handle;
diff --git a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc
index 2e3d9fd57ce..d8f55ef00d6 100644
--- a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc
+++ b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc
@@ -5,9 +5,11 @@
#include "content/browser/renderer_host/media/peer_connection_tracker_host.h"
#include "base/power_monitor/power_monitor.h"
+#include "base/task/post_task.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/webrtc/webrtc_internals.h"
#include "content/common/media/peer_connection_tracker_messages.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/webrtc_event_logger.h"
namespace content {
@@ -80,8 +82,8 @@ void PeerConnectionTrackerHost::OnAddPeerConnection(
void PeerConnectionTrackerHost::RemovePeerConnection(int lid) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&PeerConnectionTrackerHost::RemovePeerConnection, this,
lid));
return;
@@ -101,8 +103,8 @@ void PeerConnectionTrackerHost::UpdatePeerConnection(int lid,
const std::string& type,
const std::string& value) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&PeerConnectionTrackerHost::UpdatePeerConnection, this,
lid, type, value));
return;
@@ -137,8 +139,8 @@ void PeerConnectionTrackerHost::GetUserMedia(
const std::string& audio_constraints,
const std::string& video_constraints) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&PeerConnectionTrackerHost::GetUserMedia, this, origin,
audio, video, audio_constraints, video_constraints));
return;
@@ -154,8 +156,8 @@ void PeerConnectionTrackerHost::GetUserMedia(
void PeerConnectionTrackerHost::WebRtcEventLogWrite(int lid,
const std::string& output) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&PeerConnectionTrackerHost::WebRtcEventLogWrite, this,
lid, output));
return;
@@ -169,8 +171,8 @@ void PeerConnectionTrackerHost::WebRtcEventLogWrite(int lid,
}
void PeerConnectionTrackerHost::OnSuspend() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&PeerConnectionTrackerHost::SendOnSuspendOnUIThread,
this));
}
diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc
index d4d96fb5bfe..936d379fd15 100644
--- a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc
+++ b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc
@@ -4,15 +4,27 @@
#include "content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h"
+#include <cstdint>
#include <string>
#include <utility>
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
-#include "content/browser/browser_main_loop.h"
+#include "base/unguessable_token.h"
+#include "content/browser/media/audio_stream_broker.h"
#include "content/browser/media/capture/desktop_capture_device_uma_types.h"
#include "content/browser/media/forwarding_audio_stream_factory.h"
#include "content/browser/media/media_devices_permission_checker.h"
+#include "content/browser/media/media_devices_util.h"
+#include "content/browser/renderer_host/media/audio_input_device_manager.h"
+#include "content/browser/renderer_host/media/media_devices_manager.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/media_device_id.h"
#include "content/public/browser/render_frame_host.h"
@@ -20,25 +32,29 @@
#include "content/public/browser/web_contents_media_capture_id.h"
#include "content/public/common/media_stream_request.h"
#include "media/audio/audio_device_description.h"
-#include "media/audio/audio_input_device.h"
#include "media/base/audio_parameters.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "services/audio/public/mojom/audio_processing.mojom.h"
+#include "url/origin.h"
namespace content {
namespace {
-void LookUpDeviceAndRespondIfFound(
- scoped_refptr<AudioInputDeviceManager> audio_input_device_manager,
- int32_t session_id,
- base::OnceCallback<void(const MediaStreamDevice&)> response) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- const MediaStreamDevice* device =
- audio_input_device_manager->GetOpenedDeviceById(session_id);
- if (device) {
- // Copies device.
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(response), *device));
+AudioStreamBroker::LoopbackSource* GetLoopbackSourceOnUIThread(
+ int render_process_id,
+ int render_frame_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ auto* source = ForwardingAudioStreamFactory::CoreForFrame(
+ (RenderFrameHost::FromID(render_process_id, render_frame_id)));
+ if (!source) {
+ // The source of the capture has already been destroyed, so fail early.
+ return nullptr;
}
+ // Note: this pointer is sent over to the IO thread. This is safe since the
+ // destruction of |source| is posted to the IO thread and it hasn't been
+ // posted yet.
+ return source;
}
void EnumerateOutputDevices(MediaStreamManager* media_stream_manager,
@@ -59,75 +75,170 @@ void TranslateDeviceId(const std::string& device_id,
if (MediaStreamManager::DoesMediaDeviceIDMatchHMAC(
salt_and_origin.device_id_salt, salt_and_origin.origin, device_id,
device_info.device_id)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(cb), device_info.device_id));
+ cb.Run(device_info.device_id);
break;
}
}
// If we're unable to translate the device id, |cb| will not be run.
}
+void GetSaltOriginAndPermissionsOnUIThread(
+ int process_id,
+ int frame_id,
+ base::OnceCallback<void(MediaDeviceSaltAndOrigin salt_and_origin,
+ bool has_access)> cb) {
+ auto salt_and_origin = GetMediaDeviceSaltAndOrigin(process_id, frame_id);
+ bool access = MediaDevicesPermissionChecker().CheckPermissionOnUIThread(
+ MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, process_id, frame_id);
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(std::move(cb), std::move(salt_and_origin), access));
+}
+
} // namespace
+class RenderFrameAudioInputStreamFactory::Core final
+ : public mojom::RendererAudioInputStreamFactory {
+ public:
+ Core(mojom::RendererAudioInputStreamFactoryRequest request,
+ MediaStreamManager* media_stream_manager,
+ RenderFrameHost* render_frame_host);
+
+ ~Core() final;
+
+ void Init(mojom::RendererAudioInputStreamFactoryRequest request);
+
+ // mojom::RendererAudioInputStreamFactory implementation.
+ void CreateStream(
+ mojom::RendererAudioInputStreamFactoryClientPtr client,
+ int32_t session_id,
+ const media::AudioParameters& audio_params,
+ bool automatic_gain_control,
+ uint32_t shared_memory_count,
+ audio::mojom::AudioProcessingConfigPtr processing_config) final;
+
+ void AssociateInputAndOutputForAec(
+ const base::UnguessableToken& input_stream_id,
+ const std::string& output_device_id) final;
+
+ void CreateLoopbackStream(
+ mojom::RendererAudioInputStreamFactoryClientPtr client,
+ const media::AudioParameters& audio_params,
+ uint32_t shared_memory_count,
+ bool disable_local_echo,
+ AudioStreamBroker::LoopbackSource* loopback_source);
+
+ void AssociateInputAndOutputForAecAfterCheckingAccess(
+ const base::UnguessableToken& input_stream_id,
+ const std::string& output_device_id,
+ MediaDeviceSaltAndOrigin salt_and_origin,
+ bool access_granted);
+
+ void AssociateTranslatedOutputDeviceForAec(
+ const base::UnguessableToken& input_stream_id,
+ const std::string& raw_output_device_id);
+
+ MediaStreamManager* const media_stream_manager_;
+ const int process_id_;
+ const int frame_id_;
+ const url::Origin origin_;
+
+ mojo::Binding<RendererAudioInputStreamFactory> binding_;
+ // Always null-check this weak pointer before dereferencing it.
+ base::WeakPtr<ForwardingAudioStreamFactory::Core> forwarding_factory_;
+
+ base::WeakPtrFactory<Core> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(Core);
+};
+
RenderFrameAudioInputStreamFactory::RenderFrameAudioInputStreamFactory(
mojom::RendererAudioInputStreamFactoryRequest request,
- scoped_refptr<AudioInputDeviceManager> audio_input_device_manager,
+ MediaStreamManager* media_stream_manager,
RenderFrameHost* render_frame_host)
- : binding_(this, std::move(request)),
- audio_input_device_manager_(std::move(audio_input_device_manager)),
- render_frame_host_(render_frame_host),
- weak_ptr_factory_(this) {
+ : core_(new Core(std::move(request),
+ media_stream_manager,
+ render_frame_host)) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
RenderFrameAudioInputStreamFactory::~RenderFrameAudioInputStreamFactory() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Ensure |core_| is deleted on the right thread. DeleteOnIOThread isn't used
+ // as it doesn't post in case it is already executed on the right thread. That
+ // causes issues in unit tests where the UI thread and the IO thread are the
+ // same.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce([](std::unique_ptr<Core>) {}, std::move(core_)));
}
-void RenderFrameAudioInputStreamFactory::CreateStream(
- mojom::RendererAudioInputStreamFactoryClientPtr client,
- int32_t session_id,
- const media::AudioParameters& audio_params,
- bool automatic_gain_control,
- uint32_t shared_memory_count,
- audio::mojom::AudioProcessingConfigPtr processing_config) {
+RenderFrameAudioInputStreamFactory::Core::Core(
+ mojom::RendererAudioInputStreamFactoryRequest request,
+ MediaStreamManager* media_stream_manager,
+ RenderFrameHost* render_frame_host)
+ : media_stream_manager_(media_stream_manager),
+ process_id_(render_frame_host->GetProcess()->GetID()),
+ frame_id_(render_frame_host->GetRoutingID()),
+ origin_(render_frame_host->GetLastCommittedOrigin()),
+ binding_(this),
+ weak_ptr_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- TRACE_EVENT_INSTANT1("audio",
- "RenderFrameAudioInputStreamFactory::CreateStream",
- TRACE_EVENT_SCOPE_THREAD, "session id", session_id);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &LookUpDeviceAndRespondIfFound, audio_input_device_manager_,
- session_id,
- base::BindOnce(&RenderFrameAudioInputStreamFactory::
- CreateStreamAfterLookingUpDevice,
- weak_ptr_factory_.GetWeakPtr(), std::move(client),
- audio_params, automatic_gain_control,
- shared_memory_count, std::move(processing_config))));
+ ForwardingAudioStreamFactory::Core* tmp_factory =
+ ForwardingAudioStreamFactory::CoreForFrame(render_frame_host);
+
+ if (!tmp_factory) {
+ // The only case when we not have a forwarding factory at this point is when
+ // the frame belongs to an interstitial. Interstitials don't need audio, so
+ // it's fine to drop the request.
+ return;
+ }
+
+ forwarding_factory_ = tmp_factory->AsWeakPtr();
+
+ // Unretained is safe since the destruction of |this| is posted to the IO
+ // thread.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&Core::Init, base::Unretained(this), std::move(request)));
+}
+
+RenderFrameAudioInputStreamFactory::Core::~Core() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
-void RenderFrameAudioInputStreamFactory::CreateStreamAfterLookingUpDevice(
+void RenderFrameAudioInputStreamFactory::Core::Init(
+ mojom::RendererAudioInputStreamFactoryRequest request) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ binding_.Bind(std::move(request));
+}
+
+void RenderFrameAudioInputStreamFactory::Core::CreateStream(
mojom::RendererAudioInputStreamFactoryClientPtr client,
+ int32_t session_id,
const media::AudioParameters& audio_params,
bool automatic_gain_control,
uint32_t shared_memory_count,
- audio::mojom::AudioProcessingConfigPtr processing_config,
- const MediaStreamDevice& device) {
- TRACE_EVENT1(
- "audio",
- "RenderFrameAudioInputStreamFactory::CreateStreamAfterLookingUpDevice",
- "device id", device.id);
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- ForwardingAudioStreamFactory* factory =
- ForwardingAudioStreamFactory::ForFrame(render_frame_host_);
- if (!factory)
+ audio::mojom::AudioProcessingConfigPtr processing_config) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ TRACE_EVENT1("audio", "RenderFrameAudioInputStreamFactory::CreateStream",
+ "session id", session_id);
+
+ if (!forwarding_factory_)
return;
+ const MediaStreamDevice* device =
+ media_stream_manager_->audio_input_device_manager()->GetOpenedDeviceById(
+ session_id);
+
+ if (!device) {
+ TRACE_EVENT_INSTANT0("audio", "device not found", TRACE_EVENT_SCOPE_THREAD);
+ return;
+ }
+
WebContentsMediaCaptureId capture_id;
- if (WebContentsMediaCaptureId::Parse(device.id, &capture_id)) {
+ if (WebContentsMediaCaptureId::Parse(device->id, &capture_id)) {
// For MEDIA_GUM_DESKTOP_AUDIO_CAPTURE, the source is selected from
// picker window, we do not mute the source audio. For
// MEDIA_GUM_TAB_AUDIO_CAPTURE, the probable use case is Cast, we mute
@@ -135,84 +246,101 @@ void RenderFrameAudioInputStreamFactory::CreateStreamAfterLookingUpDevice(
// TODO(qiangchen): Analyze audio constraints to make a duplicating or
// diverting decision. It would give web developer more flexibility.
- RenderFrameHost* source_host = RenderFrameHost::FromID(
- capture_id.render_process_id, capture_id.main_render_frame_id);
- if (!source_host) {
- // The source of the capture has already been destroyed, so fail early.
- return;
- }
-
- factory->CreateLoopbackStream(
- render_frame_host_, source_host, audio_params, shared_memory_count,
- capture_id.disable_local_echo, std::move(client));
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&GetLoopbackSourceOnUIThread,
+ capture_id.render_process_id,
+ capture_id.main_render_frame_id),
+ base::BindOnce(
+ &RenderFrameAudioInputStreamFactory::Core::CreateLoopbackStream,
+ weak_ptr_factory_.GetWeakPtr(), std::move(client), audio_params,
+ shared_memory_count, capture_id.disable_local_echo));
- if (device.type == MEDIA_GUM_DESKTOP_AUDIO_CAPTURE)
+ if (device->type == MEDIA_GUM_DESKTOP_AUDIO_CAPTURE)
IncrementDesktopCaptureCounter(SYSTEM_LOOPBACK_AUDIO_CAPTURER_CREATED);
+ return;
} else {
- factory->CreateInputStream(render_frame_host_, device.id, audio_params,
- shared_memory_count, automatic_gain_control,
- std::move(processing_config), std::move(client));
+ forwarding_factory_->CreateInputStream(
+ process_id_, frame_id_, device->id, audio_params, shared_memory_count,
+ automatic_gain_control, std::move(processing_config),
+ std::move(client));
// Only count for captures from desktop media picker dialog and system loop
// back audio.
- if (device.type == MEDIA_GUM_DESKTOP_AUDIO_CAPTURE &&
- (media::AudioDeviceDescription::IsLoopbackDevice(device.id))) {
+ if (device->type == MEDIA_GUM_DESKTOP_AUDIO_CAPTURE &&
+ (media::AudioDeviceDescription::IsLoopbackDevice(device->id))) {
IncrementDesktopCaptureCounter(SYSTEM_LOOPBACK_AUDIO_CAPTURER_CREATED);
}
}
}
-void RenderFrameAudioInputStreamFactory::AssociateInputAndOutputForAec(
+void RenderFrameAudioInputStreamFactory::Core::CreateLoopbackStream(
+ mojom::RendererAudioInputStreamFactoryClientPtr client,
+ const media::AudioParameters& audio_params,
+ uint32_t shared_memory_count,
+ bool disable_local_echo,
+ AudioStreamBroker::LoopbackSource* loopback_source) {
+ if (!loopback_source || !forwarding_factory_)
+ return;
+
+ forwarding_factory_->CreateLoopbackStream(
+ process_id_, frame_id_, loopback_source, audio_params,
+ shared_memory_count, disable_local_echo, std::move(client));
+}
+
+void RenderFrameAudioInputStreamFactory::Core::AssociateInputAndOutputForAec(
const base::UnguessableToken& input_stream_id,
const std::string& output_device_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!IsValidDeviceId(output_device_id))
return;
- ForwardingAudioStreamFactory* factory =
- ForwardingAudioStreamFactory::ForFrame(render_frame_host_);
- if (!factory)
- return;
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(
+ &GetSaltOriginAndPermissionsOnUIThread, process_id_, frame_id_,
+ base::BindOnce(
+ &Core::AssociateInputAndOutputForAecAfterCheckingAccess,
+ weak_ptr_factory_.GetWeakPtr(), input_stream_id,
+ output_device_id)));
+}
- const int process_id = render_frame_host_->GetProcess()->GetID();
- const int frame_id = render_frame_host_->GetRoutingID();
- auto salt_and_origin = GetMediaDeviceSaltAndOrigin(process_id, frame_id);
+void RenderFrameAudioInputStreamFactory::Core::
+ AssociateInputAndOutputForAecAfterCheckingAccess(
+ const base::UnguessableToken& input_stream_id,
+ const std::string& output_device_id,
+ MediaDeviceSaltAndOrigin salt_and_origin,
+ bool access_granted) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // Check permissions for everything but the default device
- if (!media::AudioDeviceDescription::IsDefaultDevice(output_device_id) &&
- !MediaDevicesPermissionChecker().CheckPermissionOnUIThread(
- MEDIA_DEVICE_TYPE_AUDIO_OUTPUT, process_id, frame_id)) {
+ if (!forwarding_factory_ || !access_granted)
return;
- }
if (media::AudioDeviceDescription::IsDefaultDevice(output_device_id) ||
media::AudioDeviceDescription::IsCommunicationsDevice(output_device_id)) {
- factory->AssociateInputAndOutputForAec(input_stream_id, output_device_id);
+ forwarding_factory_->AssociateInputAndOutputForAec(input_stream_id,
+ output_device_id);
} else {
- auto* media_stream_manager =
- BrowserMainLoop::GetInstance()->media_stream_manager();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- EnumerateOutputDevices, media_stream_manager,
- base::BindRepeating(
- &TranslateDeviceId, output_device_id, salt_and_origin,
- base::BindRepeating(&RenderFrameAudioInputStreamFactory::
- AssociateTranslatedOutputDeviceForAec,
- weak_ptr_factory_.GetWeakPtr(),
- input_stream_id))));
+ EnumerateOutputDevices(
+ media_stream_manager_,
+ base::BindRepeating(
+ &TranslateDeviceId, output_device_id, salt_and_origin,
+ base::BindRepeating(&RenderFrameAudioInputStreamFactory::Core::
+ AssociateTranslatedOutputDeviceForAec,
+ weak_ptr_factory_.GetWeakPtr(),
+ input_stream_id)));
}
}
-void RenderFrameAudioInputStreamFactory::AssociateTranslatedOutputDeviceForAec(
- const base::UnguessableToken& input_stream_id,
- const std::string& raw_output_device_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- ForwardingAudioStreamFactory* factory =
- ForwardingAudioStreamFactory::ForFrame(render_frame_host_);
- if (factory)
- factory->AssociateInputAndOutputForAec(input_stream_id,
- raw_output_device_id);
+void RenderFrameAudioInputStreamFactory::Core::
+ AssociateTranslatedOutputDeviceForAec(
+ const base::UnguessableToken& input_stream_id,
+ const std::string& raw_output_device_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (!forwarding_factory_)
+ return;
+ forwarding_factory_->AssociateInputAndOutputForAec(input_stream_id,
+ raw_output_device_id);
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h
index 49ec1176c36..ceafa6ae239 100644
--- a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h
+++ b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h
@@ -5,72 +5,34 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_RENDER_FRAME_AUDIO_INPUT_STREAM_FACTORY_H_
-#include <cstdint>
-#include <string>
+#include <memory>
#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/common/content_export.h"
#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/common/media_stream_request.h"
-#include "mojo/public/cpp/bindings/binding.h"
-
-namespace media {
-class AudioParameters;
-} // namespace media
namespace content {
-class AudioInputDeviceManager;
+class MediaStreamManager;
class RenderFrameHost;
-// Handles a RendererAudioInputStreamFactory request for a render frame host,
-// using the provided RendererAudioInputStreamFactoryContext. This class may
-// be constructed on any thread, but must be used on the IO thread after that,
-// and also destructed on the IO thread.
-class CONTENT_EXPORT RenderFrameAudioInputStreamFactory
- : public mojom::RendererAudioInputStreamFactory {
+// Handles a RendererAudioInputStreamFactory request for a render frame host.
+// Should be constructed and destructed on the UI thread, but will process mojo
+// messages on the IO thread. This class relates to ForwardingAudioStreamFactory
+// the same way as RenderFrameAudioOutputStreamFactory, and a class diagram can
+// be found in render_frame_audio_output_stream_factory.h
+class CONTENT_EXPORT RenderFrameAudioInputStreamFactory final {
public:
RenderFrameAudioInputStreamFactory(
mojom::RendererAudioInputStreamFactoryRequest request,
- scoped_refptr<AudioInputDeviceManager> audio_input_device_manager,
+ MediaStreamManager* media_stream_manager,
RenderFrameHost* render_frame_host);
- ~RenderFrameAudioInputStreamFactory() override;
+ ~RenderFrameAudioInputStreamFactory();
private:
- // mojom::RendererAudioInputStreamFactory implementation.
- void CreateStream(
- mojom::RendererAudioInputStreamFactoryClientPtr client,
- int32_t session_id,
- const media::AudioParameters& audio_params,
- bool automatic_gain_control,
- uint32_t shared_memory_count,
- audio::mojom::AudioProcessingConfigPtr processing_config) override;
-
- void CreateStreamAfterLookingUpDevice(
- mojom::RendererAudioInputStreamFactoryClientPtr client,
- const media::AudioParameters& audio_params,
- bool automatic_gain_control,
- uint32_t shared_memory_count,
- audio::mojom::AudioProcessingConfigPtr processing_config,
- const MediaStreamDevice& device);
-
- void AssociateInputAndOutputForAec(
- const base::UnguessableToken& input_stream_id,
- const std::string& output_device_id) override;
-
- void AssociateTranslatedOutputDeviceForAec(
- const base::UnguessableToken& input_stream_id,
- const std::string& raw_output_device_id);
-
- const mojo::Binding<RendererAudioInputStreamFactory> binding_;
- const scoped_refptr<AudioInputDeviceManager> audio_input_device_manager_;
- RenderFrameHost* const render_frame_host_;
-
- base::WeakPtrFactory<RenderFrameAudioInputStreamFactory> weak_ptr_factory_;
+ class Core;
+ std::unique_ptr<Core> core_;
DISALLOW_COPY_AND_ASSIGN(RenderFrameAudioInputStreamFactory);
};
diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc
index a5ae3806e45..f2cb24bbc4b 100644
--- a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc
@@ -4,7 +4,6 @@
#include "content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h"
-#include <memory>
#include <string>
#include <utility>
@@ -12,8 +11,11 @@
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "content/browser/media/forwarding_audio_stream_factory.h"
+#include "content/browser/renderer_host/media/audio_input_device_manager.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@@ -52,7 +54,8 @@ class RenderFrameAudioInputStreamFactoryTest
audio_system_(media::AudioSystemImpl::CreateInstance()),
media_stream_manager_(std::make_unique<MediaStreamManager>(
audio_system_.get(),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))) {}
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {BrowserThread::UI}))) {}
~RenderFrameAudioInputStreamFactoryTest() override {}
@@ -63,6 +66,7 @@ class RenderFrameAudioInputStreamFactoryTest
// Set up the ForwardingAudioStreamFactory.
service_manager::Connector::TestApi connector_test_api(
ForwardingAudioStreamFactory::ForFrame(main_rfh())
+ ->core()
->get_connector_for_testing());
connector_test_api.OverrideBinderForTesting(
service_manager::Identity(audio::mojom::kServiceName),
@@ -180,17 +184,15 @@ class RenderFrameAudioInputStreamFactoryTest
TEST_F(RenderFrameAudioInputStreamFactoryTest, ConstructDestruct) {
mojom::RendererAudioInputStreamFactoryPtr factory_ptr;
- RenderFrameAudioInputStreamFactory factory(mojo::MakeRequest(&factory_ptr),
- audio_input_device_manager(),
- main_rfh());
+ RenderFrameAudioInputStreamFactory factory(
+ mojo::MakeRequest(&factory_ptr), media_stream_manager_.get(), main_rfh());
}
TEST_F(RenderFrameAudioInputStreamFactoryTest,
CreateOpenedStream_ForwardsCall) {
mojom::RendererAudioInputStreamFactoryPtr factory_ptr;
- RenderFrameAudioInputStreamFactory factory(mojo::MakeRequest(&factory_ptr),
- audio_input_device_manager(),
- main_rfh());
+ RenderFrameAudioInputStreamFactory factory(
+ mojo::MakeRequest(&factory_ptr), media_stream_manager_.get(), main_rfh());
int session_id = audio_input_device_manager()->Open(
MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, kDeviceId, kDeviceName));
@@ -210,9 +212,8 @@ TEST_F(RenderFrameAudioInputStreamFactoryTest,
CreateWebContentsCapture_ForwardsCall) {
std::unique_ptr<WebContents> source_contents = CreateTestWebContents();
mojom::RendererAudioInputStreamFactoryPtr factory_ptr;
- RenderFrameAudioInputStreamFactory factory(mojo::MakeRequest(&factory_ptr),
- audio_input_device_manager(),
- main_rfh());
+ RenderFrameAudioInputStreamFactory factory(
+ mojo::MakeRequest(&factory_ptr), media_stream_manager_.get(), main_rfh());
RenderFrameHost* main_frame = source_contents->GetMainFrame();
WebContentsMediaCaptureId capture_id(main_frame->GetProcess()->GetID(),
@@ -235,9 +236,8 @@ TEST_F(RenderFrameAudioInputStreamFactoryTest,
CreateWebContentsCaptureAfterCaptureSourceDestructed_Fails) {
std::unique_ptr<WebContents> source_contents = CreateTestWebContents();
mojom::RendererAudioInputStreamFactoryPtr factory_ptr;
- RenderFrameAudioInputStreamFactory factory(mojo::MakeRequest(&factory_ptr),
- audio_input_device_manager(),
- main_rfh());
+ RenderFrameAudioInputStreamFactory factory(
+ mojo::MakeRequest(&factory_ptr), media_stream_manager_.get(), main_rfh());
RenderFrameHost* main_frame = source_contents->GetMainFrame();
WebContentsMediaCaptureId capture_id(main_frame->GetProcess()->GetID(),
@@ -260,9 +260,8 @@ TEST_F(RenderFrameAudioInputStreamFactoryTest,
TEST_F(RenderFrameAudioInputStreamFactoryTest,
CreateStreamWithoutValidSessionId_Fails) {
mojom::RendererAudioInputStreamFactoryPtr factory_ptr;
- RenderFrameAudioInputStreamFactory factory(mojo::MakeRequest(&factory_ptr),
- audio_input_device_manager(),
- main_rfh());
+ RenderFrameAudioInputStreamFactory factory(
+ mojo::MakeRequest(&factory_ptr), media_stream_manager_.get(), main_rfh());
int session_id = 123;
mojom::RendererAudioInputStreamFactoryClientPtr client;
diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc b/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc
index dadd1cdd502..a1c650a3a30 100644
--- a/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc
+++ b/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.cc
@@ -4,71 +4,146 @@
#include "content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h"
+#include <cstdint>
+#include <string>
#include <utility>
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/containers/flat_set.h"
+#include "base/containers/unique_ptr_adapters.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "base/task/post_task.h"
+#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
+#include "base/unguessable_token.h"
#include "content/browser/media/forwarding_audio_stream_factory.h"
#include "content/browser/renderer_host/media/audio_output_authorization_handler.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
-#include "media/base/bind_to_current_loop.h"
+#include "media/base/output_device_info.h"
+#include "media/mojo/interfaces/audio_output_stream.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
namespace content {
-// This class implements media::mojom::AudioOutputStreamProvider for a single
-// streams and cleans itself up (using the |owner| pointer) when done.
-class RenderFrameAudioOutputStreamFactory::ProviderImpl final
- : public media::mojom::AudioOutputStreamProvider {
+class RenderFrameAudioOutputStreamFactory::Core final
+ : public mojom::RendererAudioOutputStreamFactory {
public:
- ProviderImpl(media::mojom::AudioOutputStreamProviderRequest request,
- RenderFrameAudioOutputStreamFactory* owner,
- const std::string& device_id)
- : owner_(owner),
- device_id_(device_id),
- binding_(this, std::move(request)) {
- DCHECK(owner_);
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // Unretained is safe since |this| owns |binding_|.
- binding_.set_connection_error_handler(
- base::BindOnce(&ProviderImpl::Done, base::Unretained(this)));
+ Core(RenderFrameHost* frame,
+ media::AudioSystem* audio_system,
+ MediaStreamManager* media_stream_manager,
+ mojom::RendererAudioOutputStreamFactoryRequest request);
+
+ ~Core() final = default;
+
+ void Init(mojom::RendererAudioOutputStreamFactoryRequest request);
+
+ size_t current_number_of_providers_for_testing() {
+ return stream_providers_.size();
}
- ~ProviderImpl() final { DCHECK_CURRENTLY_ON(BrowserThread::UI); }
+ private:
+ // This class implements media::mojom::AudioOutputStreamProvider for a single
+ // streams and cleans itself up (using the |owner| pointer) when done.
+ class ProviderImpl final : public media::mojom::AudioOutputStreamProvider {
+ public:
+ ProviderImpl(media::mojom::AudioOutputStreamProviderRequest request,
+ RenderFrameAudioOutputStreamFactory::Core* owner,
+ const std::string& device_id)
+ : owner_(owner),
+ device_id_(device_id),
+ binding_(this, std::move(request)) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // Unretained is safe since |this| owns |binding_|.
+ binding_.set_connection_error_handler(
+ base::BindOnce(&ProviderImpl::Done, base::Unretained(this)));
+ }
- void Acquire(
- const media::AudioParameters& params,
- media::mojom::AudioOutputStreamProviderClientPtr provider_client,
- const base::Optional<base::UnguessableToken>& processing_id) final {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- TRACE_EVENT1("audio",
- "RenderFrameAudioOutputStreamFactory::ProviderImpl::Acquire",
- "raw device id", device_id_);
-
- RenderFrameHost* frame = owner_->frame_;
- ForwardingAudioStreamFactory* factory =
- ForwardingAudioStreamFactory::ForFrame(frame);
- if (factory) {
- // It's possible that |frame| has already been destroyed, in which case we
- // don't need to create a stream. In this case, the renderer will get a
- // connection error since |provider_client| is dropped.
- factory->CreateOutputStream(frame, device_id_, params, processing_id,
- std::move(provider_client));
+ ~ProviderImpl() final { DCHECK_CURRENTLY_ON(BrowserThread::IO); }
+
+ void Acquire(
+ const media::AudioParameters& params,
+ media::mojom::AudioOutputStreamProviderClientPtr provider_client,
+ const base::Optional<base::UnguessableToken>& processing_id) final {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ TRACE_EVENT1("audio",
+ "RenderFrameAudioOutputStreamFactory::ProviderImpl::Acquire",
+ "raw device id", device_id_);
+
+ base::WeakPtr<ForwardingAudioStreamFactory::Core> factory =
+ owner_->forwarding_factory_;
+ if (factory) {
+ factory->CreateOutputStream(owner_->process_id_, owner_->frame_id_,
+ device_id_, params, processing_id,
+ std::move(provider_client));
+ }
+
+ // Since the stream creation has been propagated, |this| is no longer
+ // needed.
+ Done();
}
- // Since the stream creation has been propagated, |this| is no longer
- // needed.
- Done();
- }
+ void Done() { owner_->DeleteProvider(this); }
- void Done() { owner_->DeleteProvider(this); }
+ private:
+ RenderFrameAudioOutputStreamFactory::Core* const owner_;
+ const std::string device_id_;
- private:
- RenderFrameAudioOutputStreamFactory* const owner_;
- const std::string device_id_;
+ mojo::Binding<media::mojom::AudioOutputStreamProvider> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProviderImpl);
+ };
- mojo::Binding<media::mojom::AudioOutputStreamProvider> binding_;
+ using OutputStreamProviderSet =
+ base::flat_set<std::unique_ptr<media::mojom::AudioOutputStreamProvider>,
+ base::UniquePtrComparator>;
- DISALLOW_COPY_AND_ASSIGN(ProviderImpl);
+ // mojom::RendererAudioOutputStreamFactory implementation.
+ void RequestDeviceAuthorization(
+ media::mojom::AudioOutputStreamProviderRequest provider_request,
+ int32_t session_id,
+ const std::string& device_id,
+ RequestDeviceAuthorizationCallback callback) final;
+
+ // Here, the |raw_device_id| is used to create the stream, and
+ // |device_id_for_renderer| is nonempty in the case when the renderer
+ // requested a device using a |session_id|, to let it know which device was
+ // chosen. This id is hashed.
+ void AuthorizationCompleted(
+ base::TimeTicks auth_start_time,
+ media::mojom::AudioOutputStreamProviderRequest request,
+ RequestDeviceAuthorizationCallback callback,
+ media::OutputDeviceStatus status,
+ const media::AudioParameters& params,
+ const std::string& raw_device_id,
+ const std::string& device_id_for_renderer);
+
+ void DeleteProvider(media::mojom::AudioOutputStreamProvider* stream_provider);
+
+ const int process_id_;
+ const int frame_id_;
+ AudioOutputAuthorizationHandler authorization_handler_;
+
+ mojo::Binding<mojom::RendererAudioOutputStreamFactory> binding_;
+ // Always null-check this weak pointer before dereferencing it.
+ base::WeakPtr<ForwardingAudioStreamFactory::Core> forwarding_factory_;
+
+ // The OutputStreamProviders for authorized streams are kept here while
+ // waiting for the renderer to finish creating the stream, and destructed
+ // afterwards.
+ OutputStreamProviderSet stream_providers_;
+
+ // Weak pointers are used to cancel device authorizations that are in flight
+ // while |this| is destructed.
+ base::WeakPtrFactory<Core> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(Core);
};
RenderFrameAudioOutputStreamFactory::RenderFrameAudioOutputStreamFactory(
@@ -76,53 +151,92 @@ RenderFrameAudioOutputStreamFactory::RenderFrameAudioOutputStreamFactory(
media::AudioSystem* audio_system,
MediaStreamManager* media_stream_manager,
mojom::RendererAudioOutputStreamFactoryRequest request)
- : binding_(this, std::move(request)),
- frame_(frame),
- authorization_handler_(
- new AudioOutputAuthorizationHandler(audio_system,
- media_stream_manager,
- frame_->GetProcess()->GetID())),
- weak_ptr_factory_(this) {
+ : core_(new Core(frame,
+ audio_system,
+ media_stream_manager,
+ std::move(request))) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
RenderFrameAudioOutputStreamFactory::~RenderFrameAudioOutputStreamFactory() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // Ensure |core_| is deleted on the right thread. DeleteOnIOThread isn't used
+ // as it doesn't post in case it is already executed on the right thread. That
+ // causes issues in unit tests where the UI thread and the IO thread are the
+ // same.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce([](std::unique_ptr<Core>) {}, std::move(core_)));
+}
+
+size_t
+RenderFrameAudioOutputStreamFactory::CurrentNumberOfProvidersForTesting() {
+ return core_->current_number_of_providers_for_testing();
+}
+
+RenderFrameAudioOutputStreamFactory::Core::Core(
+ RenderFrameHost* frame,
+ media::AudioSystem* audio_system,
+ MediaStreamManager* media_stream_manager,
+ mojom::RendererAudioOutputStreamFactoryRequest request)
+ : process_id_(frame->GetProcess()->GetID()),
+ frame_id_(frame->GetRoutingID()),
+ authorization_handler_(audio_system, media_stream_manager, process_id_),
+ binding_(this),
+ weak_ptr_factory_(this) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ ForwardingAudioStreamFactory::Core* tmp_factory =
+ ForwardingAudioStreamFactory::CoreForFrame(frame);
+
+ if (!tmp_factory) {
+ // The only case when we not have a forwarding factory at this point is when
+ // the frame belongs to an interstitial. Interstitials don't need audio, so
+ // it's fine to drop the request.
+ return;
+ }
+
+ forwarding_factory_ = tmp_factory->AsWeakPtr();
+
+ // Unretained is safe since the destruction of |this| is posted to the IO
+ // thread.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&Core::Init, base::Unretained(this), std::move(request)));
+}
+
+void RenderFrameAudioOutputStreamFactory::Core::Init(
+ mojom::RendererAudioOutputStreamFactoryRequest request) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ binding_.Bind(std::move(request));
}
-void RenderFrameAudioOutputStreamFactory::RequestDeviceAuthorization(
+void RenderFrameAudioOutputStreamFactory::Core::RequestDeviceAuthorization(
media::mojom::AudioOutputStreamProviderRequest provider_request,
int32_t session_id,
const std::string& device_id,
RequestDeviceAuthorizationCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
TRACE_EVENT2(
"audio",
"RenderFrameAudioOutputStreamFactory::RequestDeviceAuthorization",
"device id", device_id, "session_id", session_id);
const base::TimeTicks auth_start_time = base::TimeTicks::Now();
- // TODO(https://crbug.com/837625): This thread hopping is suboptimal since
- // AudioOutputAuthorizationHandler was made to be used on the IO thread.
- // Make AudioOutputAuthorizationHandler work on the UI thread instead.
+
AudioOutputAuthorizationHandler::AuthorizationCompletedCallback
- completed_callback = media::BindToCurrentLoop(base::BindOnce(
- &RenderFrameAudioOutputStreamFactory::AuthorizationCompleted,
+ completed_callback = base::BindOnce(
+ &RenderFrameAudioOutputStreamFactory::Core::AuthorizationCompleted,
weak_ptr_factory_.GetWeakPtr(), auth_start_time,
- std::move(provider_request), std::move(callback)));
+ std::move(provider_request), std::move(callback));
- // Unretained is safe since |authorization_handler_| is deleted on the IO
- // thread.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &AudioOutputAuthorizationHandler::RequestDeviceAuthorization,
- base::Unretained(authorization_handler_.get()),
- frame_->GetRoutingID(), session_id, device_id,
- std::move(completed_callback)));
+ authorization_handler_.RequestDeviceAuthorization(
+ frame_id_, session_id, device_id, std::move(completed_callback));
}
-void RenderFrameAudioOutputStreamFactory::AuthorizationCompleted(
+void RenderFrameAudioOutputStreamFactory::Core::AuthorizationCompleted(
base::TimeTicks auth_start_time,
media::mojom::AudioOutputStreamProviderRequest request,
RequestDeviceAuthorizationCallback callback,
@@ -130,7 +244,7 @@ void RenderFrameAudioOutputStreamFactory::AuthorizationCompleted(
const media::AudioParameters& params,
const std::string& raw_device_id,
const std::string& device_id_for_renderer) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
TRACE_EVENT2("audio",
"RenderFrameAudioOutputStreamFactory::AuthorizationCompleted",
"raw device id", raw_device_id, "status", status);
@@ -148,9 +262,9 @@ void RenderFrameAudioOutputStreamFactory::AuthorizationCompleted(
}
}
-void RenderFrameAudioOutputStreamFactory::DeleteProvider(
+void RenderFrameAudioOutputStreamFactory::Core::DeleteProvider(
media::mojom::AudioOutputStreamProvider* stream_provider) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
size_t deleted = stream_providers_.erase(stream_provider);
DCHECK_EQ(1u, deleted);
}
diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h b/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h
index fbc229bdd8b..50362670e66 100644
--- a/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h
+++ b/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h
@@ -5,36 +5,41 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_RENDER_FRAME_AUDIO_OUTPUT_STREAM_FACTORY_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_RENDER_FRAME_AUDIO_OUTPUT_STREAM_FACTORY_H_
+#include <cstddef>
#include <memory>
-#include <string>
-#include "base/containers/flat_set.h"
-#include "base/containers/unique_ptr_adapters.h"
#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
#include "content/common/content_export.h"
#include "content/common/media/renderer_audio_output_stream_factory.mojom.h"
-#include "content/public/browser/browser_thread.h"
-#include "media/base/output_device_info.h"
-#include "mojo/public/cpp/bindings/binding.h"
namespace media {
class AudioSystem;
-class AudioParameters;
} // namespace media
namespace content {
-class AudioOutputAuthorizationHandler;
class MediaStreamManager;
class RenderFrameHost;
-// This class, which lives on the UI thread, takes care of stream requests from
-// a render frame. It verifies that the stream creation is allowed and then
-// forwards the request to the appropriate ForwardingAudioStreamFactory.
-class CONTENT_EXPORT RenderFrameAudioOutputStreamFactory
- : public mojom::RendererAudioOutputStreamFactory {
+// This class is related to ForwardingAudioStreamFactory as follows:
+//
+// WebContentsImpl <-- RenderFrameHostImpl
+// ^ ^
+// | |
+// ForwardingAudioStreamFactory RenderFrameAudioOutputStreamFactory
+// ^ ^
+// | |
+// FASF::Core <-- RFAOSF::Core
+//
+// Both FASF::Core and RFAOSF::Core live on (and are destructed on) the IO
+// thread. A weak pointer to ForwardingAudioStreamFactory is used since
+// WebContentsImpl is sometimes destructed shortly before RenderFrameHostImpl.
+
+// This class takes care of stream requests from a render frame. It verifies
+// that the stream creation is allowed and then forwards the request to the
+// appropriate ForwardingAudioStreamFactory. It should be constructed and
+// destructed on the UI thread, but will process mojo messages on the IO thread.
+class CONTENT_EXPORT RenderFrameAudioOutputStreamFactory final {
public:
RenderFrameAudioOutputStreamFactory(
RenderFrameHost* frame,
@@ -42,56 +47,13 @@ class CONTENT_EXPORT RenderFrameAudioOutputStreamFactory
MediaStreamManager* media_stream_manager,
mojom::RendererAudioOutputStreamFactoryRequest request);
- ~RenderFrameAudioOutputStreamFactory() override;
+ ~RenderFrameAudioOutputStreamFactory();
- size_t current_number_of_providers_for_testing() {
- return stream_providers_.size();
- }
+ size_t CurrentNumberOfProvidersForTesting();
private:
- class ProviderImpl;
- friend class ProviderImpl; // For DeleteProvider.
-
- using OutputStreamProviderSet =
- base::flat_set<std::unique_ptr<media::mojom::AudioOutputStreamProvider>,
- base::UniquePtrComparator>;
-
- // mojom::RendererAudioOutputStreamFactory implementation.
- void RequestDeviceAuthorization(
- media::mojom::AudioOutputStreamProviderRequest provider_request,
- int32_t session_id,
- const std::string& device_id,
- RequestDeviceAuthorizationCallback callback) override;
-
- // Here, the |raw_device_id| is used to create the stream, and
- // |device_id_for_renderer| is nonempty in the case when the renderer
- // requested a device using a |session_id|, to let it know which device was
- // chosen. This id is hashed.
- void AuthorizationCompleted(
- base::TimeTicks auth_start_time,
- media::mojom::AudioOutputStreamProviderRequest request,
- RequestDeviceAuthorizationCallback callback,
- media::OutputDeviceStatus status,
- const media::AudioParameters& params,
- const std::string& raw_device_id,
- const std::string& device_id_for_renderer);
-
- void DeleteProvider(media::mojom::AudioOutputStreamProvider* stream_provider);
-
- const mojo::Binding<mojom::RendererAudioOutputStreamFactory> binding_;
- RenderFrameHost* const frame_;
- const std::unique_ptr<AudioOutputAuthorizationHandler,
- BrowserThread::DeleteOnIOThread>
- authorization_handler_;
-
- // The OutputStreamProviders for authorized streams are kept here while
- // waiting for the renderer to finish creating the stream, and destructed
- // afterwards.
- OutputStreamProviderSet stream_providers_;
-
- // Weak pointers are used to cancel device authorizations that are in flight
- // while |this| is destructed.
- base::WeakPtrFactory<RenderFrameAudioOutputStreamFactory> weak_ptr_factory_;
+ class Core;
+ std::unique_ptr<Core> core_;
DISALLOW_COPY_AND_ASSIGN(RenderFrameAudioOutputStreamFactory);
};
diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc b/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
index ed17a87080b..f7f4fc6015a 100644
--- a/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/render_frame_audio_output_stream_factory_unittest.cc
@@ -5,17 +5,20 @@
#include "content/browser/renderer_host/media/render_frame_audio_output_stream_factory.h"
#include <memory>
+#include <string>
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "base/unguessable_token.h"
#include "content/browser/media/forwarding_audio_stream_factory.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/test/mock_render_process_host.h"
@@ -55,7 +58,8 @@ class RenderFrameAudioOutputStreamFactoryTest
audio_system_(media::AudioSystemImpl::CreateInstance()),
media_stream_manager_(std::make_unique<MediaStreamManager>(
audio_system_.get(),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))) {}
+ base::CreateSingleThreadTaskRunnerWithTraits(
+ {BrowserThread::UI}))) {}
~RenderFrameAudioOutputStreamFactoryTest() override {}
@@ -66,6 +70,7 @@ class RenderFrameAudioOutputStreamFactoryTest
// Set up the ForwardingAudioStreamFactory.
service_manager::Connector::TestApi connector_test_api(
ForwardingAudioStreamFactory::ForFrame(main_rfh())
+ ->core()
->get_connector_for_testing());
connector_test_api.OverrideBinderForTesting(
service_manager::Identity(audio::mojom::kServiceName),
@@ -152,7 +157,7 @@ TEST_F(RenderFrameAudioOutputStreamFactoryTest,
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1u, factory.current_number_of_providers_for_testing());
+ EXPECT_EQ(1u, factory.CurrentNumberOfProvidersForTesting());
}
TEST_F(
@@ -175,7 +180,7 @@ TEST_F(
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0u, factory.current_number_of_providers_for_testing());
+ EXPECT_EQ(0u, factory.CurrentNumberOfProvidersForTesting());
}
TEST_F(
@@ -197,7 +202,7 @@ TEST_F(
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(0u, factory.current_number_of_providers_for_testing());
+ EXPECT_EQ(0u, factory.CurrentNumberOfProvidersForTesting());
}
TEST_F(RenderFrameAudioOutputStreamFactoryTest,
@@ -225,7 +230,7 @@ TEST_F(RenderFrameAudioOutputStreamFactoryTest,
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(!!audio_service_stream_factory_.last_created_callback);
- EXPECT_EQ(0u, factory.current_number_of_providers_for_testing());
+ EXPECT_EQ(0u, factory.CurrentNumberOfProvidersForTesting());
}
TEST_F(RenderFrameAudioOutputStreamFactoryTest,
diff --git a/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher.cc b/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher.cc
index 07e01aaabe7..fbba2356d02 100644
--- a/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher.cc
+++ b/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher.cc
@@ -4,7 +4,9 @@
#include "content/browser/renderer_host/media/service_video_capture_device_launcher.h"
+#include "base/task/post_task.h"
#include "content/browser/renderer_host/media/service_launched_video_capture_device.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "media/capture/video/video_frame_receiver_on_task_runner.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
@@ -24,8 +26,8 @@ void ConcludeLaunchDeviceWithSuccess(
auto receiver_adapter =
std::make_unique<video_capture::ReceiverMediaToMojoAdapter>(
std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
- std::move(receiver),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)));
+ std::move(receiver), base::CreateSingleThreadTaskRunnerWithTraits(
+ {BrowserThread::IO})));
video_capture::mojom::ReceiverPtr receiver_proxy;
mojo::MakeStrongBinding<video_capture::mojom::Receiver>(
std::move(receiver_adapter), mojo::MakeRequest(&receiver_proxy));
diff --git a/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc b/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc
index 37c732611ce..74859ea5f35 100644
--- a/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc
@@ -6,12 +6,12 @@
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
-#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "content/browser/renderer_host/media/service_launched_video_capture_device.h"
#include "content/browser/renderer_host/media/video_capture_factory_delegate.h"
+#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "services/video_capture/public/mojom/device_factory.mojom.h"
+#include "services/video_capture/public/cpp/mock_device_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -25,45 +25,6 @@ static const std::string kStubDeviceId = "StubDevice";
static const media::VideoCaptureParams kArbitraryParams;
static const base::WeakPtr<media::VideoFrameReceiver> kNullReceiver;
-class MockDeviceFactory : public video_capture::mojom::DeviceFactory {
- public:
- void CreateDevice(const std::string& device_id,
- video_capture::mojom::DeviceRequest device_request,
- CreateDeviceCallback callback) override {
- DoCreateDevice(device_id, &device_request, callback);
- }
-
- void GetDeviceInfos(GetDeviceInfosCallback callback) override {
- DoGetDeviceInfos(callback);
- }
-
- void AddSharedMemoryVirtualDevice(
- const media::VideoCaptureDeviceInfo& device_info,
- video_capture::mojom::ProducerPtr producer,
- bool send_buffer_handles_to_producer_as_raw_file_descriptors,
- video_capture::mojom::SharedMemoryVirtualDeviceRequest virtual_device)
- override {
- DoAddVirtualDevice(device_info, producer.get(), &virtual_device);
- }
-
- void AddTextureVirtualDevice(const media::VideoCaptureDeviceInfo& device_info,
- video_capture::mojom::TextureVirtualDeviceRequest
- virtual_device) override {
- NOTIMPLEMENTED();
- }
-
- MOCK_METHOD1(DoGetDeviceInfos, void(GetDeviceInfosCallback& callback));
- MOCK_METHOD3(DoCreateDevice,
- void(const std::string& device_id,
- video_capture::mojom::DeviceRequest* device_request,
- CreateDeviceCallback& callback));
- MOCK_METHOD3(DoAddVirtualDevice,
- void(const media::VideoCaptureDeviceInfo& device_info,
- video_capture::mojom::ProducerProxy* producer,
- video_capture::mojom::SharedMemoryVirtualDeviceRequest*
- virtual_device_request));
-};
-
class MockVideoCaptureDeviceLauncherCallbacks
: public VideoCaptureDeviceLauncher::Callbacks {
public:
@@ -113,8 +74,8 @@ class ServiceVideoCaptureDeviceLauncherTest : public testing::Test {
void RunLaunchingDeviceIsAbortedTest(
video_capture::mojom::DeviceAccessResultCode service_result_code);
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- MockDeviceFactory mock_device_factory_;
+ TestBrowserThreadBundle thread_bundle_;
+ video_capture::MockDeviceFactory mock_device_factory_;
MockVideoCaptureDeviceLauncherCallbacks mock_callbacks_;
video_capture::mojom::DeviceFactoryPtr device_factory_;
std::unique_ptr<mojo::Binding<video_capture::mojom::DeviceFactory>>
diff --git a/chromium/content/browser/renderer_host/media/service_video_capture_provider.cc b/chromium/content/browser/renderer_host/media/service_video_capture_provider.cc
index 34445f23d22..f3cf7f94cd3 100644
--- a/chromium/content/browser/renderer_host/media/service_video_capture_provider.cc
+++ b/chromium/content/browser/renderer_host/media/service_video_capture_provider.cc
@@ -5,10 +5,10 @@
#include "content/browser/renderer_host/media/service_video_capture_provider.h"
#include "content/browser/renderer_host/media/service_video_capture_device_launcher.h"
-#include "content/browser/renderer_host/media/video_capture_dependencies.h"
#include "content/browser/renderer_host/media/video_capture_factory_delegate.h"
#include "content/common/child_process_host_impl.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/delegate_to_browser_gpu_service_accelerator_factory.h"
#include "content/public/common/service_manager_connection.h"
#include "mojo/public/cpp/bindings/callback_helpers.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
@@ -47,19 +47,10 @@ class ServiceConnectorImpl
std::unique_ptr<service_manager::Connector> connector_;
};
-class DelegateToBrowserGpuServiceAcceleratorFactory
- : public video_capture::mojom::AcceleratorFactory {
- public:
- void CreateJpegDecodeAccelerator(
- media::mojom::JpegDecodeAcceleratorRequest jda_request) override {
- content::VideoCaptureDependencies::CreateJpegDecodeAccelerator(
- std::move(jda_request));
- }
-};
-
std::unique_ptr<video_capture::mojom::AcceleratorFactory>
CreateAcceleratorFactory() {
- return std::make_unique<DelegateToBrowserGpuServiceAcceleratorFactory>();
+ return std::make_unique<
+ content::DelegateToBrowserGpuServiceAcceleratorFactory>();
}
} // anonymous namespace
diff --git a/chromium/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc b/chromium/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc
index 0b5aecf53b7..966647be2ab 100644
--- a/chromium/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc
@@ -10,8 +10,8 @@
#include "content/public/browser/video_capture_device_launcher.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "services/video_capture/public/mojom/device_factory.mojom.h"
-#include "services/video_capture/public/mojom/device_factory_provider.mojom.h"
+#include "services/video_capture/public/cpp/mock_device_factory.h"
+#include "services/video_capture/public/cpp/mock_device_factory_provider.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -36,63 +36,6 @@ class MockServiceConnector
void(video_capture::mojom::DeviceFactoryProviderPtr* provider));
};
-class MockDeviceFactoryProvider
- : public video_capture::mojom::DeviceFactoryProvider {
- public:
- void ConnectToDeviceFactory(
- video_capture::mojom::DeviceFactoryRequest request) override {
- DoConnectToDeviceFactory(request);
- }
-
- void InjectGpuDependencies(video_capture::mojom::AcceleratorFactoryPtr
- accelerator_factory) override {
- DoInjectGpuDependencies(accelerator_factory);
- }
-
- MOCK_METHOD1(
- DoInjectGpuDependencies,
- void(video_capture::mojom::AcceleratorFactoryPtr& accelerator_factory));
- MOCK_METHOD1(SetShutdownDelayInSeconds, void(float seconds));
- MOCK_METHOD1(DoConnectToDeviceFactory,
- void(video_capture::mojom::DeviceFactoryRequest& request));
-};
-
-class MockDeviceFactory : public video_capture::mojom::DeviceFactory {
- public:
- void GetDeviceInfos(GetDeviceInfosCallback callback) override {
- DoGetDeviceInfos(callback);
- }
- void CreateDevice(const std::string& device_id,
- video_capture::mojom::DeviceRequest device_request,
- CreateDeviceCallback callback) override {
- DoCreateDevice(device_id, &device_request, callback);
- }
- void AddSharedMemoryVirtualDevice(
- const media::VideoCaptureDeviceInfo& device_info,
- video_capture::mojom::ProducerPtr producer,
- bool send_buffer_handles_to_producer_as_raw_file_descriptors,
- video_capture::mojom::SharedMemoryVirtualDeviceRequest virtual_device)
- override {
- DoAddVirtualDevice(device_info, producer.get(), &virtual_device);
- }
- void AddTextureVirtualDevice(const media::VideoCaptureDeviceInfo& device_info,
- video_capture::mojom::TextureVirtualDeviceRequest
- virtual_device) override {
- NOTIMPLEMENTED();
- }
-
- MOCK_METHOD1(DoGetDeviceInfos, void(GetDeviceInfosCallback& callback));
- MOCK_METHOD3(DoCreateDevice,
- void(const std::string& device_id,
- video_capture::mojom::DeviceRequest* device_request,
- CreateDeviceCallback& callback));
- MOCK_METHOD3(DoAddVirtualDevice,
- void(const media::VideoCaptureDeviceInfo& device_info,
- video_capture::mojom::ProducerProxy* producer,
- video_capture::mojom::SharedMemoryVirtualDeviceRequest*
- virtual_device_request));
-};
-
class MockVideoCaptureDeviceLauncherCallbacks
: public VideoCaptureDeviceLauncher::Callbacks {
public:
@@ -147,10 +90,10 @@ class ServiceVideoCaptureProviderTest : public testing::Test {
content::TestBrowserThreadBundle test_browser_thread_bundle_;
MockServiceConnector* mock_service_connector_;
- MockDeviceFactoryProvider mock_device_factory_provider_;
+ video_capture::MockDeviceFactoryProvider mock_device_factory_provider_;
mojo::Binding<video_capture::mojom::DeviceFactoryProvider>
factory_provider_binding_;
- MockDeviceFactory mock_device_factory_;
+ video_capture::MockDeviceFactory mock_device_factory_;
mojo::Binding<video_capture::mojom::DeviceFactory> device_factory_binding_;
std::unique_ptr<ServiceVideoCaptureProvider> provider_;
base::MockCallback<VideoCaptureProvider::GetDeviceInfosCallback> results_cb_;
diff --git a/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc b/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc
index 7306b1ee393..86421309571 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc
@@ -4,12 +4,14 @@
#include "base/command_line.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/video_capture_controller.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
@@ -35,10 +37,9 @@ static const float kFrameRateToRequest = 15.0f;
class MockVideoCaptureControllerEventHandler
: public VideoCaptureControllerEventHandler {
public:
- MOCK_METHOD4(DoOnNewBuffer,
+ MOCK_METHOD3(DoOnNewBuffer,
void(VideoCaptureControllerID id,
media::mojom::VideoBufferHandlePtr* buffer_handle,
- int length,
int buffer_id));
MOCK_METHOD2(OnBufferDestroyed,
void(VideoCaptureControllerID, int buffer_id));
@@ -55,9 +56,8 @@ class MockVideoCaptureControllerEventHandler
void OnNewBuffer(VideoCaptureControllerID id,
media::mojom::VideoBufferHandlePtr buffer_handle,
- int length,
int buffer_id) override {
- DoOnNewBuffer(id, &buffer_handle, length, buffer_id);
+ DoOnNewBuffer(id, &buffer_handle, buffer_id);
}
};
@@ -243,8 +243,8 @@ IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, StartAndImmediatelyStop) {
base::Bind(&VideoCaptureBrowserTest::TearDownCaptureDeviceOnIOThread,
base::Unretained(this),
std::move(quit_run_loop_on_current_thread_cb), true);
- BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(
&VideoCaptureBrowserTest::SetUpAndStartCaptureDeviceOnIOThread,
base::Unretained(this), std::move(after_start_continuation)));
@@ -305,7 +305,7 @@ IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest,
must_wait_for_gpu_decode_to_start = false;
}));
}
- EXPECT_CALL(mock_controller_event_handler_, DoOnNewBuffer(_, _, _, _))
+ EXPECT_CALL(mock_controller_event_handler_, DoOnNewBuffer(_, _, _))
.Times(AtLeast(1));
EXPECT_CALL(mock_controller_event_handler_, OnBufferReady(_, _, _))
.WillRepeatedly(Invoke(
@@ -330,8 +330,8 @@ IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest,
}));
base::Closure do_nothing;
- BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(
&VideoCaptureBrowserTest::SetUpAndStartCaptureDeviceOnIOThread,
base::Unretained(this), std::move(do_nothing)));
diff --git a/chromium/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc b/chromium/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc
index 773dbcc181a..80175b1c299 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_buffer_pool_unittest.cc
@@ -17,7 +17,7 @@
#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/media/video_capture_controller.h"
#include "media/base/video_frame.h"
@@ -77,11 +77,14 @@ class VideoCaptureBufferPoolTest
DVLOG(1) << media::VideoPixelFormatToString(pixel_format) << " "
<< dimensions.ToString();
const int arbitrary_frame_feedback_id = 0;
- const int buffer_id = pool_->ReserveForProducer(dimensions, pixel_format,
- arbitrary_frame_feedback_id,
- &buffer_id_to_drop);
- if (buffer_id == media::VideoCaptureBufferPool::kInvalidId)
+ int buffer_id = media::VideoCaptureBufferPool::kInvalidId;
+ const auto reserve_result = pool_->ReserveForProducer(
+ dimensions, pixel_format, nullptr, arbitrary_frame_feedback_id,
+ &buffer_id, &buffer_id_to_drop);
+ if (reserve_result !=
+ media::VideoCaptureDevice::Client::ReserveResult::kSucceeded) {
return std::unique_ptr<Buffer>();
+ }
EXPECT_EQ(expected_dropped_id_, buffer_id_to_drop);
std::unique_ptr<media::VideoCaptureBufferHandle> buffer_handle =
@@ -90,18 +93,7 @@ class VideoCaptureBufferPoolTest
new Buffer(pool_, std::move(buffer_handle), buffer_id));
}
- std::unique_ptr<Buffer> ResurrectLastBuffer(
- const gfx::Size& dimensions,
- media::VideoPixelFormat pixel_format) {
- const int buffer_id =
- pool_->ResurrectLastForProducer(dimensions, pixel_format);
- if (buffer_id == media::VideoCaptureBufferPool::kInvalidId)
- return std::unique_ptr<Buffer>();
- return std::unique_ptr<Buffer>(new Buffer(
- pool_, pool_->GetHandleForInProcessAccess(buffer_id), buffer_id));
- }
-
- base::MessageLoop loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
int expected_dropped_id_;
scoped_refptr<media::VideoCaptureBufferPool> pool_;
@@ -273,125 +265,6 @@ TEST_P(VideoCaptureBufferPoolTest, BufferPool) {
buffer4.reset();
}
-// Tests that a previously-released buffer can be immediately resurrected under
-// normal conditions.
-TEST_P(VideoCaptureBufferPoolTest, ResurrectsLastBuffer) {
- ExpectDroppedId(media::VideoCaptureBufferPool::kInvalidId);
-
- // At the start, there should be nothing to resurrect.
- std::unique_ptr<Buffer> resurrected =
- ResurrectLastBuffer(gfx::Size(10, 10), GetParam());
- ASSERT_EQ(nullptr, resurrected.get());
-
- // Reserve a 10x10 buffer and fill it with 0xab values.
- std::unique_ptr<Buffer> original =
- ReserveBuffer(gfx::Size(10, 10), GetParam());
- ASSERT_NE(nullptr, original.get());
- const size_t original_mapped_size = original->mapped_size();
- memset(original->data(), 0xab, original_mapped_size);
-
- // Try to resurrect a buffer BEFORE releasing |original|. This should fail.
- resurrected = ResurrectLastBuffer(gfx::Size(10, 10), GetParam());
- ASSERT_EQ(nullptr, resurrected.get());
-
- // Release |original| and then try to resurrect it. Confirm the content of
- // the resurrected buffer is a fill of 0xab values.
- original.reset();
- resurrected = ResurrectLastBuffer(gfx::Size(10, 10), GetParam());
- ASSERT_NE(nullptr, resurrected.get());
- ASSERT_EQ(original_mapped_size, resurrected->mapped_size());
- uint8_t* resurrected_memory = reinterpret_cast<uint8_t*>(resurrected->data());
- for (size_t i = 0; i < original_mapped_size; ++i)
- EXPECT_EQ(0xab, resurrected_memory[i]) << "Mismatch at byte offset: " << i;
-
- // Now, fill the resurrected buffer with 0xbc values and release it.
- memset(resurrected_memory, 0xbc, original_mapped_size);
- resurrected.reset();
-
- // Finally, resurrect the buffer again, and confirm it contains a fill of 0xbc
- // values.
- resurrected = ResurrectLastBuffer(gfx::Size(10, 10), GetParam());
- ASSERT_NE(nullptr, resurrected.get());
- ASSERT_EQ(original_mapped_size, resurrected->mapped_size());
- resurrected_memory = reinterpret_cast<uint8_t*>(resurrected->data());
- for (size_t i = 0; i < original_mapped_size; ++i)
- EXPECT_EQ(0xbc, resurrected_memory[i]) << "Mismatch at byte offset: " << i;
-}
-
-// Tests that a buffer cannot be resurrected if its properties do not match.
-TEST_P(VideoCaptureBufferPoolTest, DoesNotResurrectIfPropertiesNotMatched) {
- ExpectDroppedId(media::VideoCaptureBufferPool::kInvalidId);
-
- // Reserve a 10x10 buffer, fill it with 0xcd values, and release it.
- std::unique_ptr<Buffer> original =
- ReserveBuffer(gfx::Size(10, 10), GetParam());
- ASSERT_NE(nullptr, original.get());
- const size_t original_mapped_size = original->mapped_size();
- memset(original->data(), 0xcd, original_mapped_size);
- original.reset();
-
- // Expect that the buffer cannot be resurrected if the dimensions do not
- // match.
- std::unique_ptr<Buffer> resurrected =
- ResurrectLastBuffer(gfx::Size(8, 8), GetParam());
- ASSERT_EQ(nullptr, resurrected.get());
-
- // Expect that the buffer cannot be resurrected if the pixel format does not
- // match.
- media::VideoPixelFormat altered_format = GetParam();
- altered_format =
- (altered_format == media::PIXEL_FORMAT_I420 ? media::PIXEL_FORMAT_ARGB
- : media::PIXEL_FORMAT_I420);
- resurrected = ResurrectLastBuffer(gfx::Size(10, 10), altered_format);
- ASSERT_EQ(nullptr, resurrected.get());
-
- // Finally, check that the buffer CAN be resurrected if all properties match.
- resurrected = ResurrectLastBuffer(gfx::Size(10, 10), GetParam());
- ASSERT_NE(nullptr, resurrected.get());
- ASSERT_EQ(original_mapped_size, resurrected->mapped_size());
- uint8_t* resurrected_memory = reinterpret_cast<uint8_t*>(resurrected->data());
- for (size_t i = 0; i < original_mapped_size; ++i)
- EXPECT_EQ(0xcd, resurrected_memory[i]) << "Mismatch at byte offset: " << i;
-}
-
-// Tests that the buffers are managed by the pool such that the last-released
-// buffer is kept around as long as possible (for successful resurrection).
-TEST_P(VideoCaptureBufferPoolTest, AvoidsClobberingForResurrectingLastBuffer) {
- ExpectDroppedId(media::VideoCaptureBufferPool::kInvalidId);
-
- // Reserve a 10x10 buffer, fill it with 0xde values, and release it.
- std::unique_ptr<Buffer> original =
- ReserveBuffer(gfx::Size(10, 10), GetParam());
- ASSERT_NE(nullptr, original.get());
- const size_t original_mapped_size = original->mapped_size();
- memset(original->data(), 0xde, original_mapped_size);
- original.reset();
-
- // Reserve all but one of the pool's buffers.
- std::vector<std::unique_ptr<Buffer>> held_buffers;
- for (int i = 0; i < kTestBufferPoolSize - 1; ++i) {
- held_buffers.push_back(ReserveBuffer(gfx::Size(10, 10), GetParam()));
- ASSERT_NE(nullptr, held_buffers.back().get());
- }
-
- // Now, attempt to resurrect the original buffer. This should succeed.
- std::unique_ptr<Buffer> resurrected =
- ResurrectLastBuffer(gfx::Size(10, 10), GetParam());
- ASSERT_NE(nullptr, resurrected.get());
- ASSERT_EQ(original_mapped_size, resurrected->mapped_size());
- uint8_t* resurrected_memory = reinterpret_cast<uint8_t*>(resurrected->data());
- for (size_t i = 0; i < original_mapped_size; ++i)
- EXPECT_EQ(0xde, resurrected_memory[i]) << "Mismatch at byte offset: " << i;
- resurrected.reset();
-
- // Reserve the final buffer in the pool, and then confirm resurrection does
- // not succeed.
- held_buffers.push_back(ReserveBuffer(gfx::Size(10, 10), GetParam()));
- ASSERT_NE(nullptr, held_buffers.back().get());
- resurrected = ResurrectLastBuffer(gfx::Size(10, 10), GetParam());
- ASSERT_EQ(nullptr, resurrected.get());
-}
-
INSTANTIATE_TEST_CASE_P(,
VideoCaptureBufferPoolTest,
testing::ValuesIn(kCapturePixelFormats));
diff --git a/chromium/content/browser/renderer_host/media/video_capture_controller.cc b/chromium/content/browser/renderer_host/media/video_capture_controller.cc
index b964d0e82f9..0602d0a05f8 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_controller.cc
@@ -47,17 +47,66 @@ static const int kInfiniteRatio = 99999;
base::UmaHistogramSparse( \
name, (height) ? ((width)*100) / (height) : kInfiniteRatio);
-void LogVideoFrameDrop(media::VideoCaptureFrameDropReason reason) {
- UMA_HISTOGRAM_ENUMERATION(
- "Media.VideoCapture.FrameDrop", reason,
- static_cast<int>(media::VideoCaptureFrameDropReason::kMaxValue) + 1);
+void LogVideoFrameDrop(media::VideoCaptureFrameDropReason reason,
+ MediaStreamType stream_type) {
+ const int kEnumCount =
+ static_cast<int>(media::VideoCaptureFrameDropReason::kMaxValue) + 1;
+ UMA_HISTOGRAM_ENUMERATION("Media.VideoCapture.FrameDrop", reason, kEnumCount);
+ switch (stream_type) {
+ case MEDIA_DEVICE_VIDEO_CAPTURE:
+ UMA_HISTOGRAM_ENUMERATION("Media.VideoCapture.FrameDrop.DeviceCapture",
+ reason, kEnumCount);
+ break;
+ case MEDIA_GUM_TAB_VIDEO_CAPTURE:
+ UMA_HISTOGRAM_ENUMERATION("Media.VideoCapture.FrameDrop.GumTabCapture",
+ reason, kEnumCount);
+ break;
+ case MEDIA_GUM_DESKTOP_VIDEO_CAPTURE:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Media.VideoCapture.FrameDrop.GumDesktopCapture", reason, kEnumCount);
+ break;
+ case MEDIA_DISPLAY_VIDEO_CAPTURE:
+ UMA_HISTOGRAM_ENUMERATION("Media.VideoCapture.FrameDrop.DisplayCapture",
+ reason, kEnumCount);
+ break;
+ default:
+ // Do nothing
+ return;
+ }
}
void LogMaxConsecutiveVideoFrameDropCountExceeded(
- media::VideoCaptureFrameDropReason reason) {
- UMA_HISTOGRAM_ENUMERATION(
- "Media.VideoCapture.MaxFrameDropExceeded", reason,
- static_cast<int>(media::VideoCaptureFrameDropReason::kMaxValue) + 1);
+ media::VideoCaptureFrameDropReason reason,
+ MediaStreamType stream_type) {
+ const int kEnumCount =
+ static_cast<int>(media::VideoCaptureFrameDropReason::kMaxValue) + 1;
+ UMA_HISTOGRAM_ENUMERATION("Media.VideoCapture.MaxFrameDropExceeded", reason,
+ kEnumCount);
+ switch (stream_type) {
+ case MEDIA_DEVICE_VIDEO_CAPTURE:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Media.VideoCapture.MaxFrameDropExceeded.DeviceCapture", reason,
+ kEnumCount);
+ break;
+ case MEDIA_GUM_TAB_VIDEO_CAPTURE:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Media.VideoCapture.MaxFrameDropExceeded.GumTabCapture", reason,
+ kEnumCount);
+ break;
+ case MEDIA_GUM_DESKTOP_VIDEO_CAPTURE:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Media.VideoCapture.MaxFrameDropExceeded.GumDesktopCapture", reason,
+ kEnumCount);
+ break;
+ case MEDIA_DISPLAY_VIDEO_CAPTURE:
+ UMA_HISTOGRAM_ENUMERATION(
+ "Media.VideoCapture.MaxFrameDropExceeded.DisplayCapture", reason,
+ kEnumCount);
+ break;
+ default:
+ // Do nothing
+ return;
+ }
}
void CallOnError(media::VideoCaptureError error,
@@ -462,13 +511,9 @@ void VideoCaptureController::OnFrameReadyInBuffer(
if (!base::ContainsValue(client->known_buffer_context_ids,
buffer_context_id)) {
client->known_buffer_context_ids.push_back(buffer_context_id);
- const size_t mapped_size =
- media::VideoCaptureFormat(frame_info->coded_size, 0.0f,
- frame_info->pixel_format)
- .ImageAllocationSize();
client->event_handler->OnNewBuffer(
client->controller_id, buffer_context_iter->CloneBufferHandle(),
- mapped_size, buffer_context_id);
+ buffer_context_id);
}
if (!base::ContainsValue(client->buffers_in_use, buffer_context_id))
@@ -487,10 +532,10 @@ void VideoCaptureController::OnFrameReadyInBuffer(
}
if (!has_received_frames_) {
- UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Width",
- frame_info->coded_size.width());
- UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Height",
- frame_info->coded_size.height());
+ UMA_HISTOGRAM_COUNTS_1M("Media.VideoCapture.Width",
+ frame_info->coded_size.width());
+ UMA_HISTOGRAM_COUNTS_1M("Media.VideoCapture.Height",
+ frame_info->coded_size.height());
UMA_HISTOGRAM_ASPECT_RATIO("Media.VideoCapture.AspectRatio",
frame_info->coded_size.width(),
frame_info->coded_size.height());
@@ -502,7 +547,7 @@ void VideoCaptureController::OnFrameReadyInBuffer(
frame_rate = video_capture_format_->frame_rate;
}
}
- UMA_HISTOGRAM_COUNTS("Media.VideoCapture.FrameRate", frame_rate);
+ UMA_HISTOGRAM_COUNTS_1M("Media.VideoCapture.FrameRate", frame_rate);
UMA_HISTOGRAM_TIMES("Media.VideoCapture.DelayUntilFirstFrame",
base::TimeTicks::Now() - time_of_start_request_);
OnLog("First frame received at VideoCaptureController");
@@ -540,7 +585,7 @@ void VideoCaptureController::OnFrameDropped(
if (++frame_drop_log_state_.drop_count >
kMaxConsecutiveFrameDropForSameReasonCount) {
frame_drop_log_state_.max_log_count_exceeded = true;
- LogMaxConsecutiveVideoFrameDropCountExceeded(reason);
+ LogMaxConsecutiveVideoFrameDropCountExceeded(reason, stream_type_);
std::ostringstream string_stream;
string_stream << "Too many consecutive frames dropped with reason code "
<< static_cast<int>(reason)
@@ -553,7 +598,7 @@ void VideoCaptureController::OnFrameDropped(
frame_drop_log_state_ = FrameDropLogState(reason);
}
- LogVideoFrameDrop(reason);
+ LogVideoFrameDrop(reason, stream_type_);
std::ostringstream string_stream;
string_stream << "Frame dropped with reason code "
<< static_cast<int>(reason);
diff --git a/chromium/content/browser/renderer_host/media/video_capture_controller_event_handler.h b/chromium/content/browser/renderer_host/media/video_capture_controller_event_handler.h
index a2564afb998..8c849cbcdf8 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_controller_event_handler.h
+++ b/chromium/content/browser/renderer_host/media/video_capture_controller_event_handler.h
@@ -38,7 +38,6 @@ class CONTENT_EXPORT VideoCaptureControllerEventHandler {
virtual void OnNewBuffer(VideoCaptureControllerID id,
media::mojom::VideoBufferHandlePtr buffer_handle,
- int length,
int buffer_id) = 0;
// A previously created buffer has been freed and will no longer be used.
diff --git a/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc
index a5af5ca6252..0e9abecdbf3 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -19,12 +19,14 @@
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/renderer_host/media/media_stream_provider.h"
#include "content/browser/renderer_host/media/mock_video_capture_provider.h"
#include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "media/base/video_frame_metadata.h"
@@ -75,7 +77,6 @@ class MockVideoCaptureControllerEventHandler
}
void OnNewBuffer(VideoCaptureControllerID id,
media::mojom::VideoBufferHandlePtr buffer_handle,
- int length,
int buffer_id) override {
DoBufferCreated(id, buffer_id);
}
@@ -163,7 +164,7 @@ class VideoCaptureControllerTest
media::VideoCaptureBufferType::kSharedMemory,
std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
controller_->GetWeakPtrForIOThread(),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})),
buffer_pool_, media::VideoCaptureJpegDecoderFactoryCB()));
}
@@ -316,11 +317,12 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
uint8_t buffer_no = 1;
const int arbitrary_frame_feedback_id = 101;
ASSERT_EQ(0.0, device_client_->GetBufferPoolUtilization());
- media::VideoCaptureDevice::Client::Buffer buffer =
- device_client_->ReserveOutputBuffer(device_format.frame_size,
- device_format.pixel_format,
- arbitrary_frame_feedback_id);
- ASSERT_TRUE(buffer.is_valid());
+ media::VideoCaptureDevice::Client::Buffer buffer;
+ const auto result_code = device_client_->ReserveOutputBuffer(
+ device_format.frame_size, device_format.pixel_format,
+ arbitrary_frame_feedback_id, &buffer);
+ ASSERT_EQ(media::VideoCaptureDevice::Client::ReserveResult::kSucceeded,
+ result_code);
auto buffer_access = buffer.handle_provider->GetHandleForInProcessAccess();
ASSERT_EQ(1.0 / kPoolSize, device_client_->GetBufferPoolUtilization());
memset(buffer_access->data(), buffer_no++, buffer_access->mapped_size());
@@ -362,11 +364,12 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
// case pretend that the Buffer pointer is held by the device for a long
// delay. This shouldn't affect anything.
const int arbitrary_frame_feedback_id_2 = 102;
- media::VideoCaptureDevice::Client::Buffer buffer2 =
- device_client_->ReserveOutputBuffer(device_format.frame_size,
- device_format.pixel_format,
- arbitrary_frame_feedback_id_2);
- ASSERT_TRUE(buffer2.is_valid());
+ media::VideoCaptureDevice::Client::Buffer buffer2;
+ const auto result_code_2 = device_client_->ReserveOutputBuffer(
+ device_format.frame_size, device_format.pixel_format,
+ arbitrary_frame_feedback_id_2, &buffer2);
+ ASSERT_EQ(media::VideoCaptureDevice::Client::ReserveResult::kSucceeded,
+ result_code_2);
auto buffer2_access = buffer2.handle_provider->GetHandleForInProcessAccess();
memset(buffer2_access->data(), buffer_no++, buffer2_access->mapped_size());
client_a_->resource_utilization_ = 0.5;
@@ -380,25 +383,13 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
arbitrary_reference_time_,
arbitrary_timestamp_);
- // The buffer should be delivered to the clients in any order.
- {
- InSequence s;
- EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1, _));
- EXPECT_CALL(*client_a_,
- DoBufferReady(client_a_route_1, device_format.frame_size));
- }
- {
- InSequence s;
- EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1, _));
- EXPECT_CALL(*client_b_,
- DoBufferReady(client_b_route_1, device_format.frame_size));
- }
- {
- InSequence s;
- EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2, _));
- EXPECT_CALL(*client_a_,
- DoBufferReady(client_a_route_2, device_format.frame_size));
- }
+ // The frame should be delivered to the clients in any order.
+ EXPECT_CALL(*client_a_,
+ DoBufferReady(client_a_route_1, device_format.frame_size));
+ EXPECT_CALL(*client_b_,
+ DoBufferReady(client_b_route_1, device_format.frame_size));
+ EXPECT_CALL(*client_a_,
+ DoBufferReady(client_a_route_2, device_format.frame_size));
base::RunLoop().RunUntilIdle();
Mock::VerifyAndClearExpectations(client_a_.get());
Mock::VerifyAndClearExpectations(client_b_.get());
@@ -411,11 +402,12 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
// Third, fourth, and fifth buffers. Pretend they all arrive at the same time.
for (int i = 0; i < kPoolSize; i++) {
const int arbitrary_frame_feedback_id = 200 + i;
- media::VideoCaptureDevice::Client::Buffer buffer =
- device_client_->ReserveOutputBuffer(device_format.frame_size,
- device_format.pixel_format,
- arbitrary_frame_feedback_id);
- ASSERT_TRUE(buffer.is_valid());
+ media::VideoCaptureDevice::Client::Buffer buffer;
+ const auto result_code = device_client_->ReserveOutputBuffer(
+ device_format.frame_size, device_format.pixel_format,
+ arbitrary_frame_feedback_id, &buffer);
+ ASSERT_EQ(media::VideoCaptureDevice::Client::ReserveResult::kSucceeded,
+ result_code);
auto buffer_access = buffer.handle_provider->GetHandleForInProcessAccess();
memset(buffer_access->data(), buffer_no++, buffer_access->mapped_size());
device_client_->OnIncomingCapturedBuffer(std::move(buffer), device_format,
@@ -423,31 +415,32 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
arbitrary_timestamp_);
}
// ReserveOutputBuffer ought to fail now, because the pool is depleted.
- ASSERT_FALSE(device_client_
- ->ReserveOutputBuffer(device_format.frame_size,
- device_format.pixel_format,
- arbitrary_frame_feedback_id)
- .is_valid());
+ media::VideoCaptureDevice::Client::Buffer buffer_fail;
+ ASSERT_EQ(
+ media::VideoCaptureDevice::Client::ReserveResult::kMaxBufferCountExceeded,
+ device_client_->ReserveOutputBuffer(
+ device_format.frame_size, device_format.pixel_format,
+ arbitrary_frame_feedback_id, &buffer_fail));
// The new client needs to be notified of the creation of |kPoolSize| buffers;
- // the old clients only |kPoolSize - 2|.
+ // the old clients only |kPoolSize - 1|.
EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_2, _))
.Times(kPoolSize);
EXPECT_CALL(*client_b_,
DoBufferReady(client_b_route_2, device_format.frame_size))
.Times(kPoolSize);
EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_1, _))
- .Times(kPoolSize - 2);
+ .Times(kPoolSize - 1);
EXPECT_CALL(*client_a_,
DoBufferReady(client_a_route_1, device_format.frame_size))
.Times(kPoolSize);
EXPECT_CALL(*client_a_, DoBufferCreated(client_a_route_2, _))
- .Times(kPoolSize - 2);
+ .Times(kPoolSize - 1);
EXPECT_CALL(*client_a_,
DoBufferReady(client_a_route_2, device_format.frame_size))
.Times(kPoolSize);
EXPECT_CALL(*client_b_, DoBufferCreated(client_b_route_1, _))
- .Times(kPoolSize - 2);
+ .Times(kPoolSize - 1);
EXPECT_CALL(*client_b_,
DoBufferReady(client_b_route_1, device_format.frame_size))
.Times(kPoolSize);
@@ -462,28 +455,30 @@ TEST_P(VideoCaptureControllerTest, NormalCaptureMultipleClients) {
EXPECT_CALL(*client_b_, DoEnded(client_b_route_1)).Times(1);
controller_->StopSession(300);
// Queue up another buffer.
- media::VideoCaptureDevice::Client::Buffer buffer3 =
- device_client_->ReserveOutputBuffer(device_format.frame_size,
- device_format.pixel_format,
- arbitrary_frame_feedback_id);
- ASSERT_TRUE(buffer3.is_valid());
+ media::VideoCaptureDevice::Client::Buffer buffer3;
+ const auto result_code_3 = device_client_->ReserveOutputBuffer(
+ device_format.frame_size, device_format.pixel_format,
+ arbitrary_frame_feedback_id, &buffer3);
+ ASSERT_EQ(media::VideoCaptureDevice::Client::ReserveResult::kSucceeded,
+ result_code_3);
auto buffer3_access = buffer3.handle_provider->GetHandleForInProcessAccess();
memset(buffer3_access->data(), buffer_no++, buffer3_access->mapped_size());
device_client_->OnIncomingCapturedBuffer(std::move(buffer3), device_format,
arbitrary_reference_time_,
arbitrary_timestamp_);
- media::VideoCaptureDevice::Client::Buffer buffer4 =
- device_client_->ReserveOutputBuffer(device_format.frame_size,
- device_format.pixel_format,
- arbitrary_frame_feedback_id);
+ media::VideoCaptureDevice::Client::Buffer buffer4;
+ const auto result_code_4 = device_client_->ReserveOutputBuffer(
+ device_format.frame_size, device_format.pixel_format,
+ arbitrary_frame_feedback_id, &buffer4);
{
// Kill A2 via session close (posts a task to disconnect, but A2 must not
// be sent either of these two buffers).
EXPECT_CALL(*client_a_, DoEnded(client_a_route_2)).Times(1);
controller_->StopSession(200);
}
- ASSERT_TRUE(buffer4.is_valid());
+ ASSERT_EQ(media::VideoCaptureDevice::Client::ReserveResult::kSucceeded,
+ result_code_4);
auto buffer4_access = buffer4.handle_provider->GetHandleForInProcessAccess();
memset(buffer4_access->data(), buffer_no++, buffer4_access->mapped_size());
device_client_->OnIncomingCapturedBuffer(std::move(buffer4), device_format,
@@ -544,10 +539,12 @@ TEST_F(VideoCaptureControllerTest, ErrorBeforeDeviceCreation) {
media::VideoCaptureFormat device_format(
capture_resolution, arbitrary_frame_rate_, media::PIXEL_FORMAT_I420);
const int arbitrary_frame_feedback_id = 101;
- media::VideoCaptureDevice::Client::Buffer buffer =
- device_client_->ReserveOutputBuffer(device_format.frame_size,
- device_format.pixel_format,
- arbitrary_frame_feedback_id);
+ media::VideoCaptureDevice::Client::Buffer buffer;
+ const auto reserve_result = device_client_->ReserveOutputBuffer(
+ device_format.frame_size, device_format.pixel_format,
+ arbitrary_frame_feedback_id, &buffer);
+ ASSERT_EQ(media::VideoCaptureDevice::Client::ReserveResult::kSucceeded,
+ reserve_result);
device_client_->OnIncomingCapturedBuffer(std::move(buffer), device_format,
arbitrary_reference_time_,
arbitrary_timestamp_);
@@ -578,11 +575,12 @@ TEST_F(VideoCaptureControllerTest, ErrorAfterDeviceCreation) {
media::VideoCaptureFormat device_format(
gfx::Size(10, 10), arbitrary_frame_rate_, media::PIXEL_FORMAT_I420);
const int arbitrary_frame_feedback_id = 101;
- media::VideoCaptureDevice::Client::Buffer buffer =
- device_client_->ReserveOutputBuffer(device_format.frame_size,
- device_format.pixel_format,
- arbitrary_frame_feedback_id);
- ASSERT_TRUE(buffer.is_valid());
+ media::VideoCaptureDevice::Client::Buffer buffer;
+ const auto result_code = device_client_->ReserveOutputBuffer(
+ device_format.frame_size, device_format.pixel_format,
+ arbitrary_frame_feedback_id, &buffer);
+ ASSERT_EQ(media::VideoCaptureDevice::Client::ReserveResult::kSucceeded,
+ result_code);
device_client_->OnError(
media::VideoCaptureError::kIntentionalErrorRaisedByUnitTest, FROM_HERE,
@@ -643,21 +641,14 @@ TEST_F(VideoCaptureControllerTest, FrameFeedbackIsReportedForSequenceOfFrames) {
.Times(1);
// Device prepares and pushes a frame.
- // For the first half of the frames we exercise ReserveOutputBuffer() while
- // for the second half we exercise ResurrectLastOutputBuffer().
// The frame is expected to arrive at |client_a_|.DoBufferReady(), which
// automatically notifies |controller_| that it has finished consuming it.
media::VideoCaptureDevice::Client::Buffer buffer;
- if (frame_index < kTestFrameSequenceLength / 2) {
- buffer = device_client_->ReserveOutputBuffer(
- arbitrary_format.frame_size, arbitrary_format.pixel_format,
- stub_frame_feedback_id);
- } else {
- buffer = device_client_->ResurrectLastOutputBuffer(
- arbitrary_format.frame_size, arbitrary_format.pixel_format,
- stub_frame_feedback_id);
- }
- ASSERT_TRUE(buffer.is_valid());
+ const auto result_code = device_client_->ReserveOutputBuffer(
+ arbitrary_format.frame_size, arbitrary_format.pixel_format,
+ stub_frame_feedback_id, &buffer);
+ ASSERT_EQ(media::VideoCaptureDevice::Client::ReserveResult::kSucceeded,
+ result_code);
device_client_->OnIncomingCapturedBuffer(
std::move(buffer), arbitrary_format, arbitrary_reference_time_,
arbitrary_timestamp_);
@@ -861,20 +852,17 @@ TEST_F(VideoCaptureControllerTest, DroppedFramesGetLoggedInUMA) {
controller_->OnFrameDropped(
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat);
controller_->OnFrameDropped(
- media::VideoCaptureFrameDropReason::
- kDeviceClientFailedToReserveBufferFromBufferPool);
+ media::VideoCaptureFrameDropReason::kBufferPoolMaxBufferCountExceeded);
controller_->OnFrameDropped(
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat);
histogram_tester.ExpectBucketCount(
- "Media.VideoCapture.FrameDrop",
+ "Media.VideoCapture.FrameDrop.DeviceCapture",
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat,
2);
histogram_tester.ExpectBucketCount(
- "Media.VideoCapture.FrameDrop",
- media::VideoCaptureFrameDropReason::
- kDeviceClientFailedToReserveBufferFromBufferPool,
- 1);
+ "Media.VideoCapture.FrameDrop.DeviceCapture",
+ media::VideoCaptureFrameDropReason::kBufferPoolMaxBufferCountExceeded, 1);
}
// Tests that too many frames dropped for the same reason emits a special UMA
@@ -890,7 +878,7 @@ TEST_F(VideoCaptureControllerTest,
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat);
}
histogram_tester.ExpectBucketCount(
- "Media.VideoCapture.FrameDrop",
+ "Media.VideoCapture.FrameDrop.DeviceCapture",
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat,
VideoCaptureController::kMaxConsecutiveFrameDropForSameReasonCount);
@@ -899,12 +887,12 @@ TEST_F(VideoCaptureControllerTest,
controller_->OnFrameDropped(
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat);
histogram_tester.ExpectBucketCount(
- "Media.VideoCapture.FrameDrop",
+ "Media.VideoCapture.FrameDrop.DeviceCapture",
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat,
VideoCaptureController::kMaxConsecutiveFrameDropForSameReasonCount);
histogram_tester.ExpectBucketCount(
- "Media.VideoCapture.MaxFrameDropExceeded",
+ "Media.VideoCapture.MaxFrameDropExceeded.DeviceCapture",
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat,
1);
}
@@ -930,7 +918,7 @@ TEST_F(VideoCaptureControllerTest,
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat);
}
histogram_tester.ExpectBucketCount(
- "Media.VideoCapture.FrameDrop",
+ "Media.VideoCapture.FrameDrop.DeviceCapture",
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat,
2 * VideoCaptureController::kMaxConsecutiveFrameDropForSameReasonCount -
1);
@@ -954,7 +942,7 @@ TEST_F(VideoCaptureControllerTest, DeliveredFrameReenablesDroppedFrameLogging) {
controller_->OnFrameDropped(
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat);
histogram_tester.ExpectBucketCount(
- "Media.VideoCapture.FrameDrop",
+ "Media.VideoCapture.FrameDrop.DeviceCapture",
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat,
VideoCaptureController::kMaxConsecutiveFrameDropForSameReasonCount + 1);
}
@@ -974,20 +962,17 @@ TEST_F(VideoCaptureControllerTest,
// Drop for a different reason
controller_->OnFrameDropped(
- media::VideoCaptureFrameDropReason::
- kDeviceClientFailedToReserveBufferFromBufferPool);
+ media::VideoCaptureFrameDropReason::kBufferPoolMaxBufferCountExceeded);
controller_->OnFrameDropped(
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat);
histogram_tester.ExpectBucketCount(
- "Media.VideoCapture.FrameDrop",
+ "Media.VideoCapture.FrameDrop.DeviceCapture",
media::VideoCaptureFrameDropReason::kDeviceClientFrameHasInvalidFormat,
VideoCaptureController::kMaxConsecutiveFrameDropForSameReasonCount + 1);
histogram_tester.ExpectBucketCount(
- "Media.VideoCapture.FrameDrop",
- media::VideoCaptureFrameDropReason::
- kDeviceClientFailedToReserveBufferFromBufferPool,
- 1);
+ "Media.VideoCapture.FrameDrop.DeviceCapture",
+ media::VideoCaptureFrameDropReason::kBufferPoolMaxBufferCountExceeded, 1);
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/video_capture_host.cc b/chromium/content/browser/renderer_host/media/video_capture_host.cc
index d35e6a28544..40301360b51 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_host.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_host.cc
@@ -8,9 +8,11 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/task/post_task.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
@@ -109,8 +111,8 @@ void VideoCaptureHost::OnError(VideoCaptureControllerID controller_id,
media::VideoCaptureError error) {
DVLOG(1) << __func__;
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&VideoCaptureHost::DoError, weak_factory_.GetWeakPtr(),
controller_id, error));
}
@@ -118,7 +120,6 @@ void VideoCaptureHost::OnError(VideoCaptureControllerID controller_id,
void VideoCaptureHost::OnNewBuffer(
VideoCaptureControllerID controller_id,
media::mojom::VideoBufferHandlePtr buffer_handle,
- int length,
int buffer_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (controllers_.find(controller_id) == controllers_.end())
@@ -158,8 +159,8 @@ void VideoCaptureHost::OnBufferReady(
void VideoCaptureHost::OnEnded(VideoCaptureControllerID controller_id) {
DVLOG(1) << __func__;
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&VideoCaptureHost::DoEnded, weak_factory_.GetWeakPtr(),
controller_id));
}
@@ -400,8 +401,8 @@ void VideoCaptureHost::NotifyStreamAdded() {
++number_of_active_streams_;
// base::Unretained() usage is safe because |render_process_host_delegate_|
// is destroyed on UI thread.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&RenderProcessHostDelegate::NotifyStreamAdded,
base::Unretained(render_process_host_delegate_.get())));
}
@@ -417,8 +418,8 @@ void VideoCaptureHost::NotifyStreamRemoved() {
--number_of_active_streams_;
// base::Unretained() usage is safe because |render_process_host_delegate_| is
// destroyed on UI thread.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&RenderProcessHostDelegate::NotifyStreamRemoved,
base::Unretained(render_process_host_delegate_.get())));
}
diff --git a/chromium/content/browser/renderer_host/media/video_capture_host.h b/chromium/content/browser/renderer_host/media/video_capture_host.h
index 5fdecfe6c63..afaf18d8102 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_host.h
+++ b/chromium/content/browser/renderer_host/media/video_capture_host.h
@@ -57,7 +57,6 @@ class CONTENT_EXPORT VideoCaptureHost
media::VideoCaptureError error) override;
void OnNewBuffer(VideoCaptureControllerID id,
media::mojom::VideoBufferHandlePtr buffer_handle,
- int length,
int buffer_id) override;
void OnBufferDestroyed(VideoCaptureControllerID id,
int buffer_id) override;
diff --git a/chromium/content/browser/renderer_host/media/video_capture_manager.cc b/chromium/content/browser/renderer_host/media/video_capture_manager.cc
index 12e9dc70f33..ec2803c1ac9 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_manager.cc
@@ -22,6 +22,7 @@
#include "build/build_config.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/renderer_host/media/video_capture_controller.h"
+#include "content/browser/screenlock_monitor/screenlock_monitor.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "content/public/common/media_stream_request.h"
@@ -85,14 +86,23 @@ VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest(
VideoCaptureManager::VideoCaptureManager(
std::unique_ptr<VideoCaptureProvider> video_capture_provider,
- base::RepeatingCallback<void(const std::string&)> emit_log_message_cb)
+ base::RepeatingCallback<void(const std::string&)> emit_log_message_cb,
+ ScreenlockMonitor* monitor)
: new_capture_session_id_(1),
video_capture_provider_(std::move(video_capture_provider)),
- emit_log_message_cb_(std::move(emit_log_message_cb)) {}
+ emit_log_message_cb_(std::move(emit_log_message_cb)),
+ screenlock_monitor_(monitor) {
+ if (screenlock_monitor_) {
+ screenlock_monitor_->AddObserver(this);
+ }
+}
VideoCaptureManager::~VideoCaptureManager() {
DCHECK(controllers_.empty());
DCHECK(device_start_request_queue_.empty());
+ if (screenlock_monitor_) {
+ screenlock_monitor_->RemoveObserver(this);
+ }
}
void VideoCaptureManager::AddVideoCaptureObserver(
@@ -114,9 +124,9 @@ void VideoCaptureManager::RegisterListener(
listeners_.AddObserver(listener);
#if defined(OS_ANDROID)
application_state_has_running_activities_ = true;
- app_status_listener_.reset(new base::android::ApplicationStatusListener(
- base::Bind(&VideoCaptureManager::OnApplicationStateChange,
- base::Unretained(this))));
+ app_status_listener_ = base::android::ApplicationStatusListener::New(
+ base::BindRepeating(&VideoCaptureManager::OnApplicationStateChange,
+ base::Unretained(this)));
#endif
}
@@ -127,14 +137,15 @@ void VideoCaptureManager::UnregisterListener(
}
void VideoCaptureManager::EnumerateDevices(
- const EnumerationCallback& client_callback) {
+ EnumerationCallback client_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
EmitLogMessage("VideoCaptureManager::EnumerateDevices", 1);
// Pass a timer for UMA histogram collection.
- video_capture_provider_->GetDeviceInfosAsync(media::BindToCurrentLoop(
- base::Bind(&VideoCaptureManager::OnDeviceInfosReceived, this,
- base::Owned(new base::ElapsedTimer()), client_callback)));
+ video_capture_provider_->GetDeviceInfosAsync(
+ media::BindToCurrentLoop(base::BindOnce(
+ &VideoCaptureManager::OnDeviceInfosReceived, this,
+ base::Owned(new base::ElapsedTimer()), std::move(client_callback))));
}
int VideoCaptureManager::Open(const MediaStreamDevice& device) {
@@ -170,9 +181,8 @@ void VideoCaptureManager::Close(int capture_session_id) {
<< capture_session_id;
EmitLogMessage(string_stream.str(), 1);
- SessionMap::iterator session_it = sessions_.find(capture_session_id);
+ auto session_it = sessions_.find(capture_session_id);
if (session_it == sessions_.end()) {
- NOTREACHED();
return;
}
@@ -249,7 +259,7 @@ void VideoCaptureManager::DoStopDevice(VideoCaptureController* controller) {
void VideoCaptureManager::ProcessDeviceStartRequestQueue() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DeviceStartQueue::iterator request = device_start_request_queue_.begin();
+ auto request = device_start_request_queue_.begin();
if (request == device_start_request_queue_.end())
return;
@@ -506,7 +516,7 @@ bool VideoCaptureManager::GetDeviceSupportedFormats(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(supported_formats->empty());
- SessionMap::iterator it = sessions_.find(capture_session_id);
+ auto it = sessions_.find(capture_session_id);
if (it == sessions_.end())
return false;
std::ostringstream string_stream;
@@ -535,7 +545,7 @@ bool VideoCaptureManager::GetDeviceFormatsInUse(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(formats_in_use->empty());
- SessionMap::iterator it = sessions_.find(capture_session_id);
+ auto it = sessions_.find(capture_session_id);
if (it == sessions_.end())
return false;
std::ostringstream string_stream;
@@ -572,7 +582,7 @@ void VideoCaptureManager::SetDesktopCaptureWindowId(
void VideoCaptureManager::MaybePostDesktopCaptureWindowId(
media::VideoCaptureSessionId session_id) {
- SessionMap::iterator session_it = sessions_.find(session_id);
+ auto session_it = sessions_.find(session_id);
if (session_it == sessions_.end())
return;
@@ -684,7 +694,7 @@ void VideoCaptureManager::OnClosed(
void VideoCaptureManager::OnDeviceInfosReceived(
base::ElapsedTimer* timer,
- const EnumerationCallback& client_callback,
+ EnumerationCallback client_callback,
const std::vector<media::VideoCaptureDeviceInfo>& device_infos) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
UMA_HISTOGRAM_TIMES(
@@ -715,7 +725,7 @@ void VideoCaptureManager::OnDeviceInfosReceived(
descriptors_and_formats);
}
- client_callback.Run(devices);
+ std::move(client_callback).Run(devices);
}
void VideoCaptureManager::DestroyControllerIfNoClients(
@@ -802,7 +812,7 @@ VideoCaptureController* VideoCaptureManager::GetOrCreateController(
const media::VideoCaptureParams& params) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- SessionMap::iterator session_it = sessions_.find(capture_session_id);
+ auto session_it = sessions_.find(capture_session_id);
if (session_it == sessions_.end())
return nullptr;
const MediaStreamDevice& device_info = session_it->second;
@@ -889,6 +899,24 @@ void VideoCaptureManager::ResumeDevices() {
}
#endif // defined(OS_ANDROID)
+void VideoCaptureManager::OnScreenLocked() {
+#if !defined(OS_ANDROID)
+ // Stop screen sharing when screen is locked on desktop platforms only.
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ EmitLogMessage("VideoCaptureManager::OnScreenLocked", 1);
+
+ std::vector<media::VideoCaptureSessionId> desktopcapture_session_ids;
+ for (auto it : sessions_) {
+ if (IsDesktopCaptureMediaType(it.second.type))
+ desktopcapture_session_ids.push_back(it.first);
+ }
+
+ for (auto session_id : desktopcapture_session_ids) {
+ Close(session_id);
+ }
+#endif // OS_ANDROID
+}
+
void VideoCaptureManager::EmitLogMessage(const std::string& message,
int verbose_log_level) {
DVLOG(verbose_log_level) << message;
diff --git a/chromium/content/browser/renderer_host/media/video_capture_manager.h b/chromium/content/browser/renderer_host/media/video_capture_manager.h
index a32d287958c..69ab00edf2e 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_manager.h
+++ b/chromium/content/browser/renderer_host/media/video_capture_manager.h
@@ -23,6 +23,7 @@
#include "content/browser/renderer_host/media/video_capture_device_launch_observer.h"
#include "content/browser/renderer_host/media/video_capture_provider.h"
#include "content/common/content_export.h"
+#include "content/public/browser/screenlock_observer.h"
#include "media/base/video_facing.h"
#include "media/capture/video/video_capture_device.h"
#include "media/capture/video/video_capture_device_info.h"
@@ -35,6 +36,7 @@
namespace content {
class VideoCaptureController;
class VideoCaptureControllerEventHandler;
+class ScreenlockMonitor;
// VideoCaptureManager is used to open/close, start/stop, enumerate available
// video capture devices, and manage VideoCaptureController's.
@@ -43,7 +45,8 @@ class VideoCaptureControllerEventHandler;
// the Browser::IO thread. A device can only be opened once.
class CONTENT_EXPORT VideoCaptureManager
: public MediaStreamProvider,
- public VideoCaptureDeviceLaunchObserver {
+ public VideoCaptureDeviceLaunchObserver,
+ public ScreenlockObserver {
public:
using VideoCaptureDevice = media::VideoCaptureDevice;
@@ -53,7 +56,8 @@ class CONTENT_EXPORT VideoCaptureManager
explicit VideoCaptureManager(
std::unique_ptr<VideoCaptureProvider> video_capture_provider,
- base::RepeatingCallback<void(const std::string&)> emit_log_message_cb);
+ base::RepeatingCallback<void(const std::string&)> emit_log_message_cb,
+ ScreenlockMonitor* monitor = nullptr);
// AddVideoCaptureObserver() can be called only before any devices are opened.
// RemoveAllVideoCaptureObservers() can be called only after all devices
@@ -172,10 +176,10 @@ class CONTENT_EXPORT VideoCaptureManager
#endif
using EnumerationCallback =
- base::Callback<void(const media::VideoCaptureDeviceDescriptors&)>;
+ base::OnceCallback<void(const media::VideoCaptureDeviceDescriptors&)>;
// Asynchronously obtains descriptors for the available devices.
// As a side-effect, updates |devices_info_cache_|.
- void EnumerateDevices(const EnumerationCallback& client_callback);
+ void EnumerateDevices(EnumerationCallback client_callback);
// VideoCaptureDeviceLaunchObserver implementation:
void OnDeviceLaunched(VideoCaptureController* controller) override;
@@ -203,7 +207,7 @@ class CONTENT_EXPORT VideoCaptureManager
void OnDeviceInfosReceived(
base::ElapsedTimer* timer,
- const EnumerationCallback& client_callback,
+ EnumerationCallback client_callback,
const std::vector<media::VideoCaptureDeviceInfo>& device_infos);
// Helpers to report an event to our Listener.
@@ -262,6 +266,9 @@ class CONTENT_EXPORT VideoCaptureManager
bool application_state_has_running_activities_;
#endif
+ // ScreenlockObserver implementation:
+ void OnScreenLocked() override;
+
void EmitLogMessage(const std::string& message, int verbose_log_level);
// Only accessed on Browser::IO thread.
@@ -288,6 +295,7 @@ class CONTENT_EXPORT VideoCaptureManager
const std::unique_ptr<VideoCaptureProvider> video_capture_provider_;
base::RepeatingCallback<void(const std::string&)> emit_log_message_cb_;
+ ScreenlockMonitor* screenlock_monitor_;
base::ObserverList<media::VideoCaptureObserver>::Unchecked capture_observers_;
diff --git a/chromium/content/browser/renderer_host/media/video_capture_manager_unittest.cc b/chromium/content/browser/renderer_host/media/video_capture_manager_unittest.cc
index ce592438e1d..b9d98f0a1d0 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_manager_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_manager_unittest.cc
@@ -18,9 +18,13 @@
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "content/browser/renderer_host/media/in_process_video_capture_provider.h"
#include "content/browser/renderer_host/media/media_stream_provider.h"
#include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
+#include "content/browser/screenlock_monitor/screenlock_monitor.h"
+#include "content/browser/screenlock_monitor/screenlock_monitor_source.h"
+#include "content/public/browser/desktop_media_id.h"
#include "content/public/common/media_stream_request.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "media/capture/video/fake_video_capture_device_factory.h"
@@ -33,6 +37,7 @@ using ::testing::AnyNumber;
using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::InvokeWithoutArgs;
+using ::testing::Mock;
using ::testing::Return;
using ::testing::SaveArg;
@@ -160,7 +165,6 @@ class MockFrameObserver : public VideoCaptureControllerEventHandler {
void OnNewBuffer(VideoCaptureControllerID id,
media::mojom::VideoBufferHandlePtr buffer_handle,
- int length,
int buffer_id) override {}
void OnBufferDestroyed(VideoCaptureControllerID id, int buffer_id) override {}
void OnBufferReady(
@@ -179,6 +183,18 @@ class MockVideoCaptureObserver : public media::VideoCaptureObserver {
MOCK_METHOD1(OnVideoCaptureStopped, void(media::VideoFacingMode));
};
+// Needed to generate ScreenLocked event to |vcm_|.
+class ScreenlockMonitorTestSource : public ScreenlockMonitorSource {
+ public:
+ ScreenlockMonitorTestSource() = default;
+ ~ScreenlockMonitorTestSource() override = default;
+
+ void GenerateScreenLockedEvent() {
+ ProcessScreenlockEvent(SCREEN_LOCK_EVENT);
+ base::RunLoop().RunUntilIdle();
+ }
+};
+
} // namespace
// Test class
@@ -188,7 +204,7 @@ class VideoCaptureManagerTest : public testing::Test {
~VideoCaptureManagerTest() override {}
void HandleEnumerationResult(
- const base::Closure& quit_closure,
+ base::OnceClosure quit_closure,
const media::VideoCaptureDeviceDescriptors& descriptors) {
MediaStreamDevices devices;
for (const auto& descriptor : descriptors) {
@@ -196,7 +212,22 @@ class VideoCaptureManagerTest : public testing::Test {
descriptor.GetNameAndModel());
}
devices_ = devices;
- quit_closure.Run();
+ std::move(quit_closure).Run();
+ }
+
+ void HandleEnumerationResultAsDisplayMediaDevices(
+ base::OnceClosure quit_closure,
+ const media::VideoCaptureDeviceDescriptors& descriptors) {
+ MediaStreamDevices devices;
+ for (const auto& descriptor : descriptors) {
+ devices.emplace_back(MEDIA_DISPLAY_VIDEO_CAPTURE,
+ DesktopMediaID(DesktopMediaID::TYPE_SCREEN,
+ DesktopMediaID::kFakeId, false)
+ .ToString(),
+ descriptor.GetNameAndModel());
+ }
+ devices_ = devices;
+ std::move(quit_closure).Run();
}
protected:
@@ -211,9 +242,14 @@ class VideoCaptureManagerTest : public testing::Test {
std::make_unique<InProcessVideoCaptureProvider>(
std::move(video_capture_system),
base::ThreadTaskRunnerHandle::Get(), kIgnoreLogMessageCB);
+ screenlock_monitor_source_ = new ScreenlockMonitorTestSource();
+ screenlock_monitor_ = std::make_unique<ScreenlockMonitor>(
+ std::unique_ptr<ScreenlockMonitorSource>(screenlock_monitor_source_));
+
vcm_ =
new VideoCaptureManager(std::move(video_capture_provider),
- base::BindRepeating([](const std::string&) {}));
+ base::BindRepeating([](const std::string&) {}),
+ ScreenlockMonitor::Get());
const int32_t kNumberOfFakeDevices = 2;
video_capture_device_factory_->SetToDefaultDevicesConfig(
kNumberOfFakeDevices);
@@ -222,8 +258,8 @@ class VideoCaptureManagerTest : public testing::Test {
base::RunLoop run_loop;
vcm_->EnumerateDevices(
- base::Bind(&VideoCaptureManagerTest::HandleEnumerationResult,
- base::Unretained(this), run_loop.QuitClosure()));
+ base::BindOnce(&VideoCaptureManagerTest::HandleEnumerationResult,
+ base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run();
ASSERT_GE(devices_.size(), 2u);
}
@@ -295,6 +331,8 @@ class VideoCaptureManagerTest : public testing::Test {
#endif
int next_client_id_;
+ ScreenlockMonitorTestSource* screenlock_monitor_source_;
+ std::unique_ptr<ScreenlockMonitor> screenlock_monitor_;
std::map<VideoCaptureControllerID, VideoCaptureController*> controllers_;
scoped_refptr<VideoCaptureManager> vcm_;
std::unique_ptr<MockMediaStreamProviderListener> listener_;
@@ -418,8 +456,8 @@ TEST_F(VideoCaptureManagerTest, ConnectAndDisconnectDevices) {
video_capture_device_factory_->SetToDefaultDevicesConfig(1);
base::RunLoop run_loop;
vcm_->EnumerateDevices(
- base::Bind(&VideoCaptureManagerTest::HandleEnumerationResult,
- base::Unretained(this), run_loop.QuitClosure()));
+ base::BindOnce(&VideoCaptureManagerTest::HandleEnumerationResult,
+ base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run();
ASSERT_EQ(devices_.size(), 1u);
@@ -427,8 +465,8 @@ TEST_F(VideoCaptureManagerTest, ConnectAndDisconnectDevices) {
video_capture_device_factory_->SetToDefaultDevicesConfig(3);
base::RunLoop run_loop2;
vcm_->EnumerateDevices(
- base::Bind(&VideoCaptureManagerTest::HandleEnumerationResult,
- base::Unretained(this), run_loop2.QuitClosure()));
+ base::BindOnce(&VideoCaptureManagerTest::HandleEnumerationResult,
+ base::Unretained(this), run_loop2.QuitClosure()));
run_loop2.Run();
ASSERT_EQ(devices_.size(), 3u);
@@ -653,7 +691,7 @@ TEST_F(VideoCaptureManagerTest, OpenTwo) {
EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
- MediaStreamDevices::iterator it = devices_.begin();
+ auto it = devices_.begin();
int video_session_id_first = vcm_->Open(*it);
++it;
@@ -795,6 +833,65 @@ TEST_F(VideoCaptureManagerTest, PauseAndResumeDevice) {
}
#endif
+// Try to open, start a device capture device, and confirm it's not affected by
+// the ScreenLocked event.
+TEST_F(VideoCaptureManagerTest, DeviceCaptureDeviceNotClosedOnScreenlock) {
+ InSequence s;
+ // ScreenLocked event shouldn't affect camera capture device.
+ EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _));
+ EXPECT_CALL(*frame_observer_, OnStarted(_));
+ EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(0);
+
+ int video_session_id = vcm_->Open(devices_.front());
+ VideoCaptureControllerID client_id = StartClient(video_session_id, true);
+
+ // Pretend screen is locked, which should not close the device.
+ screenlock_monitor_source_->GenerateScreenLockedEvent();
+ Mock::VerifyAndClearExpectations(listener_.get());
+
+ EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _));
+ StopClient(client_id);
+ vcm_->Close(video_session_id);
+
+ // Wait to check callbacks before removing the listener.
+ base::RunLoop().RunUntilIdle();
+ vcm_->UnregisterListener(listener_.get());
+}
+
+#if defined(ENABLE_SCREEN_CAPTURE) && !defined(OS_ANDROID)
+// Try to open, start a desktop capture device, and confirm it's closed on
+// ScreenLocked event on desktop platforms.
+TEST_F(VideoCaptureManagerTest, DesktopCaptureDeviceClosedOnScreenlock) {
+ InSequence s;
+ // ScreenLocked event should stop desktop capture device.
+ EXPECT_CALL(*listener_, Opened(MEDIA_DISPLAY_VIDEO_CAPTURE, _));
+ EXPECT_CALL(*frame_observer_, OnStarted(_));
+ EXPECT_CALL(*listener_, Closed(MEDIA_DISPLAY_VIDEO_CAPTURE, _));
+
+ // Simulate we add 1 fake display media device.
+ video_capture_device_factory_->SetToDefaultDevicesConfig(1);
+ base::RunLoop run_loop;
+ vcm_->EnumerateDevices(base::BindOnce(
+ &VideoCaptureManagerTest::HandleEnumerationResultAsDisplayMediaDevices,
+ base::Unretained(this), run_loop.QuitClosure()));
+ run_loop.Run();
+ ASSERT_EQ(devices_.size(), 1u);
+
+ int video_session_id = vcm_->Open(devices_.front());
+ VideoCaptureControllerID client_id = StartClient(video_session_id, true);
+
+ // Pretend screen is locked, which should close the device.
+ screenlock_monitor_source_->GenerateScreenLockedEvent();
+ Mock::VerifyAndClearExpectations(listener_.get());
+
+ StopClient(client_id);
+
+ // Wait to check callbacks before removing the listener.
+ base::RunLoop().RunUntilIdle();
+ vcm_->UnregisterListener(listener_.get());
+}
+#endif // ENABLE_SCREEN_CAPTURE && !OS_ANDROID
+
// TODO(mcasas): Add a test to check consolidation of the supported formats
// provided by the device when http://crbug.com/323913 is closed.
diff --git a/chromium/content/browser/renderer_host/overscroll_controller.cc b/chromium/content/browser/renderer_host/overscroll_controller.cc
index 73c7bbe0e26..23c45860f8f 100644
--- a/chromium/content/browser/renderer_host/overscroll_controller.cc
+++ b/chromium/content/browser/renderer_host/overscroll_controller.cc
@@ -29,6 +29,10 @@ bool IsGestureEventFromTouchpad(const blink::WebInputEvent& event) {
return gesture.SourceDevice() == blink::kWebGestureDeviceTouchpad;
}
+bool IsGestureEventFromAutoscroll(const blink::WebGestureEvent event) {
+ return event.SourceDevice() == blink::kWebGestureDeviceSyntheticAutoscroll;
+}
+
bool IsGestureScrollUpdateInertialEvent(const blink::WebInputEvent& event) {
if (event.GetType() != blink::WebInputEvent::kGestureScrollUpdate)
return false;
@@ -68,6 +72,10 @@ bool OverscrollController::ShouldProcessEvent(
event.GetType() != blink::WebInputEvent::kGestureScrollUpdate)
return false;
+ // Gesture events with Autoscroll source don't cause overscrolling.
+ if (IsGestureEventFromAutoscroll(gesture))
+ return false;
+
blink::WebGestureEvent::ScrollUnits scrollUnits;
switch (event.GetType()) {
case blink::WebInputEvent::kGestureScrollBegin:
@@ -523,6 +531,8 @@ bool OverscrollController::ProcessOverscroll(float delta_x,
if (overscroll_mode_ == OVERSCROLL_NONE)
return false;
+ overscroll_ignored_ = false;
+
// Tell the delegate about the overscroll update so that it can update
// the display accordingly (e.g. show history preview etc.).
if (delegate_) {
diff --git a/chromium/content/browser/renderer_host/overscroll_controller_unittest.cc b/chromium/content/browser/renderer_host/overscroll_controller_unittest.cc
index 166d1fe359d..fc980f1cebd 100644
--- a/chromium/content/browser/renderer_host/overscroll_controller_unittest.cc
+++ b/chromium/content/browser/renderer_host/overscroll_controller_unittest.cc
@@ -496,11 +496,18 @@ TEST_F(OverscrollControllerTest, DisableTouchpadOverscrollHistoryNavigation) {
}
// Verifies that if an overscroll happens before cool off period after a page
-// scroll, it does not trigger pull-to-refresh.
-TEST_F(OverscrollControllerTest, PullToRefreshCoolOff) {
+// scroll, it does not trigger pull-to-refresh. Verifies following sequence of
+// scrolls:
+// 1) Page scroll;
+// 2) Scroll before cool off -> PTR not triggered;
+// 3) Scroll before cool off -> PTR not triggered;
+// 4) Scroll after cool off -> PTR triggered;
+// 5) Scroll before cool off -> PTR triggered.
+TEST_F(OverscrollControllerTest, PullToRefreshBeforeCoolOff) {
ScopedPullToRefreshMode scoped_mode(
OverscrollConfig::PullToRefreshMode::kEnabled);
+ // 1) Page scroll.
base::TimeTicks timestamp =
blink::WebInputEvent::GetStaticTimeStampForTests();
@@ -510,11 +517,42 @@ TEST_F(OverscrollControllerTest, PullToRefreshCoolOff) {
SimulateAck(false);
// Simulate a touchscreen gesture scroll-update event that passes the start
+ // threshold and ACK it as processed. Pull-to-refresh should not be triggered.
+ EXPECT_FALSE(SimulateGestureScrollUpdate(
+ 0, 80, blink::kWebGestureDeviceTouchscreen, timestamp, false));
+ SimulateAck(true);
+ EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
+ EXPECT_EQ(OverscrollSource::NONE, controller_source());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+
+ timestamp += base::TimeDelta::FromSeconds(1);
+
+ // Simulate a touchscreen gesture scroll-end which would normally end
+ // pull-to-refresh, and ACK it as not processed. Nothing should happen.
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollEnd,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+ EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
+ EXPECT_EQ(OverscrollSource::NONE, controller_source());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+
+ // 2) Scroll before cool off -> PTR not triggered.
+ timestamp += base::TimeDelta::FromMilliseconds(500);
+
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollBegin,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+
+ // Simulate a touchscreen gesture scroll-update event that passes the start
// threshold and ACK it as not processed. Pull-to-refresh should not be
// triggered.
EXPECT_FALSE(SimulateGestureScrollUpdate(
0, 80, blink::kWebGestureDeviceTouchscreen, timestamp, false));
- SimulateAck(true);
+ SimulateAck(false);
EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
EXPECT_EQ(OverscrollSource::NONE, controller_source());
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
@@ -533,9 +571,8 @@ TEST_F(OverscrollControllerTest, PullToRefreshCoolOff) {
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
- // Next scroll should happen before cool off period is finished, so that it
- // does not trigger pull-to-refresh.
- timestamp += base::TimeDelta::FromSecondsD(0.5);
+ // 3) Scroll before cool off -> PTR not triggered.
+ timestamp += base::TimeDelta::FromMilliseconds(500);
EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen,
@@ -565,6 +602,173 @@ TEST_F(OverscrollControllerTest, PullToRefreshCoolOff) {
EXPECT_EQ(OverscrollSource::NONE, controller_source());
EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+
+ // 4) Scroll after cool off -> PTR triggered.
+ timestamp += base::TimeDelta::FromSeconds(1);
+
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollBegin,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+
+ // Simulate a touchscreen gesture scroll-update event that passes the start
+ // threshold and ACK it as not processed. Pull-to-refresh should be triggered.
+ EXPECT_FALSE(SimulateGestureScrollUpdate(
+ 0, 80, blink::kWebGestureDeviceTouchscreen, timestamp, false));
+ SimulateAck(false);
+ EXPECT_EQ(OVERSCROLL_SOUTH, controller_mode());
+ EXPECT_EQ(OverscrollSource::TOUCHSCREEN, controller_source());
+ EXPECT_EQ(OVERSCROLL_SOUTH, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+
+ timestamp += base::TimeDelta::FromSeconds(1);
+
+ // Simulate a touchscreen gesture scroll-end which will end pull-to-refresh,
+ // and ACK it as not processed. Pull-to-refresh should be aborted.
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollEnd,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+ EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
+ EXPECT_EQ(OverscrollSource::NONE, controller_source());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+
+ // 5) Scroll before cool off -> PTR triggered.
+ timestamp += base::TimeDelta::FromMilliseconds(500);
+
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollBegin,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+
+ // Simulate a touchscreen gesture scroll-update event that passes the start
+ // threshold and ACK it as not processed. Pull-to-refresh should be triggered.
+ EXPECT_FALSE(SimulateGestureScrollUpdate(
+ 0, 80, blink::kWebGestureDeviceTouchscreen, timestamp, false));
+ SimulateAck(false);
+ EXPECT_EQ(OVERSCROLL_SOUTH, controller_mode());
+ EXPECT_EQ(OverscrollSource::TOUCHSCREEN, controller_source());
+ EXPECT_EQ(OVERSCROLL_SOUTH, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+
+ timestamp += base::TimeDelta::FromSeconds(1);
+
+ // Simulate a touchscreen gesture scroll-end which will end pull-to-refresh,
+ // and ACK it as not processed. Pull-to-refresh should be aborted.
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollEnd,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+ EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
+ EXPECT_EQ(OverscrollSource::NONE, controller_source());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+}
+
+// Verifies that if an overscroll happens after cool off period after a page
+// scroll, it triggers pull-to-refresh. Verifies the following sequence of
+// scrolls:
+// 1) Page scroll;
+// 2) Scroll after cool off -> PTR triggered;
+// 3) Scroll before cool off -> PTR triggered;
+TEST_F(OverscrollControllerTest, PullToRefreshAfterCoolOff) {
+ ScopedPullToRefreshMode scoped_mode(
+ OverscrollConfig::PullToRefreshMode::kEnabled);
+
+ // 1) Page scroll.
+ base::TimeTicks timestamp =
+ blink::WebInputEvent::GetStaticTimeStampForTests();
+
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollBegin,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+
+ // Simulate a touchscreen gesture scroll-update event that passes the start
+ // threshold and ACK it as processed. Pull-to-refresh should not be triggered.
+ EXPECT_FALSE(SimulateGestureScrollUpdate(
+ 0, 80, blink::kWebGestureDeviceTouchscreen, timestamp, false));
+ SimulateAck(true);
+ EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
+ EXPECT_EQ(OverscrollSource::NONE, controller_source());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+
+ timestamp += base::TimeDelta::FromSeconds(1);
+
+ // Simulate a touchscreen gesture scroll-end which would normally end
+ // pull-to-refresh, and ACK it as not processed. Nothing should happen.
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollEnd,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+ EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
+ EXPECT_EQ(OverscrollSource::NONE, controller_source());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+
+ // 2) Scroll after cool off -> PTR triggered.
+ timestamp += base::TimeDelta::FromSeconds(1);
+
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollBegin,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+
+ // Simulate a touchscreen gesture scroll-update event that passes the start
+ // threshold and ACK it as not processed. Pull-to-refresh should be triggered.
+ EXPECT_FALSE(SimulateGestureScrollUpdate(
+ 0, 80, blink::kWebGestureDeviceTouchscreen, timestamp, false));
+ SimulateAck(false);
+ EXPECT_EQ(OVERSCROLL_SOUTH, controller_mode());
+ EXPECT_EQ(OverscrollSource::TOUCHSCREEN, controller_source());
+ EXPECT_EQ(OVERSCROLL_SOUTH, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+
+ timestamp += base::TimeDelta::FromSeconds(1);
+
+ // Simulate a touchscreen gesture scroll-end which will end pull-to-refresh,
+ // and ACK it as not processed. Pull-to-refresh should be aborted.
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollEnd,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+ EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
+ EXPECT_EQ(OverscrollSource::NONE, controller_source());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+
+ // 3) Scroll before cool off -> PTR triggered.
+ timestamp += base::TimeDelta::FromMilliseconds(500);
+
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollBegin,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+
+ // Simulate a touchscreen gesture scroll-update event that passes the start
+ // threshold and ACK it as not processed. Pull-to-refresh should be triggered.
+ EXPECT_FALSE(SimulateGestureScrollUpdate(
+ 0, 80, blink::kWebGestureDeviceTouchscreen, timestamp, false));
+ SimulateAck(false);
+ EXPECT_EQ(OVERSCROLL_SOUTH, controller_mode());
+ EXPECT_EQ(OverscrollSource::TOUCHSCREEN, controller_source());
+ EXPECT_EQ(OVERSCROLL_SOUTH, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
+
+ timestamp += base::TimeDelta::FromSeconds(1);
+
+ // Simulate a touchscreen gesture scroll-end which will end pull-to-refresh,
+ // and ACK it as not processed. Pull-to-refresh should be aborted.
+ EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollEnd,
+ blink::kWebGestureDeviceTouchscreen,
+ timestamp));
+ SimulateAck(false);
+ EXPECT_EQ(OVERSCROLL_NONE, controller_mode());
+ EXPECT_EQ(OverscrollSource::NONE, controller_source());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->current_mode());
+ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode());
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
index ce859120f2e..6bd32e88e38 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
@@ -70,6 +70,9 @@ void P2PSocketDispatcherHost::BindRequest(
if (!rph)
return;
+ // In case the renderer was connected previously but the network process
+ // crashed.
+ binding_.Close();
network::mojom::P2PTrustedSocketManagerClientPtr
trusted_socket_manager_client;
binding_.Bind(mojo::MakeRequest(&trusted_socket_manager_client));
diff --git a/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc b/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc
index 09c612c70a1..f4bef214757 100644
--- a/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc
+++ b/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc
@@ -57,8 +57,7 @@ BrowserPpapiHostImpl::BrowserPpapiHostImpl(
plugin_path_(plugin_path),
profile_data_directory_(profile_data_directory),
in_process_(in_process),
- external_plugin_(external_plugin),
- ssl_context_helper_(new SSLContextHelper()) {
+ external_plugin_(external_plugin) {
message_filter_ = new HostMessageFilter(ppapi_host_.get(), this);
ppapi_host_->AddHostFactoryFilter(std::unique_ptr<ppapi::host::HostFactory>(
new ContentBrowserPepperHostFactory(this)));
diff --git a/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h b/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h
index 8aeaed49765..e892474cf59 100644
--- a/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h
+++ b/chromium/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h
@@ -18,7 +18,6 @@
#include "base/observer_list.h"
#include "base/process/process.h"
#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h"
-#include "content/browser/renderer_host/pepper/ssl_context_helper.h"
#include "content/common/content_export.h"
#include "content/common/pepper_renderer_instance_data.h"
#include "content/public/browser/browser_ppapi_host.h"
@@ -100,10 +99,6 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost {
return message_filter_;
}
- const scoped_refptr<SSLContextHelper>& ssl_context_helper() const {
- return ssl_context_helper_;
- }
-
private:
friend class BrowserPpapiHostTest;
@@ -153,8 +148,6 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost {
// BrowserPpapiHost::CreateExternalPluginProcess.
bool external_plugin_;
- scoped_refptr<SSLContextHelper> ssl_context_helper_;
-
// Tracks all PP_Instances in this plugin and associated data.
std::unordered_map<PP_Instance, std::unique_ptr<InstanceData>> instance_map_;
diff --git a/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc b/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc
index 782cd8b785b..69eb47a8259 100644
--- a/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc
+++ b/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc
@@ -246,12 +246,18 @@ std::unique_ptr<ppapi::host::ResourceHost>
ContentBrowserPepperHostFactory::CreateAcceptedTCPSocket(
PP_Instance instance,
ppapi::TCPSocketVersion version,
- std::unique_ptr<net::TCPSocket> socket) {
+ network::mojom::TCPConnectedSocketPtrInfo connected_socket,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream) {
if (!CanCreateSocket())
return std::unique_ptr<ppapi::host::ResourceHost>();
- scoped_refptr<ppapi::host::ResourceMessageFilter> tcp_socket(
- new PepperTCPSocketMessageFilter(host_, instance, version,
- std::move(socket)));
+ scoped_refptr<PepperTCPSocketMessageFilter> tcp_socket(
+ base::MakeRefCounted<PepperTCPSocketMessageFilter>(
+ nullptr /* factory */, host_, instance, version));
+ tcp_socket->SetConnectedSocket(
+ std::move(connected_socket), std::move(socket_observer_request),
+ std::move(receive_stream), std::move(send_stream));
return std::unique_ptr<ppapi::host::ResourceHost>(
new ppapi::host::MessageFilterHost(host_->GetPpapiHost(), instance, 0,
tcp_socket));
diff --git a/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h b/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h
index d9b3a55c36a..4c755131198 100644
--- a/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h
+++ b/chromium/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h
@@ -10,10 +10,11 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "net/socket/tcp_socket.h"
+#include "mojo/public/cpp/system/data_pipe.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/host/host_factory.h"
#include "ppapi/shared_impl/ppb_tcp_socket_shared.h"
+#include "services/network/public/mojom/tcp_socket.mojom.h"
namespace ppapi {
class PpapiPermissions;
@@ -41,7 +42,10 @@ class ContentBrowserPepperHostFactory : public ppapi::host::HostFactory {
std::unique_ptr<ppapi::host::ResourceHost> CreateAcceptedTCPSocket(
PP_Instance instance,
ppapi::TCPSocketVersion version,
- std::unique_ptr<net::TCPSocket> socket);
+ network::mojom::TCPConnectedSocketPtrInfo connected_socket,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream);
private:
std::unique_ptr<ppapi::host::ResourceHost> CreateNewTCPSocket(
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc
index 14641886701..1e1b3bd810c 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc
@@ -15,6 +15,7 @@
#include "content/browser/renderer_host/pepper/pepper_file_system_browser_host.h"
#include "content/browser/renderer_host/pepper/pepper_security_helper.h"
#include "content/common/view_messages.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_process_host.h"
@@ -203,26 +204,21 @@ int32_t PepperFileIOHost::OnHostMsgOpen(
if (!CanOpenFileSystemURLWithPepperFlags(
open_flags, render_process_id_, file_system_url_))
return PP_ERROR_NOACCESS;
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI,
- FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&GetUIThreadStuffForInternalFileSystems, render_process_id_),
base::Bind(&PepperFileIOHost::GotUIThreadStuffForInternalFileSystems,
- AsWeakPtr(),
- context->MakeReplyMessageContext(),
+ AsWeakPtr(), context->MakeReplyMessageContext(),
platform_file_flags));
} else {
base::FilePath path = file_ref_host->GetExternalFilePath();
if (!CanOpenWithPepperFlags(open_flags, render_process_id_, path))
return PP_ERROR_NOACCESS;
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI,
- FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&GetResolvedRenderProcessId, render_process_id_),
- base::Bind(&PepperFileIOHost::GotResolvedRenderProcessId,
- AsWeakPtr(),
- context->MakeReplyMessageContext(),
- path,
+ base::Bind(&PepperFileIOHost::GotResolvedRenderProcessId, AsWeakPtr(),
+ context->MakeReplyMessageContext(), path,
platform_file_flags));
}
state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE);
@@ -399,15 +395,12 @@ int32_t PepperFileIOHost::OnHostMsgRequestOSFileHandle(
GURL document_url =
browser_ppapi_host_->GetDocumentURLForInstance(pp_instance());
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&GetPluginAllowedToCallRequestOSFileHandle,
- render_process_id_,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
+ base::Bind(&GetPluginAllowedToCallRequestOSFileHandle, render_process_id_,
document_url),
base::Bind(&PepperFileIOHost::GotPluginAllowedToCallRequestOSFileHandle,
- AsWeakPtr(),
- context->MakeReplyMessageContext()));
+ AsWeakPtr(), context->MakeReplyMessageContext()));
return PP_OK_COMPLETIONPENDING;
}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
index ca2abd58bb4..a53e31554a8 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_file_system_browser_host.cc
@@ -6,10 +6,12 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/task/post_task.h"
#include "content/browser/renderer_host/pepper/pepper_file_io_host.h"
#include "content/browser/renderer_host/pepper/quota_reservation.h"
#include "content/common/pepper_file_util.h"
#include "content/public/browser/browser_ppapi_host.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_process_host.h"
@@ -89,13 +91,11 @@ void PepperFileSystemBrowserHost::OpenExisting(const GURL& root_url,
called_open_ = true;
// Get the file system context asynchronously, and then complete the Open
// operation by calling |callback|.
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI,
- FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
base::Bind(&PepperFileSystemBrowserHost::OpenExistingFileSystem,
- weak_factory_.GetWeakPtr(),
- callback));
+ weak_factory_.GetWeakPtr(), callback));
}
int32_t PepperFileSystemBrowserHost::OnResourceMessageReceived(
@@ -137,7 +137,7 @@ void PepperFileSystemBrowserHost::CloseQuotaFile(
PepperFileIOHost* file_io_host,
const ppapi::FileGrowth& file_growth) {
int32_t id = file_io_host->pp_resource();
- FileMap::iterator it = files_.find(id);
+ auto it = files_.find(id);
if (it != files_.end()) {
files_.erase(it);
} else {
@@ -173,13 +173,11 @@ int32_t PepperFileSystemBrowserHost::OnHostMsgOpen(
return PP_ERROR_FAILED;
}
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI,
- FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
base::Bind(&PepperFileSystemBrowserHost::OpenFileSystem,
- weak_factory_.GetWeakPtr(),
- context->MakeReplyMessageContext(),
+ weak_factory_.GetWeakPtr(), context->MakeReplyMessageContext(),
file_system_type));
return PP_OK_COMPLETIONPENDING;
}
@@ -341,15 +339,12 @@ int32_t PepperFileSystemBrowserHost::OnHostMsgInitIsolatedFileSystem(
fsid,
ppapi::IsolatedFileSystemTypeToRootName(type)));
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI,
- FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&GetFileSystemContextFromRenderId, render_process_id),
base::Bind(&PepperFileSystemBrowserHost::OpenIsolatedFileSystem,
- weak_factory_.GetWeakPtr(),
- context->MakeReplyMessageContext(),
- fsid,
- type));
+ weak_factory_.GetWeakPtr(), context->MakeReplyMessageContext(),
+ fsid, type));
return PP_OK_COMPLETIONPENDING;
}
@@ -417,7 +412,7 @@ bool PepperFileSystemBrowserHost::ShouldCreateQuotaReservation() const {
storage::FileSystemType file_system_type =
PepperFileSystemTypeToFileSystemType(type_);
return !quota_manager_proxy->quota_manager()->IsStorageUnlimited(
- root_url_.GetOrigin(),
+ url::Origin::Create(root_url_),
storage::FileSystemTypeToQuotaStorageType(file_system_type));
}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc
index d1cbc98e979..ca3fcf25f9d 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc
@@ -9,9 +9,11 @@
#include <memory>
#include "base/logging.h"
+#include "base/task/post_task.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
@@ -96,7 +98,7 @@ scoped_refptr<base::TaskRunner>
PepperHostResolverMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& message) {
if (message.type() == PpapiHostMsg_HostResolver_Resolve::ID)
- return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
+ return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
return nullptr;
}
@@ -163,8 +165,8 @@ void PepperHostResolverMessageFilter::OnComplete(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
binding_.Close();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PepperHostResolverMessageFilter::OnLookupFinished, this,
result, std::move(resolved_addresses),
host_resolve_context_));
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc
index 9f0fc648abf..9023d5b8490 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.cc
@@ -10,7 +10,9 @@
#include "base/task_runner_util.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/network_service_instance.h"
#include "content/public/common/socket_permission_request.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/private/net_address_private_impl.h"
@@ -46,30 +48,32 @@ PepperNetworkMonitorHost::PepperNetworkMonitorHost(BrowserPpapiHostImpl* host,
PP_Instance instance,
PP_Resource resource)
: ResourceHost(host->GetPpapiHost(), instance, resource),
+ network_connection_tracker_(nullptr),
weak_factory_(this) {
int render_process_id;
int render_frame_id;
host->GetRenderFrameIDsForInstance(
instance, &render_process_id, &render_frame_id);
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&CanUseNetworkMonitor,
- host->external_plugin(),
- render_process_id,
- render_frame_id),
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
+ base::Bind(&CanUseNetworkMonitor, host->external_plugin(),
+ render_process_id, render_frame_id),
base::Bind(&PepperNetworkMonitorHost::OnPermissionCheckResult,
weak_factory_.GetWeakPtr()));
}
PepperNetworkMonitorHost::~PepperNetworkMonitorHost() {
- net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
+ if (network_connection_tracker_)
+ network_connection_tracker_->RemoveNetworkConnectionObserver(this);
}
-void PepperNetworkMonitorHost::OnNetworkChanged(
- net::NetworkChangeNotifier::ConnectionType type) {
- if (type == net::NetworkChangeNotifier::GetConnectionType())
+void PepperNetworkMonitorHost::OnConnectionChanged(
+ network::mojom::ConnectionType type) {
+ auto current_type = network::mojom::ConnectionType::CONNECTION_UNKNOWN;
+ network_connection_tracker_->GetConnectionType(&current_type,
+ base::DoNothing());
+ if (type == current_type)
GetAndSendNetworkList();
}
@@ -81,10 +85,21 @@ void PepperNetworkMonitorHost::OnPermissionCheckResult(
return;
}
- net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&content::GetNetworkConnectionTracker),
+ base::BindOnce(&PepperNetworkMonitorHost::SetNetworkConnectionTracker,
+ weak_factory_.GetWeakPtr()));
GetAndSendNetworkList();
}
+void PepperNetworkMonitorHost::SetNetworkConnectionTracker(
+ network::NetworkConnectionTracker* network_connection_tracker) {
+ DCHECK_EQ(network_connection_tracker_, nullptr);
+ network_connection_tracker_ = network_connection_tracker;
+ network_connection_tracker_->AddNetworkConnectionObserver(this);
+}
+
void PepperNetworkMonitorHost::GetAndSendNetworkList() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.h b/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.h
index 5e61b20fe27..6cf89098900 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_network_monitor_host.h
@@ -9,10 +9,10 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
-#include "net/base/network_change_notifier.h"
#include "net/base/network_interfaces.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/resource_host.h"
+#include "services/network/public/cpp/network_connection_tracker.h"
namespace content {
@@ -21,7 +21,7 @@ class BrowserPpapiHostImpl;
// The host for PPB_NetworkMonitor. This class lives on the IO thread.
class CONTENT_EXPORT PepperNetworkMonitorHost
: public ppapi::host::ResourceHost,
- public net::NetworkChangeNotifier::NetworkChangeObserver {
+ public network::NetworkConnectionTracker::NetworkConnectionObserver {
public:
PepperNetworkMonitorHost(BrowserPpapiHostImpl* host,
PP_Instance instance,
@@ -29,18 +29,21 @@ class CONTENT_EXPORT PepperNetworkMonitorHost
~PepperNetworkMonitorHost() override;
- // net::NetworkChangeNotifier::NetworkChangeObserver interface.
- void OnNetworkChanged(
- net::NetworkChangeNotifier::ConnectionType type) override;
+ // network::NetworkConnectionTracker::NetworkConnectionObserver interface.
+ void OnConnectionChanged(network::mojom::ConnectionType type) override;
private:
void OnPermissionCheckResult(bool can_use_network_monitor);
+ void SetNetworkConnectionTracker(
+ network::NetworkConnectionTracker* network_connection_tracker);
void GetAndSendNetworkList();
void SendNetworkList(std::unique_ptr<net::NetworkInterfaceList> list);
ppapi::host::ReplyMessageContext reply_context_;
+ network::NetworkConnectionTracker* network_connection_tracker_;
+
base::WeakPtrFactory<PepperNetworkMonitorHost> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(PepperNetworkMonitorHost);
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc
index 75774080312..e7a74ba592d 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_network_proxy_host.cc
@@ -5,10 +5,12 @@
#include "content/browser/renderer_host/pepper/pepper_network_proxy_host.h"
#include "base/bind.h"
+#include "base/task/post_task.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "content/browser/renderer_host/pepper/pepper_proxy_lookup_helper.h"
#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@@ -59,8 +61,8 @@ PepperNetworkProxyHost::PepperNetworkProxyHost(BrowserPpapiHostImpl* host,
weak_factory_(this) {
host->GetRenderFrameIDsForInstance(instance, &render_process_id_,
&render_frame_id_);
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&GetUIThreadDataOnUIThread, render_process_id_,
render_frame_id_, host->external_plugin()),
base::BindOnce(&PepperNetworkProxyHost::DidGetUIThreadData,
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.cc b/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.cc
index 0a3c9da3d24..54c4e339a43 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_print_settings_manager.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
@@ -111,8 +113,8 @@ PepperPrintSettingsManager::Result ComputeDefaultPrintSettings() {
void PepperPrintSettingsManagerImpl::GetDefaultPrintSettings(
PepperPrintSettingsManager::Callback callback) {
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE, base::Bind(ComputeDefaultPrintSettings),
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI}, base::Bind(ComputeDefaultPrintSettings),
std::move(callback));
}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper.cc b/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper.cc
index 95928393273..5861950d2bf 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper.cc
@@ -9,7 +9,9 @@
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
+#include "base/task/post_task.h"
#include "base/threading/sequenced_task_runner_handle.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h"
@@ -29,8 +31,8 @@ class PepperProxyLookupHelper::UIThreadHelper
: binding_(this),
look_up_complete_callback_(std::move(look_up_complete_callback)),
callback_task_runner_(base::SequencedTaskRunnerHandle::Get()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&UIThreadHelper::StartLookup, base::Unretained(this),
url, std::move(look_up_proxy_for_url_callback)));
}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper_unittest.cc b/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper_unittest.cc
index 25f87fdcad3..76619fea2b7 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper_unittest.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_proxy_lookup_helper_unittest.cc
@@ -14,6 +14,8 @@
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/proxy_resolution/proxy_info.h"
@@ -37,8 +39,8 @@ class PepperProxyLookupHelperTest : public testing::Test {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::RunLoop run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PepperProxyLookupHelperTest::StartLookupOnIOThread,
base::Unretained(this), run_loop.QuitClosure()));
run_loop.Run();
@@ -60,8 +62,8 @@ class PepperProxyLookupHelperTest : public testing::Test {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::RunLoop run_loop;
- BrowserThread::PostTaskAndReply(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&PepperProxyLookupHelperTest::DestroyLookupHelperOnIOThread,
base::Unretained(this)),
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc
index 429d3d217da..f0aadfcb9d3 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc
@@ -10,18 +10,23 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h"
#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/storage_partition.h"
#include "content/public/common/socket_permission_request.h"
+#include "mojo/public/cpp/bindings/callback_helpers.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
-#include "net/log/net_log_source.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "ppapi/c/pp_errors.h"
-#include "ppapi/c/private/ppb_net_address_private.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/error_conversion.h"
#include "ppapi/host/ppapi_host.h"
@@ -30,6 +35,7 @@
#include "ppapi/shared_impl/api_id.h"
#include "ppapi/shared_impl/ppb_tcp_socket_shared.h"
#include "ppapi/shared_impl/private/net_address_private_impl.h"
+#include "services/network/public/mojom/network_context.mojom.h"
#if defined(OS_CHROMEOS)
#include "chromeos/network/firewall_hole.h"
@@ -40,12 +46,15 @@ using ppapi::host::NetErrorToPepperError;
namespace {
-size_t g_num_instances = 0;
+static size_t g_num_instances = 0;
} // namespace
namespace content {
+network::mojom::NetworkContext*
+ PepperTCPServerSocketMessageFilter::network_context_for_testing = nullptr;
+
PepperTCPServerSocketMessageFilter::PepperTCPServerSocketMessageFilter(
ContentBrowserPepperHostFactory* factory,
BrowserPpapiHostImpl* host,
@@ -55,10 +64,12 @@ PepperTCPServerSocketMessageFilter::PepperTCPServerSocketMessageFilter(
factory_(factory),
instance_(instance),
state_(STATE_BEFORE_LISTENING),
+ bound_addr_(NetAddressPrivateImpl::kInvalidNetAddress),
external_plugin_(host->external_plugin()),
private_api_(private_api),
render_process_id_(0),
- render_frame_id_(0) {
+ render_frame_id_(0),
+ weak_ptr_factory_(this) {
++g_num_instances;
DCHECK(factory_);
DCHECK(ppapi_host_);
@@ -73,19 +84,35 @@ PepperTCPServerSocketMessageFilter::~PepperTCPServerSocketMessageFilter() {
}
// static
+void PepperTCPServerSocketMessageFilter::SetNetworkContextForTesting(
+ network::mojom::NetworkContext* network_context) {
+ network_context_for_testing = network_context;
+}
+
+// static
size_t PepperTCPServerSocketMessageFilter::GetNumInstances() {
return g_num_instances;
}
+void PepperTCPServerSocketMessageFilter::OnFilterDestroyed() {
+ ResourceMessageFilter::OnFilterDestroyed();
+ // Need to close all mojo pipes the socket on the UI thread. Calling Close()
+ // also ensures that future messages will be ignored, so the mojo pipes won't
+ // be re-created, so after Close() runs, |this| can be safely deleted on the
+ // IO thread.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&PepperTCPServerSocketMessageFilter::Close, this));
+}
+
scoped_refptr<base::TaskRunner>
PepperTCPServerSocketMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& message) {
switch (message.type()) {
case PpapiHostMsg_TCPServerSocket_Listen::ID:
- return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
case PpapiHostMsg_TCPServerSocket_Accept::ID:
case PpapiHostMsg_TCPServerSocket_StopListening::ID:
- return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+ return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
}
return nullptr;
}
@@ -122,16 +149,45 @@ int32_t PepperTCPServerSocketMessageFilter::OnMsgListen(
return PP_ERROR_NOACCESS;
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&PepperTCPServerSocketMessageFilter::DoListen, this,
- context->MakeReplyMessageContext(), addr, backlog));
+ net::IPAddressBytes address;
+ uint16_t port;
+
+ if (state_ != STATE_BEFORE_LISTENING ||
+ !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
+ Close();
+ return PP_ERROR_FAILED;
+ }
+
+ network::mojom::NetworkContext* network_context = network_context_for_testing;
+ if (!network_context) {
+ RenderProcessHost* render_process_host =
+ RenderProcessHost::FromID(render_process_id_);
+ network_context =
+ render_process_host->GetStoragePartition()->GetNetworkContext();
+ if (!network_context)
+ return PP_ERROR_FAILED;
+ }
+
+ state_ = STATE_LISTEN_IN_PROGRESS;
+
+ ppapi::host::ReplyMessageContext reply_context =
+ context->MakeReplyMessageContext();
+
+ network_context->CreateTCPServerSocket(
+ net::IPEndPoint(net::IPAddress(address), port), backlog,
+ pepper_socket_utils::PepperTCPNetworkAnnotationTag(),
+ mojo::MakeRequest(&socket_),
+ mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+ base::BindOnce(&PepperTCPServerSocketMessageFilter::OnListenCompleted,
+ weak_ptr_factory_.GetWeakPtr(), reply_context),
+ net::ERR_FAILED, base::nullopt /* local_addr_out */));
+
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperTCPServerSocketMessageFilter::OnMsgAccept(
const ppapi::host::HostMessageContext* context) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(context);
if (state_ != STATE_LISTENING)
@@ -140,190 +196,193 @@ int32_t PepperTCPServerSocketMessageFilter::OnMsgAccept(
state_ = STATE_ACCEPT_IN_PROGRESS;
ppapi::host::ReplyMessageContext reply_context(
context->MakeReplyMessageContext());
- int net_result = socket_->Accept(
- &accepted_socket_, &accepted_address_,
- base::Bind(&PepperTCPServerSocketMessageFilter::OnAcceptCompleted,
- base::Unretained(this), reply_context));
- if (net_result != net::ERR_IO_PENDING)
- OnAcceptCompleted(reply_context, net_result);
+
+ network::mojom::SocketObserverPtr socket_observer;
+ network::mojom::SocketObserverRequest socket_observer_request =
+ mojo::MakeRequest(&socket_observer);
+ socket_->Accept(
+ std::move(socket_observer),
+ mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+ base::BindOnce(&PepperTCPServerSocketMessageFilter::OnAcceptCompleted,
+ base::Unretained(this), reply_context,
+ std::move(socket_observer_request)),
+ net::ERR_FAILED, base::nullopt /* remote_addr */,
+ network::mojom::TCPConnectedSocketPtr(),
+ mojo::ScopedDataPipeConsumerHandle(),
+ mojo::ScopedDataPipeProducerHandle()));
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperTCPServerSocketMessageFilter::OnMsgStopListening(
const ppapi::host::HostMessageContext* context) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(context);
- state_ = STATE_CLOSED;
- socket_.reset();
-#if defined(OS_CHROMEOS)
- firewall_hole_.reset();
-#endif // defined(OS_CHROMEOS)
+ Close();
return PP_OK;
}
-void PepperTCPServerSocketMessageFilter::DoListen(
+void PepperTCPServerSocketMessageFilter::OnListenCompleted(
const ppapi::host::ReplyMessageContext& context,
- const PP_NetAddress_Private& addr,
- int32_t backlog) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ int net_result,
+ const base::Optional<net::IPEndPoint>& local_addr) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
- net::IPAddressBytes address;
- uint16_t port;
- if (state_ != STATE_BEFORE_LISTENING ||
- !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
+ // Exit early if this is called during Close().
+ if (state_ == STATE_CLOSED) {
+ DCHECK_EQ(net::ERR_FAILED, net_result);
SendListenError(context, PP_ERROR_FAILED);
- state_ = STATE_CLOSED;
return;
}
- state_ = STATE_LISTEN_IN_PROGRESS;
-
- socket_.reset(new net::TCPSocket(nullptr, nullptr, net::NetLogSource()));
- int net_result = net::OK;
- do {
- net::IPEndPoint ip_end_point(net::IPAddress(address), port);
- net_result = socket_->Open(ip_end_point.GetFamily());
- if (net_result != net::OK)
- break;
- net_result = socket_->SetDefaultOptionsForServer();
- if (net_result != net::OK)
- break;
- net_result = socket_->Bind(ip_end_point);
- if (net_result != net::OK)
- break;
- net_result = socket_->Listen(backlog);
- } while (false);
-
- if (net_result != net::ERR_IO_PENDING) {
-#if defined(OS_CHROMEOS)
- OpenFirewallHole(context, net_result);
-#else
- OnListenCompleted(context, net_result);
-#endif
- }
-}
+ DCHECK(socket_.is_bound());
+ DCHECK_EQ(state_, STATE_LISTEN_IN_PROGRESS);
-void PepperTCPServerSocketMessageFilter::OnListenCompleted(
- const ppapi::host::ReplyMessageContext& context,
- int net_result) {
- if (state_ != STATE_LISTEN_IN_PROGRESS) {
- SendListenError(context, PP_ERROR_FAILED);
- state_ = STATE_CLOSED;
- return;
- }
if (net_result != net::OK) {
SendListenError(context, NetErrorToPepperError(net_result));
+ socket_.reset();
state_ = STATE_BEFORE_LISTENING;
return;
}
- DCHECK(socket_.get());
-
- net::IPEndPoint end_point;
- PP_NetAddress_Private addr;
-
- int32_t pp_result =
- NetErrorToPepperError(socket_->GetLocalAddress(&end_point));
- if (pp_result != PP_OK) {
- SendListenError(context, pp_result);
- state_ = STATE_BEFORE_LISTENING;
- return;
- }
- if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
- end_point.address().bytes(), end_point.port(), &addr)) {
+ if (!local_addr ||
+ !NetAddressPrivateImpl::IPEndPointToNetAddress(
+ local_addr->address().bytes(), local_addr->port(), &bound_addr_)) {
SendListenError(context, PP_ERROR_FAILED);
+ socket_.reset();
state_ = STATE_BEFORE_LISTENING;
return;
}
- SendListenReply(context, PP_OK, addr);
+#if defined(OS_CHROMEOS)
+ OpenFirewallHole(context, *local_addr);
+#else
+ SendListenReply(context, PP_OK, bound_addr_);
state_ = STATE_LISTENING;
+#endif
}
#if defined(OS_CHROMEOS)
void PepperTCPServerSocketMessageFilter::OpenFirewallHole(
const ppapi::host::ReplyMessageContext& context,
- int net_result) {
- if (net_result != net::OK) {
- return;
- }
- net::IPEndPoint local_addr;
- socket_->GetLocalAddress(&local_addr);
- pepper_socket_utils::FirewallHoleOpenCallback callback =
- base::Bind(&PepperTCPServerSocketMessageFilter::OnFirewallHoleOpened,
- this, context, net_result);
+ const net::IPEndPoint& local_addr) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ pepper_socket_utils::FirewallHoleOpenCallback callback = base::BindRepeating(
+ &PepperTCPServerSocketMessageFilter::OnFirewallHoleOpened, this, context);
pepper_socket_utils::OpenTCPFirewallHole(local_addr, callback);
}
void PepperTCPServerSocketMessageFilter::OnFirewallHoleOpened(
const ppapi::host::ReplyMessageContext& context,
- int32_t net_result,
std::unique_ptr<chromeos::FirewallHole> hole) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
LOG_IF(WARNING, !hole.get()) << "Firewall hole could not be opened.";
firewall_hole_.reset(hole.release());
- OnListenCompleted(context, net_result);
+
+ SendListenReply(context, PP_OK, bound_addr_);
+ state_ = STATE_LISTENING;
}
#endif // defined(OS_CHROMEOS)
void PepperTCPServerSocketMessageFilter::OnAcceptCompleted(
const ppapi::host::ReplyMessageContext& context,
- int net_result) {
- if (state_ != STATE_ACCEPT_IN_PROGRESS) {
- SendAcceptError(context, PP_ERROR_FAILED);
- state_ = STATE_CLOSED;
+ network::mojom::SocketObserverRequest socket_observer_request,
+ int net_result,
+ const base::Optional<net::IPEndPoint>& remote_addr,
+ network::mojom::TCPConnectedSocketPtr connected_socket,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // Exit early if this is called during Close().
+ if (state_ == STATE_CLOSED) {
+ DCHECK_EQ(net::ERR_FAILED, net_result);
+ SendListenError(context, PP_ERROR_FAILED);
return;
}
- state_ = STATE_LISTENING;
+ DCHECK_EQ(state_, STATE_ACCEPT_IN_PROGRESS);
+ state_ = STATE_LISTENING;
if (net_result != net::OK) {
SendAcceptError(context, NetErrorToPepperError(net_result));
return;
}
- DCHECK(accepted_socket_.get());
-
- net::IPEndPoint ip_end_point_local;
- PP_NetAddress_Private local_addr = NetAddressPrivateImpl::kInvalidNetAddress;
- PP_NetAddress_Private remote_addr = NetAddressPrivateImpl::kInvalidNetAddress;
-
- int32_t pp_result = NetErrorToPepperError(
- accepted_socket_->GetLocalAddress(&ip_end_point_local));
- if (pp_result != PP_OK) {
- SendAcceptError(context, pp_result);
+ if (!remote_addr || !connected_socket.is_bound()) {
+ SendAcceptError(context, NetErrorToPepperError(net_result));
return;
}
+
+ DCHECK(socket_observer_request.is_pending());
+
+ PP_NetAddress_Private pp_remote_addr =
+ NetAddressPrivateImpl::kInvalidNetAddress;
+
if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
- ip_end_point_local.address().bytes(), ip_end_point_local.port(),
- &local_addr) ||
- !NetAddressPrivateImpl::IPEndPointToNetAddress(
- accepted_address_.address().bytes(), accepted_address_.port(),
- &remote_addr)) {
- SendAcceptError(context, PP_ERROR_FAILED);
+ remote_addr->address().bytes(), remote_addr->port(),
+ &pp_remote_addr)) {
+ SendAcceptError(context, PP_ERROR_ADDRESS_INVALID);
return;
}
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(
+ &PepperTCPServerSocketMessageFilter::OnAcceptCompletedOnIOThread,
+ this, context, connected_socket.PassInterface(),
+ std::move(socket_observer_request), std::move(receive_stream),
+ std::move(send_stream), bound_addr_, pp_remote_addr));
+}
+
+void PepperTCPServerSocketMessageFilter::OnAcceptCompletedOnIOThread(
+ const ppapi::host::ReplyMessageContext& context,
+ network::mojom::TCPConnectedSocketPtrInfo connected_socket,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream,
+ PP_NetAddress_Private pp_local_addr,
+ PP_NetAddress_Private pp_remote_addr) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // |factory_| is guaranteed to be non-NULL here. Only those instances created
+ // in CONNECTED state have a NULL |factory_|, while getting here requires
+ // LISTENING state.
std::unique_ptr<ppapi::host::ResourceHost> host =
- factory_->CreateAcceptedTCPSocket(instance_,
- ppapi::TCP_SOCKET_VERSION_PRIVATE,
- std::move(accepted_socket_));
+ factory_->CreateAcceptedTCPSocket(
+ instance_, ppapi::TCP_SOCKET_VERSION_PRIVATE,
+ std::move(connected_socket), std::move(socket_observer_request),
+ std::move(receive_stream), std::move(send_stream));
if (!host) {
SendAcceptError(context, PP_ERROR_NOSPACE);
return;
}
- int pending_resource_id =
- ppapi_host_->AddPendingResourceHost(std::move(host));
- if (pending_resource_id) {
- SendAcceptReply(
- context, PP_OK, pending_resource_id, local_addr, remote_addr);
+
+ int pending_host_id = ppapi_host_->AddPendingResourceHost(std::move(host));
+ if (pending_host_id) {
+ SendAcceptReply(context, PP_OK, pending_host_id, pp_local_addr,
+ pp_remote_addr);
} else {
SendAcceptError(context, PP_ERROR_NOSPACE);
}
}
+void PepperTCPServerSocketMessageFilter::Close() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // Need to do these first, as destroying Mojo pipes may invoke some of the
+ // callbacks with failure messages.
+ weak_ptr_factory_.InvalidateWeakPtrs();
+ state_ = STATE_CLOSED;
+
+ socket_.reset();
+#if defined(OS_CHROMEOS)
+ firewall_hole_.reset();
+#endif // defined(OS_CHROMEOS)
+}
+
void PepperTCPServerSocketMessageFilter::SendListenReply(
const ppapi::host::ReplyMessageContext& context,
int32_t pp_result,
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h b/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h
index 9c7be218c21..96456ab062c 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h
@@ -13,20 +13,28 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
+#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/ip_endpoint.h"
-#include "net/socket/tcp_socket.h"
#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/private/ppb_net_address_private.h"
#include "ppapi/host/resource_message_filter.h"
-
-struct PP_NetAddress_Private;
+#include "services/network/public/mojom/tcp_socket.mojom.h"
#if defined(OS_CHROMEOS)
#include "chromeos/network/firewall_hole.h"
#include "content/public/browser/browser_thread.h"
#endif // defined(OS_CHROMEOS)
+namespace network {
+namespace mojom {
+class NetworkContext;
+}
+} // namespace network
+
namespace ppapi {
namespace host {
class PpapiHost;
@@ -48,6 +56,11 @@ class CONTENT_EXPORT PepperTCPServerSocketMessageFilter
PP_Instance instance,
bool private_api);
+ // Sets a global NetworkContext object to be used instead of the real one for
+ // doing all network operations.
+ static void SetNetworkContextForTesting(
+ network::mojom::NetworkContext* network_context);
+
static size_t GetNumInstances();
protected:
@@ -63,6 +76,7 @@ class CONTENT_EXPORT PepperTCPServerSocketMessageFilter
};
// ppapi::host::ResourceMessageFilter overrides.
+ void OnFilterDestroyed() override;
scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
const IPC::Message& message) override;
int32_t OnResourceMessageReceived(
@@ -76,13 +90,31 @@ class CONTENT_EXPORT PepperTCPServerSocketMessageFilter
int32_t OnMsgStopListening(const ppapi::host::HostMessageContext* context);
void DoListen(const ppapi::host::ReplyMessageContext& context,
- const PP_NetAddress_Private& addr,
int32_t backlog);
void OnListenCompleted(const ppapi::host::ReplyMessageContext& context,
- int net_result);
- void OnAcceptCompleted(const ppapi::host::ReplyMessageContext& context,
- int net_result);
+ int net_result,
+ const base::Optional<net::IPEndPoint>& local_addr);
+ void OnAcceptCompleted(
+ const ppapi::host::ReplyMessageContext& context,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ int net_result,
+ const base::Optional<net::IPEndPoint>& remote_addr,
+ network::mojom::TCPConnectedSocketPtr connected_socket,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream);
+ void OnAcceptCompletedOnIOThread(
+ const ppapi::host::ReplyMessageContext& context,
+ network::mojom::TCPConnectedSocketPtrInfo connected_socket,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream,
+ PP_NetAddress_Private pp_local_addr,
+ PP_NetAddress_Private pp_remote_addr);
+
+ // Closes the socket and FirewallHole, if they're open, and prevents
+ // |this| from being used further, even with a new socket.
+ void Close();
void SendListenReply(const ppapi::host::ReplyMessageContext& context,
int32_t pp_result,
@@ -99,9 +131,8 @@ class CONTENT_EXPORT PepperTCPServerSocketMessageFilter
#if defined(OS_CHROMEOS)
void OpenFirewallHole(const ppapi::host::ReplyMessageContext& context,
- int net_result);
+ const net::IPEndPoint& local_addr);
void OnFirewallHoleOpened(const ppapi::host::ReplyMessageContext& context,
- int32_t net_result,
std::unique_ptr<chromeos::FirewallHole> hole);
#endif // defined(OS_CHROMEOS)
@@ -113,9 +144,9 @@ class CONTENT_EXPORT PepperTCPServerSocketMessageFilter
PP_Instance instance_;
State state_;
- std::unique_ptr<net::TCPSocket> socket_;
- std::unique_ptr<net::TCPSocket> accepted_socket_;
- net::IPEndPoint accepted_address_;
+ network::mojom::TCPServerSocketPtr socket_;
+
+ PP_NetAddress_Private bound_addr_;
#if defined(OS_CHROMEOS)
std::unique_ptr<chromeos::FirewallHole,
@@ -130,6 +161,13 @@ class CONTENT_EXPORT PepperTCPServerSocketMessageFilter
int render_process_id_;
int render_frame_id_;
+ // Used in place of the StoragePartition's NetworkContext when non-null.
+ static network::mojom::NetworkContext* network_context_for_testing;
+
+ // Vends weak pointers on the UI thread, for callbacks passed through Mojo
+ // pipes not owned by |this|. All weak pointers released in Close().
+ base::WeakPtrFactory<PepperTCPServerSocketMessageFilter> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(PepperTCPServerSocketMessageFilter);
};
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
index 6eb9ecd9c87..2e6b9ce144f 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc
@@ -6,21 +6,24 @@
#include <cstring>
#include <utility>
-#include <vector>
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h"
#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/socket_permission_request.h"
+#include "mojo/public/cpp/bindings/callback_helpers.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
#include "net/base/address_family.h"
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
@@ -28,10 +31,7 @@
#include "net/base/net_errors.h"
#include "net/log/net_log_source.h"
#include "net/log/net_log_with_source.h"
-#include "net/socket/client_socket_factory.h"
-#include "net/socket/client_socket_handle.h"
-#include "net/socket/ssl_client_socket.h"
-#include "net/socket/tcp_client_socket.h"
+#include "net/ssl/ssl_info.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/error_conversion.h"
@@ -46,10 +46,10 @@
#endif // defined(OS_CHROMEOS)
using ppapi::NetAddressPrivateImpl;
-using ppapi::host::NetErrorToPepperError;
-using ppapi::proxy::TCPSocketResourceConstants;
using ppapi::TCPSocketState;
using ppapi::TCPSocketVersion;
+using ppapi::host::NetErrorToPepperError;
+using ppapi::proxy::TCPSocketResourceConstants;
namespace {
@@ -59,99 +59,115 @@ size_t g_num_tcp_filter_instances = 0;
namespace content {
+network::mojom::NetworkContext*
+ PepperTCPSocketMessageFilter::network_context_for_testing = nullptr;
+
PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter(
ContentBrowserPepperHostFactory* factory,
BrowserPpapiHostImpl* host,
PP_Instance instance,
TCPSocketVersion version)
: version_(version),
+ host_(host),
+ factory_(factory),
+ instance_(instance),
external_plugin_(host->external_plugin()),
render_process_id_(0),
render_frame_id_(0),
binding_(this),
- host_(host),
- factory_(factory),
- instance_(instance),
+ socket_observer_binding_(this),
state_(TCPSocketState::INITIAL),
- end_of_file_reached_(false),
bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress),
socket_options_(SOCKET_OPTION_NODELAY),
rcvbuf_size_(0),
sndbuf_size_(0),
- address_index_(0),
- socket_(new net::TCPSocket(nullptr, nullptr, net::NetLogSource())),
- ssl_context_helper_(host->ssl_context_helper()),
pending_accept_(false),
+ pending_read_size_(0),
+ pending_read_pp_error_(PP_OK_COMPLETIONPENDING),
pending_read_on_unthrottle_(false),
- pending_read_net_result_(0),
+ pending_write_bytes_written_(0),
+ pending_write_pp_error_(PP_OK_COMPLETIONPENDING),
is_potentially_secure_plugin_context_(
- host->IsPotentiallySecurePluginContext(instance)) {
+ host->IsPotentiallySecurePluginContext(instance)),
+ weak_ptr_factory_(this) {
DCHECK(host);
DCHECK_CURRENTLY_ON(BrowserThread::IO);
++g_num_tcp_filter_instances;
host_->AddInstanceObserver(instance_, this);
- if (!host->GetRenderFrameIDsForInstance(
- instance, &render_process_id_, &render_frame_id_)) {
+ is_throttled_ = host_->IsThrottled(instance_);
+ if (!host->GetRenderFrameIDsForInstance(instance, &render_process_id_,
+ &render_frame_id_)) {
NOTREACHED();
}
}
-PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter(
- BrowserPpapiHostImpl* host,
- PP_Instance instance,
- TCPSocketVersion version,
- std::unique_ptr<net::TCPSocket> socket)
- : version_(version),
- external_plugin_(host->external_plugin()),
- render_process_id_(0),
- render_frame_id_(0),
- binding_(this),
- host_(host),
- factory_(nullptr),
- instance_(instance),
- state_(TCPSocketState::CONNECTED),
- end_of_file_reached_(false),
- bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress),
- socket_options_(SOCKET_OPTION_NODELAY),
- rcvbuf_size_(0),
- sndbuf_size_(0),
- address_index_(0),
- socket_(std::move(socket)),
- ssl_context_helper_(host->ssl_context_helper()),
- pending_accept_(false),
- pending_read_on_unthrottle_(false),
- pending_read_net_result_(0),
- is_potentially_secure_plugin_context_(
- host->IsPotentiallySecurePluginContext(instance)) {
- DCHECK(host);
- DCHECK_NE(version, ppapi::TCP_SOCKET_VERSION_1_0);
+void PepperTCPSocketMessageFilter::SetConnectedSocket(
+ network::mojom::TCPConnectedSocketPtrInfo connected_socket,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- ++g_num_tcp_filter_instances;
- host_->AddInstanceObserver(instance_, this);
- if (!host->GetRenderFrameIDsForInstance(
- instance, &render_process_id_, &render_frame_id_)) {
- NOTREACHED();
- }
+ // This method grabs a reference to |this|, and releases a reference on the UI
+ // thread, so something should be holding on to a reference on the current
+ // thread to prevent the object from being deleted before this method returns.
+ DCHECK(HasOneRef());
+
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(
+ &PepperTCPSocketMessageFilter::SetConnectedSocketOnUIThread, this,
+ std::move(connected_socket), std::move(socket_observer_request),
+ std::move(receive_stream), std::move(send_stream)));
}
PepperTCPSocketMessageFilter::~PepperTCPSocketMessageFilter() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (host_)
host_->RemoveInstanceObserver(instance_, this);
- if (socket_)
- socket_->Close();
- if (ssl_socket_)
- ssl_socket_->Disconnect();
--g_num_tcp_filter_instances;
}
+void PepperTCPSocketMessageFilter::SetConnectedSocketOnUIThread(
+ network::mojom::TCPConnectedSocketPtrInfo connected_socket,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK_EQ(state_.state(), TCPSocketState::INITIAL);
+
+ state_ = TCPSocketState(TCPSocketState::CONNECTED);
+ connected_socket_.Bind(std::move(connected_socket));
+ socket_observer_binding_.Bind(std::move(socket_observer_request));
+ socket_observer_binding_.set_connection_error_handler(
+ base::BindOnce(&PepperTCPSocketMessageFilter::OnSocketObserverError,
+ base::Unretained(this)));
+
+ SetStreams(std::move(receive_stream), std::move(send_stream));
+}
+
+// static
+void PepperTCPSocketMessageFilter::SetNetworkContextForTesting(
+ network::mojom::NetworkContext* network_context) {
+ network_context_for_testing = network_context;
+}
+
// static
size_t PepperTCPSocketMessageFilter::GetNumInstances() {
return g_num_tcp_filter_instances;
}
+void PepperTCPSocketMessageFilter::OnFilterDestroyed() {
+ ResourceMessageFilter::OnFilterDestroyed();
+ // Need to close all mojo pipes the socket on the UI thread. Calling Close()
+ // also ensures that future messages will be ignored, so the mojo pipes won't
+ // be re-created, so after Close() runs, |this| can be safely deleted on the
+ // IO thread.
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&PepperTCPSocketMessageFilter::Close, this));
+}
+
scoped_refptr<base::TaskRunner>
PepperTCPSocketMessageFilter::OverrideTaskRunnerForMessage(
const IPC::Message& message) {
@@ -160,14 +176,13 @@ PepperTCPSocketMessageFilter::OverrideTaskRunnerForMessage(
case PpapiHostMsg_TCPSocket_Connect::ID:
case PpapiHostMsg_TCPSocket_ConnectWithNetAddress::ID:
case PpapiHostMsg_TCPSocket_Listen::ID:
- return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
case PpapiHostMsg_TCPSocket_SSLHandshake::ID:
case PpapiHostMsg_TCPSocket_Read::ID:
case PpapiHostMsg_TCPSocket_Write::ID:
case PpapiHostMsg_TCPSocket_Accept::ID:
case PpapiHostMsg_TCPSocket_Close::ID:
case PpapiHostMsg_TCPSocket_SetOption::ID:
- return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+ return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
}
return nullptr;
}
@@ -199,13 +214,11 @@ int32_t PepperTCPSocketMessageFilter::OnResourceMessageReceived(
}
void PepperTCPSocketMessageFilter::OnThrottleStateChanged(bool is_throttled) {
- if (pending_read_on_unthrottle_ && !is_throttled) {
- DCHECK(read_buffer_);
- OnReadCompleted(pending_read_reply_message_context_,
- pending_read_net_result_);
- DCHECK(!read_buffer_);
- pending_read_on_unthrottle_ = false;
- }
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(
+ &PepperTCPSocketMessageFilter::ThrottleStateChangedOnUIThread, this,
+ is_throttled));
}
void PepperTCPSocketMessageFilter::OnHostDestroyed() {
@@ -214,18 +227,86 @@ void PepperTCPSocketMessageFilter::OnHostDestroyed() {
host_ = nullptr;
}
+void PepperTCPSocketMessageFilter::ThrottleStateChangedOnUIThread(
+ bool is_throttled) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ is_throttled_ = is_throttled;
+
+ if (pending_read_on_unthrottle_ && !is_throttled) {
+ pending_read_on_unthrottle_ = false;
+ TryRead();
+ }
+}
+
void PepperTCPSocketMessageFilter::OnComplete(
int result,
const base::Optional<net::AddressList>& resolved_addresses) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
binding_.Close();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&PepperTCPSocketMessageFilter::OnResolveCompleted, this,
- result, std::move(resolved_addresses)));
+ if (!host_resolve_context_.is_valid())
+ return;
+
+ ppapi::host::ReplyMessageContext context = host_resolve_context_;
+ host_resolve_context_ = ppapi::host::ReplyMessageContext();
+
+ if (!state_.IsPending(TCPSocketState::CONNECT)) {
+ DCHECK(state_.state() == TCPSocketState::CLOSED);
+ SendConnectError(context, PP_ERROR_FAILED);
+ return;
+ }
+
+ if (result != net::OK) {
+ SendConnectError(context, NetErrorToPepperError(result));
+ state_.CompletePendingTransition(false);
+ return;
+ }
+
+ StartConnect(context, resolved_addresses.value());
+}
+
+void PepperTCPSocketMessageFilter::OnReadError(int net_error) {
+ // If this method is called more than once, or |net_error| isn't an allowed
+ // value, just ignore the message.
+ if (pending_read_pp_error_ != PP_OK_COMPLETIONPENDING || net_error > 0 ||
+ net_error == net::ERR_IO_PENDING) {
+ return;
+ }
+
+ pending_read_pp_error_ = NetErrorToPepperError(net_error);
+ // Complete pending read with the error message if there's a pending read, and
+ // the read data pipe has already been closed. If the pipe is still open, need
+ // to wait until all data has been read before can start failing reads.
+ if (pending_read_context_.is_valid() && !receive_stream_ &&
+ !pending_read_on_unthrottle_) {
+ TryRead();
+ }
+}
+
+void PepperTCPSocketMessageFilter::OnWriteError(int net_error) {
+ // If this method is called more than once, or |net_error| isn't an allowed
+ // value, just ignore the message.
+ if (pending_write_pp_error_ != PP_OK_COMPLETIONPENDING || net_error > 0 ||
+ net_error == net::ERR_IO_PENDING) {
+ return;
+ }
+
+ pending_write_pp_error_ = NetErrorToPepperError(net_error);
+ // Complete pending write with the error message if there's a pending write,
+ // and the write data pipe has already been closed.
+ if (pending_write_context_.is_valid() && !send_stream_)
+ TryWrite();
+}
+
+void PepperTCPSocketMessageFilter::OnSocketObserverError() {
+ // Note that this method may be called while a connection is still being made.
+ socket_observer_binding_.Close();
- Release(); // Balances AddRef in OnMsgConnect.
+ // Treat this as a read and write error. If read and write errors have already
+ // been received, these calls will do nothing.
+ OnReadError(PP_ERROR_FAILED);
+ OnWriteError(PP_ERROR_FAILED);
}
int32_t PepperTCPSocketMessageFilter::OnMsgBind(
@@ -245,12 +326,45 @@ int32_t PepperTCPSocketMessageFilter::OnMsgBind(
return PP_ERROR_NOACCESS;
}
+ if (state_.IsPending(TCPSocketState::BIND))
+ return PP_ERROR_INPROGRESS;
+
+ if (!state_.IsValidTransition(TCPSocketState::BIND))
+ return PP_ERROR_FAILED;
+
+ DCHECK(!bound_socket_);
+ DCHECK(!connected_socket_);
+ DCHECK(!server_socket_);
+
+ // Validate address.
+ net::IPAddressBytes address;
+ uint16_t port;
+ if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(net_addr, &address,
+ &port)) {
+ state_.DoTransition(TCPSocketState::BIND, false);
+ return PP_ERROR_ADDRESS_INVALID;
+ }
+
+ network::mojom::NetworkContext* network_context = GetNetworkContext();
+ if (!network_context)
+ return PP_ERROR_FAILED;
+
+ // The network service doesn't allow binding a socket without first
+ // specifying if it's going to be used as a read or write socket,
+ // so just hold onto the address for now, without actually binding anything.
bind_input_addr_ = net_addr;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&PepperTCPSocketMessageFilter::DoBind, this,
- context->MakeReplyMessageContext(), net_addr));
+ state_.SetPendingTransition(TCPSocketState::BIND);
+ network_context->CreateTCPBoundSocket(
+ net::IPEndPoint(net::IPAddress(address), port),
+ pepper_socket_utils::PepperTCPNetworkAnnotationTag(),
+ mojo::MakeRequest(&bound_socket_),
+ mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+ base::BindOnce(&PepperTCPSocketMessageFilter::OnBindCompleted,
+ weak_ptr_factory_.GetWeakPtr(),
+ context->MakeReplyMessageContext()),
+ net::ERR_FAILED, base::nullopt /* local_addr */));
+
return PP_OK_COMPLETIONPENDING;
}
@@ -266,39 +380,34 @@ int32_t PepperTCPSocketMessageFilter::OnMsgConnect(
return PP_ERROR_NOACCESS;
}
- SocketPermissionRequest request(
- SocketPermissionRequest::TCP_CONNECT, host, port);
- if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_,
- true /* private_api */,
- &request,
- render_process_id_,
- render_frame_id_)) {
+ SocketPermissionRequest request(SocketPermissionRequest::TCP_CONNECT, host,
+ port);
+ if (!pepper_socket_utils::CanUseSocketAPIs(
+ external_plugin_, true /* private_api */, &request,
+ render_process_id_, render_frame_id_)) {
return PP_ERROR_NOACCESS;
}
- RenderProcessHost* render_process_host =
- RenderProcessHost::FromID(render_process_id_);
- if (!render_process_host)
+ if (!state_.IsValidTransition(TCPSocketState::CONNECT)) {
+ NOTREACHED() << "This shouldn't be reached since the renderer only tries "
+ << "to connect once.";
+ return PP_ERROR_FAILED;
+ }
+
+ network::mojom::NetworkContext* network_context = GetNetworkContext();
+ if (!network_context)
return PP_ERROR_FAILED;
- auto* storage_partition = render_process_host->GetStoragePartition();
- // Grab a reference to this class to ensure that it's fully alive if a
- // connection error occurs (i.e. ref count is higher than 0 and there's no
- // task from ResourceMessageFilterDeleteTraits to delete this object on the IO
- // thread pending). Balanced in OnComplete();
- AddRef();
network::mojom::ResolveHostClientPtr client_ptr;
binding_.Bind(mojo::MakeRequest(&client_ptr));
binding_.set_connection_error_handler(
base::BindOnce(&PepperTCPSocketMessageFilter::OnComplete,
base::Unretained(this), net::ERR_FAILED, base::nullopt));
- storage_partition->GetNetworkContext()->ResolveHost(
- net::HostPortPair(host, port), nullptr, std::move(client_ptr));
+ network_context->ResolveHost(net::HostPortPair(host, port), nullptr,
+ std::move(client_ptr));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&PepperTCPSocketMessageFilter::HostResolvingStarted, this,
- context->MakeReplyMessageContext()));
+ state_.SetPendingTransition(TCPSocketState::CONNECT);
+ host_resolve_context_ = context->MakeReplyMessageContext();
return PP_OK_COMPLETIONPENDING;
}
@@ -310,18 +419,28 @@ int32_t PepperTCPSocketMessageFilter::OnMsgConnectWithNetAddress(
content::SocketPermissionRequest request =
pepper_socket_utils::CreateSocketPermissionRequest(
content::SocketPermissionRequest::TCP_CONNECT, net_addr);
- if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_,
- IsPrivateAPI(),
- &request,
- render_process_id_,
+ if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, IsPrivateAPI(),
+ &request, render_process_id_,
render_frame_id_)) {
return PP_ERROR_NOACCESS;
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&PepperTCPSocketMessageFilter::DoConnectWithNetAddress,
- this, context->MakeReplyMessageContext(), net_addr));
+ if (!state_.IsValidTransition(TCPSocketState::CONNECT))
+ return PP_ERROR_FAILED;
+
+ state_.SetPendingTransition(TCPSocketState::CONNECT);
+
+ net::IPAddressBytes address;
+ uint16_t port;
+ if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(net_addr, &address,
+ &port)) {
+ state_.CompletePendingTransition(false);
+ return PP_ERROR_ADDRESS_INVALID;
+ }
+
+ StartConnect(
+ context->MakeReplyMessageContext(),
+ net::AddressList(net::IPEndPoint(net::IPAddress(address), port)));
return PP_OK_COMPLETIONPENDING;
}
@@ -329,103 +448,101 @@ int32_t PepperTCPSocketMessageFilter::OnMsgSSLHandshake(
const ppapi::host::HostMessageContext* context,
const std::string& server_name,
uint16_t server_port,
- const std::vector<std::vector<char> >& trusted_certs,
- const std::vector<std::vector<char> >& untrusted_certs) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ const std::vector<std::vector<char>>& trusted_certs,
+ const std::vector<std::vector<char>>& untrusted_certs) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Allow to do SSL handshake only if currently the socket has been connected
// and there isn't pending read or write.
if (!state_.IsValidTransition(TCPSocketState::SSL_CONNECT) ||
- read_buffer_.get() || write_buffer_base_.get() || write_buffer_.get()) {
+ pending_read_context_.is_valid() || pending_write_context_.is_valid()) {
return PP_ERROR_FAILED;
}
- // TODO(raymes,rsleevi): Use trusted/untrusted certificates when connecting.
- net::IPEndPoint peer_address;
- if (socket_->GetPeerAddress(&peer_address) != net::OK)
- return PP_ERROR_FAILED;
+ // If there's a pending read or write error, fail the request with that.
+ if (pending_read_pp_error_ != PP_OK_COMPLETIONPENDING) {
+ if (pending_read_pp_error_ == PP_OK)
+ pending_read_pp_error_ = PP_ERROR_FAILED;
+ return pending_read_pp_error_;
+ }
- std::unique_ptr<net::ClientSocketHandle> handle(
- new net::ClientSocketHandle());
- handle->SetSocket(base::WrapUnique<net::StreamSocket>(
- new net::TCPClientSocket(std::move(socket_), peer_address)));
- net::ClientSocketFactory* factory =
- net::ClientSocketFactory::GetDefaultFactory();
- net::HostPortPair host_port_pair(server_name, server_port);
- net::SSLClientSocketContext ssl_context;
- ssl_context.cert_verifier = ssl_context_helper_->GetCertVerifier();
- ssl_context.transport_security_state =
- ssl_context_helper_->GetTransportSecurityState();
- ssl_context.cert_transparency_verifier =
- ssl_context_helper_->GetCertTransparencyVerifier();
- ssl_context.ct_policy_enforcer = ssl_context_helper_->GetCTPolicyEnforcer();
- ssl_socket_ = factory->CreateSSLClientSocket(
- std::move(handle), host_port_pair, ssl_context_helper_->ssl_config(),
- ssl_context);
- if (!ssl_socket_) {
- LOG(WARNING) << "Failed to create an SSL client socket.";
- state_.CompletePendingTransition(false);
- return PP_ERROR_FAILED;
+ if (pending_write_pp_error_ != PP_OK_COMPLETIONPENDING) {
+ if (pending_write_pp_error_ == PP_OK)
+ pending_write_pp_error_ = PP_ERROR_FAILED;
+ return pending_write_pp_error_;
}
+ // TODO(raymes,rsleevi): Use trusted/untrusted certificates when connecting.
+
+ // Close all Mojo pipes except |connected_socket_|.
+ receive_stream_.reset();
+ read_watcher_.reset();
+ send_stream_.reset();
+ write_watcher_.reset();
+ socket_observer_binding_.Close();
+
+ network::mojom::SocketObserverPtr socket_observer;
+ socket_observer_binding_.Bind(mojo::MakeRequest(&socket_observer));
+ socket_observer_binding_.set_connection_error_handler(
+ base::BindOnce(&PepperTCPSocketMessageFilter::OnSocketObserverError,
+ base::Unretained(this)));
+
state_.SetPendingTransition(TCPSocketState::SSL_CONNECT);
- const ppapi::host::ReplyMessageContext reply_context(
- context->MakeReplyMessageContext());
- int net_result = ssl_socket_->Connect(
- base::BindOnce(&PepperTCPSocketMessageFilter::OnSSLHandshakeCompleted,
- base::Unretained(this), reply_context));
- if (net_result != net::ERR_IO_PENDING)
- OnSSLHandshakeCompleted(reply_context, net_result);
+ network::mojom::TLSClientSocketOptionsPtr tls_client_socket_options =
+ network::mojom::TLSClientSocketOptions::New();
+ tls_client_socket_options->send_ssl_info = true;
+ net::HostPortPair host_port_pair(server_name, server_port);
+ connected_socket_->UpgradeToTLS(
+ host_port_pair, std::move(tls_client_socket_options),
+ pepper_socket_utils::PepperTCPNetworkAnnotationTag(),
+ mojo::MakeRequest(&tls_client_socket_), std::move(socket_observer),
+ mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+ base::BindOnce(&PepperTCPSocketMessageFilter::OnSSLHandshakeCompleted,
+ base::Unretained(this),
+ context->MakeReplyMessageContext()),
+ net::ERR_FAILED, mojo::ScopedDataPipeConsumerHandle(),
+ mojo::ScopedDataPipeProducerHandle(), base::nullopt /* ssl_info */));
+
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperTCPSocketMessageFilter::OnMsgRead(
const ppapi::host::HostMessageContext* context,
int32_t bytes_to_read) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!state_.IsConnected() || end_of_file_reached_)
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // This only covers the case where the socket was explicitly closed from the
+ // caller, or the filter is being destroyed. Read errors and Mojo errors are
+ // handled in TryRead().
+ if (!state_.IsConnected())
return PP_ERROR_FAILED;
- if (read_buffer_.get())
+
+ if (pending_read_context_.is_valid())
return PP_ERROR_INPROGRESS;
if (bytes_to_read <= 0 ||
bytes_to_read > TCPSocketResourceConstants::kMaxReadSize) {
return PP_ERROR_BADARGUMENT;
}
- ppapi::host::ReplyMessageContext reply_context(
- context->MakeReplyMessageContext());
- read_buffer_ = new net::IOBuffer(bytes_to_read);
-
- int net_result = net::ERR_FAILED;
- if (socket_) {
- DCHECK_EQ(state_.state(), TCPSocketState::CONNECTED);
- net_result = socket_->Read(
- read_buffer_.get(), bytes_to_read,
- base::BindOnce(&PepperTCPSocketMessageFilter::OnReadCompleted,
- base::Unretained(this), reply_context));
- } else if (ssl_socket_) {
- DCHECK_EQ(state_.state(), TCPSocketState::SSL_CONNECTED);
- net_result = ssl_socket_->Read(
- read_buffer_.get(), bytes_to_read,
- base::BindOnce(&PepperTCPSocketMessageFilter::OnReadCompleted,
- base::Unretained(this), reply_context));
- }
- if (net_result != net::ERR_IO_PENDING)
- OnReadCompleted(reply_context, net_result);
+ pending_read_context_ = context->MakeReplyMessageContext();
+ pending_read_size_ = static_cast<uint32_t>(bytes_to_read);
+ TryRead();
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperTCPSocketMessageFilter::OnMsgWrite(
const ppapi::host::HostMessageContext* context,
const std::string& data) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!state_.IsConnected())
return PP_ERROR_FAILED;
- if (write_buffer_base_.get() || write_buffer_.get())
+ if (pending_write_context_.is_valid())
return PP_ERROR_INPROGRESS;
+ DCHECK(pending_write_data_.empty());
+ DCHECK_EQ(0u, pending_write_bytes_written_);
+
size_t data_size = data.size();
if (data_size == 0 ||
data_size >
@@ -433,11 +550,9 @@ int32_t PepperTCPSocketMessageFilter::OnMsgWrite(
return PP_ERROR_BADARGUMENT;
}
- write_buffer_base_ = base::MakeRefCounted<net::IOBuffer>(data_size);
- memcpy(write_buffer_base_->data(), data.data(), data_size);
- write_buffer_ = base::MakeRefCounted<net::DrainableIOBuffer>(
- write_buffer_base_, data_size);
- DoWrite(context->MakeReplyMessageContext());
+ pending_write_data_ = data;
+ pending_write_context_ = context->MakeReplyMessageContext();
+ TryWrite();
return PP_OK_COMPLETIONPENDING;
}
@@ -446,6 +561,12 @@ int32_t PepperTCPSocketMessageFilter::OnMsgListen(
int32_t backlog) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (state_.IsPending(TCPSocketState::LISTEN))
+ return PP_ERROR_INPROGRESS;
+
+ if (!state_.IsValidTransition(TCPSocketState::LISTEN))
+ return PP_ERROR_FAILED;
+
// This is only supported by PPB_TCPSocket v1.1 or above.
if (version_ != ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) {
NOTREACHED();
@@ -455,59 +576,64 @@ int32_t PepperTCPSocketMessageFilter::OnMsgListen(
content::SocketPermissionRequest request =
pepper_socket_utils::CreateSocketPermissionRequest(
content::SocketPermissionRequest::TCP_LISTEN, bind_input_addr_);
- if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_,
- false /* private_api */,
- &request,
- render_process_id_,
- render_frame_id_)) {
+ if (!pepper_socket_utils::CanUseSocketAPIs(
+ external_plugin_, false /* private_api */, &request,
+ render_process_id_, render_frame_id_)) {
return PP_ERROR_NOACCESS;
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&PepperTCPSocketMessageFilter::DoListen, this,
- context->MakeReplyMessageContext(), backlog));
+ DCHECK(bound_socket_);
+ DCHECK(!server_socket_);
+
+ state_.SetPendingTransition(TCPSocketState::LISTEN);
+
+ bound_socket_->Listen(
+ backlog, mojo::MakeRequest(&server_socket_),
+ mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+ base::BindOnce(&PepperTCPSocketMessageFilter::OnListenCompleted,
+ base::Unretained(this),
+ context->MakeReplyMessageContext()),
+ net::ERR_FAILED));
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperTCPSocketMessageFilter::OnMsgAccept(
const ppapi::host::HostMessageContext* context) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (pending_accept_)
return PP_ERROR_INPROGRESS;
if (state_.state() != TCPSocketState::LISTENING)
return PP_ERROR_FAILED;
+ DCHECK(server_socket_);
+
pending_accept_ = true;
- ppapi::host::ReplyMessageContext reply_context(
- context->MakeReplyMessageContext());
- int net_result = socket_->Accept(
- &accepted_socket_, &accepted_address_,
- base::Bind(&PepperTCPSocketMessageFilter::OnAcceptCompleted,
- base::Unretained(this), reply_context));
- if (net_result != net::ERR_IO_PENDING)
- OnAcceptCompleted(reply_context, net_result);
+
+ network::mojom::SocketObserverPtr socket_observer;
+ network::mojom::SocketObserverRequest socket_observer_request =
+ mojo::MakeRequest(&socket_observer);
+ server_socket_->Accept(
+ std::move(socket_observer),
+ mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+ base::BindOnce(&PepperTCPSocketMessageFilter::OnAcceptCompleted,
+ base::Unretained(this),
+ context->MakeReplyMessageContext(),
+ std::move(socket_observer_request)),
+ net::ERR_FAILED, base::nullopt /* remote_addr */,
+ network::mojom::TCPConnectedSocketPtr(),
+ mojo::ScopedDataPipeConsumerHandle(),
+ mojo::ScopedDataPipeProducerHandle()));
return PP_OK_COMPLETIONPENDING;
}
int32_t PepperTCPSocketMessageFilter::OnMsgClose(
const ppapi::host::HostMessageContext* context) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (state_.state() == TCPSocketState::CLOSED)
return PP_OK;
- state_.DoTransition(TCPSocketState::CLOSE, true);
-#if defined(OS_CHROMEOS)
- // Close the firewall hole, it is no longer needed.
- firewall_hole_.reset();
-#endif // defined(OS_CHROMEOS)
- // Make sure we get no further callbacks from |socket_| or |ssl_socket_|.
- if (socket_) {
- socket_->Close();
- } else if (ssl_socket_) {
- ssl_socket_->Disconnect();
- }
+ Close();
return PP_OK;
}
@@ -515,19 +641,37 @@ int32_t PepperTCPSocketMessageFilter::OnMsgSetOption(
const ppapi::host::HostMessageContext* context,
PP_TCPSocket_Option name,
const ppapi::SocketOptionData& value) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Options are only applied if |this| is currently being used as a client
+ // socket, or is going to be used as one - they are ignored for server
+ // sockets.
switch (name) {
case PP_TCPSOCKET_OPTION_NO_DELAY: {
bool boolean_value = false;
if (!value.GetBool(&boolean_value))
return PP_ERROR_BADARGUMENT;
- // If the socket is already connected, proxy the value to TCPSocket.
- if (state_.state() == TCPSocketState::CONNECTED)
- return socket_->SetNoDelay(boolean_value) ? PP_OK : PP_ERROR_FAILED;
+ // If |connected_socket_| is connecting or has connected, pass the setting
+ // along.
+ if (connected_socket_.is_bound()) {
+ connected_socket_->SetNoDelay(
+ boolean_value,
+ // Callback that converts a bool to a net error code which it then
+ // passes to the common completion callback routine.
+ base::BindOnce(
+ [](base::OnceCallback<void(int)> completion_callback,
+ bool success) {
+ std::move(completion_callback)
+ .Run(success ? net::OK : net::ERR_FAILED);
+ },
+ CreateCompletionCallback<
+ PpapiPluginMsg_TCPSocket_SetOptionReply>(context)));
+ return PP_OK_COMPLETIONPENDING;
+ }
- // TCPSocket instance is not yet created. So remember the value here.
+ // TCPConnectedSocket instance is not yet created. So remember the value
+ // here.
if (boolean_value) {
socket_options_ |= SOCKET_OPTION_NODELAY;
} else {
@@ -541,10 +685,14 @@ int32_t PepperTCPSocketMessageFilter::OnMsgSetOption(
integer_value > TCPSocketResourceConstants::kMaxSendBufferSize)
return PP_ERROR_BADARGUMENT;
- // If the socket is already connected, proxy the value to TCPSocket.
- if (state_.state() == TCPSocketState::CONNECTED) {
- return NetErrorToPepperError(
- socket_->SetSendBufferSize(integer_value));
+ // If |connected_socket_| is connecting or has connected, pass the setting
+ // along.
+ if (connected_socket_.is_bound()) {
+ connected_socket_->SetSendBufferSize(
+ integer_value,
+ CreateCompletionCallback<PpapiPluginMsg_TCPSocket_SetOptionReply>(
+ context));
+ return PP_OK_COMPLETIONPENDING;
}
// TCPSocket instance is not yet created. So remember the value here.
@@ -558,13 +706,18 @@ int32_t PepperTCPSocketMessageFilter::OnMsgSetOption(
integer_value > TCPSocketResourceConstants::kMaxReceiveBufferSize)
return PP_ERROR_BADARGUMENT;
- // If the socket is already connected, proxy the value to TCPSocket.
- if (state_.state() == TCPSocketState::CONNECTED) {
- return NetErrorToPepperError(
- socket_->SetReceiveBufferSize(integer_value));
+ // If |connected_socket_| is connecting or has connected, pass the setting
+ // along.
+ if (connected_socket_.is_bound()) {
+ connected_socket_->SetReceiveBufferSize(
+ integer_value,
+ CreateCompletionCallback<PpapiPluginMsg_TCPSocket_SetOptionReply>(
+ context));
+ return PP_OK_COMPLETIONPENDING;
}
- // TCPSocket instance is not yet created. So remember the value here.
+ // TCPConnectedSocket instance is not yet created. So remember the value
+ // here.
socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE;
rcvbuf_size_ = integer_value;
return PP_OK;
@@ -574,469 +727,498 @@ int32_t PepperTCPSocketMessageFilter::OnMsgSetOption(
return PP_ERROR_BADARGUMENT;
}
}
+ return PP_OK;
}
-void PepperTCPSocketMessageFilter::DoBind(
- const ppapi::host::ReplyMessageContext& context,
- const PP_NetAddress_Private& net_addr) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+void PepperTCPSocketMessageFilter::TryRead() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(state_.IsConnected());
+ DCHECK(pending_read_context_.is_valid());
+ DCHECK_GT(pending_read_size_, 0u);
+ DCHECK(!pending_read_on_unthrottle_);
- if (state_.IsPending(TCPSocketState::BIND)) {
- SendBindError(context, PP_ERROR_INPROGRESS);
- return;
- }
- if (!state_.IsValidTransition(TCPSocketState::BIND)) {
- SendBindError(context, PP_ERROR_FAILED);
+ if (is_throttled_) {
+ pending_read_on_unthrottle_ = true;
return;
}
- int pp_result = PP_OK;
- do {
- net::IPAddressBytes address;
- uint16_t port;
- if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(
- net_addr, &address, &port)) {
- pp_result = PP_ERROR_ADDRESS_INVALID;
- break;
- }
- net::IPEndPoint bind_addr(net::IPAddress(address), port);
-
- DCHECK(!socket_->IsValid());
- pp_result = NetErrorToPepperError(socket_->Open(bind_addr.GetFamily()));
- if (pp_result != PP_OK)
- break;
-
- pp_result = NetErrorToPepperError(socket_->SetDefaultOptionsForServer());
- if (pp_result != PP_OK)
- break;
-
- pp_result = NetErrorToPepperError(socket_->Bind(bind_addr));
- if (pp_result != PP_OK)
- break;
+ // This loop's body will generally run only once, unless there's a read error,
+ // in which case, it will start over, to re-apply the initial logic.
+ while (true) {
+ // As long as the read stream is still open, try to read data, even if a
+ // read error has been received from the SocketObserver, as there may still
+ // be data on the pipe.
+ if (!receive_stream_.is_valid()) {
+ // If no read error has been received yet, wait to receive one through
+ // the SocketObserver interface.
+ if (pending_read_pp_error_ == PP_OK_COMPLETIONPENDING) {
+ DCHECK(socket_observer_binding_.is_bound());
+ break;
+ }
- net::IPEndPoint ip_end_point_local;
- pp_result =
- NetErrorToPepperError(socket_->GetLocalAddress(&ip_end_point_local));
- if (pp_result != PP_OK)
+ // Otherwise, pass along the read error.
+ SendReadError(pending_read_pp_error_);
+ // If the socket was closed gracefully, only return OK for a single
+ // read.
+ if (pending_read_pp_error_ == PP_OK)
+ pending_read_pp_error_ = PP_ERROR_FAILED;
break;
+ }
- PP_NetAddress_Private local_addr =
- NetAddressPrivateImpl::kInvalidNetAddress;
- if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
- ip_end_point_local.address().bytes(), ip_end_point_local.port(),
- &local_addr)) {
- pp_result = PP_ERROR_ADDRESS_INVALID;
+ DCHECK(read_watcher_);
+ const void* buffer = nullptr;
+ uint32_t num_bytes = 0;
+ int mojo_result = receive_stream_->BeginReadData(&buffer, &num_bytes,
+ MOJO_READ_DATA_FLAG_NONE);
+ if (mojo_result == MOJO_RESULT_SHOULD_WAIT) {
+ read_watcher_->ArmOrNotify();
break;
}
- SendBindReply(context, PP_OK, local_addr);
- state_.DoTransition(TCPSocketState::BIND, true);
- return;
- } while (false);
- if (socket_->IsValid())
- socket_->Close();
- SendBindError(context, pp_result);
- state_.DoTransition(TCPSocketState::BIND, false);
-}
-
-void PepperTCPSocketMessageFilter::HostResolvingStarted(
- const ppapi::host::ReplyMessageContext& context) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!state_.IsValidTransition(TCPSocketState::CONNECT)) {
- NOTREACHED() << "This shouldn't be reached since the renderer only tries "
- << "to connect once.";
- SendConnectError(context, PP_ERROR_FAILED);
- return;
- }
-
- state_.SetPendingTransition(TCPSocketState::CONNECT);
- address_index_ = 0;
- address_list_.clear();
- host_resolve_context_ = context;
-}
-
-void PepperTCPSocketMessageFilter::DoConnectWithNetAddress(
- const ppapi::host::ReplyMessageContext& context,
- const PP_NetAddress_Private& net_addr) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (!state_.IsValidTransition(TCPSocketState::CONNECT)) {
- SendConnectError(context, PP_ERROR_FAILED);
- return;
- }
+ // On a Mojo pipe error (which may indicate a graceful close, network error,
+ // or network service crash), close read pipe and restart the loop.
+ if (mojo_result != MOJO_RESULT_OK) {
+ read_watcher_.reset();
+ receive_stream_.reset();
+ continue;
+ }
- state_.SetPendingTransition(TCPSocketState::CONNECT);
+ // This is guaranteed by Mojo.
+ DCHECK_GT(num_bytes, 0u);
- net::IPAddressBytes address;
- uint16_t port;
- if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(
- net_addr, &address, &port)) {
- state_.CompletePendingTransition(false);
- SendConnectError(context, PP_ERROR_ADDRESS_INVALID);
- return;
+ uint32_t bytes_to_copy = std::min(num_bytes, pending_read_size_);
+ SendReadReply(PP_OK, std::string(reinterpret_cast<const char*>(buffer),
+ bytes_to_copy));
+ receive_stream_->EndReadData(bytes_to_copy);
+ break;
}
-
- // Copy the single IPEndPoint to address_list_.
- address_index_ = 0;
- address_list_.clear();
- address_list_.push_back(net::IPEndPoint(net::IPAddress(address), port));
- StartConnect(context);
}
-void PepperTCPSocketMessageFilter::DoWrite(
- const ppapi::host::ReplyMessageContext& context) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(write_buffer_base_.get());
- DCHECK(write_buffer_.get());
- DCHECK_GT(write_buffer_->BytesRemaining(), 0);
+void PepperTCPSocketMessageFilter::TryWrite() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(state_.IsConnected());
+ DCHECK(pending_write_context_.is_valid());
+ DCHECK(!pending_write_data_.empty());
+ DCHECK_LT(pending_write_bytes_written_, pending_write_data_.size());
+
+ // The structure of this code largely mirrors TryRead() above, with a couple
+ // differences. The loop will repeat until all bytes are written, there's an
+ // error, or no more buffer space is available. Also, it's possible for a
+ // Mojo write to succeed, but a write to the underlying socket to fail. In
+ // that case, the failure might not be returned to the caller until it tries
+ // to write again. Since the socket APIs themselves don't guarantee that
+ // data has been successfully received by the remote server on success, this
+ // should not cause unexpected problems for consumers.
+ while (true) {
+ if (!send_stream_.is_valid()) {
+ if (pending_write_pp_error_ == PP_OK_COMPLETIONPENDING) {
+ DCHECK(socket_observer_binding_.is_bound());
+ break;
+ }
+ SendWriteReply(pending_write_pp_error_);
+ // Mirror handling of "OK" read errors, only sending "OK" for a single
+ // write, though getting "OK" from a write is probably nonsense, anyways.
+ if (pending_write_pp_error_ == PP_OK)
+ pending_write_pp_error_ = PP_ERROR_FAILED;
+ break;
+ }
- int net_result = net::ERR_FAILED;
- if (socket_) {
- DCHECK_EQ(state_.state(), TCPSocketState::CONNECTED);
- net_result = socket_->Write(
- write_buffer_.get(), write_buffer_->BytesRemaining(),
- base::BindOnce(&PepperTCPSocketMessageFilter::OnWriteCompleted,
- base::Unretained(this), context),
- static_cast<net::NetworkTrafficAnnotationTag>(
- pepper_socket_utils::PepperTCPNetworkAnnotationTag()));
- } else if (ssl_socket_) {
- DCHECK_EQ(state_.state(), TCPSocketState::SSL_CONNECTED);
- net_result = ssl_socket_->Write(
- write_buffer_.get(), write_buffer_->BytesRemaining(),
- base::BindOnce(&PepperTCPSocketMessageFilter::OnWriteCompleted,
- base::Unretained(this), context),
- static_cast<net::NetworkTrafficAnnotationTag>(
- pepper_socket_utils::PepperTCPNetworkAnnotationTag()));
- }
- if (net_result != net::ERR_IO_PENDING)
- OnWriteCompleted(context, net_result);
-}
-
-void PepperTCPSocketMessageFilter::DoListen(
- const ppapi::host::ReplyMessageContext& context,
- int32_t backlog) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (state_.IsPending(TCPSocketState::LISTEN)) {
- SendListenReply(context, PP_ERROR_INPROGRESS);
- return;
- }
- if (!state_.IsValidTransition(TCPSocketState::LISTEN)) {
- SendListenReply(context, PP_ERROR_FAILED);
- return;
- }
-
- int32_t pp_result = NetErrorToPepperError(socket_->Listen(backlog));
-#if defined(OS_CHROMEOS)
- OpenFirewallHole(context, pp_result);
-#else
- OnListenCompleted(context, pp_result);
-#endif
-}
+ DCHECK(write_watcher_);
-void PepperTCPSocketMessageFilter::OnResolveCompleted(
- int net_result,
- const base::Optional<net::AddressList>& resolved_addresses) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!host_resolve_context_.is_valid())
- return;
+ uint32_t num_bytes =
+ pending_write_data_.size() - pending_write_bytes_written_;
+ DCHECK_GT(num_bytes, 0u);
+ int mojo_result = send_stream_->WriteData(
+ pending_write_data_.data() + pending_write_bytes_written_, &num_bytes,
+ MOJO_WRITE_DATA_FLAG_NONE);
+ if (mojo_result == MOJO_RESULT_SHOULD_WAIT) {
+ write_watcher_->ArmOrNotify();
+ break;
+ }
- ppapi::host::ReplyMessageContext context = host_resolve_context_;
- host_resolve_context_ = ppapi::host::ReplyMessageContext();
+ // On a Mojo pipe error (which may indicate a graceful close, network error,
+ // or network service crash), close write pipe and restart the loop.
+ if (mojo_result != MOJO_RESULT_OK) {
+ write_watcher_.reset();
+ send_stream_.reset();
+ continue;
+ }
- if (!state_.IsPending(TCPSocketState::CONNECT)) {
- DCHECK(state_.state() == TCPSocketState::CLOSED);
- SendConnectError(context, PP_ERROR_FAILED);
- return;
- }
+ // This is guaranteed by Mojo.
+ DCHECK_GT(num_bytes, 0u);
- if (net_result != net::OK) {
- SendConnectError(context, NetErrorToPepperError(net_result));
- state_.CompletePendingTransition(false);
- return;
+ pending_write_bytes_written_ += num_bytes;
+ // If all bytes were written, nothing left to do.
+ if (pending_write_bytes_written_ == pending_write_data_.size()) {
+ SendWriteReply(pending_write_bytes_written_);
+ break;
+ }
}
-
- address_list_ = resolved_addresses.value();
- StartConnect(context);
}
void PepperTCPSocketMessageFilter::StartConnect(
- const ppapi::host::ReplyMessageContext& context) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ const ppapi::host::ReplyMessageContext& context,
+ const net::AddressList& address_list) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(state_.IsPending(TCPSocketState::CONNECT));
- DCHECK_LT(address_index_, address_list_.size());
-
- if (!socket_->IsValid()) {
- int net_result = socket_->Open(address_list_[address_index_].GetFamily());
- if (net_result != net::OK) {
- OnConnectCompleted(context, net_result);
- return;
- }
- }
-
- socket_->SetDefaultOptionsForClient();
-
- if (!(socket_options_ & SOCKET_OPTION_NODELAY)) {
- if (!socket_->SetNoDelay(false)) {
- OnConnectCompleted(context, net::ERR_FAILED);
- return;
- }
- }
- if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) {
- int net_result = socket_->SetReceiveBufferSize(rcvbuf_size_);
- if (net_result != net::OK) {
- OnConnectCompleted(context, net_result);
- return;
- }
- }
- if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE) {
- int net_result = socket_->SetSendBufferSize(sndbuf_size_);
- if (net_result != net::OK) {
- OnConnectCompleted(context, net_result);
+ DCHECK(!address_list.empty());
+
+ network::mojom::SocketObserverPtr socket_observer;
+ socket_observer_binding_.Bind(mojo::MakeRequest(&socket_observer));
+
+ socket_observer_binding_.set_connection_error_handler(
+ base::BindOnce(&PepperTCPSocketMessageFilter::OnSocketObserverError,
+ base::Unretained(this)));
+
+ network::mojom::TCPConnectedSocketOptionsPtr socket_options =
+ network::mojom::TCPConnectedSocketOptions::New();
+ socket_options->no_delay = !!(socket_options_ & SOCKET_OPTION_NODELAY);
+ if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE)
+ socket_options->receive_buffer_size = rcvbuf_size_;
+ if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE)
+ socket_options->send_buffer_size = sndbuf_size_;
+
+ network::mojom::NetworkContext::CreateTCPConnectedSocketCallback callback =
+ mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+ base::BindOnce(&PepperTCPSocketMessageFilter::OnConnectCompleted,
+ weak_ptr_factory_.GetWeakPtr(), context),
+ net::ERR_FAILED, base::nullopt, base::nullopt,
+ mojo::ScopedDataPipeConsumerHandle(),
+ mojo::ScopedDataPipeProducerHandle());
+ if (bound_socket_) {
+ bound_socket_->Connect(address_list, std::move(socket_options),
+ mojo::MakeRequest(&connected_socket_),
+ std::move(socket_observer), std::move(callback));
+ } else {
+ network::mojom::NetworkContext* network_context = GetNetworkContext();
+ if (!network_context) {
+ // This will delete |callback|, which will invoke OnConnectCompleted()
+ // with an error.
return;
}
+ network_context->CreateTCPConnectedSocket(
+ base::nullopt /* local_addr */, address_list, std::move(socket_options),
+ pepper_socket_utils::PepperTCPNetworkAnnotationTag(),
+ mojo::MakeRequest(&connected_socket_), std::move(socket_observer),
+ std::move(callback));
}
-
- int net_result = socket_->Connect(
- address_list_[address_index_],
- base::BindOnce(&PepperTCPSocketMessageFilter::OnConnectCompleted,
- base::Unretained(this), context));
- if (net_result != net::ERR_IO_PENDING)
- OnConnectCompleted(context, net_result);
}
void PepperTCPSocketMessageFilter::OnConnectCompleted(
const ppapi::host::ReplyMessageContext& context,
- int net_result) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ int net_result,
+ const base::Optional<net::IPEndPoint>& local_addr,
+ const base::Optional<net::IPEndPoint>& peer_addr,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!state_.IsPending(TCPSocketState::CONNECT)) {
- DCHECK(state_.state() == TCPSocketState::CLOSED);
- SendConnectError(context, PP_ERROR_FAILED);
+ int32_t pp_result = NetErrorToPepperError(net_result);
+
+ if (state_.state() == TCPSocketState::CLOSED) {
+ // If this is called as a result of Close() being invoked and closing the
+ // pipe, fail the request without doing anything.
+ DCHECK_EQ(net_result, net::ERR_FAILED);
+ SendConnectError(context, pp_result);
return;
}
- int32_t pp_result = NetErrorToPepperError(net_result);
- do {
- if (pp_result != PP_OK)
- break;
+ DCHECK(state_.IsPending(TCPSocketState::CONNECT));
- net::IPEndPoint ip_end_point_local;
- net::IPEndPoint ip_end_point_remote;
- pp_result =
- NetErrorToPepperError(socket_->GetLocalAddress(&ip_end_point_local));
- if (pp_result != PP_OK)
- break;
- pp_result =
- NetErrorToPepperError(socket_->GetPeerAddress(&ip_end_point_remote));
+ do {
if (pp_result != PP_OK)
break;
- PP_NetAddress_Private local_addr =
+ PP_NetAddress_Private pp_local_addr =
NetAddressPrivateImpl::kInvalidNetAddress;
- PP_NetAddress_Private remote_addr =
+ PP_NetAddress_Private pp_remote_addr =
NetAddressPrivateImpl::kInvalidNetAddress;
- if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
- ip_end_point_local.address().bytes(), ip_end_point_local.port(),
- &local_addr) ||
+ if (!local_addr || !peer_addr ||
+ !NetAddressPrivateImpl::IPEndPointToNetAddress(
+ local_addr->address().bytes(), local_addr->port(),
+ &pp_local_addr) ||
!NetAddressPrivateImpl::IPEndPointToNetAddress(
- ip_end_point_remote.address().bytes(), ip_end_point_remote.port(),
- &remote_addr)) {
+ peer_addr->address().bytes(), peer_addr->port(), &pp_remote_addr)) {
pp_result = PP_ERROR_ADDRESS_INVALID;
break;
}
- SendConnectReply(context, PP_OK, local_addr, remote_addr);
+ SetStreams(std::move(receive_stream), std::move(send_stream));
+
+ bound_socket_.reset();
+
+ SendConnectReply(context, PP_OK, pp_local_addr, pp_remote_addr);
state_.CompletePendingTransition(true);
return;
} while (false);
- if (version_ == ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) {
- DCHECK_EQ(1u, address_list_.size());
+ // Handle errors.
- SendConnectError(context, pp_result);
- state_.CompletePendingTransition(false);
- } else {
- // We have to recreate |socket_| because it doesn't allow a second connect
- // attempt. We won't lose any state such as bound address or set options,
- // because in the private or v1.0 API, connect must be the first operation.
- socket_.reset(new net::TCPSocket(nullptr, nullptr, net::NetLogSource()));
-
- if (address_index_ + 1 < address_list_.size()) {
- DCHECK_EQ(version_, ppapi::TCP_SOCKET_VERSION_PRIVATE);
- address_index_++;
- StartConnect(context);
- } else {
- SendConnectError(context, pp_result);
- // In order to maintain backward compatibility, allow further attempts to
- // connect the socket.
- state_ = TCPSocketState(TCPSocketState::INITIAL);
- }
+ // This can happen even when the network service is behaving correctly, as
+ // we may see the |socket_observer_binding_| closed before receiving an
+ // error.
+ pending_read_pp_error_ = PP_OK_COMPLETIONPENDING;
+ pending_write_pp_error_ = PP_OK_COMPLETIONPENDING;
+
+ Close();
+ SendConnectError(context, pp_result);
+
+ if (version_ != ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) {
+ // In order to maintain backward compatibility, allow further attempts
+ // to connect the socket.
+ state_ = TCPSocketState(TCPSocketState::INITIAL);
}
}
void PepperTCPSocketMessageFilter::OnSSLHandshakeCompleted(
const ppapi::host::ReplyMessageContext& context,
- int net_result) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ int net_result,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream,
+ const base::Optional<net::SSLInfo>& ssl_info) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!state_.IsPending(TCPSocketState::SSL_CONNECT)) {
- DCHECK(state_.state() == TCPSocketState::CLOSED);
- SendSSLHandshakeReply(context, PP_ERROR_FAILED);
+ int pp_result = NetErrorToPepperError(net_result);
+ if (state_.state() == TCPSocketState::CLOSED) {
+ // If this is called as a result of Close() being invoked and closing the
+ // pipe, fail the request without doing anything.
+ DCHECK_EQ(net_result, net::ERR_FAILED);
+ SendSSLHandshakeReply(context, pp_result, base::nullopt /* ssl_info */);
return;
}
- SendSSLHandshakeReply(context, NetErrorToPepperError(net_result));
- state_.CompletePendingTransition(net_result == net::OK);
-}
+ DCHECK(state_.IsPending(TCPSocketState::SSL_CONNECT));
-void PepperTCPSocketMessageFilter::OnReadCompleted(
- const ppapi::host::ReplyMessageContext& context,
- int net_result) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(read_buffer_.get());
+ if (pp_result == PP_OK && !ssl_info)
+ pp_result = PP_ERROR_FAILED;
- if (host_ && host_->IsThrottled(instance_)) {
- pending_read_on_unthrottle_ = true;
- pending_read_reply_message_context_ = context;
- pending_read_net_result_ = net_result;
- return;
- }
+ state_.CompletePendingTransition(pp_result == PP_OK);
- if (net_result > 0) {
- SendReadReply(
- context, PP_OK, std::string(read_buffer_->data(), net_result));
- } else if (net_result == 0) {
- end_of_file_reached_ = true;
- SendReadReply(context, PP_OK, std::string());
+ if (pp_result != PP_OK) {
+ Close();
} else {
- SendReadError(context, NetErrorToPepperError(net_result));
+ SetStreams(std::move(receive_stream), std::move(send_stream));
}
- read_buffer_ = nullptr;
+
+ SendSSLHandshakeReply(context, pp_result, ssl_info);
}
-void PepperTCPSocketMessageFilter::OnWriteCompleted(
+void PepperTCPSocketMessageFilter::OnBindCompleted(
const ppapi::host::ReplyMessageContext& context,
- int net_result) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(write_buffer_base_.get());
- DCHECK(write_buffer_.get());
-
- // Note: For partial writes of 0 bytes, don't continue writing to avoid a
- // likely infinite loop.
- if (net_result > 0) {
- write_buffer_->DidConsume(net_result);
- if (write_buffer_->BytesRemaining() > 0 && state_.IsConnected()) {
- DoWrite(context);
- return;
- }
+ int net_result,
+ const base::Optional<net::IPEndPoint>& local_addr) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ int pp_result = NetErrorToPepperError(net_result);
+ if (state_.state() == TCPSocketState::CLOSED) {
+ // If this is called as a result of Close() being invoked and closing the
+ // pipe, fail the request without doing anything.
+ DCHECK_EQ(net_result, net::ERR_FAILED);
+ SendBindError(context, pp_result);
+ return;
}
- if (net_result >= 0)
- SendWriteReply(context, write_buffer_->BytesConsumed());
- else
- SendWriteReply(context, NetErrorToPepperError(net_result));
+ DCHECK(bound_socket_);
+ DCHECK(state_.IsPending(TCPSocketState::BIND));
+
+ PP_NetAddress_Private bound_address =
+ NetAddressPrivateImpl::kInvalidNetAddress;
+ if (pp_result == PP_OK &&
+ (!local_addr || !NetAddressPrivateImpl::IPEndPointToNetAddress(
+ local_addr->address().bytes(), local_addr->port(),
+ &bound_address))) {
+ pp_result = PP_ERROR_ADDRESS_INVALID;
+ }
- write_buffer_ = nullptr;
- write_buffer_base_ = nullptr;
+ if (pp_result != PP_OK) {
+ bound_socket_.reset();
+ } else {
+ bind_output_ip_endpoint_ = *local_addr;
+ }
+
+ SendBindReply(context, pp_result, bound_address);
+ state_.CompletePendingTransition(pp_result == PP_OK);
}
void PepperTCPSocketMessageFilter::OnListenCompleted(
const ppapi::host::ReplyMessageContext& context,
- int32_t pp_result) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- SendListenReply(context, pp_result);
- state_.DoTransition(TCPSocketState::LISTEN, pp_result == PP_OK);
-}
+ int net_result) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
-#if defined(OS_CHROMEOS)
-void PepperTCPSocketMessageFilter::OpenFirewallHole(
- const ppapi::host::ReplyMessageContext& context,
- int32_t pp_result) {
- if (pp_result != PP_OK) {
+ int pp_result = NetErrorToPepperError(net_result);
+ if (state_.state() == TCPSocketState::CLOSED) {
+ // If this is called as a result of Close() being invoked and closing the
+ // pipe, fail the request without doing anything.
+ DCHECK_EQ(net_result, net::ERR_FAILED);
+ SendListenReply(context, pp_result);
return;
}
- net::IPEndPoint local_addr;
- // Has already been called successfully in DoBind().
- socket_->GetLocalAddress(&local_addr);
- pepper_socket_utils::FirewallHoleOpenCallback callback =
- base::Bind(&PepperTCPSocketMessageFilter::OnFirewallHoleOpened, this,
- context, pp_result);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&pepper_socket_utils::OpenTCPFirewallHole, local_addr,
- callback));
-}
+ DCHECK(state_.IsPending(TCPSocketState::LISTEN));
-void PepperTCPSocketMessageFilter::OnFirewallHoleOpened(
- const ppapi::host::ReplyMessageContext& context,
- int32_t result,
- std::unique_ptr<chromeos::FirewallHole> hole) {
- LOG_IF(WARNING, !hole.get()) << "Firewall hole could not be opened.";
- firewall_hole_.reset(hole.release());
+#if defined(OS_CHROMEOS)
+ if (pp_result == PP_OK) {
+ OpenFirewallHole(context);
+ return;
+ }
+#endif // defined(OS_CHROMEOS)
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&PepperTCPSocketMessageFilter::OnListenCompleted, this,
- context, result));
+ SendListenReply(context, pp_result);
+ state_.CompletePendingTransition(pp_result == PP_OK);
+ if (pp_result != PP_OK)
+ Close();
}
-#endif // defined(OS_CHROMEOS)
void PepperTCPSocketMessageFilter::OnAcceptCompleted(
const ppapi::host::ReplyMessageContext& context,
- int net_result) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ network::mojom::SocketObserverRequest socket_observer_request,
+ int net_result,
+ const base::Optional<net::IPEndPoint>& remote_addr,
+ network::mojom::TCPConnectedSocketPtr connected_socket,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(pending_accept_);
pending_accept_ = false;
-
if (net_result != net::OK) {
SendAcceptError(context, NetErrorToPepperError(net_result));
return;
}
- DCHECK(accepted_socket_.get());
-
- net::IPEndPoint ip_end_point_local;
- PP_NetAddress_Private local_addr = NetAddressPrivateImpl::kInvalidNetAddress;
- PP_NetAddress_Private remote_addr = NetAddressPrivateImpl::kInvalidNetAddress;
-
- int32_t pp_result = NetErrorToPepperError(
- accepted_socket_->GetLocalAddress(&ip_end_point_local));
- if (pp_result != PP_OK) {
- SendAcceptError(context, pp_result);
+ if (!remote_addr || !connected_socket.is_bound()) {
+ SendAcceptError(context, NetErrorToPepperError(net_result));
return;
}
+
+ DCHECK(socket_observer_request.is_pending());
+
+ PP_NetAddress_Private pp_remote_addr =
+ NetAddressPrivateImpl::kInvalidNetAddress;
+
if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
- ip_end_point_local.address().bytes(), ip_end_point_local.port(),
- &local_addr) ||
- !NetAddressPrivateImpl::IPEndPointToNetAddress(
- accepted_address_.address().bytes(), accepted_address_.port(),
- &remote_addr)) {
+ remote_addr->address().bytes(), remote_addr->port(),
+ &pp_remote_addr)) {
SendAcceptError(context, PP_ERROR_ADDRESS_INVALID);
return;
}
+ PP_NetAddress_Private bound_address =
+ NetAddressPrivateImpl::kInvalidNetAddress;
+ bool success = NetAddressPrivateImpl::IPEndPointToNetAddress(
+ bind_output_ip_endpoint_.address().bytes(),
+ bind_output_ip_endpoint_.port(), &bound_address);
+ // This conversion should succeed, since it succeeded in OnBindComplete()
+ // already.
+ DCHECK(success);
+
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&PepperTCPSocketMessageFilter::OnAcceptCompletedOnIOThread,
+ this, context, connected_socket.PassInterface(),
+ std::move(socket_observer_request),
+ std::move(receive_stream), std::move(send_stream),
+ bound_address, pp_remote_addr));
+}
+
+void PepperTCPSocketMessageFilter::OnAcceptCompletedOnIOThread(
+ const ppapi::host::ReplyMessageContext& context,
+ network::mojom::TCPConnectedSocketPtrInfo connected_socket,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream,
+ PP_NetAddress_Private pp_local_addr,
+ PP_NetAddress_Private pp_remote_addr) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
// |factory_| is guaranteed to be non-NULL here. Only those instances created
// in CONNECTED state have a NULL |factory_|, while getting here requires
// LISTENING state.
+ DCHECK(factory_);
+
std::unique_ptr<ppapi::host::ResourceHost> host =
- factory_->CreateAcceptedTCPSocket(instance_, version_,
- std::move(accepted_socket_));
+ factory_->CreateAcceptedTCPSocket(
+ instance_, version_, std::move(connected_socket),
+ std::move(socket_observer_request), std::move(receive_stream),
+ std::move(send_stream));
if (!host) {
SendAcceptError(context, PP_ERROR_NOSPACE);
return;
}
+
int pending_host_id =
host_->GetPpapiHost()->AddPendingResourceHost(std::move(host));
- if (pending_host_id)
- SendAcceptReply(context, PP_OK, pending_host_id, local_addr, remote_addr);
- else
+ if (pending_host_id) {
+ SendAcceptReply(context, PP_OK, pending_host_id, pp_local_addr,
+ pp_remote_addr);
+ } else {
SendAcceptError(context, PP_ERROR_NOSPACE);
+ }
}
+void PepperTCPSocketMessageFilter::SetStreams(
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream) {
+ DCHECK(!read_watcher_);
+ DCHECK(!write_watcher_);
+
+ receive_stream_ = std::move(receive_stream);
+ read_watcher_ = std::make_unique<mojo::SimpleWatcher>(
+ FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL);
+ read_watcher_->Watch(
+ receive_stream_.get(),
+ MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
+ base::BindRepeating(
+ [](PepperTCPSocketMessageFilter* message_filter,
+ MojoResult /* result */,
+ const mojo::HandleSignalsState& /* state */) {
+ // TryRead will correctly handle both cases (data ready to be
+ // read, and the pipe was closed).
+ message_filter->TryRead();
+ },
+ base::Unretained(this)));
+
+ send_stream_ = std::move(send_stream);
+ write_watcher_ = std::make_unique<mojo::SimpleWatcher>(
+ FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL);
+ write_watcher_->Watch(
+ send_stream_.get(),
+ MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
+ base::BindRepeating(
+ [](PepperTCPSocketMessageFilter* message_filter,
+ MojoResult /* result */,
+ const mojo::HandleSignalsState& /* state */) {
+ // TryRead will correctly handle both cases (data ready to be
+ // read, and the pipe was closed).
+ message_filter->TryWrite();
+ },
+ base::Unretained(this)));
+}
+
+#if defined(OS_CHROMEOS)
+void PepperTCPSocketMessageFilter::OpenFirewallHole(
+ const ppapi::host::ReplyMessageContext& context) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ pepper_socket_utils::FirewallHoleOpenCallback callback = base::BindRepeating(
+ &PepperTCPSocketMessageFilter::OnFirewallHoleOpened, this, context);
+ pepper_socket_utils::OpenTCPFirewallHole(bind_output_ip_endpoint_, callback);
+}
+
+void PepperTCPSocketMessageFilter::OnFirewallHoleOpened(
+ const ppapi::host::ReplyMessageContext& context,
+ std::unique_ptr<chromeos::FirewallHole> hole) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(state_.IsPending(TCPSocketState::LISTEN));
+ LOG_IF(WARNING, !hole.get()) << "Firewall hole could not be opened.";
+ firewall_hole_.reset(hole.release());
+
+ SendListenReply(context, PP_OK);
+ state_.CompletePendingTransition(true);
+}
+#endif // defined(OS_CHROMEOS)
+
void PepperTCPSocketMessageFilter::SendBindReply(
const ppapi::host::ReplyMessageContext& context,
int32_t pp_result,
@@ -1069,24 +1251,21 @@ void PepperTCPSocketMessageFilter::SendConnectReply(
void PepperTCPSocketMessageFilter::SendConnectError(
const ppapi::host::ReplyMessageContext& context,
int32_t pp_error) {
- SendConnectReply(context,
- pp_error,
- NetAddressPrivateImpl::kInvalidNetAddress,
+ SendConnectReply(context, pp_error, NetAddressPrivateImpl::kInvalidNetAddress,
NetAddressPrivateImpl::kInvalidNetAddress);
}
void PepperTCPSocketMessageFilter::SendSSLHandshakeReply(
const ppapi::host::ReplyMessageContext& context,
- int32_t pp_result) {
+ int32_t pp_result,
+ const base::Optional<net::SSLInfo>& ssl_info) {
ppapi::host::ReplyMessageContext reply_context(context);
reply_context.params.set_result(pp_result);
ppapi::PPB_X509Certificate_Fields certificate_fields;
if (pp_result == PP_OK) {
- // Our socket is guaranteed to be an SSL socket if we get here.
- net::SSLInfo ssl_info;
- ssl_socket_->GetSSLInfo(&ssl_info);
- if (ssl_info.cert.get()) {
- pepper_socket_utils::GetCertificateFields(*ssl_info.cert.get(),
+ DCHECK(ssl_info);
+ if (ssl_info->cert.get()) {
+ pepper_socket_utils::GetCertificateFields(*ssl_info->cert,
&certificate_fields);
}
}
@@ -1094,27 +1273,36 @@ void PepperTCPSocketMessageFilter::SendSSLHandshakeReply(
PpapiPluginMsg_TCPSocket_SSLHandshakeReply(certificate_fields));
}
-void PepperTCPSocketMessageFilter::SendReadReply(
- const ppapi::host::ReplyMessageContext& context,
- int32_t pp_result,
- const std::string& data) {
- ppapi::host::ReplyMessageContext reply_context(context);
- reply_context.params.set_result(pp_result);
- SendReply(reply_context, PpapiPluginMsg_TCPSocket_ReadReply(data));
+void PepperTCPSocketMessageFilter::SendReadReply(int32_t pp_result,
+ const std::string& data) {
+ DCHECK(pending_read_context_.is_valid());
+ DCHECK_GT(pending_read_size_, 0u);
+
+ pending_read_context_.params.set_result(pp_result);
+ SendReply(pending_read_context_, PpapiPluginMsg_TCPSocket_ReadReply(data));
+
+ pending_read_context_ = ppapi::host::ReplyMessageContext();
+ pending_read_size_ = 0;
}
-void PepperTCPSocketMessageFilter::SendReadError(
- const ppapi::host::ReplyMessageContext& context,
- int32_t pp_error) {
- SendReadReply(context, pp_error, std::string());
+void PepperTCPSocketMessageFilter::SendReadError(int32_t pp_error) {
+ SendReadReply(pp_error, std::string());
}
-void PepperTCPSocketMessageFilter::SendWriteReply(
- const ppapi::host::ReplyMessageContext& context,
- int32_t pp_result) {
- ppapi::host::ReplyMessageContext reply_context(context);
- reply_context.params.set_result(pp_result);
- SendReply(reply_context, PpapiPluginMsg_TCPSocket_WriteReply());
+void PepperTCPSocketMessageFilter::SendWriteReply(int32_t pp_result) {
+ DCHECK(pending_write_context_.is_valid());
+ DCHECK(!pending_write_data_.empty());
+ DCHECK(pp_result <= 0 ||
+ static_cast<uint32_t>(pp_result) == pending_write_data_.size());
+ DCHECK(pp_result <= 0 ||
+ static_cast<uint32_t>(pp_result) == pending_write_bytes_written_);
+
+ pending_write_context_.params.set_result(pp_result);
+ SendReply(pending_write_context_, PpapiPluginMsg_TCPSocket_WriteReply());
+
+ pending_write_context_ = ppapi::host::ReplyMessageContext();
+ pending_write_data_.clear();
+ pending_write_bytes_written_ = 0;
}
void PepperTCPSocketMessageFilter::SendListenReply(
@@ -1133,19 +1321,77 @@ void PepperTCPSocketMessageFilter::SendAcceptReply(
const PP_NetAddress_Private& remote_addr) {
ppapi::host::ReplyMessageContext reply_context(context);
reply_context.params.set_result(pp_result);
- SendReply(reply_context,
- PpapiPluginMsg_TCPSocket_AcceptReply(
- pending_host_id, local_addr, remote_addr));
+ SendReply(reply_context, PpapiPluginMsg_TCPSocket_AcceptReply(
+ pending_host_id, local_addr, remote_addr));
}
void PepperTCPSocketMessageFilter::SendAcceptError(
const ppapi::host::ReplyMessageContext& context,
int32_t pp_error) {
- SendAcceptReply(context,
- pp_error,
- 0,
+ SendAcceptReply(context, pp_error, 0,
NetAddressPrivateImpl::kInvalidNetAddress,
NetAddressPrivateImpl::kInvalidNetAddress);
}
+void PepperTCPSocketMessageFilter::Close() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // Need to do these first, as destroying Mojo pipes may invoke some of the
+ // callbacks with failure messages.
+ weak_ptr_factory_.InvalidateWeakPtrs();
+ state_.DoTransition(TCPSocketState::CLOSE, true);
+
+#if defined(OS_CHROMEOS)
+ // Close the firewall hole, it is no longer needed.
+ firewall_hole_.reset();
+#endif // defined(OS_CHROMEOS)
+
+ // Make sure there are no further callbacks from Mojo, which could end up in a
+ // double free (Add ref on the UI thread, while a deletion is pending on the
+ // IO thread), and that they're closed on the correct thread.
+ bound_socket_.reset();
+ connected_socket_.reset();
+ tls_client_socket_.reset();
+ server_socket_.reset();
+ binding_.Close();
+ socket_observer_binding_.Close();
+
+ read_watcher_.reset();
+ receive_stream_.reset();
+ write_watcher_.reset();
+ send_stream_.reset();
+}
+
+network::mojom::NetworkContext*
+PepperTCPSocketMessageFilter::GetNetworkContext() const {
+ if (network_context_for_testing)
+ return network_context_for_testing;
+
+ RenderProcessHost* render_process_host =
+ RenderProcessHost::FromID(render_process_id_);
+ if (!render_process_host)
+ return nullptr;
+
+ return render_process_host->GetStoragePartition()->GetNetworkContext();
+}
+
+template <class ReturnMessage>
+base::OnceCallback<void(int result)>
+PepperTCPSocketMessageFilter::CreateCompletionCallback(
+ const ppapi::host::HostMessageContext* context) {
+ return mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+ base::BindOnce(&PepperTCPSocketMessageFilter::ReturnResult<ReturnMessage>,
+ base::Unretained(this),
+ context->MakeReplyMessageContext()),
+ net::ERR_FAILED);
+}
+
+template <class ReturnMessage>
+void PepperTCPSocketMessageFilter::ReturnResult(
+ ppapi::host::ReplyMessageContext context,
+ int net_result) {
+ context.params.set_result(NetErrorToPepperError(net_result));
+ SendReply(context, ReturnMessage());
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
index 03648b64ef4..8c49f6c4268 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
@@ -15,32 +15,28 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
-#include "content/browser/renderer_host/pepper/ssl_context_helper.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/address_list.h"
#include "net/base/ip_endpoint.h"
-#include "net/socket/tcp_socket.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/ppb_tcp_socket.h"
#include "ppapi/c/private/ppb_net_address_private.h"
#include "ppapi/host/resource_message_filter.h"
#include "ppapi/shared_impl/ppb_tcp_socket_shared.h"
#include "services/network/public/mojom/network_context.mojom.h"
+#include "services/network/public/mojom/tcp_socket.mojom.h"
+#include "services/network/public/mojom/tls_socket.mojom.h"
#if defined(OS_CHROMEOS)
#include "chromeos/network/firewall_hole.h"
-#include "content/public/browser/browser_thread.h"
#endif // defined(OS_CHROMEOS)
-namespace net {
-class DrainableIOBuffer;
-class IOBuffer;
-class SSLClientSocket;
-}
-
namespace ppapi {
class SocketOptionData;
@@ -54,21 +50,38 @@ namespace content {
class BrowserPpapiHostImpl;
class ContentBrowserPepperHostFactory;
+// Handles communication between Pepper and TCP socket Mojo interfaces. The Mojo
+// interfaces and all class variables live on the UI thread, while the class is
+// created on and receives IPCs on the IO thread (The IPCs are then passed to
+// the UI thread).
class CONTENT_EXPORT PepperTCPSocketMessageFilter
: public ppapi::host::ResourceMessageFilter,
public BrowserPpapiHostImpl::InstanceObserver,
- public network::mojom::ResolveHostClient {
+ public network::mojom::ResolveHostClient,
+ public network::mojom::SocketObserver {
public:
+ // |factory| must be non-nullptr unless the consumer immediately calls
+ // SetConnectedSocket(). SetConnectedSocket() must be a separate method,
+ // because something must already be holding onto a reference to |this| when a
+ // task is posted to the UI thread (Which requires grabbing another reference,
+ // which could potentially be released before the constructor returns).
PepperTCPSocketMessageFilter(ContentBrowserPepperHostFactory* factory,
BrowserPpapiHostImpl* host,
PP_Instance instance,
ppapi::TCPSocketVersion version);
- // Used for creating already connected sockets.
- PepperTCPSocketMessageFilter(BrowserPpapiHostImpl* host,
- PP_Instance instance,
- ppapi::TCPSocketVersion version,
- std::unique_ptr<net::TCPSocket> socket);
+ // Switches state to CONNECTED using the provided pipes. May only be called
+ // before any messages are received,
+ void SetConnectedSocket(
+ network::mojom::TCPConnectedSocketPtrInfo connected_socket,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream);
+
+ // Sets a global NetworkContext object to be used instead of the real one for
+ // doing all network operations.
+ static void SetNetworkContextForTesting(
+ network::mojom::NetworkContext* network_context);
static size_t GetNumInstances();
@@ -81,7 +94,14 @@ class CONTENT_EXPORT PepperTCPSocketMessageFilter
~PepperTCPSocketMessageFilter() override;
+ void SetConnectedSocketOnUIThread(
+ network::mojom::TCPConnectedSocketPtrInfo connected_socket,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream);
+
// ppapi::host::ResourceMessageFilter overrides.
+ void OnFilterDestroyed() override;
scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
const IPC::Message& message) override;
int32_t OnResourceMessageReceived(
@@ -92,11 +112,21 @@ class CONTENT_EXPORT PepperTCPSocketMessageFilter
void OnThrottleStateChanged(bool is_throttled) override;
void OnHostDestroyed() override;
+ void ThrottleStateChangedOnUIThread(bool is_throttled);
+
// network::mojom::ResolveHostClient overrides.
void OnComplete(
int result,
const base::Optional<net::AddressList>& resolved_addresses) override;
+ // network::mojom::SocketObserver overrides.
+ void OnReadError(int net_error) override;
+ void OnWriteError(int net_error) override;
+
+ // Called either when the SocketObserver Mojo pipe has an error, or bad data
+ // is received from it.
+ void OnSocketObserverError();
+
int32_t OnMsgBind(const ppapi::host::HostMessageContext* context,
const PP_NetAddress_Private& net_addr);
int32_t OnMsgConnect(const ppapi::host::HostMessageContext* context,
@@ -123,38 +153,73 @@ class CONTENT_EXPORT PepperTCPSocketMessageFilter
PP_TCPSocket_Option name,
const ppapi::SocketOptionData& value);
- void DoBind(const ppapi::host::ReplyMessageContext& context,
- const PP_NetAddress_Private& net_addr);
- void HostResolvingStarted(const ppapi::host::ReplyMessageContext& context);
- void DoConnectWithNetAddress(const ppapi::host::ReplyMessageContext& context,
- const PP_NetAddress_Private& net_addr);
- void DoWrite(const ppapi::host::ReplyMessageContext& context);
- void DoListen(const ppapi::host::ReplyMessageContext& context,
- int32_t backlog);
+ // Attempts to read up to |pending_read_size_| bytes from |receive_stream_|.
+ // If any bytes are read, or there's an error, returns that information to
+ // |pending_read_context_|.
+ void TryRead();
+
+ // Attempts to write |pending_write_data_| to |send_stream_|.
+ // |pending_write_bytes_written_| reflects how much of the data has been
+ // written to the stream so far. Once all bytes are written, or there's an
+ // error, returns that information to |pending_write_context_|.
+ void TryWrite();
void OnResolveCompleted(
int net_result,
const base::Optional<net::AddressList>& resolved_addresses);
- void StartConnect(const ppapi::host::ReplyMessageContext& context);
+
+ // Attempts to connect to all addresses in |address_list| in order.
+ void StartConnect(const ppapi::host::ReplyMessageContext& context,
+ const net::AddressList& address_list);
void OnConnectCompleted(const ppapi::host::ReplyMessageContext& context,
- int net_result);
- void OnSSLHandshakeCompleted(const ppapi::host::ReplyMessageContext& context,
- int net_result);
- void OnReadCompleted(const ppapi::host::ReplyMessageContext& context,
- int net_result);
- void OnWriteCompleted(const ppapi::host::ReplyMessageContext& context,
- int net_result);
- void OnAcceptCompleted(const ppapi::host::ReplyMessageContext& context,
- int net_result);
+ int net_result,
+ const base::Optional<net::IPEndPoint>& local_addr,
+ const base::Optional<net::IPEndPoint>& peer_addr,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream);
+
+ void OnSSLHandshakeCompleted(
+ const ppapi::host::ReplyMessageContext& context,
+ int net_result,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream,
+ const base::Optional<net::SSLInfo>& ssl_info);
void OnListenCompleted(const ppapi::host::ReplyMessageContext& context,
- int32_t pp_result);
+ int net_result);
+
+ void OnBindCompleted(const ppapi::host::ReplyMessageContext& context,
+ int net_result,
+ const base::Optional<net::IPEndPoint>& local_addr);
+
+ void OnAcceptCompleted(
+ const ppapi::host::ReplyMessageContext& context,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ int net_result,
+ const base::Optional<net::IPEndPoint>& remote_addr,
+ network::mojom::TCPConnectedSocketPtr connected_socket,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream);
+
+ void OnAcceptCompletedOnIOThread(
+ const ppapi::host::ReplyMessageContext& context,
+ network::mojom::TCPConnectedSocketPtrInfo connected_socket,
+ network::mojom::SocketObserverRequest socket_observer_request,
+ mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream,
+ PP_NetAddress_Private pp_local_addr,
+ PP_NetAddress_Private pp_remote_addr);
+
+ // Sets the read/write streams and constructs watchers for them, which are not
+ // armed until there's an attempt to use them that can't complete
+ // synchronously.
+ void SetStreams(mojo::ScopedDataPipeConsumerHandle receive_stream,
+ mojo::ScopedDataPipeProducerHandle send_stream);
+
#if defined(OS_CHROMEOS)
- void OpenFirewallHole(const ppapi::host::ReplyMessageContext& context,
- int32_t pp_result);
+ void OpenFirewallHole(const ppapi::host::ReplyMessageContext& context);
void OnFirewallHoleOpened(const ppapi::host::ReplyMessageContext& context,
- int32_t result,
std::unique_ptr<chromeos::FirewallHole> hole);
#endif // defined(OS_CHROMEOS)
@@ -170,14 +235,13 @@ class CONTENT_EXPORT PepperTCPSocketMessageFilter
void SendConnectError(const ppapi::host::ReplyMessageContext& context,
int32_t pp_error);
void SendSSLHandshakeReply(const ppapi::host::ReplyMessageContext& context,
- int32_t pp_result);
- void SendReadReply(const ppapi::host::ReplyMessageContext& context,
- int32_t pp_result,
- const std::string& data);
- void SendReadError(const ppapi::host::ReplyMessageContext& context,
- int32_t pp_error);
- void SendWriteReply(const ppapi::host::ReplyMessageContext& context,
- int32_t pp_result);
+ int32_t pp_result,
+ const base::Optional<net::SSLInfo>& ssl_info);
+ // The read and write reply messages use the |pending_*_context_| fields, and
+ // clear fields related to the pending read / write request as needed.
+ void SendReadReply(int32_t pp_result, const std::string& data);
+ void SendReadError(int32_t pp_error);
+ void SendWriteReply(int32_t pp_result);
void SendListenReply(const ppapi::host::ReplyMessageContext& context,
int32_t pp_result);
void SendAcceptReply(const ppapi::host::ReplyMessageContext& context,
@@ -188,47 +252,64 @@ class CONTENT_EXPORT PepperTCPSocketMessageFilter
void SendAcceptError(const ppapi::host::ReplyMessageContext& context,
int32_t pp_error);
+ // Closes any open Mojo pipe, and prevents new ones from being opened.
+ void Close();
+
+ network::mojom::NetworkContext* GetNetworkContext() const;
+
bool IsPrivateAPI() const {
return version_ == ppapi::TCP_SOCKET_VERSION_PRIVATE;
}
+ // These are used to create a callback that:
+ // 1) if invoked with a network error code, will pass a message of the
+ // requested type to |context| with the corresponding Pepper error.
+ // 2) If destroyed without being invoked, will pass a message of the requested
+ // type to |context| with PP_ERROR_FAILED.
+ template <class ReturnMessage>
+ base::OnceCallback<void(int net_result)> CreateCompletionCallback(
+ const ppapi::host::HostMessageContext* context);
+ template <class ReturnMessage>
+ void ReturnResult(ppapi::host::ReplyMessageContext context, int net_result);
+
// The following fields are used on both the UI and IO thread.
const ppapi::TCPSocketVersion version_;
+ // The following fields are used only on the IO thread.
+ // Non-owning ptr.
+ BrowserPpapiHostImpl* host_;
+ // Non-owning ptr.
+ ContentBrowserPepperHostFactory* factory_;
+ PP_Instance instance_;
+
// The following fields are used only on the UI thread.
const bool external_plugin_;
+ // Mirrors state of host_->IsThrottled(), but is on UI thread.
+ bool is_throttled_;
+
int render_process_id_;
int render_frame_id_;
// A reference to |this| must always be taken while |binding_| is bound to
// ensure that if the error callback is called the object is alive.
mojo::Binding<network::mojom::ResolveHostClient> binding_;
-
- // The following fields are used only on the IO thread.
- // Non-owning ptr.
- BrowserPpapiHostImpl* host_;
- // Non-owning ptr.
- ContentBrowserPepperHostFactory* factory_;
- PP_Instance instance_;
+ mojo::Binding<network::mojom::SocketObserver> socket_observer_binding_;
ppapi::TCPSocketState state_;
- bool end_of_file_reached_;
// This is the address requested to bind. Please note that this is not the
// bound address. For example, |bind_input_addr_| may have port set to 0.
// It is used to check permission for listening.
PP_NetAddress_Private bind_input_addr_;
+ // The bound address.
+ net::IPEndPoint bind_output_ip_endpoint_;
+
#if defined(OS_CHROMEOS)
- std::unique_ptr<chromeos::FirewallHole,
- content::BrowserThread::DeleteOnUIThread>
- firewall_hole_;
+ std::unique_ptr<chromeos::FirewallHole> firewall_hole_;
#endif // defined(OS_CHROMEOS)
- // Used for DNS request.
- std::unique_ptr<net::HostResolver::Request> request_;
-
// Bitwise-or of SocketOption flags. This stores the state about whether
// each option is set before Connect() is called.
int socket_options_;
@@ -237,42 +318,56 @@ class CONTENT_EXPORT PepperTCPSocketMessageFilter
int32_t rcvbuf_size_;
int32_t sndbuf_size_;
- // |address_list_| may store multiple addresses when
- // PPB_TCPSocket_Private.Connect() is used, which involves name resolution.
- // In that case, we will try each address in the list until a connection is
- // successfully established.
- net::AddressList address_list_;
- // Where we are in the above list.
- size_t address_index_;
ppapi::host::ReplyMessageContext host_resolve_context_;
- // Non-null unless an SSL connection is requested.
- std::unique_ptr<net::TCPSocket> socket_;
- // Non-null if an SSL connection is requested.
- std::unique_ptr<net::SSLClientSocket> ssl_socket_;
-
- scoped_refptr<net::IOBuffer> read_buffer_;
-
- // TCPSocket::Write() may not always write the full buffer, but we would
- // rather have our DoWrite() do so whenever possible. To do this, we may have
- // to call the former multiple times for each of the latter. This entails
- // using a DrainableIOBuffer, which requires an underlying base IOBuffer.
- scoped_refptr<net::IOBuffer> write_buffer_base_;
- scoped_refptr<net::DrainableIOBuffer> write_buffer_;
- scoped_refptr<SSLContextHelper> ssl_context_helper_;
+ // Holds socket if Bind() is called. Will be used to create a connected or
+ // server socket, depending on the next call.
+ network::mojom::TCPBoundSocketPtr bound_socket_;
+ // Holds socket if Connect() is called.
+ network::mojom::TCPConnectedSocketPtr connected_socket_;
+ // Holds socket if socket was upgraded to SSL.
+ network::mojom::TLSClientSocketPtr tls_client_socket_;
+ // Holds socket if Listen() is called.
+ network::mojom::TCPServerSocketPtr server_socket_;
+
+ // Read/write pipes and their watchers. Both the watchers are configured so
+ // that they must be armed to receive a notification.
+ mojo::ScopedDataPipeConsumerHandle receive_stream_;
+ std::unique_ptr<mojo::SimpleWatcher> read_watcher_;
+ mojo::ScopedDataPipeProducerHandle send_stream_;
+ std::unique_ptr<mojo::SimpleWatcher> write_watcher_;
bool pending_accept_;
- std::unique_ptr<net::TCPSocket> accepted_socket_;
- net::IPEndPoint accepted_address_;
+ uint32_t pending_read_size_;
+ ppapi::host::ReplyMessageContext pending_read_context_;
+ // This is set to an error other than PP_OK_COMPLETIONPENDING when a read
+ // error is received through the SocketObserver interface. If the
+ // SocketObserver interface is destroyed and this still hasn't been changed
+ // from its initial value of PP_OK_COMPLETIONPENDING, it's set to
+ // PP_ERROR_FAILED.
+ int pending_read_pp_error_;
// If the plugin is throttled, we defer completing socket reads until
// the plugin is unthrottled.
bool pending_read_on_unthrottle_;
- ppapi::host::ReplyMessageContext pending_read_reply_message_context_;
- int pending_read_net_result_;
+
+ std::string pending_write_data_;
+ // Number of bytes from |pending_write_data_| that have already been written.
+ // Always less than the size of |pending_write_data_|.
+ size_t pending_write_bytes_written_;
+ ppapi::host::ReplyMessageContext pending_write_context_;
+ // This mirrors |pending_read_pp_error_|.
+ int pending_write_pp_error_;
const bool is_potentially_secure_plugin_context_;
+ // Used in place of the StoragePartition's NetworkContext when non-null.
+ static network::mojom::NetworkContext* network_context_for_testing;
+
+ // Vends weak pointers on the UI thread, for callbacks passed through Mojo
+ // pipes not owned by |this|. All weak pointers released in Close().
+ base::WeakPtrFactory<PepperTCPSocketMessageFilter> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(PepperTCPSocketMessageFilter);
};
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc b/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc
index 7a19d458a19..2bc70d2b4cd 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc
@@ -10,10 +10,12 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
@@ -130,8 +132,8 @@ void PepperUDPSocketMessageFilter::OnFilterDestroyed() {
// that future messages will be ignored, so the mojo pipes won't be
// re-created, so after Close() runs, |this| can be safely deleted on the IO
// thread.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&PepperUDPSocketMessageFilter::Close, this));
}
@@ -146,7 +148,7 @@ PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage(
case PpapiHostMsg_UDPSocket_SendTo::ID:
case PpapiHostMsg_UDPSocket_JoinGroup::ID:
case PpapiHostMsg_UDPSocket_LeaveGroup::ID:
- return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
+ return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
}
return nullptr;
}
@@ -717,8 +719,8 @@ void PepperUDPSocketMessageFilter::SendRecvFromResult(
const PP_NetAddress_Private& addr) {
// Unlike SendReply, which is safe to call on any thread, SendUnsolicitedReply
// calls are only safe to make on the IO thread.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&PepperUDPSocketMessageFilter::SendRecvFromResultOnIOThread, this,
result, data, addr));
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.cc b/chromium/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.cc
index 232ed55c4eb..15eeaa43a17 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/pepper/pepper_vpn_provider_message_filter_chromeos.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/pepper_vpn_provider_resource_host_proxy.h"
@@ -93,7 +95,7 @@ PepperVpnProviderMessageFilter::OverrideTaskRunnerForMessage(
case PpapiHostMsg_VpnProvider_Bind::ID:
case PpapiHostMsg_VpnProvider_SendPacket::ID:
case PpapiHostMsg_VpnProvider_OnPacketReceivedReply::ID:
- return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
+ return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
}
return nullptr;
}
diff --git a/chromium/content/browser/renderer_host/pepper/quota_reservation.cc b/chromium/content/browser/renderer_host/pepper/quota_reservation.cc
index 932c7dd645d..72f61233fea 100644
--- a/chromium/content/browser/renderer_host/pepper/quota_reservation.cc
+++ b/chromium/content/browser/renderer_host/pepper/quota_reservation.cc
@@ -8,6 +8,8 @@
#include "base/bind.h"
#include "base/callback.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "storage/browser/fileapi/file_system_operation_runner.h"
#include "storage/browser/fileapi/quota/open_file_handle.h"
@@ -46,7 +48,7 @@ QuotaReservation::QuotaReservation(
QuotaReservation::~QuotaReservation() {
// We should have no open files at this point.
DCHECK(files_.size() == 0);
- for (FileMap::iterator it = files_.begin(); it != files_.end(); ++it)
+ for (auto it = files_.begin(); it != files_.end(); ++it)
delete it->second;
}
@@ -81,7 +83,7 @@ int64_t QuotaReservation::OpenFile(int32_t id,
void QuotaReservation::CloseFile(int32_t id,
const ppapi::FileGrowth& file_growth) {
- FileMap::iterator it = files_.find(id);
+ auto it = files_.find(id);
if (it != files_.end()) {
it->second->UpdateMaxWrittenOffset(file_growth.max_written_offset);
it->second->AddAppendModeWriteAmount(file_growth.append_mode_write_amount);
@@ -95,9 +97,8 @@ void QuotaReservation::CloseFile(int32_t id,
void QuotaReservation::ReserveQuota(int64_t amount,
const ppapi::FileGrowthMap& file_growths,
const ReserveQuotaCallback& callback) {
- for (FileMap::iterator it = files_.begin(); it != files_.end(); ++it) {
- ppapi::FileGrowthMap::const_iterator growth_it =
- file_growths.find(it->first);
+ for (auto it = files_.begin(); it != files_.end(); ++it) {
+ auto growth_it = file_growths.find(it->first);
if (growth_it != file_growths.end()) {
it->second->UpdateMaxWrittenOffset(growth_it->second.max_written_offset);
it->second->AddAppendModeWriteAmount(
@@ -116,12 +117,12 @@ void QuotaReservation::OnClientCrash() { quota_reservation_->OnClientCrash(); }
void QuotaReservation::GotReservedQuota(const ReserveQuotaCallback& callback,
base::File::Error error) {
ppapi::FileSizeMap file_sizes;
- for (FileMap::iterator it = files_.begin(); it != files_.end(); ++it)
+ for (auto it = files_.begin(); it != files_.end(); ++it)
file_sizes[it->first] = it->second->GetMaxWrittenOffset();
if (file_system_context_.get()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(callback, quota_reservation_->remaining_quota(),
file_sizes));
} else {
diff --git a/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc b/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc
index 204ed5af76e..cc2f82f564a 100644
--- a/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc
+++ b/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc
@@ -136,9 +136,8 @@ void GotReservedQuota(int64_t* reserved_quota_ptr,
*reserved_quota_ptr = reserved_quota;
file_growths_ptr->clear();
- for (ppapi::FileSizeMap::const_iterator it = maximum_written_offsets.begin();
- it != maximum_written_offsets.end();
- ++it)
+ for (auto it = maximum_written_offsets.begin();
+ it != maximum_written_offsets.end(); ++it)
(*file_growths_ptr)[it->first] = ppapi::FileGrowth(it->second, 0);
}
diff --git a/chromium/content/browser/renderer_host/pepper/ssl_context_helper.cc b/chromium/content/browser/renderer_host/pepper/ssl_context_helper.cc
deleted file mode 100644
index 1d6fb4c9621..00000000000
--- a/chromium/content/browser/renderer_host/pepper/ssl_context_helper.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/pepper/ssl_context_helper.h"
-
-#include "net/cert/cert_verifier.h"
-#include "net/cert/ct_policy_enforcer.h"
-#include "net/cert/multi_log_ct_verifier.h"
-#include "net/http/transport_security_state.h"
-
-namespace content {
-
-SSLContextHelper::SSLContextHelper() {}
-
-SSLContextHelper::~SSLContextHelper() {}
-
-net::CertVerifier* SSLContextHelper::GetCertVerifier() {
- if (!cert_verifier_)
- cert_verifier_ = net::CertVerifier::CreateDefault();
- return cert_verifier_.get();
-}
-
-net::TransportSecurityState* SSLContextHelper::GetTransportSecurityState() {
- if (!transport_security_state_)
- transport_security_state_.reset(new net::TransportSecurityState());
- return transport_security_state_.get();
-}
-
-net::CTVerifier* SSLContextHelper::GetCertTransparencyVerifier() {
- if (!cert_transparency_verifier_)
- cert_transparency_verifier_.reset(new net::MultiLogCTVerifier());
- return cert_transparency_verifier_.get();
-}
-
-net::CTPolicyEnforcer* SSLContextHelper::GetCTPolicyEnforcer() {
- if (!ct_policy_enforcer_)
- ct_policy_enforcer_.reset(new net::DefaultCTPolicyEnforcer());
- return ct_policy_enforcer_.get();
-}
-
-} // namespace content
diff --git a/chromium/content/browser/renderer_host/pepper/ssl_context_helper.h b/chromium/content/browser/renderer_host/pepper/ssl_context_helper.h
deleted file mode 100644
index d2b880ec96e..00000000000
--- a/chromium/content/browser/renderer_host/pepper/ssl_context_helper.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_SSL_CONTEXT_HELPER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_SSL_CONTEXT_HELPER_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "net/ssl/ssl_config_service.h"
-
-namespace net {
-class CertVerifier;
-class CTPolicyEnforcer;
-class CTVerifier;
-class TransportSecurityState;
-}
-
-namespace content {
-
-class SSLContextHelper : public base::RefCounted<SSLContextHelper> {
- public:
- SSLContextHelper();
-
- net::CertVerifier* GetCertVerifier();
- net::TransportSecurityState* GetTransportSecurityState();
- net::CTVerifier* GetCertTransparencyVerifier();
- net::CTPolicyEnforcer* GetCTPolicyEnforcer();
- const net::SSLConfig& ssl_config() { return ssl_config_; }
-
- private:
- friend class base::RefCounted<SSLContextHelper>;
-
- ~SSLContextHelper();
-
- // This is lazily created. Users should use GetCertVerifier to retrieve it.
- std::unique_ptr<net::CertVerifier> cert_verifier_;
- // This is lazily created. Users should use GetTransportSecurityState to
- // retrieve it.
- std::unique_ptr<net::TransportSecurityState> transport_security_state_;
- // This is lazily created. Users should use GetCertTransparencyVerifier to
- // retrieve it.
- std::unique_ptr<net::CTVerifier> cert_transparency_verifier_;
- // This is lazily created. Users should use GetCTPolicyEnforcer to
- // retrieve it.
- std::unique_ptr<net::CTPolicyEnforcer> ct_policy_enforcer_;
-
- // The default SSL configuration settings are used, as opposed to Chrome's SSL
- // settings.
- net::SSLConfig ssl_config_;
-
- DISALLOW_COPY_AND_ASSIGN(SSLContextHelper);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_SSL_CONTEXT_HELPER_H_
diff --git a/chromium/content/browser/renderer_host/popup_window_mac.h b/chromium/content/browser/renderer_host/popup_window_mac.h
index 424e75fa241..1b3d65da55f 100644
--- a/chromium/content/browser/renderer_host/popup_window_mac.h
+++ b/chromium/content/browser/renderer_host/popup_window_mac.h
@@ -7,7 +7,7 @@
#import "base/mac/scoped_nsobject.h"
#include "base/macros.h"
-#include "third_party/blink/public/web/web_popup_type.h"
+#include "content/public/common/widget_type.h"
#include "ui/gfx/geometry/rect.h"
@class NSWindow;
@@ -21,7 +21,6 @@ namespace content {
class PopupWindowMac {
public:
PopupWindowMac(const gfx::Rect& content_rect,
- blink::WebPopupType popup_type,
RenderWidgetHostViewCocoa* cocoa_view);
~PopupWindowMac();
diff --git a/chromium/content/browser/renderer_host/popup_window_mac.mm b/chromium/content/browser/renderer_host/popup_window_mac.mm
index c77d21aeecd..76001b3e373 100644
--- a/chromium/content/browser/renderer_host/popup_window_mac.mm
+++ b/chromium/content/browser/renderer_host/popup_window_mac.mm
@@ -83,12 +83,10 @@
namespace content {
PopupWindowMac::PopupWindowMac(const gfx::Rect& content_rect,
- blink::WebPopupType popup_type,
RenderWidgetHostViewCocoa* cocoa_view)
: cocoa_view_(cocoa_view) {
- bool activatable = popup_type == blink::kWebPopupTypeNone;
[cocoa_view_ setCloseOnDeactivate:YES];
- [cocoa_view_ setCanBeKeyView:activatable ? YES : NO];
+ [cocoa_view_ setCanBeKeyView:NO];
popup_window_.reset([[RenderWidgetPopupWindow alloc]
initWithContentRect:gfx::ScreenRectToNSRect(content_rect)
diff --git a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
index c78d73722dd..0c01ec046dd 100644
--- a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
+++ b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
@@ -34,11 +34,20 @@ void RenderFrameMetadataProviderImpl::Bind(
render_frame_metadata_observer_client_binding_.Close();
render_frame_metadata_observer_client_binding_.Bind(std::move(client_request),
task_runner_);
+
+ if (pending_report_all_frame_submission_.has_value()) {
+ ReportAllFrameSubmissionsForTesting(*pending_report_all_frame_submission_);
+ pending_report_all_frame_submission_.reset();
+ }
}
void RenderFrameMetadataProviderImpl::ReportAllFrameSubmissionsForTesting(
bool enabled) {
- DCHECK(render_frame_metadata_observer_ptr_);
+ if (!render_frame_metadata_observer_ptr_) {
+ pending_report_all_frame_submission_ = enabled;
+ return;
+ }
+
render_frame_metadata_observer_ptr_->ReportAllFrameSubmissionsForTesting(
enabled);
}
diff --git a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h
index 1e5fdb2bfa5..bcec96f40ea 100644
--- a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h
+++ b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h
@@ -80,6 +80,8 @@ class CONTENT_EXPORT RenderFrameMetadataProviderImpl
render_frame_metadata_observer_client_binding_;
mojom::RenderFrameMetadataObserverPtr render_frame_metadata_observer_ptr_;
+ base::Optional<bool> pending_report_all_frame_submission_;
+
base::WeakPtrFactory<RenderFrameMetadataProviderImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderFrameMetadataProviderImpl);
diff --git a/chromium/content/browser/renderer_host/render_message_filter.cc b/chromium/content/browser/renderer_host/render_message_filter.cc
index cc6d5b62567..96f0ddcb9df 100644
--- a/chromium/content/browser/renderer_host/render_message_filter.cc
+++ b/chromium/content/browser/renderer_host/render_message_filter.cc
@@ -25,13 +25,7 @@
#include "content/browser/bad_message.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/browser_main_loop.h"
-#include "content/browser/cache_storage/cache_storage_cache.h"
-#include "content/browser/cache_storage/cache_storage_cache_handle.h"
-#include "content/browser/cache_storage/cache_storage_context_impl.h"
-#include "content/browser/cache_storage/cache_storage_manager.h"
#include "content/browser/child_process_security_policy_impl.h"
-#include "content/browser/code_cache/generated_code_cache.h"
-#include "content/browser/code_cache/generated_code_cache_context.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
@@ -46,6 +40,7 @@
#include "content/common/view_messages.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/storage_partition.h"
@@ -61,7 +56,6 @@
#include "net/base/io_buffer.h"
#include "net/base/mime_util.h"
#include "net/base/request_priority.h"
-#include "net/http/http_cache.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "services/network/public/mojom/network_context.mojom.h"
@@ -84,36 +78,11 @@
#include "base/threading/platform_thread.h"
#endif
-using blink::mojom::CacheStorageError;
-
namespace content {
namespace {
const uint32_t kRenderFilteredMessageClasses[] = {ViewMsgStart};
-void NoOpCacheStorageErrorCallback(CacheStorageCacheHandle cache_handle,
- CacheStorageError error) {}
-
-base::Optional<url::Origin> GetRendererOrigin(const GURL& url,
- int render_process_id) {
- GURL requesting_url =
- ChildProcessSecurityPolicyImpl::GetInstance()->GetOriginLock(
- render_process_id);
-
- if (!requesting_url.is_valid() || !url.is_valid())
- return base::nullopt;
-
- url::Origin origin = url::Origin::Create(requesting_url);
-
- // Don't cache the code corresponding to unique origins. The same-origin
- // checks should always fail for unique origins but the serialized value of
- // unique origins does not ensure this.
- if (origin.unique())
- return base::nullopt;
-
- return origin;
-}
-
} // namespace
RenderMessageFilter::RenderMessageFilter(
@@ -121,9 +90,7 @@ RenderMessageFilter::RenderMessageFilter(
BrowserContext* browser_context,
net::URLRequestContextGetter* request_context,
RenderWidgetHelper* render_widget_helper,
- MediaInternals* media_internals,
- CacheStorageContextImpl* cache_storage_context,
- GeneratedCodeCacheContext* generated_code_cache_context)
+ MediaInternals* media_internals)
: BrowserMessageFilter(kRenderFilteredMessageClasses,
arraysize(kRenderFilteredMessageClasses)),
BrowserAssociatedInterface<mojom::RenderMessageFilter>(this, this),
@@ -133,8 +100,6 @@ RenderMessageFilter::RenderMessageFilter(
render_widget_helper_(render_widget_helper),
render_process_id_(render_process_id),
media_internals_(media_internals),
- cache_storage_context_(cache_storage_context),
- generated_code_cache_context_(generated_code_cache_context),
weak_ptr_factory_(this) {
DCHECK(request_context_.get());
@@ -174,12 +139,11 @@ void RenderMessageFilter::GenerateRoutingID(
}
void RenderMessageFilter::CreateNewWidget(int32_t opener_id,
- blink::WebPopupType popup_type,
mojom::WidgetPtr widget,
CreateNewWidgetCallback callback) {
int route_id = MSG_ROUTING_NONE;
- render_widget_helper_->CreateNewWidget(opener_id, popup_type,
- std::move(widget), &route_id);
+ render_widget_helper_->CreateNewWidget(opener_id, std::move(widget),
+ &route_id);
std::move(callback).Run(route_id);
}
@@ -227,114 +191,6 @@ void RenderMessageFilter::SetThreadPriority(int32_t ns_tid,
}
#endif
-void RenderMessageFilter::DidGenerateCacheableMetadata(
- const GURL& url,
- base::Time expected_response_time,
- const std::vector<uint8_t>& data) {
- if (!url.SchemeIsHTTPOrHTTPS()) {
- bad_message::ReceivedBadMessage(
- this, bad_message::RMF_BAD_URL_CACHEABLE_METADATA);
- return;
- }
-
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (!base::FeatureList::IsEnabled(features::kIsolatedCodeCache)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&RenderMessageFilter::DidGenerateCacheableMetadataOnUI,
- this, url, expected_response_time, data));
- } else {
- if (!generated_code_cache_context_->generated_code_cache())
- return;
-
- base::Optional<url::Origin> requesting_origin =
- GetRendererOrigin(url, render_process_id_);
- if (!requesting_origin)
- return;
-
- generated_code_cache_context_->generated_code_cache()->WriteData(
- url, *requesting_origin, expected_response_time, data);
- }
-}
-
-void RenderMessageFilter::FetchCachedCode(const GURL& url,
- FetchCachedCodeCallback callback) {
- if (!generated_code_cache_context_->generated_code_cache()) {
- std::move(callback).Run(base::Time(), std::vector<uint8_t>());
- return;
- }
-
- base::Optional<url::Origin> requesting_origin =
- GetRendererOrigin(url, render_process_id_);
- if (!requesting_origin) {
- std::move(callback).Run(base::Time(), std::vector<uint8_t>());
- return;
- }
-
- base::RepeatingCallback<void(const base::Time&, const std::vector<uint8_t>&)>
- read_callback = base::BindRepeating(
- &RenderMessageFilter::OnReceiveCachedCode,
- weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback));
- generated_code_cache_context_->generated_code_cache()->FetchEntry(
- url, *requesting_origin, read_callback);
-}
-
-void RenderMessageFilter::OnReceiveCachedCode(
- FetchCachedCodeCallback callback,
- const base::Time& response_time,
- const std::vector<uint8_t>& data) {
- // TODO(crbug.com/867848): Pass the data as a mojo data pipe instead
- // of vector<uint8>
- std::move(callback).Run(response_time, data);
-}
-
-void RenderMessageFilter::ClearCodeCacheEntry(const GURL& url) {
- if (!generated_code_cache_context_->generated_code_cache())
- return;
-
- base::Optional<url::Origin> requesting_origin =
- GetRendererOrigin(url, render_process_id_);
- if (!requesting_origin)
- return;
-
- generated_code_cache_context_->generated_code_cache()->DeleteEntry(
- url, *requesting_origin);
-}
-
-void RenderMessageFilter::DidGenerateCacheableMetadataInCacheStorage(
- const GURL& url,
- base::Time expected_response_time,
- const std::vector<uint8_t>& data,
- const url::Origin& cache_storage_origin,
- const std::string& cache_storage_cache_name) {
- scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(data.size()));
- if (!data.empty())
- memcpy(buf->data(), &data.front(), data.size());
-
- cache_storage_context_->cache_manager()->OpenCache(
- cache_storage_origin, CacheStorageOwner::kCacheAPI,
- cache_storage_cache_name,
- base::BindOnce(&RenderMessageFilter::OnCacheStorageOpenCallback,
- weak_ptr_factory_.GetWeakPtr(), url,
- expected_response_time, buf, data.size()));
-}
-
-void RenderMessageFilter::OnCacheStorageOpenCallback(
- const GURL& url,
- base::Time expected_response_time,
- scoped_refptr<net::IOBuffer> buf,
- int buf_len,
- CacheStorageCacheHandle cache_handle,
- CacheStorageError error) {
- if (error != CacheStorageError::kSuccess || !cache_handle.value())
- return;
- CacheStorageCache* cache = cache_handle.value();
- cache->WriteSideData(
- base::BindOnce(&NoOpCacheStorageErrorCallback, std::move(cache_handle)),
- url, expected_response_time, buf, buf_len);
-}
-
void RenderMessageFilter::OnMediaLogEvents(
const std::vector<media::MediaLogEvent>& events) {
// OnMediaLogEvents() is always dispatched to the UI thread for handling.
@@ -348,23 +204,4 @@ void RenderMessageFilter::HasGpuProcess(HasGpuProcessCallback callback) {
GpuProcessHost::GetHasGpuProcess(std::move(callback));
}
-void RenderMessageFilter::DidGenerateCacheableMetadataOnUI(
- const GURL& url,
- base::Time expected_response_time,
- const std::vector<uint8_t>& data) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RenderProcessHost* host = RenderProcessHost::FromID(render_process_id_);
- if (!host)
- return;
-
- // Use the same priority for the metadata write as for script
- // resources (see defaultPriorityForResourceType() in WebKit's
- // CachedResource.cpp). Note that WebURLRequest::PriorityMedium
- // corresponds to net::LOW (see ConvertWebKitPriorityToNetPriority()
- // in weburlloader_impl.cc).
- const net::RequestPriority kPriority = net::LOW;
- host->GetStoragePartition()->GetNetworkContext()->WriteCacheMetadata(
- url, kPriority, expected_response_time, data);
-}
-
} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_message_filter.h b/chromium/content/browser/renderer_host/render_message_filter.h
index 76eda81660d..925508cf8d6 100644
--- a/chromium/content/browser/renderer_host/render_message_filter.h
+++ b/chromium/content/browser/renderer_host/render_message_filter.h
@@ -22,10 +22,10 @@
#include "content/public/browser/browser_associated_interface.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/common/widget_type.h"
#include "gpu/config/gpu_info.h"
#include "ipc/message_filter.h"
#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h"
-#include "third_party/blink/public/web/web_popup_type.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/native_widget_types.h"
@@ -42,23 +42,15 @@ struct MediaLogEvent;
}
namespace net {
-class IOBuffer;
class URLRequestContextGetter;
}
-namespace url {
-class Origin;
-}
-
namespace content {
class BrowserContext;
-class CacheStorageContextImpl;
-class CacheStorageCacheHandle;
class MediaInternals;
class RenderWidgetHelper;
class ResourceContext;
class ResourceDispatcherHostImpl;
-class GeneratedCodeCacheContext;
// This class filters out incoming IPC messages for the renderer process on the
// IPC thread.
@@ -72,9 +64,7 @@ class CONTENT_EXPORT RenderMessageFilter
BrowserContext* browser_context,
net::URLRequestContextGetter* request_context,
RenderWidgetHelper* render_widget_helper,
- MediaInternals* media_internals,
- CacheStorageContextImpl* cache_storage_context,
- GeneratedCodeCacheContext* generated_code_cache_context);
+ MediaInternals* media_internals);
// BrowserMessageFilter methods:
bool OnMessageReceived(const IPC::Message& message) override;
@@ -96,23 +86,11 @@ class CONTENT_EXPORT RenderMessageFilter
// mojom::RenderMessageFilter:
void GenerateRoutingID(GenerateRoutingIDCallback routing_id) override;
void CreateNewWidget(int32_t opener_id,
- blink::WebPopupType popup_type,
mojom::WidgetPtr widget,
CreateNewWidgetCallback callback) override;
void CreateFullscreenWidget(int opener_id,
mojom::WidgetPtr widget,
CreateFullscreenWidgetCallback callback) override;
- void DidGenerateCacheableMetadata(const GURL& url,
- base::Time expected_response_time,
- const std::vector<uint8_t>& data) override;
- void FetchCachedCode(const GURL& url, FetchCachedCodeCallback) override;
- void ClearCodeCacheEntry(const GURL& url) override;
- void DidGenerateCacheableMetadataInCacheStorage(
- const GURL& url,
- base::Time expected_response_time,
- const std::vector<uint8_t>& data,
- const url::Origin& cache_storage_origin,
- const std::string& cache_storage_cache_name) override;
void HasGpuProcess(HasGpuProcessCallback callback) override;
#if defined(OS_LINUX)
void SetThreadPriority(int32_t ns_tid,
@@ -126,25 +104,11 @@ class CONTENT_EXPORT RenderMessageFilter
base::ThreadPriority priority);
#endif
- void OnReceiveCachedCode(FetchCachedCodeCallback callback,
- const base::Time& response_time,
- const std::vector<uint8_t>& data);
- void OnCacheStorageOpenCallback(const GURL& url,
- base::Time expected_response_time,
- scoped_refptr<net::IOBuffer> buf,
- int buf_len,
- CacheStorageCacheHandle cache_handle,
- blink::mojom::CacheStorageError error);
void OnMediaLogEvents(const std::vector<media::MediaLogEvent>&);
bool CheckBenchmarkingEnabled() const;
bool CheckPreparsedJsCachingEnabled() const;
- // NetworkContext must be called from the UI thread.
- void DidGenerateCacheableMetadataOnUI(const GURL& url,
- base::Time expected_response_time,
- const std::vector<uint8_t>& data);
-
// Cached resource request dispatcher host, guaranteed to be non-null. We do
// not own it; it is managed by the BrowserProcess, which has a wider scope
// than we do.
@@ -161,11 +125,6 @@ class CONTENT_EXPORT RenderMessageFilter
int render_process_id_;
MediaInternals* media_internals_;
- CacheStorageContextImpl* cache_storage_context_;
-
- // TODO(crbug.com/867347): Consider registering its own Mojo interface rather
- // than going through RenderMessageFilter.
- GeneratedCodeCacheContext* generated_code_cache_context_;
base::WeakPtrFactory<RenderMessageFilter> weak_ptr_factory_;
diff --git a/chromium/content/browser/renderer_host/render_process_host_browsertest.cc b/chromium/content/browser/renderer_host/render_process_host_browsertest.cc
index b168086cac1..4ae24e5d37c 100644
--- a/chromium/content/browser/renderer_host/render_process_host_browsertest.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_browsertest.cc
@@ -6,11 +6,13 @@
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h"
#include "build/build_config.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_launcher_utils.h"
#include "content/public/browser/render_frame_host.h"
@@ -753,8 +755,8 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, KillProcessZerosAudioStreams) {
// Cycle UI and IO loop once to ensure OnChannelClosing() has been delivered
// to audio stream owners and they get a chance to notify of stream closure.
base::RunLoop run_loop;
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- media::BindToCurrentLoop(run_loop.QuitClosure()));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ media::BindToCurrentLoop(run_loop.QuitClosure()));
run_loop.Run();
}
@@ -852,8 +854,8 @@ IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
// Cycle UI and IO loop once to ensure OnChannelClosing() has been delivered
// to audio stream owners and they get a chance to notify of stream closure.
base::RunLoop run_loop;
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- media::BindToCurrentLoop(run_loop.QuitClosure()));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ media::BindToCurrentLoop(run_loop.QuitClosure()));
run_loop.Run();
}
@@ -917,8 +919,8 @@ IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
// Cycle UI and IO loop once to ensure OnChannelClosing() has been delivered
// to audio stream owners and they get a chance to notify of stream closure.
base::RunLoop run_loop;
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- media::BindToCurrentLoop(run_loop.QuitClosure()));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ media::BindToCurrentLoop(run_loop.QuitClosure()));
run_loop.Run();
}
diff --git a/chromium/content/browser/renderer_host/render_process_host_impl.cc b/chromium/content/browser/renderer_host/render_process_host_impl.cc
index 989b52793c4..cb57a9ea444 100644
--- a/chromium/content/browser/renderer_host/render_process_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_impl.cc
@@ -53,6 +53,7 @@
#include "base/synchronization/lock.h"
#include "base/sys_info.h"
#include "base/task/post_task.h"
+#include "base/thread_annotations.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -84,6 +85,8 @@
#include "content/browser/cache_storage/cache_storage_context_impl.h"
#include "content/browser/cache_storage/cache_storage_dispatcher_host.h"
#include "content/browser/child_process_security_policy_impl.h"
+#include "content/browser/code_cache/generated_code_cache.h"
+#include "content/browser/code_cache/generated_code_cache_context.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/dom_storage_message_filter.h"
@@ -111,6 +114,7 @@
#include "content/browser/permissions/permission_service_impl.h"
#include "content/browser/push_messaging/push_messaging_manager.h"
#include "content/browser/renderer_host/clipboard_host_impl.h"
+#include "content/browser/renderer_host/code_cache_host_impl.h"
#include "content/browser/renderer_host/embedded_frame_sink_provider_impl.h"
#include "content/browser/renderer_host/file_utilities_host_impl.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
@@ -150,7 +154,9 @@
#include "content/common/service_manager/service_manager_connection_impl.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/notification_service.h"
@@ -201,7 +207,6 @@
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h"
-#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
#include "services/service_manager/embedder/switches.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/connector.h"
@@ -417,13 +422,13 @@ class SiteProcessMap : public base::SupportsUserData::Data {
// two WebContents with blank SiteInstances. If that occurs, keeping the
// exising entry and not overwriting it is a predictable behavior that is
// safe.
- SiteToProcessMap::iterator i = map_.find(site);
+ auto i = map_.find(site);
if (i == map_.end())
map_[site] = process;
}
RenderProcessHost* FindProcess(const std::string& site) {
- SiteToProcessMap::iterator i = map_.find(site);
+ auto i = map_.find(site);
if (i != map_.end())
return i->second;
return nullptr;
@@ -438,9 +443,8 @@ class SiteProcessMap : public base::SupportsUserData::Data {
if (i->second == host)
sites.insert(i->first);
}
- for (std::set<std::string>::iterator i = sites.begin(); i != sites.end();
- ++i) {
- SiteToProcessMap::iterator iter = map_.find(*i);
+ for (auto i = sites.begin(); i != sites.end(); ++i) {
+ auto iter = map_.find(*i);
if (iter != map_.end()) {
DCHECK_EQ(iter->second, host);
map_.erase(iter);
@@ -522,8 +526,8 @@ class SessionStorageHolder : public base::SupportsUserData::Data {
session_storage_namespaces_awaiting_close_.release());
}
- void Hold(const SessionStorageNamespaceMap& sessions, int view_route_id) {
- (*session_storage_namespaces_awaiting_close_)[view_route_id] = sessions;
+ void Hold(const SessionStorageNamespaceMap& sessions, int widget_route_id) {
+ (*session_storage_namespaces_awaiting_close_)[widget_route_id] = sessions;
}
void Release(int old_route_id) {
@@ -577,6 +581,15 @@ class SpareRenderProcessHostManager : public RenderProcessHostObserver {
RenderProcessHostImpl::GetMaxRendererProcessCount())
return;
+ // Don't create a spare renderer when the system is under load. This is
+ // currently approximated by only looking at the memory pressure. See also
+ // https://crbug.com/852905.
+ auto* memory_monitor = base::MemoryPressureMonitor::Get();
+ if (memory_monitor &&
+ memory_monitor->GetCurrentPressureLevel() >=
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE)
+ return;
+
spare_render_process_host_ = RenderProcessHostImpl::CreateRenderProcessHost(
browser_context, nullptr /* storage_partition_impl */,
nullptr /* site_instance */, false /* is_for_guests_only */);
@@ -832,8 +845,8 @@ class RenderProcessHostIsReadyObserver : public RenderProcessHostObserver {
private:
void PostTask() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&RenderProcessHostIsReadyObserver::CallTask,
weak_factory_.GetWeakPtr()));
}
@@ -1228,6 +1241,18 @@ void GetNetworkChangeManager(
GetNetworkService()->GetNetworkChangeManager(std::move(request));
}
+std::set<int>& GetCurrentCorbPluginExceptions() {
+ static base::NoDestructor<std::set<int>> s_data;
+ return *s_data;
+}
+
+void OnNetworkServiceCrash() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ network::mojom::NetworkService* network_service = GetNetworkService();
+ for (int process_id : GetCurrentCorbPluginExceptions())
+ network_service->AddCorbExceptionForPlugin(process_id);
+}
+
void RemoveCorbExceptionForPluginOnIOThread(int process_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -1243,10 +1268,11 @@ void RemoveCorbExceptionForPluginOnUIThread(int process_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ GetCurrentCorbPluginExceptions().erase(process_id);
GetNetworkService()->RemoveCorbExceptionForPlugin(process_id);
} else {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&RemoveCorbExceptionForPluginOnIOThread, process_id));
}
}
@@ -1259,15 +1285,23 @@ void AddCorbExceptionForPluginOnUIThread(int process_id) {
// In this case the exception won't be added via NetworkService (because of
// the early return below), but we need to proactively do clean-up on IO
// thread.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&RemoveCorbExceptionForPluginOnIOThread, process_id));
return;
}
process->CleanupCorbExceptionForPluginUponDestruction();
- if (base::FeatureList::IsEnabled(network::features::kNetworkService))
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ static NetworkServiceCrashHandlerId s_crash_handler_id;
+ if (s_crash_handler_id.is_null()) {
+ s_crash_handler_id = RegisterNetworkServiceCrashHandler(
+ base::BindRepeating(&OnNetworkServiceCrash));
+ }
+
+ GetCurrentCorbPluginExceptions().insert(process_id);
GetNetworkService()->AddCorbExceptionForPlugin(process_id);
+ }
}
// This is the entry point (i.e. this is called on the IO thread *before*
@@ -1280,8 +1314,8 @@ void AddCorbExceptionForPluginOnIOThread(int process_id) {
if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
network::CrossOriginReadBlocking::AddExceptionForPlugin(process_id);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&AddCorbExceptionForPluginOnUIThread, process_id));
}
@@ -1310,7 +1344,7 @@ class RenderProcessHostImpl::ConnectionFilterController
}
base::Lock lock_;
- ConnectionFilterImpl* filter_;
+ ConnectionFilterImpl* filter_ PT_GUARDED_BY(lock_);
};
// Held by the RPH's BrowserContext's ServiceManagerConnection, ownership
@@ -1370,9 +1404,8 @@ class RenderProcessHostImpl::ConnectionFilterImpl : public ConnectionFilter {
std::unique_ptr<service_manager::BinderRegistry> registry_;
scoped_refptr<ConnectionFilterController> controller_;
- // Guards |enabled_|.
base::Lock enabled_lock_;
- bool enabled_ = true;
+ bool enabled_ GUARDED_BY(enabled_lock_) = true;
base::WeakPtrFactory<ConnectionFilterImpl> weak_factory_;
@@ -1561,7 +1594,6 @@ RenderProcessHostImpl::RenderProcessHostImpl(
permission_service_context_(new PermissionServiceContext(this)),
indexed_db_factory_(new IndexedDBDispatcherHost(
id_,
- storage_partition_impl_->GetURLRequestContext(),
storage_partition_impl_->GetIndexedDBContext(),
ChromeBlobStorageContext::GetFor(browser_context_))),
service_worker_dispatcher_host_(new ServiceWorkerDispatcherHost(
@@ -1594,9 +1626,10 @@ RenderProcessHostImpl::RenderProcessHostImpl(
if (!GetBrowserContext()->IsOffTheRecord() &&
!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGpuShaderDiskCache)) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CacheShaderInfo, GetID(),
- storage_partition_impl_->GetPath()));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&CacheShaderInfo, GetID(),
+ storage_partition_impl_->GetPath()));
}
push_messaging_manager_.reset(new PushMessagingManager(
@@ -1610,13 +1643,13 @@ RenderProcessHostImpl::RenderProcessHostImpl(
InitializeChannelProxy();
- if (!features::IsUsingWindowService()) {
+ if (!features::IsMultiProcessMash()) {
const int id = GetID();
const uint64_t tracing_id =
ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(id);
gpu_client_.reset(new viz::GpuClient(
std::make_unique<BrowserGpuClientDelegate>(), id, tracing_id,
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})));
}
GetMemoryDumpProvider().AddHost(this);
@@ -1680,8 +1713,8 @@ RenderProcessHostImpl::~RenderProcessHostImpl() {
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGpuShaderDiskCache)) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&RemoveShaderInfo, GetID()));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&RemoveShaderInfo, GetID()));
}
GetMemoryDumpProvider().RemoveHost(this);
@@ -1755,7 +1788,7 @@ bool RenderProcessHostImpl::Init() {
// is created. On Mac audio thread is the UI thread, a hang monitor is not
// necessary or recommended.
media::AudioManager::StartHangMonitorIfNeeded(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
}
#endif // !defined(OS_MACOSX)
@@ -1779,7 +1812,7 @@ bool RenderProcessHostImpl::Init() {
// on separate threads.
in_process_renderer_.reset(
g_renderer_main_thread_factory(InProcessChildThreadParams(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
&mojo_invitation_, child_connection_->service_token())));
base::Thread::Options options;
@@ -1841,7 +1874,7 @@ void RenderProcessHostImpl::EnableSendQueue() {
void RenderProcessHostImpl::InitializeChannelProxy() {
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
// Acquire a Connector which will route connections to a new instance of the
// renderer service.
@@ -1944,14 +1977,10 @@ void RenderProcessHostImpl::CreateMessageFilters() {
scoped_refptr<net::URLRequestContextGetter> request_context(
storage_partition_impl_->GetURLRequestContext());
- // TODO(crbug.com/867347): Consider registering Mojo interface for
- // GeneratedCodeCache rather than going through RenderMessageFilter.
scoped_refptr<RenderMessageFilter> render_message_filter =
base::MakeRefCounted<RenderMessageFilter>(
GetID(), GetBrowserContext(), request_context.get(),
- widget_helper_.get(), media_internals,
- storage_partition_impl_->GetCacheStorageContext(),
- storage_partition_impl_->GetGeneratedCodeCacheContext());
+ widget_helper_.get(), media_internals);
AddFilter(render_message_filter.get());
render_frame_message_filter_ = new RenderFrameMessageFilter(
@@ -1983,8 +2012,9 @@ void RenderProcessHostImpl::CreateMessageFilters() {
storage_partition_impl_->GetFileSystemContext(),
storage_partition_impl_->GetServiceWorkerContext(),
storage_partition_impl_->GetPrefetchURLLoaderService(),
+ BrowserContext::GetSharedCorsOriginAccessList(browser_context),
std::move(get_contexts_callback),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
AddFilter(resource_message_filter_.get());
@@ -2027,13 +2057,23 @@ void RenderProcessHostImpl::BindCacheStorage(
}
// Send the binding to IO thread, because Cache Storage handles Mojo IPC on IO
// thread entirely.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CacheStorageDispatcherHost::AddBinding,
cache_storage_dispatcher_host_, std::move(request),
origin));
}
+void RenderProcessHostImpl::BindFileSystemManager(
+ blink::mojom::FileSystemManagerRequest request) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&FileSystemManagerImpl::BindRequest,
+ base::Unretained(file_system_manager_impl_.get()),
+ std::move(request)));
+}
+
void RenderProcessHostImpl::CancelProcessShutdownDelayForUnload() {
if (IsKeepAliveRefCountDisabled())
return;
@@ -2047,8 +2087,8 @@ void RenderProcessHostImpl::DelayProcessShutdownForUnload(
return;
IncrementKeepAliveRefCount(RenderProcessHost::KeepAliveClientType::kUnload);
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&RenderProcessHostImpl::CancelProcessShutdownDelayForUnload,
weak_factory_.GetWeakPtr()),
@@ -2110,11 +2150,10 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
registry.get(),
base::Bind(&CreateMemoryCoordinatorHandleForRenderProcess, GetID()));
}
- if (resource_coordinator::IsResourceCoordinatorEnabled()) {
- AddUIThreadInterface(
- registry.get(),
- base::Bind(&CreateProcessResourceCoordinator, base::Unretained(this)));
- }
+
+ AddUIThreadInterface(
+ registry.get(),
+ base::Bind(&CreateProcessResourceCoordinator, base::Unretained(this)));
AddUIThreadInterface(registry.get(),
base::BindRepeating(&ClipboardHostImpl::Create));
@@ -2150,8 +2189,14 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
base::Unretained(push_messaging_manager_.get())));
file_system_manager_impl_.reset(new FileSystemManagerImpl(
- GetID(), storage_partition_impl_->GetFileSystemContext(),
+ GetID(), MSG_ROUTING_NONE,
+ storage_partition_impl_->GetFileSystemContext(),
ChromeBlobStorageContext::GetFor(GetBrowserContext())));
+ // This interface is still exposed by the RenderProcessHost's registry so
+ // that it can be accessed by PepperFileSystemHost. Blink accesses this
+ // interface through RenderFrameHost/RendererInterfaceBinders.
+ // TODO(https://crbug.com/873661): Make PepperFileSystemHost access this with
+ // the RenderFrameHost's registry, and remove this registration.
registry->AddInterface(
base::BindRepeating(&FileSystemManagerImpl::BindRequest,
base::Unretained(file_system_manager_impl_.get())));
@@ -2191,6 +2236,12 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
registry->AddInterface(
base::Bind(&metrics::CreateSingleSampleMetricsProvider));
+ registry->AddInterface(base::BindRepeating(
+ &CodeCacheHostImpl::Create, GetID(),
+ base::RetainedRef(storage_partition_impl_->GetCacheStorageContext()),
+ base::RetainedRef(
+ storage_partition_impl_->GetGeneratedCodeCacheContext())));
+
#if BUILDFLAG(ENABLE_REPORTING)
registry->AddInterface(
base::Bind(&CreateReportingServiceProxy, storage_partition_impl_));
@@ -2218,10 +2269,18 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
&RenderProcessHostImpl::CreateRendererHost, base::Unretained(this)));
if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // Using an opaque origin here should be safe - the URLLoaderFactory created
+ // for such origin shouldn't have any special privileges.
+ //
+ // TODO(lukasza): https://crbug.com/871827: Use the actual origin that will
+ // be used as |request_initiator|. The origin should come from the browser
+ // process.
+ const url::Origin kSafeOrigin = url::Origin();
+
AddUIThreadInterface(
registry.get(),
base::Bind(&RenderProcessHostImpl::CreateURLLoaderFactory,
- base::Unretained(this)));
+ base::Unretained(this), kSafeOrigin));
}
registry->AddInterface(
@@ -2246,8 +2305,10 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
AddUIThreadInterface(registry.get(),
base::BindRepeating(&GetNetworkChangeManager));
- registry->AddInterface(base::BindRepeating(
- &RenderProcessHostImpl::BindVideoDecoderService, base::Unretained(this)));
+ AddUIThreadInterface(
+ registry.get(),
+ base::BindRepeating(&RenderProcessHostImpl::BindVideoDecoderService,
+ base::Unretained(this)));
// ---- Please do not register interfaces below this line ------
//
@@ -2479,14 +2540,7 @@ mojom::Renderer* RenderProcessHostImpl::GetRendererInterface() {
resource_coordinator::ProcessResourceCoordinator*
RenderProcessHostImpl::GetProcessResourceCoordinator() {
- if (process_resource_coordinator_)
- return process_resource_coordinator_.get();
-
- if (!resource_coordinator::IsResourceCoordinatorEnabled()) {
- process_resource_coordinator_ =
- std::make_unique<resource_coordinator::ProcessResourceCoordinator>(
- nullptr);
- } else {
+ if (!process_resource_coordinator_) {
auto* connection = ServiceManagerConnection::GetForProcess();
process_resource_coordinator_ =
std::make_unique<resource_coordinator::ProcessResourceCoordinator>(
@@ -2496,23 +2550,35 @@ RenderProcessHostImpl::GetProcessResourceCoordinator() {
}
void RenderProcessHostImpl::CreateURLLoaderFactory(
+ const url::Origin& origin,
network::mojom::URLLoaderFactoryRequest request) {
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ResourceMessageFilter::Clone, resource_message_filter_,
std::move(request)));
return;
}
- network::mojom::URLLoaderFactoryParamsPtr params =
- network::mojom::URLLoaderFactoryParams::New();
- params->process_id = id_;
- params->disable_web_security =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableWebSecurity);
- SiteIsolationPolicy::PopulateURLLoaderFactoryParamsPtrForCORB(params.get());
- storage_partition_impl_->GetNetworkContext()->CreateURLLoaderFactory(
- std::move(request), std::move(params));
+
+ network::mojom::NetworkContext* network_context =
+ storage_partition_impl_->GetNetworkContext();
+ network::mojom::URLLoaderFactoryPtrInfo embedder_provided_factory =
+ GetContentClient()->browser()->CreateURLLoaderFactoryForNetworkRequests(
+ this, network_context, origin);
+ if (embedder_provided_factory) {
+ mojo::FuseInterface(std::move(request),
+ std::move(embedder_provided_factory));
+ } else {
+ network::mojom::URLLoaderFactoryParamsPtr params =
+ network::mojom::URLLoaderFactoryParams::New();
+ params->process_id = GetID();
+ params->disable_web_security =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableWebSecurity);
+ SiteIsolationPolicy::PopulateURLLoaderFactoryParamsPtrForCORB(params.get());
+ network_context->CreateURLLoaderFactory(std::move(request),
+ std::move(params));
+ }
}
void RenderProcessHostImpl::SetIsNeverSuitableForReuse() {
@@ -2586,8 +2652,6 @@ void RenderProcessHostImpl::ShutdownForBadMessage(
std::string site_isolation_mode;
if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites())
site_isolation_mode += "spp ";
- if (SiteIsolationPolicy::IsTopDocumentIsolationEnabled())
- site_isolation_mode += "tdi ";
if (SiteIsolationPolicy::AreIsolatedOriginsEnabled())
site_isolation_mode += "io ";
if (site_isolation_mode.empty())
@@ -2998,7 +3062,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kEnableWebVR,
switches::kExplicitlyAllowedPorts,
switches::kFileUrlPathAlias,
- switches::kForceColorProfile,
+ switches::kForceDisplayColorProfile,
switches::kForceDeviceScaleFactor,
switches::kForceGpuMemAvailableMb,
switches::kForceGpuRasterization,
@@ -3119,7 +3183,11 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
renderer_cmd->AppendSwitch(switches::kDisableDatabases);
}
-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+#if defined(OS_ANDROID)
+ if (browser_cmd.HasSwitch(switches::kDisableGpuCompositing)) {
+ renderer_cmd->AppendSwitch(switches::kDisableGpuCompositing);
+ }
+#elif !defined(OS_CHROMEOS)
#if !BUILDFLAG(ENABLE_MUS)
// If gpu compositing is not being used, tell the renderer at startup. This
// is inherently racey, as it may change while the renderer is being launched,
@@ -3130,11 +3198,11 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
// no need to check this state and forward it.
if (ImageTransportFactory::GetInstance()->IsGpuCompositingDisabled())
renderer_cmd->AppendSwitch(switches::kDisableGpuCompositing);
-#else
+#else // BUILDFLAG(ENABLE_MUS)
// TODO(tonikitoo): Check if renderer should use software compositing
// through some mechanism that isn't ImageTransportFactory with mus.
-#endif
-#endif
+#endif // !BUILDFLAG(ENABLE_MUS)
+#endif // defined(OS_ANDROID)
// Add kWaitForDebugger to let renderer process wait for a debugger.
if (browser_cmd.HasSwitch(switches::kWaitForDebuggerChildren)) {
@@ -3276,7 +3344,7 @@ bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
IPC_BEGIN_MESSAGE_MAP(RenderProcessHostImpl, msg)
IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction,
OnUserMetricsRecordAction)
- IPC_MESSAGE_HANDLER(ViewHostMsg_Close_ACK, OnCloseACK)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_Close_ACK, OnCloseACK)
IPC_MESSAGE_HANDLER(AecDumpMsg_RegisterAecDumpConsumer,
OnRegisterAecDumpConsumer)
IPC_MESSAGE_HANDLER(AecDumpMsg_UnregisterAecDumpConsumer,
@@ -3410,8 +3478,8 @@ void RenderProcessHostImpl::Cleanup() {
return;
if (is_initialized_) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&WebRtcLog::ClearLogMessageCallback, GetID()));
}
@@ -3561,9 +3629,9 @@ void RenderProcessHostImpl::SetEchoCanceller3(
if (!aec3_set_callback_.is_null()) {
MediaStreamManager::SendMessageToNativeLog("RPHI: Failed to set AEC3");
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), false,
- "Operation already in progress"));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), false,
+ "Operation already in progress"));
return;
}
@@ -3935,12 +4003,6 @@ RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSiteInstance(
render_process_host = GetSoleProcessHostForSite(
browser_context, site_url, site_instance->lock_url());
break;
- case SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS:
- DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled());
- DCHECK(!site_instance->is_for_service_worker());
- render_process_host = GetDefaultSubframeProcessHost(
- browser_context, site_instance, is_for_guests_only);
- break;
case SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE:
render_process_host =
FindReusableProcessHostForSiteInstance(site_instance);
@@ -4210,7 +4272,7 @@ void RenderProcessHost::SetHungRendererAnalysisFunction(
void RenderProcessHostImpl::ReleaseOnCloseACK(
RenderProcessHost* host,
const SessionStorageNamespaceMap& sessions,
- int view_route_id) {
+ int widget_route_id) {
DCHECK(host);
if (sessions.empty())
return;
@@ -4220,7 +4282,7 @@ void RenderProcessHostImpl::ReleaseOnCloseACK(
holder = new SessionStorageHolder();
host->SetUserData(kSessionStorageHolderKey, base::WrapUnique(holder));
}
- holder->Hold(sessions, view_route_id);
+ holder->Hold(sessions, widget_route_id);
}
void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) {
@@ -4294,6 +4356,14 @@ void RenderProcessHostImpl::UpdateProcessPriority() {
return;
}
+ if (!has_recorded_media_stream_frame_depth_metric_ && !visible_clients_ &&
+ media_stream_count_) {
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ "BrowserRenderProcessHost.InvisibleMediaStreamFrameDepth", frame_depth_,
+ 50);
+ has_recorded_media_stream_frame_depth_metric_ = true;
+ }
+
const ChildProcessLauncherPriority priority(
visible_clients_ > 0 || base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableRendererBackgrounding),
@@ -4462,12 +4532,12 @@ void RenderProcessHostImpl::OnUserMetricsRecordAction(
base::RecordComputedAction(action);
}
-void RenderProcessHostImpl::OnCloseACK(int old_route_id) {
+void RenderProcessHostImpl::OnCloseACK(int closed_widget_route_id) {
SessionStorageHolder* holder =
static_cast<SessionStorageHolder*>(GetUserData(kSessionStorageHolderKey));
if (!holder)
return;
- holder->Release(old_route_id);
+ holder->Release(closed_widget_route_id);
}
void RenderProcessHostImpl::OnGpuSwitched() {
@@ -4475,23 +4545,6 @@ void RenderProcessHostImpl::OnGpuSwitched() {
}
// static
-RenderProcessHost* RenderProcessHostImpl::GetDefaultSubframeProcessHost(
- BrowserContext* browser_context,
- SiteInstanceImpl* site_instance,
- bool is_for_guests_only) {
- DefaultSubframeProcessHostHolder* holder =
- static_cast<DefaultSubframeProcessHostHolder*>(
- browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey));
- if (!holder) {
- holder = new DefaultSubframeProcessHostHolder(browser_context);
- browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey,
- base::WrapUnique(holder));
- }
-
- return holder->GetProcessHost(site_instance, is_for_guests_only);
-}
-
-// static
RenderProcessHost*
RenderProcessHostImpl::FindReusableProcessHostForSiteInstance(
SiteInstanceImpl* site_instance) {
@@ -4554,15 +4607,15 @@ void RenderProcessHostImpl::CreateMediaStreamTrackMetricsHost(
}
void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread,
weak_factory_.GetWeakPtr(), id));
}
void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&RenderProcessHostImpl::UnregisterAecDumpConsumerOnUIThread,
weak_factory_.GetWeakPtr(), id));
diff --git a/chromium/content/browser/renderer_host/render_process_host_impl.h b/chromium/content/browser/renderer_host/render_process_host_impl.h
index 37bc9b79afd..f11aa8252ea 100644
--- a/chromium/content/browser/renderer_host/render_process_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_process_host_impl.h
@@ -24,6 +24,7 @@
#include "base/process/process.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/cache_storage/cache_storage_dispatcher_host.h"
#include "content/browser/child_process_launcher.h"
@@ -39,6 +40,7 @@
#include "content/common/media/renderer_audio_output_stream_factory.mojom.h"
#include "content/common/renderer.mojom.h"
#include "content/common/renderer_host.mojom.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/service_manager_connection.h"
@@ -57,6 +59,7 @@
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/mojom/associated_interfaces/associated_interfaces.mojom.h"
#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom.h"
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gl/gpu_switching_observer.h"
@@ -216,6 +219,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
resource_coordinator::ProcessResourceCoordinator*
GetProcessResourceCoordinator() override;
void CreateURLLoaderFactory(
+ const url::Origin& origin,
network::mojom::URLLoaderFactoryRequest request) override;
void SetIsNeverSuitableForReuse() override;
@@ -255,11 +259,12 @@ class CONTENT_EXPORT RenderProcessHostImpl
// Used to extend the lifetime of the sessions until the render view
// in the renderer is fully closed. This is static because its also called
- // with mock hosts as input in test cases.
- static void ReleaseOnCloseACK(
- RenderProcessHost* host,
- const SessionStorageNamespaceMap& sessions,
- int view_route_id);
+ // with mock hosts as input in test cases. The RenderWidget routing associated
+ // with the view is used as the key since the WidgetMsg_Close and
+ // WidgetHostMsg_Close_ACK logic is centered around RenderWidgets.
+ static void ReleaseOnCloseACK(RenderProcessHost* host,
+ const SessionStorageNamespaceMap& sessions,
+ int widget_route_id);
// Register/unregister the host identified by the host id in the global host
// list.
@@ -315,7 +320,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
// handles all cases. These cases include:
// - process-per-site: see
// RegisterSoleProcessHostForSite/GetSoleProcessHostForSite.
- // - TDI: see GetDefaultSubframeProcessHost.
// - REUSE_PENDING_OR_COMMITTED reuse policy (for ServiceWorkers and OOPIFs):
// see FindReusableProcessHostForSiteInstance.
// - normal process reuse when over process limit: see
@@ -445,6 +449,9 @@ class CONTENT_EXPORT RenderProcessHostImpl
// before the process shuts down.
void DelayProcessShutdownForUnload(const base::TimeDelta& timeout);
+ // Binds request to the FileSystemManager instance owned by the render process
+ // host, and is used by workers via RendererInterfaceBinders.
+ void BindFileSystemManager(blink::mojom::FileSystemManagerRequest request);
FileSystemManagerImpl* GetFileSystemManagerForTesting() {
return file_system_manager_impl_.get();
}
@@ -532,7 +539,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
// Control message handlers.
void OnUserMetricsRecordAction(const std::string& action);
- void OnCloseACK(int old_route_id);
+ void OnCloseACK(int closed_widget_route_id);
// Generates a command line to be used to spawn a renderer and appends the
// results to |*command_line|.
@@ -575,12 +582,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
base::TimeTicks start,
base::TimeTicks end);
- // Returns the default subframe RenderProcessHost to use for |site_instance|.
- static RenderProcessHost* GetDefaultSubframeProcessHost(
- BrowserContext* browser_context,
- SiteInstanceImpl* site_instance,
- bool is_for_guests_only);
-
// Get an existing RenderProcessHost associated with the given browser
// context, if possible. The renderer process is chosen randomly from
// suitable renderers that share the same context and type (determined by the
@@ -648,7 +649,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
registry->AddInterface(
base::Bind(&InterfaceGetter<CallbackType>::GetInterfaceOnUIThread,
instance_weak_factory_->GetWeakPtr(), callback),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}));
}
// Callback to unblock process shutdown after waiting for unload handlers to
@@ -887,6 +888,9 @@ class CONTENT_EXPORT RenderProcessHostImpl
bool cleanup_corb_exception_for_plugin_upon_destruction_ = false;
+ // Fields for recording MediaStream UMA.
+ bool has_recorded_media_stream_frame_depth_metric_ = false;
+
base::WeakPtrFactory<RenderProcessHostImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl);
diff --git a/chromium/content/browser/renderer_host/render_view_host_delegate.h b/chromium/content/browser/renderer_host/render_view_host_delegate.h
index f2d59fbd1f4..f529058d126 100644
--- a/chromium/content/browser/renderer_host/render_view_host_delegate.h
+++ b/chromium/content/browser/renderer_host/render_view_host_delegate.h
@@ -16,7 +16,6 @@
#include "content/common/content_export.h"
#include "content/common/render_message_filter.mojom.h"
#include "net/base/load_states.h"
-#include "third_party/blink/public/web/web_popup_type.h"
class GURL;
@@ -125,26 +124,24 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// widget should be created associated with the given |route_id| in the
// process |render_process_id|, but it should not be shown yet. That should
// happen in response to ShowCreatedWidget.
- // |popup_type| indicates if the widget is a popup and what kind of popup it
- // is (select, autofill...).
virtual void CreateNewWidget(int32_t render_process_id,
- int32_t route_id,
- mojom::WidgetPtr widget,
- blink::WebPopupType popup_type) {}
+ int32_t widget_route_id,
+ mojom::WidgetPtr widget) {}
// Creates a full screen RenderWidget. Similar to above.
virtual void CreateNewFullscreenWidget(int32_t render_process_id,
- int32_t route_id,
+ int32_t widget_route_id,
mojom::WidgetPtr widget) {}
// Show the newly created widget with the specified bounds.
// The widget is identified by the route_id passed to CreateNewWidget.
virtual void ShowCreatedWidget(int process_id,
- int route_id,
+ int widget_route_id,
const gfx::Rect& initial_rect) {}
// Show the newly created full screen widget. Similar to above.
- virtual void ShowCreatedFullscreenWidget(int process_id, int route_id) {}
+ virtual void ShowCreatedFullscreenWidget(int process_id,
+ int widget_route_id) {}
// Returns the SessionStorageNamespace the render view should use. Might
// create the SessionStorageNamespace on the fly.
diff --git a/chromium/content/browser/renderer_host/render_view_host_delegate_view.cc b/chromium/content/browser/renderer_host/render_view_host_delegate_view.cc
index 746ea590371..ac2f6c67d0c 100644
--- a/chromium/content/browser/renderer_host/render_view_host_delegate_view.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_delegate_view.cc
@@ -21,7 +21,7 @@ int RenderViewHostDelegateView::GetBottomControlsHeight() const {
return 0;
}
-bool RenderViewHostDelegateView::DoBrowserControlsShrinkBlinkSize() const {
+bool RenderViewHostDelegateView::DoBrowserControlsShrinkRendererSize() const {
return false;
}
diff --git a/chromium/content/browser/renderer_host/render_view_host_delegate_view.h b/chromium/content/browser/renderer_host/render_view_host_delegate_view.h
index 62e97446fb0..3b77252b775 100644
--- a/chromium/content/browser/renderer_host/render_view_host_delegate_view.h
+++ b/chromium/content/browser/renderer_host/render_view_host_delegate_view.h
@@ -80,8 +80,8 @@ class CONTENT_EXPORT RenderViewHostDelegateView {
// Returns the height of the bottom controls in DIP.
virtual int GetBottomControlsHeight() const;
- // Returns true if the browser controls resize Blink's view size.
- virtual bool DoBrowserControlsShrinkBlinkSize() const;
+ // Returns true if the browser controls resize the renderer's view size.
+ virtual bool DoBrowserControlsShrinkRendererSize() const;
// Do post-event tasks for gesture events.
virtual void GestureEventAck(const blink::WebGestureEvent& event,
diff --git a/chromium/content/browser/renderer_host/render_view_host_impl.cc b/chromium/content/browser/renderer_host/render_view_host_impl.cc
index a25a92f7eb0..20e2b14881a 100644
--- a/chromium/content/browser/renderer_host/render_view_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_impl.cc
@@ -23,6 +23,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_info.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
@@ -52,10 +53,14 @@
#include "content/common/renderer.mojom.h"
#include "content/common/swapped_out_messages.h"
#include "content/common/view_messages.h"
+// TODO(ajwong): Remove widget_messages.h when WidgetHostMsg_Close is moved to
+// only RenderWidgetHostImpl.
+#include "content/common/widget_messages.h"
#include "content/public/browser/ax_event_notification_details.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/native_web_keyboard_event.h"
@@ -70,8 +75,6 @@
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/context_menu_params.h"
-#include "content/public/common/file_chooser_file_info.h"
-#include "content/public/common/file_chooser_params.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
@@ -93,7 +96,6 @@
#include "url/url_constants.h"
#if defined(OS_WIN)
-#include "base/win/win_client_metrics.h"
#include "ui/display/win/screen_win.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/platform_font_win.h"
@@ -118,30 +120,33 @@ using RoutingIDViewMap = base::hash_map<RenderViewHostID, RenderViewHostImpl*>;
base::LazyInstance<RoutingIDViewMap>::Leaky g_routing_id_view_map =
LAZY_INSTANCE_INITIALIZER;
-void GetPlatformSpecificPrefs(RendererPreferences* prefs) {
#if defined(OS_WIN)
- NONCLIENTMETRICS_XP metrics = {0};
- base::win::GetNonClientMetrics(&metrics);
-
- prefs->caption_font_family_name = metrics.lfCaptionFont.lfFaceName;
- prefs->caption_font_height = gfx::PlatformFontWin::GetFontSize(
- metrics.lfCaptionFont);
-
- prefs->small_caption_font_family_name = metrics.lfSmCaptionFont.lfFaceName;
- prefs->small_caption_font_height = gfx::PlatformFontWin::GetFontSize(
- metrics.lfSmCaptionFont);
-
- prefs->menu_font_family_name = metrics.lfMenuFont.lfFaceName;
- prefs->menu_font_height = gfx::PlatformFontWin::GetFontSize(
- metrics.lfMenuFont);
-
- prefs->status_font_family_name = metrics.lfStatusFont.lfFaceName;
- prefs->status_font_height = gfx::PlatformFontWin::GetFontSize(
- metrics.lfStatusFont);
+// Fetches the name and font size of a particular Windows system font.
+void GetFontInfo(gfx::PlatformFontWin::SystemFont system_font,
+ base::string16* name,
+ int32_t* size) {
+ const gfx::Font& font = gfx::PlatformFontWin::GetSystemFont(system_font);
+ *name = base::UTF8ToUTF16(font.GetFontName());
+ *size = font.GetFontSize();
+}
+#endif // OS_WIN
- prefs->message_font_family_name = metrics.lfMessageFont.lfFaceName;
- prefs->message_font_height = gfx::PlatformFontWin::GetFontSize(
- metrics.lfMessageFont);
+void GetPlatformSpecificPrefs(RendererPreferences* prefs) {
+#if defined(OS_WIN)
+ // Note that what is called "height" in this struct is actually the font size;
+ // font "height" typically includes ascender, descender, and padding and is
+ // often a third or so larger than the given font size.
+ GetFontInfo(gfx::PlatformFontWin::SystemFont::kCaption,
+ &prefs->caption_font_family_name, &prefs->caption_font_height);
+ GetFontInfo(gfx::PlatformFontWin::SystemFont::kSmallCaption,
+ &prefs->small_caption_font_family_name,
+ &prefs->small_caption_font_height);
+ GetFontInfo(gfx::PlatformFontWin::SystemFont::kMenu,
+ &prefs->menu_font_family_name, &prefs->menu_font_height);
+ GetFontInfo(gfx::PlatformFontWin::SystemFont::kMessage,
+ &prefs->message_font_family_name, &prefs->message_font_height);
+ GetFontInfo(gfx::PlatformFontWin::SystemFont::kStatus,
+ &prefs->status_font_family_name, &prefs->status_font_height);
prefs->vertical_scroll_bar_width_in_dips =
display::win::ScreenWin::GetSystemMetricsInDIP(SM_CXVSCROLL);
@@ -182,8 +187,7 @@ RenderViewHost* RenderViewHost::From(RenderWidgetHost* rwh) {
RenderViewHostImpl* RenderViewHostImpl::FromID(int process_id, int routing_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RoutingIDViewMap* views = g_routing_id_view_map.Pointer();
- RoutingIDViewMap::iterator it =
- views->find(RenderViewHostID(process_id, routing_id));
+ auto it = views->find(RenderViewHostID(process_id, routing_id));
return it == views->end() ? nullptr : it->second;
}
@@ -244,16 +248,13 @@ RenderViewHostImpl::RenderViewHostImpl(
if (!is_active_)
GetWidget()->UpdatePriority();
- if (ResourceDispatcherHostImpl::Get()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &ResourceDispatcherHostImpl::OnRenderViewHostCreated,
- base::Unretained(ResourceDispatcherHostImpl::Get()),
- GetProcess()->GetID(), GetRoutingID(),
- base::RetainedRef(
- GetProcess()->GetStoragePartition()->GetURLRequestContext())));
- }
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(
+ &ResourceDispatcherHostImpl::OnRenderViewHostCreated,
+ GetProcess()->GetID(), GetRoutingID(),
+ base::RetainedRef(
+ GetProcess()->GetStoragePartition()->GetURLRequestContext())));
close_timeout_.reset(new TimeoutMonitor(base::Bind(
&RenderViewHostImpl::ClosePageTimeout, weak_factory_.GetWeakPtr())));
@@ -262,13 +263,10 @@ RenderViewHostImpl::RenderViewHostImpl(
}
RenderViewHostImpl::~RenderViewHostImpl() {
- if (ResourceDispatcherHostImpl::Get()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&ResourceDispatcherHostImpl::OnRenderViewHostDeleted,
- base::Unretained(ResourceDispatcherHostImpl::Get()),
- GetProcess()->GetID(), GetRoutingID()));
- }
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&ResourceDispatcherHostImpl::OnRenderViewHostDeleted,
+ GetProcess()->GetID(), GetRoutingID()));
// Detach the routing ID as the object is going away.
GetProcess()->RemoveRoute(GetRoutingID());
@@ -584,9 +582,6 @@ WebPreferences RenderViewHostImpl::ComputeWebkitPrefs() {
if (delegate_ && delegate_->HasPersistentVideo())
prefs.media_controls_enabled = false;
- prefs.background_video_track_optimization_enabled =
- base::FeatureList::IsEnabled(media::kBackgroundVideoTrackOptimization);
-
GetContentClient()->browser()->OverrideWebkitPrefs(this, &prefs);
return prefs;
}
@@ -723,8 +718,7 @@ void RenderViewHostImpl::DirectoryEnumerationFinished(
int request_id,
const std::vector<base::FilePath>& files) {
// Grant the security access requested to the given files.
- for (std::vector<base::FilePath>::const_iterator file = files.begin();
- file != files.end(); ++file) {
+ for (auto file = files.begin(); file != files.end(); ++file) {
ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
GetProcess()->GetID(), *file);
}
@@ -734,14 +728,10 @@ void RenderViewHostImpl::DirectoryEnumerationFinished(
}
void RenderViewHostImpl::RenderWidgetWillSetIsLoading(bool is_loading) {
- if (ResourceDispatcherHostImpl::Get()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &ResourceDispatcherHostImpl::OnRenderViewHostSetIsLoading,
- base::Unretained(ResourceDispatcherHostImpl::Get()),
- GetProcess()->GetID(), GetRoutingID(), is_loading));
- }
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&ResourceDispatcherHostImpl::OnRenderViewHostSetIsLoading,
+ GetProcess()->GetID(), GetRoutingID(), is_loading));
}
bool RenderViewHostImpl::SuddenTerminationAllowed() const {
@@ -778,13 +768,13 @@ bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderViewHostImpl, msg)
- IPC_MESSAGE_HANDLER(FrameHostMsg_RenderProcessGone, OnRenderProcessGone)
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowFullscreenWidget,
OnShowFullscreenWidget)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnUpdateTargetURL)
- IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose)
- IPC_MESSAGE_HANDLER(ViewHostMsg_RequestSetBounds, OnRequestSetBounds)
+ // TODO:(ajwong): Move OnClose to RenderWidgetHostOwnerDelegate.
+ // https://crbug.com/545684
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_Close, OnClose)
IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentAvailableInMainFrame,
OnDocumentAvailableInMainFrame)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidContentsPreferredSizeChange,
@@ -809,44 +799,37 @@ void RenderViewHostImpl::ShutdownAndDestroy() {
// in the renderer has wound down.
if (GetProcess()->IsInitializedAndNotDead()) {
RenderProcessHostImpl::ReleaseOnCloseACK(
- GetProcess(),
- delegate_->GetSessionStorageNamespaceMap(),
- GetRoutingID());
+ GetProcess(), delegate_->GetSessionStorageNamespaceMap(),
+ GetWidget()->GetRoutingID());
}
GetWidget()->ShutdownAndDestroyWidget(false);
delete this;
}
-void RenderViewHostImpl::CreateNewWidget(int32_t route_id,
- mojom::WidgetPtr widget,
- blink::WebPopupType popup_type) {
- delegate_->CreateNewWidget(GetProcess()->GetID(), route_id, std::move(widget),
- popup_type);
+void RenderViewHostImpl::CreateNewWidget(int32_t widget_route_id,
+ mojom::WidgetPtr widget) {
+ delegate_->CreateNewWidget(GetProcess()->GetID(), widget_route_id,
+ std::move(widget));
}
-void RenderViewHostImpl::CreateNewFullscreenWidget(int32_t route_id,
+void RenderViewHostImpl::CreateNewFullscreenWidget(int32_t widget_route_id,
mojom::WidgetPtr widget) {
- delegate_->CreateNewFullscreenWidget(GetProcess()->GetID(), route_id,
+ delegate_->CreateNewFullscreenWidget(GetProcess()->GetID(), widget_route_id,
std::move(widget));
}
-void RenderViewHostImpl::OnShowWidget(int route_id,
+void RenderViewHostImpl::OnShowWidget(int widget_route_id,
const gfx::Rect& initial_rect) {
- delegate_->ShowCreatedWidget(GetProcess()->GetID(), route_id, initial_rect);
- Send(new ViewMsg_SetBounds_ACK(route_id));
-}
-
-void RenderViewHostImpl::OnShowFullscreenWidget(int route_id) {
- delegate_->ShowCreatedFullscreenWidget(GetProcess()->GetID(), route_id);
- Send(new ViewMsg_SetBounds_ACK(route_id));
+ delegate_->ShowCreatedWidget(GetProcess()->GetID(), widget_route_id,
+ initial_rect);
+ Send(new WidgetMsg_SetBounds_ACK(widget_route_id));
}
-void RenderViewHostImpl::OnRenderProcessGone(int status, int exit_code) {
- // Do nothing, otherwise RenderWidgetHostImpl will assume it is not a
- // RenderViewHostImpl and destroy itself.
- // TODO(nasko): Remove this hack once RenderViewHost and RenderWidgetHost are
- // decoupled.
+void RenderViewHostImpl::OnShowFullscreenWidget(int widget_route_id) {
+ delegate_->ShowCreatedFullscreenWidget(GetProcess()->GetID(),
+ widget_route_id);
+ Send(new WidgetMsg_SetBounds_ACK(widget_route_id));
}
void RenderViewHostImpl::OnUpdateTargetURL(const GURL& url) {
@@ -863,12 +846,6 @@ void RenderViewHostImpl::OnClose() {
ClosePageIgnoringUnloadEvents();
}
-void RenderViewHostImpl::OnRequestSetBounds(const gfx::Rect& bounds) {
- if (is_active_)
- delegate_->RequestSetBounds(bounds);
- Send(new ViewMsg_SetBounds_ACK(GetRoutingID()));
-}
-
void RenderViewHostImpl::OnDocumentAvailableInMainFrame(
bool uses_temporary_zoom_level) {
delegate_->DocumentAvailableInMainFrame(this);
@@ -933,9 +910,9 @@ bool RenderViewHostImpl::ShouldContributePriorityToProcess() {
return is_active_;
}
-void RenderViewHostImpl::RenderWidgetDidShutdown() {
- bool rv = Send(new ViewMsg_Close(GetRoutingID()));
- DCHECK(rv);
+void RenderViewHostImpl::RequestSetBounds(const gfx::Rect& bounds) {
+ if (is_active_)
+ delegate_->RequestSetBounds(bounds);
}
WebPreferences RenderViewHostImpl::GetWebkitPreferences() {
@@ -987,10 +964,6 @@ void RenderViewHostImpl::NotifyMoveOrResizeStarted() {
Send(new ViewMsg_MoveOrResizeStarted(GetRoutingID()));
}
-void RenderViewHostImpl::SelectWordAroundCaret() {
- Send(new ViewMsg_SelectWordAroundCaret(GetRoutingID()));
-}
-
void RenderViewHostImpl::PostRenderViewReady() {
GetProcess()->PostTaskWhenProcessIsReady(base::BindOnce(
&RenderViewHostImpl::RenderViewReady, weak_factory_.GetWeakPtr()));
diff --git a/chromium/content/browser/renderer_host/render_view_host_impl.h b/chromium/content/browser/renderer_host/render_view_host_impl.h
index af7f7b0d580..e70977a3f79 100644
--- a/chromium/content/browser/renderer_host/render_view_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_view_host_impl.h
@@ -31,7 +31,6 @@
#include "net/base/load_states.h"
#include "third_party/blink/public/web/web_ax_enums.h"
#include "third_party/blink/public/web/web_console_message.h"
-#include "third_party/blink/public/web/web_popup_type.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/mojo/window_open_disposition.mojom.h"
@@ -110,7 +109,6 @@ class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
WebPreferences GetWebkitPreferences() override;
void UpdateWebkitPreferences(const WebPreferences& prefs) override;
void OnWebkitPreferencesChanged() override;
- void SelectWordAroundCaret() override;
// RenderProcessHostObserver implementation
void RenderProcessExited(RenderProcessHost* host,
@@ -193,11 +191,8 @@ class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
sudden_termination_allowed_ = enabled;
}
- // Creates a new RenderWidget with the given route id. |popup_type| indicates
- // if this widget is a popup and what kind of popup it is (select, autofill).
- void CreateNewWidget(int32_t route_id,
- mojom::WidgetPtr widget,
- blink::WebPopupType popup_type);
+ // Creates a new RenderWidget with the given route id.
+ void CreateNewWidget(int32_t route_id, mojom::WidgetPtr widget);
// Creates a full screen RenderWidget.
void CreateNewFullscreenWidget(int32_t route_id, mojom::WidgetPtr widget);
@@ -239,19 +234,17 @@ class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
bool MayRenderWidgetForwardKeyboardEvent(
const NativeWebKeyboardEvent& key_event) override;
bool ShouldContributePriorityToProcess() override;
- void RenderWidgetDidShutdown() override;
+ void RequestSetBounds(const gfx::Rect& bounds) override;
// IPC message handlers.
void OnShowView(int route_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture);
- void OnShowWidget(int route_id, const gfx::Rect& initial_rect);
- void OnShowFullscreenWidget(int route_id);
- void OnRenderProcessGone(int status, int error_code);
+ void OnShowWidget(int widget_route_id, const gfx::Rect& initial_rect);
+ void OnShowFullscreenWidget(int widget_route_id);
void OnUpdateTargetURL(const GURL& url);
void OnClose();
- void OnRequestSetBounds(const gfx::Rect& bounds);
void OnDocumentAvailableInMainFrame(bool uses_temporary_zoom_level);
void OnDidContentsPreferredSizeChange(const gfx::Size& new_size);
void OnPasteFromSelectionClipboard();
diff --git a/chromium/content/browser/renderer_host/render_widget_helper.cc b/chromium/content/browser/renderer_host/render_widget_helper.cc
index c54233d8e1c..2fe97895d9c 100644
--- a/chromium/content/browser/renderer_host/render_widget_helper.cc
+++ b/chromium/content/browser/renderer_host/render_widget_helper.cc
@@ -8,11 +8,13 @@
#include "base/bind_helpers.h"
#include "base/lazy_instance.h"
#include "base/posix/eintr_wrapper.h"
+#include "base/task/post_task.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/common/view_messages.h"
+#include "content/public/browser/browser_task_traits.h"
namespace content {
namespace {
@@ -39,7 +41,7 @@ RenderWidgetHelper::~RenderWidgetHelper() {
// Delete this RWH from the map if it is found.
WidgetHelperMap& widget_map = g_widget_helpers.Get();
- WidgetHelperMap::iterator it = widget_map.find(render_process_id_);
+ auto it = widget_map.find(render_process_id_);
if (it != widget_map.end() && it->second == this)
widget_map.erase(it);
}
@@ -50,9 +52,9 @@ void RenderWidgetHelper::Init(
render_process_id_ = render_process_id;
resource_dispatcher_host_ = resource_dispatcher_host;
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AddWidgetHelper, render_process_id_,
- base::WrapRefCounted(this)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&AddWidgetHelper, render_process_id_,
+ base::WrapRefCounted(this)));
}
int RenderWidgetHelper::GetNextRoutingID() {
@@ -69,37 +71,35 @@ RenderWidgetHelper* RenderWidgetHelper::FromProcessHostID(
}
void RenderWidgetHelper::CreateNewWidget(int opener_id,
- blink::WebPopupType popup_type,
mojom::WidgetPtr widget,
int* route_id) {
*route_id = GetNextRoutingID();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&RenderWidgetHelper::OnCreateWidgetOnUI, this, opener_id,
- *route_id, widget.PassInterface(), popup_type));
+ *route_id, widget.PassInterface()));
}
void RenderWidgetHelper::CreateNewFullscreenWidget(int opener_id,
mojom::WidgetPtr widget,
int* route_id) {
*route_id = GetNextRoutingID();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&RenderWidgetHelper::OnCreateFullscreenWidgetOnUI, this,
opener_id, *route_id, widget.PassInterface()));
}
void RenderWidgetHelper::OnCreateWidgetOnUI(int32_t opener_id,
int32_t route_id,
- mojom::WidgetPtrInfo widget_info,
- blink::WebPopupType popup_type) {
+ mojom::WidgetPtrInfo widget_info) {
mojom::WidgetPtr widget;
widget.Bind(std::move(widget_info));
RenderViewHostImpl* host = RenderViewHostImpl::FromID(
render_process_id_, opener_id);
if (host)
- host->CreateNewWidget(route_id, std::move(widget), popup_type);
+ host->CreateNewWidget(route_id, std::move(widget));
}
void RenderWidgetHelper::OnCreateFullscreenWidgetOnUI(
diff --git a/chromium/content/browser/renderer_host/render_widget_helper.h b/chromium/content/browser/renderer_host/render_widget_helper.h
index 30012c94a8c..3ceda85b738 100644
--- a/chromium/content/browser/renderer_host/render_widget_helper.h
+++ b/chromium/content/browser/renderer_host/render_widget_helper.h
@@ -18,7 +18,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/global_request_id.h"
-#include "third_party/blink/public/web/web_popup_type.h"
+#include "content/public/common/widget_type.h"
#include "ui/gfx/native_widget_types.h"
namespace content {
@@ -50,7 +50,6 @@ class RenderWidgetHelper
// IO THREAD ONLY -----------------------------------------------------------
void CreateNewWidget(int opener_id,
- blink::WebPopupType popup_type,
mojom::WidgetPtr,
int* route_id);
void CreateNewFullscreenWidget(int opener_id,
@@ -67,8 +66,7 @@ class RenderWidgetHelper
// Called on the UI thread to finish creating a widget.
void OnCreateWidgetOnUI(int32_t opener_id,
int32_t route_id,
- mojom::WidgetPtrInfo widget,
- blink::WebPopupType popup_type);
+ mojom::WidgetPtrInfo widget);
// Called on the UI thread to create a fullscreen widget.
void OnCreateFullscreenWidgetOnUI(int32_t opener_id,
diff --git a/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc b/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc
index 373ecd28b14..f7bb0bcd2d4 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc
@@ -4,18 +4,11 @@
#include <vector>
-#include "base/optional.h"
#include "base/run_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "base/test/bind_test_util.h"
#include "base/time/time.h"
-#include "components/viz/common/features.h"
-#include "components/viz/common/frame_sinks/copy_output_request.h"
-#include "components/viz/common/frame_sinks/copy_output_result.h"
-#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/quads/render_pass.h"
-#include "components/viz/common/surfaces/local_surface_id.h"
-#include "content/browser/bad_message.h"
#include "content/browser/renderer_host/input/input_router_impl.h"
+#include "content/browser/renderer_host/input/synthetic_smooth_drag_gesture.h"
#include "content/browser/renderer_host/input/touch_action_filter.h"
#include "content/browser/renderer_host/input/touch_emulator.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -25,37 +18,24 @@
#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
+#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
-#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/public/platform/web_mouse_event.h"
-#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/events/base_event_utils.h"
-#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/latency/latency_info.h"
namespace content {
-class RenderWidgetHostBrowserTest : public ContentBrowserTest {
- protected:
- WebContentsImpl* web_contents() const {
- return static_cast<WebContentsImpl*>(shell()->web_contents());
- }
-
- TouchActionFilter* GetTouchActionFilterForWidget(RenderWidgetHostImpl* rwhi) {
- return &static_cast<InputRouterImpl*>(rwhi->input_router())
- ->touch_action_filter_;
- }
-};
-
-// The --site-per-porcess version of RenderWidgetHostBrowserTest.
-class RenderWidgetHostSitePerProcessTest : public RenderWidgetHostBrowserTest {
+// This test enables --site-per-porcess flag.
+class RenderWidgetHostSitePerProcessTest : public ContentBrowserTest {
public:
void SetUpCommandLine(base::CommandLine* command_line) override {
IsolateAllSitesForTesting(command_line);
@@ -66,70 +46,17 @@ class RenderWidgetHostSitePerProcessTest : public RenderWidgetHostBrowserTest {
SetupCrossSiteRedirector(embedded_test_server());
ASSERT_TRUE(embedded_test_server()->Start());
}
-};
-IN_PROC_BROWSER_TEST_F(RenderWidgetHostBrowserTest,
- ProhibitsCopyRequestsFromRenderer) {
- NavigateToURL(shell(), GURL("data:text/html,<!doctype html>"
- "<body style='background-color: red;'></body>"));
-
- // Wait for the view's surface to become available.
- auto* const view = static_cast<RenderWidgetHostViewBase*>(
- shell()->web_contents()->GetRenderWidgetHostView());
- while (!view->IsSurfaceAvailableForCopy()) {
- base::RunLoop run_loop;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, run_loop.QuitClosure(),
- base::TimeDelta::FromMilliseconds(250));
- run_loop.Run();
+ protected:
+ WebContentsImpl* web_contents() const {
+ return static_cast<WebContentsImpl*>(shell()->web_contents());
}
- // The browser process should be allowed to make a CopyOutputRequest.
- bool did_receive_copy_result = false;
- base::RunLoop run_loop;
- view->CopyFromSurface(gfx::Rect(), gfx::Size(),
- base::BindOnce(
- [](bool* success, base::OnceClosure quit_closure,
- const SkBitmap& bitmap) {
- *success = !bitmap.drawsNothing();
- std::move(quit_closure).Run();
- },
- &did_receive_copy_result, run_loop.QuitClosure()));
- run_loop.Run();
- ASSERT_TRUE(did_receive_copy_result);
-
- // Create a simulated-from-renderer CompositorFrame with a CopyOutputRequest.
- viz::CompositorFrame frame;
- std::unique_ptr<viz::RenderPass> pass = viz::RenderPass::Create();
- const gfx::Rect output_rect =
- gfx::Rect(view->GetCompositorViewportPixelSize());
- pass->SetNew(1 /* render pass id */, output_rect, output_rect,
- gfx::Transform());
- bool did_receive_aborted_copy_result = false;
- pass->copy_requests.push_back(std::make_unique<viz::CopyOutputRequest>(
- viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
- base::BindOnce(
- [](bool* got_nothing, std::unique_ptr<viz::CopyOutputResult> result) {
- *got_nothing = result->IsEmpty();
- },
- &did_receive_aborted_copy_result)));
- frame.render_pass_list.push_back(std::move(pass));
-
- // Submit the frame and expect the renderer to be instantly killed.
- auto* const host = RenderWidgetHostImpl::From(view->GetRenderWidgetHost());
- RenderProcessHostKillWaiter waiter(host->GetProcess());
- host->SubmitCompositorFrame(viz::LocalSurfaceId(), std::move(frame),
- base::nullopt, 0);
- base::Optional<bad_message::BadMessageReason> result = waiter.Wait();
- ASSERT_TRUE(result.has_value());
- EXPECT_EQ(bad_message::RWH_COPY_REQUEST_ATTEMPT, *result);
-
- // Check that the copy request result callback received an empty result. In a
- // normal browser, the requestor (in the render process) might never see a
- // response to the copy request before the process is killed. Nevertheless,
- // ensure the result is empty, just in case there is a race.
- EXPECT_TRUE(did_receive_aborted_copy_result);
-}
+ TouchActionFilter* GetTouchActionFilterForWidget(RenderWidgetHostImpl* rwhi) {
+ return &static_cast<InputRouterImpl*>(rwhi->input_router())
+ ->touch_action_filter_;
+ }
+};
class TestInputEventObserver : public RenderWidgetHost::InputEventObserver {
public:
@@ -163,8 +90,7 @@ class TestInputEventObserver : public RenderWidgetHost::InputEventObserver {
blink::WebInputEvent::Type acked_touch_event_type_;
};
-class RenderWidgetHostTouchEmulatorBrowserTest
- : public RenderWidgetHostBrowserTest {
+class RenderWidgetHostTouchEmulatorBrowserTest : public ContentBrowserTest {
public:
RenderWidgetHostTouchEmulatorBrowserTest()
: view_(nullptr),
@@ -174,7 +100,7 @@ class RenderWidgetHostTouchEmulatorBrowserTest
simulated_event_time_delta_(base::TimeDelta::FromMilliseconds(100)) {}
void SetUpOnMainThread() override {
- RenderWidgetHostBrowserTest::SetUpOnMainThread();
+ ContentBrowserTest::SetUpOnMainThread();
NavigateToURL(shell(),
GURL("data:text/html,<!doctype html>"
@@ -217,6 +143,58 @@ class RenderWidgetHostTouchEmulatorBrowserTest
base::TimeDelta simulated_event_time_delta_;
};
+// Synthetic mouse events not allowed on Android.
+#if !defined(OS_ANDROID)
+// This test makes sure that TouchEmulator doesn't emit a GestureScrollEnd without a valid
+// unique_touch_event_id when it sees a GestureFlingStart terminating the underlying mouse
+// scroll sequence. If the GestureScrollEnd is given a unique_touch_event_id of 0, then a
+// crash will occur.
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostTouchEmulatorBrowserTest,
+ TouchEmulatorPinchWithGestureFling) {
+ auto* touch_emulator = host()->GetTouchEmulator();
+ touch_emulator->Enable(TouchEmulator::Mode::kEmulatingTouchFromMouse,
+ ui::GestureProviderConfigType::GENERIC_MOBILE);
+ touch_emulator->SetPinchGestureModeForTesting(true);
+
+ TestInputEventObserver observer;
+ host()->AddInputEventObserver(&observer);
+
+ SyntheticSmoothDragGestureParams params;
+ params.start_point = gfx::PointF(10.f, 110.f);
+ params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
+ params.distances.push_back(gfx::Vector2d(0, -10));
+ params.distances.push_back(gfx::Vector2d(0, -10));
+ params.distances.push_back(gfx::Vector2d(0, -10));
+ params.distances.push_back(gfx::Vector2d(0, -10));
+ params.speed_in_pixels_s = 1200;
+
+ std::unique_ptr<SyntheticSmoothDragGesture> gesture(
+ new SyntheticSmoothDragGesture(params));
+
+ InputEventAckWaiter scroll_end_ack_waiter(
+ host(), blink::WebInputEvent::kGestureScrollEnd);
+ base::RunLoop run_loop;
+ host()->QueueSyntheticGesture(
+ std::move(gesture),
+ base::BindOnce(
+ base::BindLambdaForTesting([&](SyntheticGesture::Result result) {
+ EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
+ run_loop.Quit();
+ })));
+ run_loop.Run();
+ scroll_end_ack_waiter.Wait();
+
+ // Verify that a GestureFlingStart was suppressed by the TouchEmulator, and
+ // that we generated a GestureScrollEnd and routed it without crashing.
+ TestInputEventObserver::EventTypeVector dispatched_events =
+ observer.GetAndResetDispatchedEventTypes();
+ auto it_gse = std::find(dispatched_events.begin(), dispatched_events.end(),
+ blink::WebInputEvent::kGestureScrollEnd);
+ EXPECT_NE(dispatched_events.end(), it_gse);
+ EXPECT_TRUE(touch_emulator->suppress_next_fling_cancel_for_testing());
+}
+#endif // !defined(OS_ANDROID)
+
IN_PROC_BROWSER_TEST_F(RenderWidgetHostTouchEmulatorBrowserTest,
TouchEmulator) {
// All touches will be immediately acked instead of sending them to the
diff --git a/chromium/content/browser/renderer_host/render_widget_host_delegate.cc b/chromium/content/browser/renderer_host/render_widget_host_delegate.cc
index aa01d7b2207..82ce0212717 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_delegate.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_delegate.cc
@@ -12,6 +12,14 @@
namespace content {
+bool RenderWidgetHostDelegate::DoBrowserControlsShrinkRendererSize() const {
+ return false;
+}
+
+int RenderWidgetHostDelegate::GetTopControlsHeight() const {
+ return 0;
+}
+
KeyboardEventProcessingResult RenderWidgetHostDelegate::PreHandleKeyboardEvent(
const NativeWebKeyboardEvent& event) {
return KeyboardEventProcessingResult::NOT_HANDLED;
diff --git a/chromium/content/browser/renderer_host/render_widget_host_delegate.h b/chromium/content/browser/renderer_host/render_widget_host_delegate.h
index 387c81db0e0..883409580f8 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_delegate.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_delegate.h
@@ -56,6 +56,15 @@ struct NativeWebKeyboardEvent;
// of the RenderWidgetHost.
class CONTENT_EXPORT RenderWidgetHostDelegate {
public:
+ // Functions for controlling the browser top controls slide behavior with page
+ // gesture scrolling.
+ virtual void SetTopControlsShownRatio(
+ RenderWidgetHostImpl* render_widget_host,
+ float ratio) {}
+ virtual bool DoBrowserControlsShrinkRendererSize() const;
+ virtual int GetTopControlsHeight() const;
+ virtual void SetTopControlsGestureScrollInProgress(bool in_progress) {}
+
// The RenderWidgetHost has just been created.
virtual void RenderWidgetCreated(RenderWidgetHostImpl* render_widget_host) {}
diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.cc b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
index 437b43ade73..807466aeeda 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
@@ -15,7 +15,6 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/containers/hash_tables.h"
-#include "base/debug/dump_without_crashing.h"
#include "base/i18n/rtl.h"
#include "base/lazy_instance.h"
#include "base/location.h"
@@ -73,6 +72,7 @@
#include "content/common/text_input_state.h"
#include "content/common/view_messages.h"
#include "content/common/visual_properties.h"
+#include "content/common/widget_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/keyboard_event_processing_result.h"
@@ -347,7 +347,6 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
visual_properties_ack_pending_(false),
auto_resize_enabled_(false),
waiting_for_screen_rects_ack_(false),
- needs_repainting_on_restore_(false),
is_unresponsive_(false),
in_flight_event_count_(0),
in_get_backing_store_(false),
@@ -454,8 +453,7 @@ RenderWidgetHostImpl* RenderWidgetHostImpl::FromID(
int32_t routing_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RoutingIDWidgetMap* widgets = g_routing_id_widget_map.Pointer();
- RoutingIDWidgetMap::iterator it = widgets->find(
- RenderWidgetHostID(process_id, routing_id));
+ auto it = widgets->find(RenderWidgetHostID(process_id, routing_id));
return it == widgets->end() ? NULL : it->second;
}
@@ -557,8 +555,8 @@ void RenderWidgetHostImpl::SendScreenRects() {
last_view_screen_rect_ = view_->GetViewBounds();
last_window_screen_rect_ = view_->GetBoundsInRootWindow();
view_->WillSendScreenRects();
- Send(new ViewMsg_UpdateScreenRects(
- GetRoutingID(), last_view_screen_rect_, last_window_screen_rect_));
+ Send(new WidgetMsg_UpdateScreenRects(GetRoutingID(), last_view_screen_rect_,
+ last_window_screen_rect_));
waiting_for_screen_rects_ack_ = true;
}
@@ -611,41 +609,9 @@ void RenderWidgetHostImpl::ShutdownAndDestroyWidget(bool also_delete) {
RejectMouseLockOrUnlockIfNecessary();
if (process_->IsInitializedAndNotDead()) {
- // This logic below simulates the routing behavior from when RenderWidget
- // associated with RenderViews shared the same routing IDs.
- //
- // In the original code, the sharing of the routing ID yielded a bastardized
- // version of dynamic dispatch wherein the ultimate static code path that
- // handled a ViewMsg_Close changed based on if
- //
- // (a) the RenderWidgetImpl was also a RenderViewImpl
- // (b) the RenderViewImpl hooked the message in OnMessageReceived
- //
- // In the current code, if RenderWidgetImpl IS NOT a RenderViewImpl,
- // RenderWidgetHost WILL NOT have a |owner_delegate_| and the message can
- // be dispatched directly. This is the simplest case.
- //
- // If RenderWidgetImpl IS is a RenderViewImpl, then on some platforms
- // (seems like only Mac?) RenderViewImpl overrides ViewMsg::OnClose to do
- // additional processing before passing it up to RenderWidgetImpl::OnClose.
- //
- // When it is not overridden, the message delegated up via
- // IPC_MESSAGE_UNHANDLED to the RenderWidget's message dispatching.
- //
- // Basically, there are 2 overlapping hand-written implementations of
- // dynamic dispatch occuring: one via IPC_MESSAGE_UNHANDLED, and another
- // via calling the super-class method.
- //
- // TODO(ajwong): Once the routing_id split CL lands, remove one of these
- // implementaions of hand-written dyanmic dispatch. The world does not
- // need so many implementations of what's effectively "virtual."
- if (owner_delegate_) {
- owner_delegate_->RenderWidgetDidShutdown();
- } else {
- // Tell the non-view RendererWidget to close.
- bool rv = Send(new ViewMsg_Close(routing_id_));
- DCHECK(rv);
- }
+ // Tell the RendererWidget to close.
+ bool rv = Send(new WidgetMsg_Close(routing_id_));
+ DCHECK(rv);
}
Destroy(also_delete);
@@ -667,26 +633,27 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostImpl, msg)
IPC_MESSAGE_HANDLER(FrameHostMsg_RenderProcessGone, OnRenderProcessGone)
IPC_MESSAGE_HANDLER(FrameHostMsg_HittestData, OnHittestData)
- IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose)
- IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateScreenRects_ACK,
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_Close, OnClose)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_UpdateScreenRects_ACK,
OnUpdateScreenRectsAck)
- IPC_MESSAGE_HANDLER(ViewHostMsg_RequestSetBounds, OnRequestSetBounds)
- IPC_MESSAGE_HANDLER(ViewHostMsg_SetTooltipText, OnSetTooltipText)
- IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnSetCursor)
- IPC_MESSAGE_HANDLER(ViewHostMsg_AutoscrollStart, OnAutoscrollStart)
- IPC_MESSAGE_HANDLER(ViewHostMsg_AutoscrollFling, OnAutoscrollFling)
- IPC_MESSAGE_HANDLER(ViewHostMsg_AutoscrollEnd, OnAutoscrollEnd)
- IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged,
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_RequestSetBounds, OnRequestSetBounds)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_SetTooltipText, OnSetTooltipText)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_SetCursor, OnSetCursor)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_AutoscrollStart, OnAutoscrollStart)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_AutoscrollFling, OnAutoscrollFling)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_AutoscrollEnd, OnAutoscrollEnd)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_TextInputStateChanged,
OnTextInputStateChanged)
- IPC_MESSAGE_HANDLER(ViewHostMsg_LockMouse, OnLockMouse)
- IPC_MESSAGE_HANDLER(ViewHostMsg_UnlockMouse, OnUnlockMouse)
- IPC_MESSAGE_HANDLER(ViewHostMsg_SelectionBoundsChanged,
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_LockMouse, OnLockMouse)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_UnlockMouse, OnUnlockMouse)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_SelectionBoundsChanged,
OnSelectionBoundsChanged)
- IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeTouched, OnFocusedNodeTouched)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_FocusedNodeTouched, OnFocusedNodeTouched)
IPC_MESSAGE_HANDLER(DragHostMsg_StartDragging, OnStartDragging)
IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor)
- IPC_MESSAGE_HANDLER(ViewHostMsg_ForceRedrawComplete, OnForceRedrawComplete)
- IPC_MESSAGE_HANDLER(ViewHostMsg_FrameSwapMessages,
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_ForceRedrawComplete,
+ OnForceRedrawComplete)
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_FrameSwapMessages,
OnFrameSwapMessagesReceived)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -732,7 +699,7 @@ void RenderWidgetHostImpl::WasHidden() {
// If we have a renderer, then inform it that we are being hidden so it can
// reduce its resource utilization.
- Send(new ViewMsg_WasHidden(routing_id_));
+ Send(new WidgetMsg_WasHidden(routing_id_));
// Tell the RenderProcessHost we were hidden.
process_->UpdateClientPriority(this);
@@ -760,12 +727,9 @@ void RenderWidgetHostImpl::WasShown(bool record_presentation_time) {
SendScreenRects();
RestartInputEventAckTimeoutIfNecessary();
- // Always repaint on restore.
- bool needs_repainting = true;
- needs_repainting_on_restore_ = false;
- Send(new ViewMsg_WasShown(
- routing_id_, needs_repainting,
- record_presentation_time ? base::TimeTicks::Now() : base::TimeTicks()));
+ Send(new WidgetMsg_WasShown(routing_id_, record_presentation_time
+ ? base::TimeTicks::Now()
+ : base::TimeTicks()));
process_->UpdateClientPriority(this);
@@ -779,7 +743,8 @@ void RenderWidgetHostImpl::WasShown(bool record_presentation_time) {
// It's possible for our size to be out of sync with the renderer. The
// following is one case that leads to this:
- // 1. SynchronizeVisualProperties -> Send ViewMsg_SynchronizeVisualProperties
+ // 1. SynchronizeVisualProperties -> Send
+ // WidgetMsg_SynchronizeVisualProperties
// to render.
// 2. SynchronizeVisualProperties -> do nothing as
// sync_visual_props_ack_pending_ is true
@@ -791,7 +756,7 @@ void RenderWidgetHostImpl::WasShown(bool record_presentation_time) {
// necessary. SynchronizeVisualProperties does nothing if the sizes are
// already in sync.
//
- // TODO: ideally ViewMsg_WasShown would take a size. This way, the renderer
+ // TODO: ideally WidgetMsg_WasShown would take a size. This way, the renderer
// could handle both the restore and resize at once. This isn't that big a
// deal as RenderWidget::WasShown delays updating, so that the resize from
// SynchronizeVisualProperties is usually processed before the renderer is
@@ -845,7 +810,7 @@ bool RenderWidgetHostImpl::GetVisualProperties(
visual_properties->bottom_controls_height *= device_scale;
}
visual_properties->browser_controls_shrink_blink_size =
- view_->DoBrowserControlsShrinkBlinkSize();
+ view_->DoBrowserControlsShrinkRendererSize();
visual_properties->visible_viewport_size = view_->GetVisibleViewportSize();
// TODO(ccameron): GetLocalSurfaceId is not synchronized with the device
// scale factor of the surface. Fix this.
@@ -968,8 +933,8 @@ bool RenderWidgetHostImpl::SynchronizeVisualProperties(
!old_visual_properties_ || old_visual_properties_->new_size.width() !=
visual_properties->new_size.width();
bool sent_visual_properties = false;
- if (Send(new ViewMsg_SynchronizeVisualProperties(routing_id_,
- *visual_properties))) {
+ if (Send(new WidgetMsg_SynchronizeVisualProperties(routing_id_,
+ *visual_properties))) {
visual_properties_ack_pending_ = needs_ack;
old_visual_properties_.swap(visual_properties);
sent_visual_properties = true;
@@ -1015,6 +980,13 @@ void RenderWidgetHostImpl::Blur() {
focused_widget->SetPageFocus(false);
}
+void RenderWidgetHostImpl::FlushForTesting() {
+ if (associated_widget_input_handler_)
+ return associated_widget_input_handler_.FlushForTesting();
+ if (widget_input_handler_)
+ return widget_input_handler_.FlushForTesting();
+}
+
void RenderWidgetHostImpl::SetPageFocus(bool focused) {
is_focused_ = focused;
@@ -1053,7 +1025,7 @@ void RenderWidgetHostImpl::LostCapture() {
}
void RenderWidgetHostImpl::SetActive(bool active) {
- Send(new ViewMsg_SetActive(routing_id_, active));
+ Send(new WidgetMsg_SetActive(routing_id_, active));
}
void RenderWidgetHostImpl::LostMouseLock() {
@@ -1062,7 +1034,7 @@ void RenderWidgetHostImpl::LostMouseLock() {
}
void RenderWidgetHostImpl::SendMouseLockLost() {
- Send(new ViewMsg_MouseLockLost(routing_id_));
+ Send(new WidgetMsg_MouseLockLost(routing_id_));
}
void RenderWidgetHostImpl::ViewDestroyed() {
@@ -1188,7 +1160,8 @@ void RenderWidgetHostImpl::StopInputEventAckTimeout() {
void RenderWidgetHostImpl::DidNavigate(uint32_t next_source_id) {
current_content_source_id_ = next_source_id;
- did_receive_first_frame_after_navigation_ = false;
+ // Stop the flinging after navigating to a new page.
+ StopFling();
if (enable_surface_synchronization_) {
// Resize messages before navigation are not acked, so reset
@@ -1565,7 +1538,7 @@ void RenderWidgetHostImpl::SetCursor(const WebCursor& cursor) {
void RenderWidgetHostImpl::ShowContextMenuAtPoint(
const gfx::Point& point,
const ui::MenuSourceType source_type) {
- Send(new ViewMsg_ShowContextMenu(GetRoutingID(), source_type, point));
+ Send(new WidgetMsg_ShowContextMenu(GetRoutingID(), source_type, point));
}
void RenderWidgetHostImpl::SendCursorVisibilityState(bool is_visible) {
@@ -1634,6 +1607,9 @@ void RenderWidgetHostImpl::GetScreenInfo(ScreenInfo* result) {
else
DisplayUtil::GetDefaultScreenInfo(result);
+ if (display::Display::HasForceRasterColorProfile())
+ result->color_space = display::Display::GetForcedRasterColorProfile();
+
// TODO(sievers): find a way to make this done another way so the method
// can be const.
if (IsUseZoomForDSFEnabled())
@@ -1773,7 +1749,7 @@ void RenderWidgetHostImpl::GetSnapshotFromBrowser(
if (from_surface) {
pending_surface_browser_snapshots_.insert(
std::make_pair(snapshot_id, callback));
- Send(new ViewMsg_ForceRedraw(GetRoutingID(), snapshot_id));
+ Send(new WidgetMsg_ForceRedraw(GetRoutingID(), snapshot_id));
return;
}
@@ -1786,7 +1762,7 @@ void RenderWidgetHostImpl::GetSnapshotFromBrowser(
#endif
// TODO(nzolghadr): Remove the duplication here and the if block just above.
pending_browser_snapshots_.insert(std::make_pair(snapshot_id, callback));
- Send(new ViewMsg_ForceRedraw(GetRoutingID(), snapshot_id));
+ Send(new WidgetMsg_ForceRedraw(GetRoutingID(), snapshot_id));
}
void RenderWidgetHostImpl::SelectionChanged(const base::string16& text,
@@ -1797,7 +1773,7 @@ void RenderWidgetHostImpl::SelectionChanged(const base::string16& text,
}
void RenderWidgetHostImpl::OnSelectionBoundsChanged(
- const ViewHostMsg_SelectionBounds_Params& params) {
+ const WidgetHostMsg_SelectionBounds_Params& params) {
if (view_)
view_->SelectionBoundsChanged(params);
}
@@ -1961,7 +1937,7 @@ void RenderWidgetHostImpl::CancelUpdateTextDirection() {
void RenderWidgetHostImpl::NotifyTextDirection() {
if (text_direction_updated_) {
if (!text_direction_canceled_)
- Send(new ViewMsg_SetTextDirection(GetRoutingID(), text_direction_));
+ Send(new WidgetMsg_SetTextDirection(GetRoutingID(), text_direction_));
text_direction_updated_ = false;
text_direction_canceled_ = false;
}
@@ -2001,7 +1977,7 @@ void RenderWidgetHostImpl::RejectMouseLockOrUnlockIfNecessary() {
DCHECK(!pending_mouse_lock_request_ || !IsMouseLocked());
if (pending_mouse_lock_request_) {
pending_mouse_lock_request_ = false;
- Send(new ViewMsg_LockMouse_ACK(routing_id_, false));
+ Send(new WidgetMsg_LockMouse_ACK(routing_id_, false));
} else if (IsMouseLocked()) {
view_->UnlockMouse();
}
@@ -2190,10 +2166,12 @@ void RenderWidgetHostImpl::OnUpdateScreenRectsAck() {
}
void RenderWidgetHostImpl::OnRequestSetBounds(const gfx::Rect& bounds) {
- if (view_) {
+ if (owner_delegate_) {
+ owner_delegate_->RequestSetBounds(bounds);
+ } else if (view_) {
view_->SetBounds(bounds);
- Send(new ViewMsg_SetBounds_ACK(routing_id_));
}
+ Send(new WidgetMsg_SetBounds_ACK(routing_id_));
}
void RenderWidgetHostImpl::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
@@ -2257,22 +2235,25 @@ void RenderWidgetHostImpl::OnSetCursor(const WebCursor& cursor) {
void RenderWidgetHostImpl::OnAutoscrollStart(const gfx::PointF& position) {
GetView()->OnAutoscrollStart();
- WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::Build(
- WebInputEvent::kGestureScrollBegin,
- blink::kWebGestureDeviceSyntheticAutoscroll);
- scroll_begin.SetPositionInWidget(position);
-
- ForwardGestureEventWithLatencyInfo(
- scroll_begin, ui::LatencyInfo(ui::SourceEventType::OTHER));
-
- // Send a GFS event with zero velocity to make sure that the scroll sequence
- // will end with the GFC generated in |OnAutoscrollEnd()|; Otherwise if the
- // user cancels the autoscroll without moving the mouse, the GFC will get
- // filtered since no GFS is sent in the sequence. https://crbug.com/829794
- OnAutoscrollFling(gfx::Vector2dF());
+ sent_autoscroll_scroll_begin_ = false;
+ autoscroll_start_position_ = position;
}
void RenderWidgetHostImpl::OnAutoscrollFling(const gfx::Vector2dF& velocity) {
+ if (!sent_autoscroll_scroll_begin_ && velocity != gfx::Vector2dF()) {
+ // Send a GSB event with valid delta hints.
+ WebGestureEvent scroll_begin = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::kGestureScrollBegin,
+ blink::kWebGestureDeviceSyntheticAutoscroll);
+ scroll_begin.SetPositionInWidget(autoscroll_start_position_);
+ scroll_begin.data.scroll_begin.delta_x_hint = velocity.x();
+ scroll_begin.data.scroll_begin.delta_y_hint = velocity.y();
+
+ ForwardGestureEventWithLatencyInfo(
+ scroll_begin, ui::LatencyInfo(ui::SourceEventType::OTHER));
+ sent_autoscroll_scroll_begin_ = true;
+ }
+
WebGestureEvent event = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureFlingStart,
blink::kWebGestureDeviceSyntheticAutoscroll);
@@ -2284,6 +2265,11 @@ void RenderWidgetHostImpl::OnAutoscrollFling(const gfx::Vector2dF& velocity) {
}
void RenderWidgetHostImpl::OnAutoscrollEnd() {
+ // Don't send a GFC if no GSB is sent.
+ if (!sent_autoscroll_scroll_begin_)
+ return;
+
+ sent_autoscroll_scroll_begin_ = false;
WebGestureEvent cancel_event = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureFlingCancel,
blink::kWebGestureDeviceSyntheticAutoscroll);
@@ -2356,7 +2342,7 @@ void RenderWidgetHostImpl::OnProcessSwapMessage(const IPC::Message& message) {
void RenderWidgetHostImpl::OnLockMouse(bool user_gesture,
bool privileged) {
if (pending_mouse_lock_request_) {
- Send(new ViewMsg_LockMouse_ACK(routing_id_, false));
+ Send(new WidgetMsg_LockMouse_ACK(routing_id_, false));
return;
}
@@ -2633,7 +2619,7 @@ bool RenderWidgetHostImpl::IsIgnoringInputEvents() const {
}
void RenderWidgetHostImpl::SetBackgroundOpaque(bool opaque) {
- Send(new ViewMsg_SetBackgroundOpaque(GetRoutingID(), opaque));
+ Send(new WidgetMsg_SetBackgroundOpaque(GetRoutingID(), opaque));
}
bool RenderWidgetHostImpl::GotResponseToLockMouseRequest(bool allowed) {
@@ -2650,11 +2636,11 @@ bool RenderWidgetHostImpl::GotResponseToLockMouseRequest(bool allowed) {
pending_mouse_lock_request_ = false;
if (!view_ || !view_->HasFocus()|| !view_->LockMouse()) {
- Send(new ViewMsg_LockMouse_ACK(routing_id_, false));
+ Send(new WidgetMsg_LockMouse_ACK(routing_id_, false));
return false;
}
- Send(new ViewMsg_LockMouse_ACK(routing_id_, true));
+ Send(new WidgetMsg_LockMouse_ACK(routing_id_, true));
return true;
}
@@ -2678,7 +2664,7 @@ void RenderWidgetHostImpl::DidReceiveRendererFrame() {
}
void RenderWidgetHostImpl::WindowSnapshotReachedScreen(int snapshot_id) {
- DCHECK(base::MessageLoopForUI::IsCurrent());
+ DCHECK(base::MessageLoopCurrentForUI::IsSet());
if (!pending_surface_browser_snapshots_.empty()) {
GetView()->CopyFromSurface(
@@ -2730,7 +2716,7 @@ void RenderWidgetHostImpl::OnSnapshotFromSurfaceReceived(
image = gfx::Image::CreateFrom1xBitmap(bitmap);
// Any pending snapshots with a lower ID than the one received are considered
// to be implicitly complete, and returned the same snapshot data.
- PendingSnapshotMap::iterator it = pending_surface_browser_snapshots_.begin();
+ auto it = pending_surface_browser_snapshots_.begin();
while (it != pending_surface_browser_snapshots_.end()) {
if (it->first <= snapshot_id) {
it->second.Run(image);
@@ -2745,7 +2731,7 @@ void RenderWidgetHostImpl::OnSnapshotReceived(int snapshot_id,
gfx::Image image) {
// Any pending snapshots with a lower ID than the one received are considered
// to be implicitly complete, and returned the same snapshot data.
- PendingSnapshotMap::iterator it = pending_browser_snapshots_.begin();
+ auto it = pending_browser_snapshots_.begin();
while (it != pending_browser_snapshots_.end()) {
if (it->first <= snapshot_id) {
it->second.Run(image);
@@ -2875,59 +2861,8 @@ void RenderWidgetHostImpl::SubmitCompositorFrame(
viz::CompositorFrame frame,
base::Optional<viz::HitTestRegionList> hit_test_region_list,
uint64_t submit_time) {
- // Ensure there are no CopyOutputRequests stowed-away in the CompositorFrame.
- // For security/privacy reasons, renderers are not allowed to make copy
- // requests because they could use this to gain access to content from another
- // domain (e.g., in a child frame).
- if (frame.HasCopyOutputRequests()) {
- bad_message::ReceivedBadMessage(GetProcess(),
- bad_message::RWH_COPY_REQUEST_ATTEMPT);
- return;
- }
-
- auto new_surface_properties =
- RenderWidgetSurfaceProperties::FromCompositorFrame(frame);
-
- if (local_surface_id == last_local_surface_id_ &&
- new_surface_properties != last_surface_properties_) {
- std::string error = base::StringPrintf(
- "[OOPIF? %d] %s\n", view_ && view_->IsRenderWidgetHostViewChildFrame(),
- new_surface_properties.ToDiffString(last_surface_properties_).c_str());
- LOG(ERROR) << "Surface invariants violation: " << error;
-
- static int invariants_violation_count = 0;
- ++invariants_violation_count;
- UMA_HISTOGRAM_COUNTS_1000("Compositing.SurfaceInvariantsViolations",
- invariants_violation_count);
-
- if (features::IsSurfaceInvariantsViolationLoggingEnabled()) {
- static auto* crash_key = base::debug::AllocateCrashKeyString(
- "surface-invariants-violation", base::debug::CrashKeySize::Size256);
- base::debug::ScopedCrashKeyString key_value(crash_key, error);
- base::debug::DumpWithoutCrashing();
- }
-
- if (view_) {
- frame.metadata.begin_frame_ack.has_damage = false;
- view_->OnDidNotProduceFrame(frame.metadata.begin_frame_ack);
- }
- std::vector<viz::ReturnedResource> resources =
- viz::TransferableResource::ReturnResources(frame.resource_list);
- renderer_compositor_frame_sink_->DidReceiveCompositorFrameAck(resources);
-
- return;
- }
-
- last_local_surface_id_ = local_surface_id;
- last_surface_properties_ = new_surface_properties;
-
last_received_content_source_id_ = frame.metadata.content_source_id;
- // |has_damage| is not transmitted.
- frame.metadata.begin_frame_ack.has_damage = true;
-
- last_frame_metadata_ = frame.metadata.Clone();
-
if (enable_surface_synchronization_) {
if (view_) {
// If Surface Synchronization is on, then |new_content_rendering_timeout_|
@@ -2964,12 +2899,10 @@ void RenderWidgetHostImpl::SubmitCompositorFrame(
// After navigation, if a frame belonging to the new page is received, stop
// the timer that triggers clearing the graphics of the last page.
- if (last_received_content_source_id_ >= current_content_source_id_) {
- did_receive_first_frame_after_navigation_ = true;
- if (new_content_rendering_timeout_ &&
- new_content_rendering_timeout_->IsRunning()) {
- new_content_rendering_timeout_->Stop();
- }
+ if (last_received_content_source_id_ >= current_content_source_id_ &&
+ new_content_rendering_timeout_ &&
+ new_content_rendering_timeout_->IsRunning()) {
+ new_content_rendering_timeout_->Stop();
}
}
}
@@ -3057,8 +2990,8 @@ void RenderWidgetHostImpl::ProgressFlingIfNeeded(TimeTicks current_time) {
}
void RenderWidgetHostImpl::ForceFirstFrameAfterNavigationTimeout() {
- if (did_receive_first_frame_after_navigation_ ||
- !new_content_rendering_timeout_) {
+ if (!new_content_rendering_timeout_ ||
+ !new_content_rendering_timeout_->IsRunning()) {
return;
}
new_content_rendering_timeout_->Stop();
diff --git a/chromium/content/browser/renderer_host/render_widget_host_impl.h b/chromium/content/browser/renderer_host/render_widget_host_impl.h
index c2d8cd56243..dba7b4276f5 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.h
@@ -49,7 +49,6 @@
#include "content/common/input/input_handler.mojom.h"
#include "content/common/render_frame_metadata.mojom.h"
#include "content/common/render_widget_surface_properties.h"
-#include "content/common/view_message_enums.h"
#include "content/common/widget.mojom.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/common/input_event_ack_state.h"
@@ -76,7 +75,7 @@
class SkBitmap;
struct FrameHostMsg_HittestData_Params;
-struct ViewHostMsg_SelectionBounds_Params;
+struct WidgetHostMsg_SelectionBounds_Params;
namespace blink {
class WebInputEvent;
@@ -188,6 +187,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
void NotifyTextDirection() override;
void Focus() override;
void Blur() override;
+ void FlushForTesting() override;
void SetActive(bool active) override;
void ForwardMouseEvent(const blink::WebMouseEvent& mouse_event) override;
void ForwardWheelEvent(const blink::WebMouseWheelEvent& wheel_event) override;
@@ -611,10 +611,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl
render_frame_metadata_observer_client_request,
mojom::RenderFrameMetadataObserverPtr render_frame_metadata_observer);
- const viz::CompositorFrameMetadata& last_frame_metadata() {
- return last_frame_metadata_;
- }
-
RenderFrameMetadataProviderImpl* render_frame_metadata_provider() {
return &render_frame_metadata_provider_;
}
@@ -762,7 +758,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
private:
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest,
DontPostponeInputEventAckTimeout);
- FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, HiddenPaint);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, HideShowMessages);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, RendererExitedNoDrag);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest,
StopAndStartInputEventAckTimeout);
@@ -819,7 +815,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
bool privileged);
void OnUnlockMouse();
void OnSelectionBoundsChanged(
- const ViewHostMsg_SelectionBounds_Params& params);
+ const WidgetHostMsg_SelectionBounds_Params& params);
void OnSetNeedsBeginFrames(bool needs_begin_frames);
void OnHittestData(const FrameHostMsg_HittestData_Params& params);
void OnFocusedNodeTouched(bool editable);
@@ -992,12 +988,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// The observers watching us.
base::ObserverList<RenderWidgetHostObserver>::Unchecked observers_;
- // If true, then we should repaint when restoring even if we have a
- // backingstore. This flag is set to true if we receive a paint message
- // while is_hidden_ to true. Even though we tell the render widget to hide
- // itself, a paint message could already be in flight at that point.
- bool needs_repainting_on_restore_;
-
// This is true if the renderer is currently unresponsive.
bool is_unresponsive_;
@@ -1125,12 +1115,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl
device::mojom::WakeLockPtr wake_lock_;
#endif
- // These information are used to verify that the renderer does not misbehave
- // when it comes to allocating LocalSurfaceIds. If surface properties change,
- // a new LocalSurfaceId must be created.
- viz::LocalSurfaceId last_local_surface_id_;
- RenderWidgetSurfaceProperties last_surface_properties_;
-
mojo::Binding<viz::mojom::CompositorFrameSink> compositor_frame_sink_binding_;
viz::mojom::CompositorFrameSinkClientPtr renderer_compositor_frame_sink_;
@@ -1138,18 +1122,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// we have a view. This is only used if |enable_viz_| is true.
base::OnceCallback<void(const viz::FrameSinkId&)> create_frame_sink_callback_;
- viz::CompositorFrameMetadata last_frame_metadata_;
-
std::unique_ptr<FrameTokenMessageQueue> frame_token_message_queue_;
- // If a CompositorFrame is submitted that references SharedBitmaps that don't
- // exist yet, we keep it here until they are available.
- struct {
- viz::LocalSurfaceId local_surface_id;
- viz::CompositorFrame frame;
- base::Optional<viz::HitTestRegionList> hit_test_region_list;
- } saved_frame_;
-
bool enable_surface_synchronization_ = false;
bool enable_viz_ = false;
@@ -1184,7 +1158,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl
std::unique_ptr<FlingSchedulerBase> fling_scheduler_;
- bool did_receive_first_frame_after_navigation_ = true;
+ bool sent_autoscroll_scroll_begin_ = false;
+ gfx::PointF autoscroll_start_position_;
base::WeakPtrFactory<RenderWidgetHostImpl> weak_factory_;
diff --git a/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc b/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc
index e3d18fefaf8..f19fe1edf21 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -4,6 +4,8 @@
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
+#include <algorithm>
+#include <deque>
#include <vector>
#include "base/debug/crash_logging.h"
@@ -32,11 +34,11 @@ namespace {
// Transforms WebTouchEvent touch positions from the root view coordinate
// space to the target view coordinate space.
void TransformEventTouchPositions(blink::WebTouchEvent* event,
- const gfx::Vector2dF& delta) {
+ const gfx::Transform& transform) {
for (unsigned i = 0; i < event->touches_length; ++i) {
- event->touches[i].SetPositionInWidget(
- event->touches[i].PositionInWidget().x + delta.x(),
- event->touches[i].PositionInWidget().y + delta.y());
+ gfx::PointF point(event->touches[i].PositionInWidget());
+ transform.TransformPoint(&point);
+ event->touches[i].SetPositionInWidget(point);
}
}
@@ -82,6 +84,142 @@ bool IsMouseButtonDown(const blink::WebMouseEvent& event) {
namespace content {
+// A class to implement a queue for tracking outbound TouchEvents, and making
+// sure that their acks are returned to the appropriate root view in order.
+// This is important to ensure proper operation of the GestureProvider.
+// Some challenges include:
+// * differentiating between native and emulated TouchEvents, as the latter ack
+// to the TouchEmulator's GestureProvider,
+// * making sure all events from destroyed renderers are acked properly, and
+// without delaying acks from other renderers, and
+// * making sure events are only acked if the root_view (at the time of the
+// out-bound event) is still valid.
+// Some of this logic, e.g. the last item above, is shared with
+// RenderWidgetHostViewBase.
+class TouchEventAckQueue {
+ public:
+ enum class TouchEventAckStatus { TouchEventNotAcked, TouchEventAcked };
+ enum class TouchEventSource { SystemTouchEvent, EmulatedTouchEvent };
+ struct AckData {
+ uint32_t touch_event_id;
+ RenderWidgetHostViewBase* target_view;
+ RenderWidgetHostViewBase* root_view;
+ TouchEventSource touch_event_source;
+ TouchEventAckStatus touch_event_ack_status;
+ InputEventAckState ack_result;
+ };
+
+ TouchEventAckQueue() {}
+
+ void Add(uint32_t touch_event_id,
+ RenderWidgetHostViewBase* target_view,
+ RenderWidgetHostViewBase* root_view,
+ TouchEventSource touch_event_source,
+ TouchEventAckStatus touch_event_ack_status,
+ InputEventAckState ack_result);
+
+ void Add(uint32_t touch_event_id,
+ RenderWidgetHostViewBase* target_view,
+ RenderWidgetHostViewBase* root_view,
+ TouchEventSource touch_event_source);
+
+ void MarkAcked(uint32_t touch_event_id,
+ InputEventAckState ack_result,
+ RenderWidgetHostViewBase* target_view);
+
+ void UpdateQueueAfterTargetDestroyed(RenderWidgetHostViewBase* target_view);
+
+ private:
+ void ProcessAckedTouchEvents();
+ void ReportTouchEventAckQueueUmaStats();
+
+ std::deque<AckData> ack_queue_;
+};
+
+void TouchEventAckQueue::Add(uint32_t touch_event_id,
+ RenderWidgetHostViewBase* target_view,
+ RenderWidgetHostViewBase* root_view,
+ TouchEventSource touch_event_source,
+ TouchEventAckStatus touch_event_ack_status,
+ InputEventAckState ack_result) {
+ AckData data = {
+ touch_event_id, target_view, root_view, touch_event_source,
+ touch_event_ack_status, ack_result};
+ ack_queue_.push_back(data);
+ if (touch_event_ack_status == TouchEventAckStatus::TouchEventAcked)
+ ProcessAckedTouchEvents();
+ ReportTouchEventAckQueueUmaStats();
+}
+
+void TouchEventAckQueue::Add(uint32_t touch_event_id,
+ RenderWidgetHostViewBase* target_view,
+ RenderWidgetHostViewBase* root_view,
+ TouchEventSource touch_event_source) {
+ Add(touch_event_id, target_view, root_view, touch_event_source,
+ TouchEventAckStatus::TouchEventNotAcked, INPUT_EVENT_ACK_STATE_UNKNOWN);
+}
+
+void TouchEventAckQueue::MarkAcked(uint32_t touch_event_id,
+ InputEventAckState ack_result,
+ RenderWidgetHostViewBase* target_view) {
+ auto it = find_if(ack_queue_.begin(), ack_queue_.end(),
+ [touch_event_id](AckData data) {
+ return data.touch_event_id == touch_event_id;
+ });
+ if (it == ack_queue_.end())
+ return;
+ DCHECK(it->touch_event_ack_status != TouchEventAckStatus::TouchEventAcked);
+ DCHECK(target_view && target_view == it->target_view);
+ it->touch_event_ack_status = TouchEventAckStatus::TouchEventAcked;
+ it->ack_result = ack_result;
+ ProcessAckedTouchEvents();
+}
+
+void TouchEventAckQueue::ProcessAckedTouchEvents() {
+ if (ack_queue_.empty())
+ return;
+
+ // TODO(wjmaclean): modify the following loop to actually forward the acks
+ // to the root_view. Must verify that the root_view at the time the event
+ // was registered still exists.
+ while (!ack_queue_.empty() && ack_queue_.front().touch_event_ack_status ==
+ TouchEventAckStatus::TouchEventAcked) {
+ // TODO(wjmaclean): We will eventually ack touch events to the root_view
+ // here. Each ack will require confirmation that the touch event's root
+ // view (at the time of event dispatch) is still valid, otherwise we just
+ // discard the ack.
+ ack_queue_.pop_front();
+ }
+}
+
+void TouchEventAckQueue::ReportTouchEventAckQueueUmaStats() {
+ size_t count = ack_queue_.size();
+ UMA_HISTOGRAM_COUNTS_10000("Event.FrameEventRouting.TouchEventAckQueueSize",
+ count);
+ // TODO(wjmaclean): is it worth also recording how many different renderers
+ // are waiting on touch event acks at the time of reporting?
+}
+
+void TouchEventAckQueue::UpdateQueueAfterTargetDestroyed(
+ RenderWidgetHostViewBase* target_view) {
+ // If a queue entry's root view is being destroyed, just delete it.
+ ack_queue_.erase(remove_if(ack_queue_.begin(), ack_queue_.end(),
+ [target_view](AckData data) {
+ return data.root_view == target_view;
+ }),
+ ack_queue_.end());
+
+ // Otherwise, mark its status accordingly.
+ for_each(ack_queue_.begin(), ack_queue_.end(), [target_view](AckData data) {
+ if (data.target_view == target_view) {
+ data.touch_event_ack_status = TouchEventAckStatus::TouchEventAcked;
+ data.ack_result = INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
+ }
+ });
+
+ ProcessAckedTouchEvents();
+}
+
void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
RenderWidgetHostViewBase* view) {
// RenderWidgetHostViewBase::RemoveObserver() should only ever be called
@@ -106,6 +244,7 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
touch_target_.target = nullptr;
active_touches_ = 0;
}
+ touch_event_ack_queue_->UpdateQueueAfterTargetDestroyed(view);
if (view == wheel_target_.target)
wheel_target_.target = nullptr;
@@ -202,6 +341,7 @@ RenderWidgetHostInputEventRouter::RenderWidgetHostInputEventRouter()
gesture_pinch_did_send_scroll_begin_(false),
event_targeter_(std::make_unique<RenderWidgetTargeter>(this)),
use_viz_hit_test_(features::IsVizHitTestingEnabled()),
+ touch_event_ack_queue_(new TouchEventAckQueue),
weak_ptr_factory_(this) {}
RenderWidgetHostInputEventRouter::~RenderWidgetHostInputEventRouter() {
@@ -216,6 +356,7 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindMouseEventTarget(
RenderWidgetHostViewBase* target = nullptr;
bool needs_transform_point = true;
bool latched_target = true;
+ bool should_verify_result = false;
if (root_view->IsMouseLocked()) {
target = root_view->host()->delegate()->GetMouseLockWidget()->GetView();
}
@@ -234,8 +375,14 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindMouseEventTarget(
auto result = FindViewAtLocation(
root_view, event.PositionInWidget(), event.PositionInScreen(),
viz::EventSource::MOUSE, &transformed_point);
+ // Due to performance concerns we do not verify mouse move events.
+ should_verify_result = (event.GetType() == blink::WebInputEvent::kMouseMove)
+ ? false
+ : result.should_verify_result;
if (result.should_query_view) {
- return {result.view, true, transformed_point, latched_target};
+ DCHECK(!should_verify_result);
+ return {result.view, true, transformed_point, latched_target,
+ should_verify_result};
}
target = result.view;
// |transformed_point| is already transformed.
@@ -246,10 +393,11 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindMouseEventTarget(
if (!root_view->TransformPointToCoordSpaceForView(
event.PositionInWidget(), target, &transformed_point,
viz::EventSource::MOUSE)) {
- return {nullptr, false, base::nullopt, latched_target};
+ return {nullptr, false, base::nullopt, latched_target, false};
}
}
- return {target, false, transformed_point, latched_target};
+ return {target, false, transformed_point, latched_target,
+ should_verify_result};
}
RenderWidgetTargetResult
@@ -263,25 +411,21 @@ RenderWidgetHostInputEventRouter::FindMouseWheelEventTarget(
if (!root_view->TransformPointToCoordSpaceForView(
event.PositionInWidget(), target, &transformed_point,
viz::EventSource::MOUSE)) {
- return {nullptr, false, base::nullopt, true};
+ return {nullptr, false, base::nullopt, true, false};
}
- return {target, false, transformed_point, true};
+ return {target, false, transformed_point, true, false};
}
- if (event.phase == blink::WebMouseWheelEvent::kPhaseBegan) {
- auto result = FindViewAtLocation(
- root_view, event.PositionInWidget(), event.PositionInScreen(),
- viz::EventSource::MOUSE, &transformed_point);
- return {result.view, result.should_query_view, transformed_point, false};
- }
- // For non-begin events, the target found for the previous phaseBegan is
- // used.
- return {nullptr, false, base::nullopt, true};
-
- auto result = FindViewAtLocation(root_view, event.PositionInWidget(),
- event.PositionInScreen(),
- viz::EventSource::MOUSE, &transformed_point);
- return {result.view, result.should_query_view, transformed_point, false};
+ if (event.phase == blink::WebMouseWheelEvent::kPhaseBegan) {
+ auto result = FindViewAtLocation(
+ root_view, event.PositionInWidget(), event.PositionInScreen(),
+ viz::EventSource::MOUSE, &transformed_point);
+ return {result.view, result.should_query_view, transformed_point, false,
+ result.should_verify_result};
+ }
+ // For non-begin events, the target found for the previous phaseBegan is
+ // used.
+ return {nullptr, false, base::nullopt, true, false};
}
RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindViewAtLocation(
@@ -294,16 +438,17 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindViewAtLocation(
// hit testing.
if (owner_map_.size() <= 1) {
*transformed_point = point;
- return {root_view, false, *transformed_point, false};
+ return {root_view, false, *transformed_point, false, false};
}
viz::FrameSinkId frame_sink_id;
bool query_renderer = false;
+ bool should_verify_result = false;
if (use_viz_hit_test_) {
viz::HitTestQuery* query = GetHitTestQuery(GetHostFrameSinkManager(),
root_view->GetRootFrameSinkId());
if (!query)
- return {root_view, false, base::nullopt, false};
+ return {root_view, false, base::nullopt, false, false};
// |point_in_screen| is in the coordinate space of of the screen, but the
// display HitTestQuery does a hit test in the coordinate space of the root
// window. The following translation should account for that discrepancy.
@@ -321,8 +466,18 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindViewAtLocation(
} else {
*transformed_point = point;
}
+ // To ensure the correctness of viz hit testing with cc generated data, we
+ // verify hit test results when:
+ // a) We use cc generated data to do synchronous hit testing and
+ // b) We use HitTestQuery to find the target (instead of reusing previous
+ // targets when hit testing latched events) and
+ // c) We are not hit testing MouseMove events which is too frequent to
+ // verify it without impacting performance.
+ // The code that implements c) locates in |FindMouseEventTarget|.
if (target.flags & viz::HitTestRegionFlags::kHitTestAsk)
query_renderer = true;
+ else if (features::IsVizHitTestingSurfaceLayerEnabled())
+ should_verify_result = true;
} else {
// The hittest delegate is used to reject hittesting quads based on extra
// hittesting data send by the renderer.
@@ -344,7 +499,8 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindViewAtLocation(
*transformed_point = point;
}
- return {view, query_renderer, *transformed_point, false};
+ return {view, query_renderer, *transformed_point, false,
+ should_verify_result};
}
void RenderWidgetHostInputEventRouter::RouteMouseEvent(
@@ -548,7 +704,7 @@ RenderWidgetTargetResult RenderWidgetHostInputEventRouter::FindTouchEventTarget(
// Tests may call this without an initial TouchStart, so check event type
// explicitly here.
if (active_touches_ || event.GetType() != blink::WebInputEvent::kTouchStart)
- return {nullptr, false, base::nullopt, true};
+ return {nullptr, false, base::nullopt, true, false};
active_touches_ += CountChangedTouchPoints(event);
gfx::PointF original_point = gfx::PointF(event.touches[0].PositionInWidget());
@@ -564,23 +720,27 @@ void RenderWidgetHostInputEventRouter::DispatchTouchEvent(
RenderWidgetHostViewBase* target,
const blink::WebTouchEvent& touch_event,
const ui::LatencyInfo& latency,
- const base::Optional<gfx::PointF>& target_location) {
+ const base::Optional<gfx::PointF>& target_location,
+ bool is_emulated_touchevent) {
DCHECK(blink::WebInputEvent::IsTouchEventType(touch_event.GetType()) &&
touch_event.GetType() != blink::WebInputEvent::kTouchScrollStarted);
bool is_sequence_start = !touch_target_.target && target;
if (is_sequence_start) {
touch_target_.target = target;
- // TODO(wjmaclean): Instead of just computing a delta, we should extract
- // the complete transform. We assume it doesn't change for the duration
- // of the touch sequence, though this could be wrong; a better approach
- // might be to always transform each point to the |touch_target_.target|
- // for the duration of the sequence.
- if (target_location.has_value()) {
- touch_target_.delta =
- target_location.value() - touch_event.touches[0].PositionInWidget();
- } else {
- touch_target_.delta = gfx::Vector2dF();
+ // For now we only compute the transform at TouchStart, but in a follow-on
+ // CL this will be computed for all events in order to account for css
+ // animations, pinches, etc.
+ if (!root_view->GetTransformToViewCoordSpace(touch_target_.target,
+ &touch_target_.transform)) {
+ // Fall-back to just using the delta if we are unable to get the full
+ // transform.
+ touch_target_.transform.MakeIdentity();
+ if (target_location.has_value()) {
+ touch_target_.transform.Translate(
+ target_location.value() -
+ touch_event.touches[0].PositionInWidget());
+ }
}
DCHECK(touchscreen_gesture_target_map_.find(
@@ -610,7 +770,15 @@ void RenderWidgetHostInputEventRouter::DispatchTouchEvent(
base::debug::DumpWithoutCrashing();
}
+ TouchEventAckQueue::TouchEventSource event_source =
+ is_emulated_touchevent
+ ? TouchEventAckQueue::TouchEventSource::EmulatedTouchEvent
+ : TouchEventAckQueue::TouchEventSource::SystemTouchEvent;
if (!touch_target_.target) {
+ touch_event_ack_queue_->Add(
+ touch_event.unique_touch_event_id, nullptr, root_view, event_source,
+ TouchEventAckQueue::TouchEventAckStatus::TouchEventAcked,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
TouchEventWithLatencyInfo touch_with_latency(touch_event, latency);
root_view->ProcessAckedTouchEvent(touch_with_latency,
INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
@@ -625,8 +793,11 @@ void RenderWidgetHostInputEventRouter::DispatchTouchEvent(
}
}
+ touch_event_ack_queue_->Add(touch_event.unique_touch_event_id,
+ touch_target_.target, root_view, event_source);
+
blink::WebTouchEvent event(touch_event);
- TransformEventTouchPositions(&event, touch_target_.delta);
+ TransformEventTouchPositions(&event, touch_target_.transform);
touch_target_.target->ProcessTouchEvent(event, latency);
if (!active_touches_)
@@ -637,6 +808,8 @@ void RenderWidgetHostInputEventRouter::ProcessAckedTouchEvent(
const TouchEventWithLatencyInfo& event,
InputEventAckState ack_result,
RenderWidgetHostViewBase* view) {
+ touch_event_ack_queue_->MarkAcked(event.event.unique_touch_event_id,
+ ack_result, view);
// TODO(wjmaclean): Eventually we will keep track of which outgoing touch
// events are emulated and which aren't, so the decision to hand off to the
// touch emulator won't just rely on the existence of the touch emulator.
@@ -1058,7 +1231,7 @@ RenderWidgetHostInputEventRouter::FindTouchscreenGestureEventTarget(
// target we could just return nullptr for pinch events, but since we know
// where they are going we return the correct target.
if (blink::WebInputEvent::IsPinchGestureEventType(gesture_event.GetType()))
- return {root_view, false, gesture_event.PositionInWidget(), true};
+ return {root_view, false, gesture_event.PositionInWidget(), true, false};
// Android sends gesture events that have no corresponding touch sequence, so
// these we hit-test explicitly.
@@ -1073,7 +1246,7 @@ RenderWidgetHostInputEventRouter::FindTouchscreenGestureEventTarget(
// Remaining gesture events will defer to the gesture event target queue
// during dispatch.
- return {nullptr, false, base::nullopt, true};
+ return {nullptr, false, base::nullopt, true, false};
}
bool RenderWidgetHostInputEventRouter::IsViewInMap(
@@ -1091,11 +1264,6 @@ void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
const blink::WebGestureEvent& gesture_event,
const ui::LatencyInfo& latency,
const base::Optional<gfx::PointF>& target_location) {
- // Temporary logging for https://crbug.com/824774.
- static auto* target_source_key = base::debug::AllocateCrashKeyString(
- "touchscreen-gesture-target-source", base::debug::CrashKeySize::Size32);
- base::debug::SetCrashKeyString(target_source_key, "input");
-
if (gesture_event.GetType() == blink::WebInputEvent::kGesturePinchBegin) {
in_touchscreen_gesture_pinch_ = true;
// If the root view wasn't already receiving the gesture stream, then we
@@ -1179,14 +1347,20 @@ void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
// are not associated with touch events, because non-synthetic events can be
// created by ContentView. These will use the target found by the
// RenderWidgetTargeter. These gesture events should always have a
- // unique_touch_event_id of 0.
+ // unique_touch_event_id of 0. They must have a non-null target in order
+ // to get the coordinate transform.
+ DCHECK(target);
touchscreen_gesture_target_.target = target;
touchscreen_gesture_target_in_map_ = IsViewInMap(target);
- base::debug::SetCrashKeyString(target_source_key, "touch_id=0");
- touchscreen_gesture_target_.delta =
- target_location.has_value()
- ? target_location.value() - gesture_event.PositionInWidget()
- : gfx::Vector2dF();
+ if (!root_view->GetTransformToViewCoordSpace(
+ touchscreen_gesture_target_.target,
+ &touchscreen_gesture_target_.transform)) {
+ touchscreen_gesture_target_.transform.MakeIdentity();
+ if (target_location.has_value()) {
+ touch_target_.transform.Translate(target_location.value() -
+ gesture_event.PositionInWidget());
+ }
+ }
} else if (no_matching_id && is_gesture_start) {
// A long-standing Windows issues where occasionally a GestureStart is
// encountered with no targets in the event queue. We never had a repro for
@@ -1209,8 +1383,13 @@ void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
// this is the best we can do until we fix https://crbug.com/595422.
touchscreen_gesture_target_.target = result.view;
touchscreen_gesture_target_in_map_ = IsViewInMap(result.view);
- base::debug::SetCrashKeyString(target_source_key, "no_matching_id");
- touchscreen_gesture_target_.delta = transformed_point - original_point;
+ if (!root_view->GetTransformToViewCoordSpace(
+ touchscreen_gesture_target_.target,
+ &touchscreen_gesture_target_.transform)) {
+ touchscreen_gesture_target_.transform.MakeIdentity();
+ if (target_location.has_value())
+ touch_target_.transform.Translate(transformed_point - original_point);
+ }
} else if (is_gesture_start) {
touchscreen_gesture_target_ = gesture_target_it->second;
touchscreen_gesture_target_map_.erase(gesture_target_it);
@@ -1239,28 +1418,9 @@ void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
}
blink::WebGestureEvent event(gesture_event);
- event.SetPositionInWidget(event.PositionInWidget() +
- touchscreen_gesture_target_.delta);
- // Temporary logging for https://crbug.com/824774.
- static auto* target_ptr_key = base::debug::AllocateCrashKeyString(
- "touchscreen-gesture-target-ptr", base::debug::CrashKeySize::Size64);
- base::debug::SetCrashKeyString(
- target_ptr_key,
- base::StringPrintf("%p", touchscreen_gesture_target_.target));
- static auto* root_ptr_key = base::debug::AllocateCrashKeyString(
- "touchscreen-gesture-root-ptr", base::debug::CrashKeySize::Size64);
- base::debug::SetCrashKeyString(root_ptr_key,
- base::StringPrintf("%p", root_view));
- static auto* target_ptr_in_map_key = base::debug::AllocateCrashKeyString(
- "touchscreen-gesture-target-in-map", base::debug::CrashKeySize::Size32);
- base::debug::SetCrashKeyString(
- target_ptr_in_map_key,
- touchscreen_gesture_target_in_map_ ? "true" : "false");
- static auto* map_size_key = base::debug::AllocateCrashKeyString(
- "touchscreen-gesture-map-size", base::debug::CrashKeySize::Size32);
- base::debug::SetCrashKeyString(
- map_size_key,
- base::StringPrintf("%u", static_cast<int>(owner_map_.size())));
+ gfx::PointF transformed_point(gesture_event.PositionInWidget());
+ touchscreen_gesture_target_.transform.TransformPoint(&transformed_point);
+ event.SetPositionInWidget(transformed_point);
if (events_being_flushed_) {
touchscreen_gesture_target_.target->host()
@@ -1287,7 +1447,7 @@ RenderWidgetHostInputEventRouter::FindTouchpadGestureEventTarget(
const blink::WebGestureEvent& event) const {
if (event.GetType() != blink::WebInputEvent::kGesturePinchBegin &&
event.GetType() != blink::WebInputEvent::kGestureFlingCancel) {
- return {nullptr, false, base::nullopt, true};
+ return {nullptr, false, base::nullopt, true, false};
}
gfx::PointF transformed_point;
@@ -1473,8 +1633,8 @@ void RenderWidgetHostInputEventRouter::DispatchEventToTarget(
INPUT_EVENT_ACK_STATE_CONSUMED);
return;
}
- DispatchTouchEvent(root_view, target, touch_event, latency,
- target_location);
+ DispatchTouchEvent(root_view, target, touch_event, latency, target_location,
+ false /* not emulated */);
return;
}
if (blink::WebInputEvent::IsGestureEventType(event.GetType())) {
@@ -1535,7 +1695,7 @@ void RenderWidgetHostInputEventRouter::ForwardEmulatedTouchEvent(
gfx::PointF transformed_point = target->TransformRootPointToViewCoordSpace(
gfx::PointF(position_in_widget.x, position_in_widget.y));
DispatchTouchEvent(last_emulated_event_root_view_, target, event,
- ui::LatencyInfo(), transformed_point);
+ ui::LatencyInfo(), transformed_point, true /* emulated */);
}
void RenderWidgetHostInputEventRouter::SetCursor(const WebCursor& cursor) {
@@ -1580,4 +1740,11 @@ void RenderWidgetHostInputEventRouter::SetMouseCaptureTarget(
mouse_capture_target_.target = nullptr;
}
+RenderWidgetHostImpl*
+RenderWidgetHostInputEventRouter::GetMouseCaptureWidgetForTests() const {
+ if (mouse_capture_target_.target)
+ return mouse_capture_target_.target->host();
+ return nullptr;
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_widget_host_input_event_router.h b/chromium/content/browser/renderer_host/render_widget_host_input_event_router.h
index f32c2cee069..7bcc75bd74e 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_input_event_router.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_input_event_router.h
@@ -15,7 +15,6 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "build/build_config.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/host/hit_test/hit_test_query.h"
#include "components/viz/service/surfaces/surface_hittest_delegate.h"
@@ -26,16 +25,10 @@
#include "content/common/content_export.h"
#include "content/public/common/input_event_ack_state.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
+#include "ui/gfx/transform.h"
struct FrameHostMsg_HittestData_Params;
-#if defined(OS_WIN)
-// Flaky on Windows. https://crbug.com/868308
-#define MAYBE_TouchpadPinchOverOOPIF DISABLED_TouchpadPinchOverOOPIF
-#else
-#define MAYBE_TouchpadPinchOverOOPIF TouchpadPinchOverOOPIF
-#endif // OS_WIN
-
namespace blink {
class WebGestureEvent;
class WebInputEvent;
@@ -60,6 +53,7 @@ class RenderWidgetHostView;
class RenderWidgetHostViewBase;
class RenderWidgetTargeter;
class TouchEmulator;
+class TouchEventAckQueue;
// Class owned by WebContentsImpl for the purpose of directing input events
// to the correct RenderWidgetHost on pages with multiple RenderWidgetHosts.
@@ -133,6 +127,7 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
// Allows a target to claim or release capture of mouse events.
void SetMouseCaptureTarget(RenderWidgetHostViewBase* target,
bool captures_dragging);
+ RenderWidgetHostImpl* GetMouseCaptureWidgetForTests() const;
std::vector<RenderWidgetHostView*> GetRenderWidgetHostViewsForTests() const;
RenderWidgetTargeter* GetRenderWidgetTargeterForTests();
@@ -171,6 +166,7 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
struct TargetData {
RenderWidgetHostViewBase* target;
gfx::Vector2dF delta;
+ gfx::Transform transform;
TargetData() : target(nullptr) {}
};
@@ -253,7 +249,8 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
RenderWidgetHostViewBase* target,
const blink::WebTouchEvent& touch_event,
const ui::LatencyInfo& latency,
- const base::Optional<gfx::PointF>& target_location);
+ const base::Optional<gfx::PointF>& target_location,
+ bool is_emulated);
// Assumes |gesture_event| has coordinates in root view's coordinate space.
void DispatchTouchscreenGestureEvent(
RenderWidgetHostViewBase* root_view,
@@ -336,6 +333,7 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
bool events_being_flushed_ = false;
std::unique_ptr<TouchEmulator> touch_emulator_;
+ std::unique_ptr<TouchEventAckQueue> touch_event_ack_queue_;
base::WeakPtrFactory<RenderWidgetHostInputEventRouter> weak_ptr_factory_;
@@ -350,7 +348,7 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
FRIEND_TEST_ALL_PREFIXES(SitePerProcessHitTestBrowserTest,
InputEventRouterTouchpadGestureTargetTest);
FRIEND_TEST_ALL_PREFIXES(SitePerProcessHitTestBrowserTest,
- MAYBE_TouchpadPinchOverOOPIF);
+ TouchpadPinchOverOOPIF);
FRIEND_TEST_ALL_PREFIXES(SitePerProcessMouseWheelHitTestBrowserTest,
InputEventRouterWheelTargetTest);
FRIEND_TEST_ALL_PREFIXES(SitePerProcessMacBrowserTest,
diff --git a/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h b/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h
index a7678f05d79..3f625967d3d 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h
@@ -11,21 +11,34 @@
#import "content/browser/renderer_host/popup_window_mac.h"
#import "content/browser/renderer_host/render_widget_host_view_cocoa.h"
#include "content/common/render_widget_host_ns_view.mojom.h"
+#include "content/public/common/widget_type.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
#include "ui/accelerated_widget_mac/display_ca_layer_tree.h"
#include "ui/display/display_observer.h"
namespace content {
// Bridge to a locally-hosted NSView -- this is always instantiated in the same
-// process as the NSView. The caller of this interface may exist in another
-// process.
+// process as the NSView. The owner of this class may exist in another
+// process. Because the owner may exist in another process, this class must
+// be destroyed explicitly by its Destroy method.
class RenderWidgetHostNSViewBridgeLocal
: public mojom::RenderWidgetHostNSViewBridge,
public display::DisplayObserver {
public:
+ // Create a bridge that will directly access its client in the same process
+ // via pointers. This object must be explicitly deleted.
RenderWidgetHostNSViewBridgeLocal(
mojom::RenderWidgetHostNSViewClient* client,
- RenderWidgetHostNSViewLocalClient* local_client);
+ RenderWidgetHostNSViewClientHelper* client_helper);
+
+ // Create a bridge that will access its client in another process via a mojo
+ // interface. This object will be deleted when |bridge_request|'s connection
+ // closes.
+ RenderWidgetHostNSViewBridgeLocal(
+ mojom::RenderWidgetHostNSViewClientAssociatedPtr client,
+ mojom::RenderWidgetHostNSViewBridgeAssociatedRequest bridge_request);
+
~RenderWidgetHostNSViewBridgeLocal() override;
// TODO(ccameron): RenderWidgetHostViewMac and other functions currently use
@@ -35,8 +48,8 @@ class RenderWidgetHostNSViewBridgeLocal
RenderWidgetHostViewCocoa* GetRenderWidgetHostViewCocoa();
// mojom::RenderWidgetHostNSViewBridge implementation.
- void InitAsPopup(const gfx::Rect& content_rect,
- blink::WebPopupType popup_type) override;
+ void InitAsPopup(const gfx::Rect& content_rect) override;
+ void SetParentWebContentsNSView(uint64_t parent_ns_view_id) override;
void DisableDisplay() override;
void MakeFirstResponder() override;
void SetBounds(const gfx::Rect& rect) override;
@@ -62,16 +75,25 @@ class RenderWidgetHostNSViewBridgeLocal
void UnlockKeyboard() override;
private:
- bool IsPopup() const {
- // TODO(ccameron): If this is not equivalent to |popup_window_| then
- // there are bugs.
- return popup_type_ != blink::kWebPopupTypeNone;
- }
+ void Initialize(mojom::RenderWidgetHostNSViewClient* client,
+ RenderWidgetHostNSViewClientHelper* client_helper);
+
+ bool IsPopup() const { return !!popup_window_; }
+
+ // Called on a mojo connection error, deletes |this|.
+ void OnConnectionError();
// display::DisplayObserver implementation.
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) override;
+ // If the client for |this| is in another process and to be accessed via
+ // mojo, then |remote_client_| and |binding_| maintain this interface, and
+ // |remote_client_helper_| is a wrapper around |remote_client_|.
+ mojom::RenderWidgetHostNSViewClientAssociatedPtr remote_client_;
+ mojo::AssociatedBinding<mojom::RenderWidgetHostNSViewBridge> binding_;
+ std::unique_ptr<RenderWidgetHostNSViewClientHelper> remote_client_helper_;
+
// The NSView used for input and display.
base::scoped_nsobject<RenderWidgetHostViewCocoa> cocoa_view_;
@@ -81,7 +103,6 @@ class RenderWidgetHostNSViewBridgeLocal
// The window used for popup widgets, and its helper.
std::unique_ptr<PopupWindowMac> popup_window_;
- blink::WebPopupType popup_type_ = blink::kWebPopupTypeNone;
// The background CALayer which is hosted by |cocoa_view_|, and is used as
// the root of |display_ca_layer_tree_|.
diff --git a/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.mm b/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.mm
index 9df5543cc21..f2f17542f83 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.mm
@@ -6,9 +6,12 @@
#include "base/mac/scoped_cftyperef.h"
#include "base/strings/sys_string_conversions.h"
+#include "content/browser/renderer_host/render_widget_host_ns_view_client_helper.h"
#include "content/common/cursors/webcursor.h"
#import "skia/ext/skia_utils_mac.h"
+#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
#import "ui/base/cocoa/animation_utils.h"
+#include "ui/base/cocoa/ns_view_ids.h"
#include "ui/display/screen.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/gfx/mac/coordinate_conversion.h"
@@ -17,12 +20,35 @@ namespace content {
RenderWidgetHostNSViewBridgeLocal::RenderWidgetHostNSViewBridgeLocal(
mojom::RenderWidgetHostNSViewClient* client,
- RenderWidgetHostNSViewLocalClient* local_client) {
+ RenderWidgetHostNSViewClientHelper* client_helper)
+ : binding_(nullptr) {
+ Initialize(client, client_helper);
+}
+
+RenderWidgetHostNSViewBridgeLocal::RenderWidgetHostNSViewBridgeLocal(
+ mojom::RenderWidgetHostNSViewClientAssociatedPtr client,
+ mojom::RenderWidgetHostNSViewBridgeAssociatedRequest bridge_request)
+ : remote_client_(std::move(client)), binding_(this) {
+ binding_.Bind(std::move(bridge_request),
+ ui::WindowResizeHelperMac::Get()->task_runner());
+ // This object will be destroyed when its connection is closed.
+ binding_.set_connection_error_handler(
+ base::BindOnce(&RenderWidgetHostNSViewBridgeLocal::OnConnectionError,
+ base::Unretained(this)));
+ remote_client_helper_ =
+ RenderWidgetHostNSViewClientHelper::CreateForMojoClient(
+ remote_client_.get());
+ Initialize(remote_client_.get(), remote_client_helper_.get());
+}
+
+void RenderWidgetHostNSViewBridgeLocal::Initialize(
+ mojom::RenderWidgetHostNSViewClient* client,
+ RenderWidgetHostNSViewClientHelper* client_helper) {
display::Screen::GetScreen()->AddObserver(this);
cocoa_view_.reset([[RenderWidgetHostViewCocoa alloc]
- initWithClient:client
- withLocalClient:local_client]);
+ initWithClient:client
+ withClientHelper:client_helper]);
background_layer_.reset([[CALayer alloc] init]);
display_ca_layer_tree_ =
@@ -45,17 +71,30 @@ RenderWidgetHostNSViewBridgeLocal::~RenderWidgetHostNSViewBridgeLocal() {
popup_window_.reset();
}
+void RenderWidgetHostNSViewBridgeLocal::OnConnectionError() {
+ delete this;
+}
+
RenderWidgetHostViewCocoa*
RenderWidgetHostNSViewBridgeLocal::GetRenderWidgetHostViewCocoa() {
return cocoa_view_;
}
void RenderWidgetHostNSViewBridgeLocal::InitAsPopup(
- const gfx::Rect& content_rect,
- blink::WebPopupType popup_type) {
- popup_type_ = popup_type;
- popup_window_ =
- std::make_unique<PopupWindowMac>(content_rect, popup_type_, cocoa_view_);
+ const gfx::Rect& content_rect) {
+ popup_window_ = std::make_unique<PopupWindowMac>(content_rect, cocoa_view_);
+}
+
+void RenderWidgetHostNSViewBridgeLocal::SetParentWebContentsNSView(
+ uint64_t parent_ns_view_id) {
+ NSView* parent_ns_view = ui::NSViewIds::GetNSView(parent_ns_view_id);
+ // If the browser passed an invalid handle, then there is no recovery.
+ CHECK(parent_ns_view);
+ // Set the frame and autoresizing mask of the RenderWidgetHostViewCocoa as is
+ // done by WebContentsViewMac.
+ [cocoa_view_ setFrame:[parent_ns_view bounds]];
+ [cocoa_view_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ [parent_ns_view addSubview:cocoa_view_];
}
void RenderWidgetHostNSViewBridgeLocal::MakeFirstResponder() {
diff --git a/chromium/content/browser/renderer_host/render_widget_host_ns_view_client.h b/chromium/content/browser/renderer_host/render_widget_host_ns_view_client_helper.h
index 5efb19f2379..b8f764eab1d 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_ns_view_client.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_ns_view_client_helper.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 CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_CLIENT_H_
-#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_CLIENT_H_
+#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_CLIENT_HELPER_H_
+#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_CLIENT_HELPER_H_
#include "base/macros.h"
@@ -22,6 +22,10 @@ class LatencyInfo;
namespace content {
+namespace mojom {
+class RenderWidgetHostNSViewClient;
+} // namespace mojom
+
class BrowserAccessibilityManager;
struct EditCommand;
struct NativeWebKeyboardEvent;
@@ -32,10 +36,16 @@ struct NativeWebKeyboardEvent;
// instantiated in the local process. This is to implement functions that
// cannot be sent across mojo (e.g, GetRootBrowserAccessibilityManager), or
// to avoid unnecessary translation of event types.
-class RenderWidgetHostNSViewLocalClient {
+class RenderWidgetHostNSViewClientHelper {
public:
- RenderWidgetHostNSViewLocalClient() {}
- virtual ~RenderWidgetHostNSViewLocalClient() {}
+ // Create a RenderWidgetHostNSViewClientHelper that will only implement
+ // functionality through mojo (this is in contrast with an in-process
+ // RenderWidgetHostNSViewClientHelper that would use raw pointer access).
+ static std::unique_ptr<RenderWidgetHostNSViewClientHelper>
+ CreateForMojoClient(content::mojom::RenderWidgetHostNSViewClient* client);
+
+ RenderWidgetHostNSViewClientHelper() {}
+ virtual ~RenderWidgetHostNSViewClientHelper() {}
// Return the RenderWidget's BrowserAccessibilityManager.
// TODO(ccameron): This returns nullptr for non-local NSViews. A scheme for
@@ -73,9 +83,9 @@ class RenderWidgetHostNSViewLocalClient {
const blink::WebGestureEvent& smart_magnify_event) = 0;
private:
- DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostNSViewLocalClient);
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostNSViewClientHelper);
};
} // namespace content
-#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_CLIENT_H_
+#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_CLIENT_HELPER_H_
diff --git a/chromium/content/browser/renderer_host/render_widget_host_ns_view_client_helper.mm b/chromium/content/browser/renderer_host/render_widget_host_ns_view_client_helper.mm
new file mode 100644
index 00000000000..40bac2663af
--- /dev/null
+++ b/chromium/content/browser/renderer_host/render_widget_host_ns_view_client_helper.mm
@@ -0,0 +1,100 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "render_widget_host_ns_view_client_helper.h"
+
+#include "content/browser/renderer_host/input/web_input_event_builders_mac.h"
+#include "content/common/render_widget_host_ns_view.mojom.h"
+#include "content/public/browser/native_web_keyboard_event.h"
+
+namespace content {
+
+namespace {
+
+class ForwardingClientHelper : public RenderWidgetHostNSViewClientHelper {
+ public:
+ explicit ForwardingClientHelper(mojom::RenderWidgetHostNSViewClient* client)
+ : client_(client) {}
+
+ private:
+ std::unique_ptr<InputEvent> TranslateEvent(
+ const blink::WebInputEvent& web_event) {
+ return std::make_unique<InputEvent>(web_event, ui::LatencyInfo());
+ }
+
+ // RenderWidgetHostNSViewClientHelper implementation.
+ BrowserAccessibilityManager* GetRootBrowserAccessibilityManager() override {
+ return nullptr;
+ }
+ void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event,
+ const ui::LatencyInfo& latency_info) override {
+ const blink::WebKeyboardEvent* web_event =
+ static_cast<const blink::WebKeyboardEvent*>(&key_event);
+ std::unique_ptr<InputEvent> input_event =
+ std::make_unique<InputEvent>(*web_event, latency_info);
+ client_->ForwardKeyboardEvent(std::move(input_event),
+ key_event.skip_in_browser);
+ }
+ void ForwardKeyboardEventWithCommands(
+ const NativeWebKeyboardEvent& key_event,
+ const ui::LatencyInfo& latency_info,
+ const std::vector<EditCommand>& commands) override {
+ const blink::WebKeyboardEvent* web_event =
+ static_cast<const blink::WebKeyboardEvent*>(&key_event);
+ std::unique_ptr<InputEvent> input_event =
+ std::make_unique<InputEvent>(*web_event, latency_info);
+ client_->ForwardKeyboardEventWithCommands(
+ std::move(input_event), key_event.skip_in_browser, commands);
+ }
+ void RouteOrProcessMouseEvent(
+ const blink::WebMouseEvent& web_event) override {
+ client_->RouteOrProcessMouseEvent(TranslateEvent(web_event));
+ }
+ void RouteOrProcessTouchEvent(
+ const blink::WebTouchEvent& web_event) override {
+ client_->RouteOrProcessTouchEvent(TranslateEvent(web_event));
+ }
+ void RouteOrProcessWheelEvent(
+ const blink::WebMouseWheelEvent& web_event) override {
+ client_->RouteOrProcessWheelEvent(TranslateEvent(web_event));
+ }
+ void ForwardMouseEvent(const blink::WebMouseEvent& web_event) override {
+ client_->ForwardMouseEvent(TranslateEvent(web_event));
+ }
+ void ForwardWheelEvent(const blink::WebMouseWheelEvent& web_event) override {
+ client_->ForwardWheelEvent(TranslateEvent(web_event));
+ }
+ void GestureBegin(blink::WebGestureEvent begin_event,
+ bool is_synthetically_injected) override {
+ // The gesture type is not yet known, but assign a type to avoid
+ // serialization asserts (the type will be stripped on the other side).
+ begin_event.SetType(blink::WebInputEvent::kGestureScrollBegin);
+ client_->GestureBegin(TranslateEvent(begin_event),
+ is_synthetically_injected);
+ }
+ void GestureUpdate(blink::WebGestureEvent update_event) override {
+ client_->GestureUpdate(TranslateEvent(update_event));
+ }
+ void GestureEnd(blink::WebGestureEvent end_event) override {
+ client_->GestureEnd(TranslateEvent(end_event));
+ }
+ void SmartMagnify(const blink::WebGestureEvent& web_event) override {
+ client_->SmartMagnify(TranslateEvent(web_event));
+ }
+
+ mojom::RenderWidgetHostNSViewClient* client_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(ForwardingClientHelper);
+};
+
+} // namespace
+
+// static
+std::unique_ptr<RenderWidgetHostNSViewClientHelper>
+RenderWidgetHostNSViewClientHelper::CreateForMojoClient(
+ content::mojom::RenderWidgetHostNSViewClient* client) {
+ return std::make_unique<ForwardingClientHelper>(client);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h b/chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h
index 24a08a3fdf6..0ba7bbc5422 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h
@@ -57,8 +57,9 @@ class CONTENT_EXPORT RenderWidgetHostOwnerDelegate {
// priority to the RenderProcessHost.
virtual bool ShouldContributePriorityToProcess() = 0;
- // Called when the RenderWidgetHost has shutdown.
- virtual void RenderWidgetDidShutdown() = 0;
+ // Notify the OwnerDelegate that the renderer has requested a change in
+ // the bounds of the content area.
+ virtual void RequestSetBounds(const gfx::Rect& bounds) = 0;
protected:
virtual ~RenderWidgetHostOwnerDelegate() {}
diff --git a/chromium/content/browser/renderer_host/render_widget_host_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_unittest.cc
index 138cac8c271..5c5bcdf6377 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -40,6 +40,7 @@
#include "content/common/render_frame_metadata.mojom.h"
#include "content/common/view_messages.h"
#include "content/common/visual_properties.h"
+#include "content/common/widget_messages.h"
#include "content/public/browser/keyboard_event_processing_result.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
@@ -955,7 +956,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_FALSE(host_->SynchronizeVisualProperties());
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// The zoom has changed so host should send out a sync message
process_->sink().ClearMessages();
@@ -965,7 +966,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_NEAR(new_zoom_level, host_->old_visual_properties_->zoom_level, 0.01);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// The initial bounds is the empty rect, so setting it to the same thing
// shouldn't send the resize message.
@@ -974,7 +975,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
host_->SynchronizeVisualProperties();
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// No visual properties ACK if the physical backing gets set, but the view
// bounds are zero.
@@ -992,7 +993,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_EQ(original_size.size(), host_->old_visual_properties_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// Setting the bounds and physical backing size to nonzero should send out
// the notification and expect an ack.
@@ -1002,7 +1003,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_TRUE(host_->visual_properties_ack_pending_);
EXPECT_EQ(original_size.size(), host_->old_visual_properties_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
cc::RenderFrameMetadata metadata;
metadata.viewport_size_in_pixels = original_size.size();
metadata.local_surface_id = base::nullopt;
@@ -1024,7 +1025,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_FALSE(host_->SynchronizeVisualProperties());
EXPECT_TRUE(host_->visual_properties_ack_pending_);
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// Send a update that's a visual properties ACK, but for the original_size we
// sent. Since this isn't the second_size, the message handler should
@@ -1036,7 +1037,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_TRUE(host_->visual_properties_ack_pending_);
EXPECT_EQ(third_size.size(), host_->old_visual_properties_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// Send the visual properties ACK for the latest size.
process_->sink().ClearMessages();
@@ -1046,7 +1047,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_EQ(third_size.size(), host_->old_visual_properties_->new_size);
EXPECT_FALSE(process_->sink().GetFirstMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// Now clearing the bounds should send out a notification but we shouldn't
// expect a visual properties ACK (since the renderer won't ack empty sizes).
@@ -1058,7 +1059,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_EQ(gfx::Size(), host_->old_visual_properties_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// Send a rect that has no area but has either width or height set.
process_->sink().ClearMessages();
@@ -1067,7 +1068,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_EQ(gfx::Size(0, 30), host_->old_visual_properties_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// Set the same size again. It should not be sent again.
process_->sink().ClearMessages();
@@ -1075,7 +1076,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_EQ(gfx::Size(0, 30), host_->old_visual_properties_->new_size);
EXPECT_FALSE(process_->sink().GetFirstMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// A different size should be sent again, however.
view_->SetBounds(gfx::Rect(0, 0, 0, 31));
@@ -1083,7 +1084,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_EQ(gfx::Size(0, 31), host_->old_visual_properties_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// An invalid LocalSurfaceId should result in no change to the
// |visual_properties_ack_pending_| bit.
@@ -1094,7 +1095,7 @@ TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_EQ(gfx::Size(25, 25), host_->old_visual_properties_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
}
// Test that a resize event is sent if SynchronizeVisualProperties() is called
@@ -1111,7 +1112,7 @@ TEST_F(RenderWidgetHostTest, ResizeScreenInfo) {
host_->SynchronizeVisualProperties();
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
process_->sink().ClearMessages();
screen_info.orientation_angle = 180;
@@ -1121,7 +1122,7 @@ TEST_F(RenderWidgetHostTest, ResizeScreenInfo) {
host_->SynchronizeVisualProperties();
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
process_->sink().ClearMessages();
screen_info.device_scale_factor = 2.f;
@@ -1130,7 +1131,7 @@ TEST_F(RenderWidgetHostTest, ResizeScreenInfo) {
host_->SynchronizeVisualProperties();
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
process_->sink().ClearMessages();
// No screen change.
@@ -1138,7 +1139,7 @@ TEST_F(RenderWidgetHostTest, ResizeScreenInfo) {
host_->SynchronizeVisualProperties();
EXPECT_FALSE(host_->visual_properties_ack_pending_);
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
}
// Test for crbug.com/25097. If a renderer crashes between a resize and the
@@ -1155,7 +1156,7 @@ TEST_F(RenderWidgetHostTest, ResizeThenCrash) {
EXPECT_TRUE(host_->visual_properties_ack_pending_);
EXPECT_EQ(original_size.size(), host_->old_visual_properties_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
// Simulate a renderer crash before the update message. Ensure all the
// visual properties ACK logic is cleared. Must clear the view first so it
@@ -1192,10 +1193,10 @@ TEST_F(RenderWidgetHostTest, Background) {
const IPC::Message* set_background =
process_->sink().GetUniqueMessageMatching(
- ViewMsg_SetBackgroundOpaque::ID);
+ WidgetMsg_SetBackgroundOpaque::ID);
ASSERT_TRUE(set_background);
std::tuple<bool> sent_background;
- ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
+ WidgetMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
EXPECT_FALSE(std::get<0>(sent_background));
host_->SetView(nullptr);
@@ -1203,14 +1204,15 @@ TEST_F(RenderWidgetHostTest, Background) {
}
#endif
-// Test that we don't paint when we're hidden, but we still send the ACK. Most
-// of the rest of the painting is tested in the GetBackingStore* ones.
-TEST_F(RenderWidgetHostTest, HiddenPaint) {
+// Test that the RenderWidgetHost tells the renderer when it is hidden and
+// shown, and can accept a racey update from the renderer after hiding.
+TEST_F(RenderWidgetHostTest, HideShowMessages) {
// Hide the widget, it should have sent out a message to the renderer.
EXPECT_FALSE(host_->is_hidden_);
host_->WasHidden();
EXPECT_TRUE(host_->is_hidden_);
- EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_WasHidden::ID));
+ EXPECT_TRUE(
+ process_->sink().GetUniqueMessageMatching(WidgetMsg_WasHidden::ID));
// Send it an update as from the renderer.
process_->sink().ClearMessages();
@@ -1224,13 +1226,9 @@ TEST_F(RenderWidgetHostTest, HiddenPaint) {
host_->WasShown(false /* record_presentation_time */);
EXPECT_FALSE(host_->is_hidden_);
- // It should have sent out a restored message with a request to paint.
- const IPC::Message* restored = process_->sink().GetUniqueMessageMatching(
- ViewMsg_WasShown::ID);
- ASSERT_TRUE(restored);
- std::tuple<bool, base::TimeTicks> needs_repaint;
- ViewMsg_WasShown::Read(restored, &needs_repaint);
- EXPECT_TRUE(std::get<0>(needs_repaint));
+ // It should have sent out a restored message.
+ EXPECT_TRUE(
+ process_->sink().GetUniqueMessageMatching(WidgetMsg_WasShown::ID));
}
TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) {
@@ -1563,7 +1561,16 @@ TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
// Test that the rendering timeout for newly loaded content fires when enough
// time passes without receiving a new compositor frame. This test assumes
// Surface Synchronization is off.
-TEST_F(RenderWidgetHostTest, NewContentRenderingTimeoutWithoutSurfaceSync) {
+// Disabled due to flakiness on Android. See https://crbug.com/892700.
+#if defined(OS_ANDROID)
+#define MAYBE_NewContentRenderingTimeoutWithoutSurfaceSync \
+ DISABLED_NewContentRenderingTimeoutWithoutSurfaceSync
+#else
+#define MAYBE_NewContentRenderingTimeoutWithoutSurfaceSync \
+ NewContentRenderingTimeoutWithoutSurfaceSync
+#endif
+TEST_F(RenderWidgetHostTest,
+ NewContentRenderingTimeoutWithoutSurfaceSync_MAYBE) {
// If Surface Synchronization is on, we have a separate code path for
// cancelling new content rendering timeout that is tested separately.
if (features::IsSurfaceSynchronizationEnabled())
@@ -2000,7 +2007,7 @@ TEST_F(RenderWidgetHostInitialSizeTest, InitialSize) {
// size has actually changed).
EXPECT_FALSE(host_->SynchronizeVisualProperties());
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
EXPECT_EQ(initial_size_, host_->old_visual_properties_->new_size);
EXPECT_TRUE(host_->visual_properties_ack_pending_);
}
@@ -2011,7 +2018,7 @@ TEST_F(RenderWidgetHostTest, HideUnthrottlesResize) {
process_->sink().ClearMessages();
EXPECT_TRUE(host_->SynchronizeVisualProperties());
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID));
+ WidgetMsg_SynchronizeVisualProperties::ID));
EXPECT_EQ(original_size, host_->old_visual_properties_->new_size);
EXPECT_TRUE(host_->visual_properties_ack_pending_);
@@ -2052,7 +2059,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_MessageThenFrame) {
EXPECT_EQ(0u, host_->processed_frame_messages_count());
host_->OnMessageReceived(
- ViewHostMsg_FrameSwapMessages(0, frame_token, messages));
+ WidgetHostMsg_FrameSwapMessages(0, frame_token, messages));
EXPECT_EQ(1u, host_->frame_token_message_queue_->size());
EXPECT_EQ(0u, host_->processed_frame_messages_count());
@@ -2090,7 +2097,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_FrameThenMessage) {
EXPECT_EQ(0u, host_->processed_frame_messages_count());
host_->OnMessageReceived(
- ViewHostMsg_FrameSwapMessages(0, frame_token, messages));
+ WidgetHostMsg_FrameSwapMessages(0, frame_token, messages));
EXPECT_EQ(0u, host_->frame_token_message_queue_->size());
EXPECT_EQ(1u, host_->processed_frame_messages_count());
}
@@ -2111,12 +2118,12 @@ TEST_F(RenderWidgetHostTest, FrameToken_MultipleMessagesThenTokens) {
EXPECT_EQ(0u, host_->processed_frame_messages_count());
host_->OnMessageReceived(
- ViewHostMsg_FrameSwapMessages(0, frame_token1, messages1));
+ WidgetHostMsg_FrameSwapMessages(0, frame_token1, messages1));
EXPECT_EQ(1u, host_->frame_token_message_queue_->size());
EXPECT_EQ(0u, host_->processed_frame_messages_count());
host_->OnMessageReceived(
- ViewHostMsg_FrameSwapMessages(0, frame_token2, messages2));
+ WidgetHostMsg_FrameSwapMessages(0, frame_token2, messages2));
EXPECT_EQ(2u, host_->frame_token_message_queue_->size());
EXPECT_EQ(0u, host_->processed_frame_messages_count());
@@ -2177,12 +2184,12 @@ TEST_F(RenderWidgetHostTest, FrameToken_MultipleTokensThenMessages) {
EXPECT_EQ(0u, host_->processed_frame_messages_count());
host_->OnMessageReceived(
- ViewHostMsg_FrameSwapMessages(0, frame_token1, messages1));
+ WidgetHostMsg_FrameSwapMessages(0, frame_token1, messages1));
EXPECT_EQ(0u, host_->frame_token_message_queue_->size());
EXPECT_EQ(1u, host_->processed_frame_messages_count());
host_->OnMessageReceived(
- ViewHostMsg_FrameSwapMessages(0, frame_token2, messages2));
+ WidgetHostMsg_FrameSwapMessages(0, frame_token2, messages2));
EXPECT_EQ(0u, host_->frame_token_message_queue_->size());
EXPECT_EQ(2u, host_->processed_frame_messages_count());
}
@@ -2203,12 +2210,12 @@ TEST_F(RenderWidgetHostTest, FrameToken_DroppedFrame) {
EXPECT_EQ(0u, host_->processed_frame_messages_count());
host_->OnMessageReceived(
- ViewHostMsg_FrameSwapMessages(0, frame_token1, messages1));
+ WidgetHostMsg_FrameSwapMessages(0, frame_token1, messages1));
EXPECT_EQ(1u, host_->frame_token_message_queue_->size());
EXPECT_EQ(0u, host_->processed_frame_messages_count());
host_->OnMessageReceived(
- ViewHostMsg_FrameSwapMessages(0, frame_token2, messages2));
+ WidgetHostMsg_FrameSwapMessages(0, frame_token2, messages2));
EXPECT_EQ(2u, host_->frame_token_message_queue_->size());
EXPECT_EQ(0u, host_->processed_frame_messages_count());
@@ -2249,7 +2256,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_RendererCrash) {
host_->SetView(nullptr);
host_->OnMessageReceived(
- ViewHostMsg_FrameSwapMessages(0, frame_token1, messages1));
+ WidgetHostMsg_FrameSwapMessages(0, frame_token1, messages1));
EXPECT_EQ(1u, host_->frame_token_message_queue_->size());
EXPECT_EQ(0u, host_->processed_frame_messages_count());
@@ -2275,7 +2282,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_RendererCrash) {
host_->Init();
host_->OnMessageReceived(
- ViewHostMsg_FrameSwapMessages(0, frame_token3, messages3));
+ WidgetHostMsg_FrameSwapMessages(0, frame_token3, messages3));
EXPECT_EQ(1u, host_->frame_token_message_queue_->size());
EXPECT_EQ(0u, host_->processed_frame_messages_count());
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_android.cc b/chromium/content/browser/renderer_host/render_widget_host_view_android.cc
index c0460f053f2..5cb90605f13 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -62,8 +62,6 @@
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/browser/renderer_host/ui_events_helper.h"
#include "content/common/content_switches_internal.h"
-#include "content/common/input_messages.h"
-#include "content/common/view_messages.h"
#include "content/public/browser/android/compositor.h"
#include "content/public/browser/android/synchronous_compositor_client.h"
#include "content/public/browser/browser_thread.h"
@@ -73,8 +71,6 @@
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/use_zoom_for_dsf_policy.h"
-#include "ipc/ipc_message_macros.h"
-#include "ipc/ipc_message_start.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
@@ -249,17 +245,6 @@ void RenderWidgetHostViewAndroid::RemoveDestructionObserver(
destruction_observers_.RemoveObserver(observer);
}
-bool RenderWidgetHostViewAndroid::OnMessageReceived(
- const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
- IPC_MESSAGE_HANDLER(ViewHostMsg_SelectWordAroundCaretAck,
- OnSelectWordAroundCaretAck)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
void RenderWidgetHostViewAndroid::InitAsChild(gfx::NativeView parent_view) {
NOTIMPLEMENTED();
}
@@ -473,9 +458,9 @@ bool RenderWidgetHostViewAndroid::IsShowing() {
return is_showing_ && view_.parent();
}
-void RenderWidgetHostViewAndroid::OnSelectWordAroundCaretAck(bool did_select,
- int start_adjust,
- int end_adjust) {
+void RenderWidgetHostViewAndroid::SelectWordAroundCaretAck(bool did_select,
+ int start_adjust,
+ int end_adjust) {
if (!selection_popup_controller_)
return;
selection_popup_controller_->OnSelectWordAroundCaretAck(
@@ -514,9 +499,9 @@ gfx::Size RenderWidgetHostViewAndroid::GetCompositorViewportPixelSize() const {
return view_.GetPhysicalBackingSize();
}
-bool RenderWidgetHostViewAndroid::DoBrowserControlsShrinkBlinkSize() const {
+bool RenderWidgetHostViewAndroid::DoBrowserControlsShrinkRendererSize() const {
auto* delegate_view = GetRenderViewHostDelegateView();
- return delegate_view ? delegate_view->DoBrowserControlsShrinkBlinkSize()
+ return delegate_view ? delegate_view->DoBrowserControlsShrinkRendererSize()
: false;
}
@@ -678,18 +663,18 @@ bool RenderWidgetHostViewAndroid::TransformPointToCoordSpaceForView(
RenderWidgetHostViewBase* target_view,
gfx::PointF* transformed_point,
viz::EventSource source) {
- if (target_view == this || !delegated_frame_host_) {
+ if (target_view == this) {
*transformed_point = point;
return true;
}
- // In TransformPointToLocalCoordSpace() there is a Point-to-Pixel conversion,
- // but it is not necessary here because the final target view is responsible
- // for converting before computing the final transform.
- viz::SurfaceId surface_id = delegated_frame_host_->SurfaceId();
+ viz::SurfaceId surface_id = GetCurrentSurfaceId();
if (!surface_id.is_valid())
return false;
+ // In TransformPointToLocalCoordSpace() there is a Point-to-Pixel conversion,
+ // but it is not necessary here because the final target view is responsible
+ // for converting before computing the final transform.
return target_view->TransformPointToLocalCoordSpace(
point, surface_id, transformed_point, source);
}
@@ -889,8 +874,7 @@ void RenderWidgetHostViewAndroid::CopyFromSurface(
const gfx::Size& output_size,
base::OnceCallback<void(const SkBitmap&)> callback) {
TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::CopyFromSurface");
- if (!features::IsSurfaceSynchronizationEnabled() &&
- !IsSurfaceAvailableForCopy()) {
+ if (!IsSurfaceAvailableForCopy()) {
std::move(callback).Run(SkBitmap());
return;
}
@@ -1315,8 +1299,6 @@ void RenderWidgetHostViewAndroid::UpdateTouchSelectionController(
DCHECK(touch_selection_controller_client_manager_);
touch_selection_controller_client_manager_->UpdateClientSelectionBounds(
selection.start, selection.end, this, nullptr);
- touch_selection_controller_client_manager_->SetPageScaleFactor(
- page_scale_factor);
// Set parameters for adaptive handle orientation.
gfx::SizeF viewport_size(scrollable_viewport_size_dip);
@@ -1566,7 +1548,7 @@ void RenderWidgetHostViewAndroid::RequestDisallowInterceptTouchEvent() {
void RenderWidgetHostViewAndroid::TransformPointToRootSurface(
gfx::PointF* point) {
*point += gfx::Vector2d(
- 0, DoBrowserControlsShrinkBlinkSize() ? GetTopControlsHeight() : 0);
+ 0, DoBrowserControlsShrinkRendererSize() ? GetTopControlsHeight() : 0);
}
// TODO(jrg): Find out the implications and answer correctly here,
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_android.h b/chromium/content/browser/renderer_host/render_widget_host_view_android.h
index 6d3920e20e8..85cb772fd1e 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_android.h
@@ -95,7 +95,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
}
// RenderWidgetHostView implementation.
- bool OnMessageReceived(const IPC::Message& msg) override;
void InitAsChild(gfx::NativeView parent_view) override;
void InitAsPopup(RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos) override;
@@ -119,7 +118,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
base::OnceCallback<void(const SkBitmap&)> callback) override;
void EnsureSurfaceSynchronizedForLayoutTest() override;
uint32_t GetCaptureSequenceNumber() const override;
- bool DoBrowserControlsShrinkBlinkSize() const override;
+ bool DoBrowserControlsShrinkRendererSize() const override;
float GetTopControlsHeight() const override;
float GetBottomControlsHeight() const override;
int GetMouseWheelMinimumGranularity() const override;
@@ -290,9 +289,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void ShowContextMenuAtPoint(const gfx::Point& point, ui::MenuSourceType);
void DismissTextHandles();
void SetTextHandlesTemporarilyHidden(bool hide_handles);
- void OnSelectWordAroundCaretAck(bool did_select,
- int start_adjust,
- int end_adjust);
+ void SelectWordAroundCaretAck(bool did_select,
+ int start_adjust,
+ int end_adjust);
void SynchronousFrameMetadata(viz::CompositorFrameMetadata frame_metadata);
@@ -392,8 +391,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
bool Animate(base::TimeTicks frame_time);
void RequestDisallowInterceptTouchEvent();
- bool SyncCompositorOnMessageReceived(const IPC::Message& message);
-
void ComputeEventLatencyOSTouchHistograms(const ui::MotionEvent& event);
void CreateOverscrollControllerIfPossible();
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc
index b01698c8111..7d4ada0eb03 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -22,9 +22,11 @@
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
+#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/browser/bad_message.h"
+#include "content/browser/compositor/surface_utils.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
@@ -127,6 +129,10 @@
#include "ui/wm/core/ime_util_chromeos.h"
#endif
+#if defined(OS_FUCHSIA)
+#include "ui/base/ime/input_method_keyboard_controller.h"
+#endif
+
using gfx::RectToSkIRect;
using gfx::SkIRectToRect;
@@ -364,7 +370,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(
is_guest_view_hack_(is_guest_view_hack),
device_scale_factor_(0.0f),
event_handler_(new RenderWidgetHostViewEventHandler(host(), this, this)),
- frame_sink_id_(features::IsUsingWindowService()
+ frame_sink_id_(features::IsMultiProcessMash()
? viz::FrameSinkId()
: is_guest_view_hack_
? AllocateFrameSinkIdForGuestViewHack()
@@ -403,6 +409,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(
// RenderWidgetHostViewAura, RenderWidgetHostView implementation:
void RenderWidgetHostViewAura::InitAsChild(gfx::NativeView parent_view) {
+ DCHECK_EQ(widget_type_, WidgetType::kFrame);
if (is_mus_browser_plugin_guest_)
return;
CreateAuraWindow(aura::client::WINDOW_TYPE_CONTROL);
@@ -416,6 +423,7 @@ void RenderWidgetHostViewAura::InitAsChild(gfx::NativeView parent_view) {
void RenderWidgetHostViewAura::InitAsPopup(
RenderWidgetHostView* parent_host_view,
const gfx::Rect& bounds_in_screen) {
+ DCHECK_EQ(widget_type_, WidgetType::kPopup);
// Popups never have |is_mus_browser_plugin_guest_| set to true.
DCHECK(!is_mus_browser_plugin_guest_);
@@ -465,6 +473,7 @@ void RenderWidgetHostViewAura::InitAsPopup(
void RenderWidgetHostViewAura::InitAsFullscreen(
RenderWidgetHostView* reference_host_view) {
+ DCHECK_EQ(widget_type_, WidgetType::kFrame);
// Webview Fullscreen doesn't go through InitAsFullscreen(), so
// |is_mus_browser_plugin_guest_| is always false.
DCHECK(!is_mus_browser_plugin_guest_);
@@ -561,7 +570,7 @@ gfx::NativeViewAccessible RenderWidgetHostViewAura::GetNativeViewAccessible() {
return manager->GetRoot()->GetNativeViewAccessible();
#endif
- NOTIMPLEMENTED();
+ NOTIMPLEMENTED_LOG_ONCE();
return static_cast<gfx::NativeViewAccessible>(nullptr);
}
@@ -751,7 +760,7 @@ void RenderWidgetHostViewAura::SetInsets(const gfx::Insets& insets) {
void RenderWidgetHostViewAura::FocusedNodeTouched(bool editable) {
#if defined(OS_WIN)
auto* input_method = GetInputMethod();
- if (!input_method)
+ if (!input_method || !input_method->GetInputMethodKeyboardController())
return;
auto* controller = input_method->GetInputMethodKeyboardController();
if (editable && host()->GetView() && host()->delegate()) {
@@ -831,12 +840,30 @@ uint32_t RenderWidgetHostViewAura::GetCaptureSequenceNumber() const {
return latest_capture_sequence_number_;
}
+bool RenderWidgetHostViewAura::DoBrowserControlsShrinkRendererSize() const {
+ return host()->delegate() &&
+ host()->delegate()->DoBrowserControlsShrinkRendererSize();
+}
+
+float RenderWidgetHostViewAura::GetTopControlsHeight() const {
+ return host()->delegate() ? host()->delegate()->GetTopControlsHeight() : 0;
+}
+
void RenderWidgetHostViewAura::CopyFromSurface(
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
base::OnceCallback<void(const SkBitmap&)> callback) {
- delegated_frame_host_->CopyFromCompositingSurface(src_subrect, dst_size,
- std::move(callback));
+ base::WeakPtr<RenderWidgetHostImpl> popup_host;
+ base::WeakPtr<DelegatedFrameHost> popup_frame_host;
+ if (popup_child_host_view_) {
+ popup_host = popup_child_host_view_->host()->GetWeakPtr();
+ popup_frame_host =
+ popup_child_host_view_->GetDelegatedFrameHost()->GetWeakPtr();
+ }
+ RenderWidgetHostViewBase::CopyMainAndPopupFromSurface(
+ host()->GetWeakPtr(), delegated_frame_host_->GetWeakPtr(), popup_host,
+ popup_frame_host, src_subrect, dst_size, device_scale_factor_,
+ std::move(callback));
}
#if defined(OS_WIN)
@@ -904,8 +931,23 @@ void RenderWidgetHostViewAura::DidStopFlinging() {
}
void RenderWidgetHostViewAura::TransformPointToRootSurface(gfx::PointF* point) {
- aura::Window::ConvertPointToTarget(window_, window_->GetRootWindow(), point);
- window_->GetRootWindow()->transform().TransformPoint(point);
+ aura::Window* root = window_->GetRootWindow();
+ aura::Window::ConvertPointToTarget(window_, root, point);
+ root->GetRootWindow()->transform().TransformPoint(point);
+
+// On ChromeOS, the root surface is the whole desktop. When using the
+// window-service converting to screen coordinates gives us that.
+#if defined(OS_CHROMEOS)
+ if (features::IsUsingWindowService()) {
+ aura::client::ScreenPositionClient* screen_client =
+ aura::client::GetScreenPositionClient(root);
+ if (screen_client) {
+ gfx::Point rounded_point(point->x(), point->y());
+ screen_client->ConvertPointToScreen(root, &rounded_point);
+ *point = gfx::PointF(rounded_point);
+ }
+ }
+#endif
}
gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() {
@@ -938,10 +980,13 @@ gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() {
bounds.Inset(GetSystemMetrics(SM_CXPADDEDBORDER),
GetSystemMetrics(SM_CXPADDEDBORDER));
}
+
+ // Pixels come back from GetWindowHost, so we need to convert those back to
+ // DIPs here.
+ bounds = display::Screen::GetScreen()->ScreenToDIPRectInWindow(top_level,
+ bounds);
}
- bounds =
- display::Screen::GetScreen()->ScreenToDIPRectInWindow(top_level, bounds);
#endif
return bounds;
@@ -965,6 +1010,15 @@ void RenderWidgetHostViewAura::DidOverscroll(
void RenderWidgetHostViewAura::GestureEventAck(
const blink::WebGestureEvent& event,
InputEventAckState ack_result) {
+ const blink::WebInputEvent::Type event_type = event.GetType();
+ if (event_type == blink::WebGestureEvent::kGestureScrollBegin ||
+ event_type == blink::WebGestureEvent::kGestureScrollEnd) {
+ if (host()->delegate()) {
+ host()->delegate()->SetTopControlsGestureScrollInProgress(
+ event_type == blink::WebGestureEvent::kGestureScrollBegin);
+ }
+ }
+
if (overscroll_controller_) {
overscroll_controller_->ReceivedEventACK(
event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result));
@@ -975,7 +1029,7 @@ void RenderWidgetHostViewAura::GestureEventAck(
// action would complete at the end of the active fling progress which
// causes noticeable delay in cases that the fling velocity is large.
// https://crbug.com/797855
- if (event.GetType() == blink::WebInputEvent::kGestureScrollUpdate &&
+ if (event_type == blink::WebInputEvent::kGestureScrollUpdate &&
event.data.scroll_update.inertial_phase ==
blink::WebGestureEvent::kMomentumPhase &&
overscroll_controller_->overscroll_mode() != OVERSCROLL_NONE) {
@@ -1129,9 +1183,8 @@ RenderWidgetHostViewAura::AccessibilityGetNativeViewAccessible() {
return nullptr;
}
-void RenderWidgetHostViewAura::SetMainFrameAXTreeID(
- ui::AXTreeIDRegistry::AXTreeID id) {
- window_->SetProperty(ui::kChildAXTreeID, id);
+void RenderWidgetHostViewAura::SetMainFrameAXTreeID(ui::AXTreeID id) {
+ window_->SetProperty(ui::kChildAXTreeID, new std::string(id.ToString()));
}
bool RenderWidgetHostViewAura::LockMouse() {
@@ -1236,7 +1289,7 @@ ui::TextInputMode RenderWidgetHostViewAura::GetTextInputMode() const {
}
base::i18n::TextDirection RenderWidgetHostViewAura::GetTextDirection() const {
- NOTIMPLEMENTED();
+ NOTIMPLEMENTED_LOG_ONCE();
return base::i18n::UNKNOWN_DIRECTION;
}
@@ -1346,7 +1399,7 @@ bool RenderWidgetHostViewAura::GetTextRange(gfx::Range* range) const {
bool RenderWidgetHostViewAura::GetCompositionTextRange(
gfx::Range* range) const {
// TODO(suzhe): implement this method when fixing http://crbug.com/55130.
- NOTIMPLEMENTED();
+ NOTIMPLEMENTED_LOG_ONCE();
return false;
}
@@ -1366,13 +1419,13 @@ bool RenderWidgetHostViewAura::GetSelectionRange(gfx::Range* range) const {
bool RenderWidgetHostViewAura::SetSelectionRange(const gfx::Range& range) {
// TODO(suzhe): implement this method when fixing http://crbug.com/55130.
- NOTIMPLEMENTED();
+ NOTIMPLEMENTED_LOG_ONCE();
return false;
}
bool RenderWidgetHostViewAura::DeleteRange(const gfx::Range& range) {
// TODO(suzhe): implement this method when fixing http://crbug.com/55130.
- NOTIMPLEMENTED();
+ NOTIMPLEMENTED_LOG_ONCE();
return false;
}
@@ -1474,12 +1527,6 @@ bool RenderWidgetHostViewAura::ShouldDoLearning() {
////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, display::DisplayObserver implementation:
-void RenderWidgetHostViewAura::OnDisplayAdded(
- const display::Display& new_display) {}
-
-void RenderWidgetHostViewAura::OnDisplayRemoved(
- const display::Display& old_display) {}
-
void RenderWidgetHostViewAura::OnDisplayMetricsChanged(
const display::Display& display,
uint32_t metrics) {
@@ -1535,7 +1582,7 @@ bool RenderWidgetHostViewAura::ShouldDescendIntoChildForEventHandling(
}
bool RenderWidgetHostViewAura::CanFocus() {
- return popup_type_ == blink::kWebPopupTypeNone;
+ return widget_type_ == WidgetType::kFrame;
}
void RenderWidgetHostViewAura::OnCaptureLost() {
@@ -1668,16 +1715,23 @@ bool RenderWidgetHostViewAura::TransformPointToCoordSpaceForView(
// In TransformPointToLocalCoordSpace() there is a Point-to-Pixel conversion,
// but it is not necessary here because the final target view is responsible
// for converting before computing the final transform.
- if (!HasFallbackSurface())
- return false;
return target_view->TransformPointToLocalCoordSpace(
point, GetCurrentSurfaceId(), transformed_point, source);
}
viz::FrameSinkId RenderWidgetHostViewAura::GetRootFrameSinkId() {
- if (window_ && window_->GetHost() && window_->GetHost()->compositor())
- return window_->GetHost()->compositor()->frame_sink_id();
- return viz::FrameSinkId();
+ if (!window_ || !window_->GetHost() || !window_->GetHost()->compositor())
+ return viz::FrameSinkId();
+
+ // In single-process mash the root is provided by Ash. Have
+ // HostFrameSinkManager walk the tree to find the right root.
+ if (features::IsSingleProcessMash()) {
+ base::Optional<viz::FrameSinkId> root =
+ GetHostFrameSinkManager()->FindRootFrameSinkId(frame_sink_id_);
+ return root ? *root : viz::FrameSinkId();
+ }
+
+ return window_->GetHost()->compositor()->frame_sink_id();
}
viz::SurfaceId RenderWidgetHostViewAura::GetCurrentSurfaceId() const {
@@ -1703,6 +1757,13 @@ void RenderWidgetHostViewAura::FocusedNodeChanged(
if (!editable && virtual_keyboard_requested_ && window_) {
virtual_keyboard_requested_ = false;
+ if (input_method && input_method->GetInputMethodKeyboardController()) {
+ input_method->GetInputMethodKeyboardController()
+ ->DismissVirtualKeyboard();
+ }
+ }
+#elif defined(OS_FUCHSIA)
+ if (!editable && window_) {
if (input_method) {
input_method->GetInputMethodKeyboardController()
->DismissVirtualKeyboard();
@@ -1714,7 +1775,7 @@ void RenderWidgetHostViewAura::FocusedNodeChanged(
void RenderWidgetHostViewAura::ScheduleEmbed(
ws::mojom::WindowTreeClientPtr client,
base::OnceCallback<void(const base::UnguessableToken&)> callback) {
- DCHECK(features::IsUsingWindowService());
+ DCHECK(features::IsMultiProcessMash());
aura::Env::GetInstance()->ScheduleEmbed(std::move(client),
std::move(callback));
}
@@ -1890,12 +1951,12 @@ RenderWidgetHostViewAura::~RenderWidgetHostViewAura() {
DetachFromInputMethod();
}
if (popup_parent_host_view_) {
- DCHECK(popup_parent_host_view_->popup_child_host_view_ == nullptr ||
+ DCHECK(!popup_parent_host_view_->popup_child_host_view_ ||
popup_parent_host_view_->popup_child_host_view_ == this);
popup_parent_host_view_->SetPopupChild(nullptr);
}
if (popup_child_host_view_) {
- DCHECK(popup_child_host_view_->popup_parent_host_view_ == nullptr ||
+ DCHECK(!popup_child_host_view_->popup_parent_host_view_ ||
popup_child_host_view_->popup_parent_host_view_ == this);
popup_child_host_view_->popup_parent_host_view_ = nullptr;
}
@@ -1917,8 +1978,6 @@ void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) {
DCHECK(!is_mus_browser_plugin_guest_);
window_ = new aura::Window(this);
window_->SetName("RenderWidgetHostViewAura");
- window_->SetProperty(aura::client::kEmbedType,
- aura::client::WindowEmbedType::EMBED_IN_OWNER);
event_handler_->set_window(window_);
window_observer_.reset(new WindowObserver(this));
@@ -1936,7 +1995,7 @@ void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) {
if (frame_sink_id_.is_valid())
window_->SetEmbedFrameSinkId(frame_sink_id_);
- if (!features::IsUsingWindowService())
+ if (!features::IsMultiProcessMash())
return;
// Embed the renderer into the Window.
@@ -2051,6 +2110,19 @@ bool RenderWidgetHostViewAura::SynchronizeVisualProperties(
return host()->SynchronizeVisualProperties();
}
+void RenderWidgetHostViewAura::OnDidUpdateVisualPropertiesComplete(
+ const cc::RenderFrameMetadata& metadata) {
+ DCHECK(window_);
+
+ if (host()->delegate()) {
+ host()->delegate()->SetTopControlsShownRatio(
+ host(), metadata.top_controls_shown_ratio);
+ }
+
+ SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
+ metadata.local_surface_id);
+}
+
ui::InputMethod* RenderWidgetHostViewAura::GetInputMethod() const {
if (!window_)
return nullptr;
@@ -2085,7 +2157,7 @@ RenderWidgetHostViewAura::GetTouchSelectionControllerClientManager() {
}
bool RenderWidgetHostViewAura::NeedsInputGrab() {
- return popup_type_ == blink::kWebPopupTypePage;
+ return widget_type_ == WidgetType::kPopup;
}
bool RenderWidgetHostViewAura::NeedsMouseCapture() {
@@ -2354,7 +2426,7 @@ void RenderWidgetHostViewAura::OnUpdateTextInputStateCalled(
if (state && state->type != ui::TEXT_INPUT_TYPE_NONE &&
state->mode != ui::TEXT_INPUT_MODE_NONE) {
bool show_virtual_keyboard = true;
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_FUCHSIA)
show_virtual_keyboard =
last_pointer_type_ == ui::EventPointerType::POINTER_TYPE_TOUCH;
#endif
@@ -2460,10 +2532,8 @@ viz::ScopedSurfaceIdAllocator
RenderWidgetHostViewAura::DidUpdateVisualProperties(
const cc::RenderFrameMetadata& metadata) {
base::OnceCallback<void()> allocation_task = base::BindOnce(
- base::IgnoreResult(
- &RenderWidgetHostViewAura::SynchronizeVisualProperties),
- weak_ptr_factory_.GetWeakPtr(), cc::DeadlinePolicy::UseDefaultDeadline(),
- metadata.local_surface_id);
+ &RenderWidgetHostViewAura::OnDidUpdateVisualPropertiesComplete,
+ weak_ptr_factory_.GetWeakPtr(), metadata);
return window_->GetSurfaceIdAllocator(std::move(allocation_task));
}
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura.h b/chromium/content/browser/renderer_host/render_widget_host_view_aura.h
index f237a3d5651..cfb4918a3cb 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -137,6 +137,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
void SetTooltipText(const base::string16& tooltip_text) override;
void DisplayTooltipText(const base::string16& tooltip_text) override;
uint32_t GetCaptureSequenceNumber() const override;
+ bool DoBrowserControlsShrinkRendererSize() const override;
+ float GetTopControlsHeight() const override;
bool IsSurfaceAvailableForCopy() const override;
void CopyFromSurface(
const gfx::Rect& src_rect,
@@ -162,7 +164,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
BrowserAccessibilityDelegate* delegate, bool for_root_frame) override;
gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() override;
gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() override;
- void SetMainFrameAXTreeID(ui::AXTreeIDRegistry::AXTreeID id) override;
+ void SetMainFrameAXTreeID(ui::AXTreeID id) override;
bool LockMouse() override;
void UnlockMouse() override;
bool LockKeyboard(base::Optional<base::flat_set<ui::DomCode>> codes) override;
@@ -244,8 +246,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
bool ShouldDoLearning() override;
// Overridden from display::DisplayObserver:
- void OnDisplayAdded(const display::Display& new_display) override;
- void OnDisplayRemoved(const display::Display& old_display) override;
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) override;
@@ -469,6 +469,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
const base::Optional<viz::LocalSurfaceId>&
child_allocated_local_surface_id);
+ void OnDidUpdateVisualPropertiesComplete(
+ const cc::RenderFrameMetadata& metadata);
+
// Tracks whether SnapToPhysicalPixelBoundary() has been called.
bool has_snapped_to_boundary() { return has_snapped_to_boundary_; }
void ResetHasSnappedToBoundary() { has_snapped_to_boundary_ = false; }
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index dba7c7d3e47..50d09e66b2a 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -62,6 +62,7 @@
#include "content/common/input_messages.h"
#include "content/common/text_input_state.h"
#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/browser/keyboard_event_processing_result.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents_view_delegate.h"
@@ -138,6 +139,18 @@ using blink::WebTouchPoint;
using ui::WebInputEventTraits;
using viz::FrameEvictionManager;
+#define EXPECT_EVICTED(view) \
+ { \
+ EXPECT_FALSE((view)->HasPrimarySurface()); \
+ EXPECT_FALSE((view)->HasSavedFrame()); \
+ }
+
+#define EXPECT_HAS_FRAME(view) \
+ { \
+ EXPECT_TRUE((view)->HasPrimarySurface()); \
+ EXPECT_TRUE((view)->HasSavedFrame()); \
+ }
+
namespace content {
void InstallDelegatedFrameHostClient(
@@ -300,6 +313,10 @@ class FakeRenderWidgetHostViewAura : public RenderWidgetHostViewAura {
return GetDelegatedFrameHost()->HasFallbackSurface();
}
+ bool HasSavedFrame() const {
+ return GetDelegatedFrameHost()->HasSavedFrame();
+ }
+
void ReclaimResources(const std::vector<viz::ReturnedResource>& resources) {
GetDelegatedFrameHost()->ReclaimResources(resources);
}
@@ -1123,6 +1140,7 @@ TEST_F(RenderWidgetHostViewAuraTest, PositionChildPopup) {
// Verify that when the popup is initialized for the first time, it correctly
// treats the input bounds as screen coordinates.
+ view_->SetWidgetType(WidgetType::kPopup);
view_->InitAsPopup(parent_view_, bounds_in_screen);
gfx::Rect final_bounds_in_screen = view_->GetViewBounds();
@@ -1171,36 +1189,38 @@ TEST_F(RenderWidgetHostViewAuraTest, ParentMovementUpdatesScreenRect) {
// Flush the state after initial setup is done.
widget_host_->OnMessageReceived(
- ViewHostMsg_UpdateScreenRects_ACK(widget_host_->GetRoutingID()));
+ WidgetHostMsg_UpdateScreenRects_ACK(widget_host_->GetRoutingID()));
widget_host_->OnMessageReceived(
- ViewHostMsg_UpdateScreenRects_ACK(widget_host_->GetRoutingID()));
+ WidgetHostMsg_UpdateScreenRects_ACK(widget_host_->GetRoutingID()));
sink_->ClearMessages();
// Move parents.
parent2->SetBounds(gfx::Rect(20, 20, 200, 200));
ASSERT_EQ(1U, sink_->message_count());
const IPC::Message* msg = sink_->GetMessageAt(0);
- ASSERT_EQ(static_cast<uint32_t>(ViewMsg_UpdateScreenRects::ID), msg->type());
- ViewMsg_UpdateScreenRects::Param params;
- ViewMsg_UpdateScreenRects::Read(msg, &params);
+ ASSERT_EQ(static_cast<uint32_t>(WidgetMsg_UpdateScreenRects::ID),
+ msg->type());
+ WidgetMsg_UpdateScreenRects::Param params;
+ WidgetMsg_UpdateScreenRects::Read(msg, &params);
EXPECT_EQ(gfx::Rect(24, 24, 100, 100), std::get<0>(params));
EXPECT_EQ(gfx::Rect(1, 1, 300, 300), std::get<1>(params));
sink_->ClearMessages();
widget_host_->OnMessageReceived(
- ViewHostMsg_UpdateScreenRects_ACK(widget_host_->GetRoutingID()));
+ WidgetHostMsg_UpdateScreenRects_ACK(widget_host_->GetRoutingID()));
// There should not be any pending update.
EXPECT_EQ(0U, sink_->message_count());
parent1->SetBounds(gfx::Rect(10, 10, 300, 300));
ASSERT_EQ(1U, sink_->message_count());
msg = sink_->GetMessageAt(0);
- ASSERT_EQ(static_cast<uint32_t>(ViewMsg_UpdateScreenRects::ID), msg->type());
- ViewMsg_UpdateScreenRects::Read(msg, &params);
+ ASSERT_EQ(static_cast<uint32_t>(WidgetMsg_UpdateScreenRects::ID),
+ msg->type());
+ WidgetMsg_UpdateScreenRects::Read(msg, &params);
EXPECT_EQ(gfx::Rect(33, 33, 100, 100), std::get<0>(params));
EXPECT_EQ(gfx::Rect(10, 10, 300, 300), std::get<1>(params));
sink_->ClearMessages();
widget_host_->OnMessageReceived(
- ViewHostMsg_UpdateScreenRects_ACK(widget_host_->GetRoutingID()));
+ WidgetHostMsg_UpdateScreenRects_ACK(widget_host_->GetRoutingID()));
// There should not be any pending update.
EXPECT_EQ(0U, sink_->message_count());
}
@@ -1228,6 +1248,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DestroyFullscreenOnBlur) {
view_ = nullptr;
}
+#if defined(OS_CHROMEOS)
// Checks that a popup view is destroyed when a user clicks outside of the popup
// view and focus does not change. This is the case when the user clicks on the
// desktop background on Chrome OS.
@@ -1236,11 +1257,12 @@ TEST_F(RenderWidgetHostViewAuraTest, DestroyPopupClickOutsidePopup) {
parent_view_->Focus();
EXPECT_TRUE(parent_view_->HasFocus());
+ view_->SetWidgetType(WidgetType::kPopup);
view_->InitAsPopup(parent_view_, gfx::Rect(10, 10, 100, 100));
aura::Window* window = view_->GetNativeView();
ASSERT_TRUE(window != nullptr);
- gfx::Point click_point;
+ gfx::Point click_point(0, 0);
EXPECT_FALSE(window->GetBoundsInRootWindow().Contains(click_point));
aura::Window* parent_window = parent_view_->GetNativeView();
EXPECT_FALSE(parent_window->GetBoundsInRootWindow().Contains(click_point));
@@ -1263,11 +1285,12 @@ TEST_F(RenderWidgetHostViewAuraTest, DestroyPopupTapOutsidePopup) {
parent_view_->Focus();
EXPECT_TRUE(parent_view_->HasFocus());
+ view_->SetWidgetType(WidgetType::kPopup);
view_->InitAsPopup(parent_view_, gfx::Rect(10, 10, 100, 100));
aura::Window* window = view_->GetNativeView();
ASSERT_TRUE(window != nullptr);
- gfx::Point tap_point;
+ gfx::Point tap_point(0, 0);
EXPECT_FALSE(window->GetBoundsInRootWindow().Contains(tap_point));
aura::Window* parent_window = parent_view_->GetNativeView();
EXPECT_FALSE(parent_window->GetBoundsInRootWindow().Contains(tap_point));
@@ -1281,9 +1304,9 @@ TEST_F(RenderWidgetHostViewAuraTest, DestroyPopupTapOutsidePopup) {
widget_host_ = nullptr;
view_ = nullptr;
}
+#endif
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
-
// On Desktop Linux, select boxes need mouse capture in order to work. Test that
// when a select box is opened via a mouse press that it retains mouse capture
// after the mouse is released.
@@ -1296,7 +1319,7 @@ TEST_F(RenderWidgetHostViewAuraTest, PopupRetainsCaptureAfterMouseRelease) {
parent_view_->GetNativeView()->GetRootWindow(), gfx::Point(300, 300));
generator.PressLeftButton();
- view_->SetPopupType(blink::kWebPopupTypePage);
+ view_->SetWidgetType(WidgetType::kPopup);
view_->InitAsPopup(parent_view_, gfx::Rect(10, 10, 100, 100));
ASSERT_TRUE(view_->NeedsMouseCapture());
aura::Window* window = view_->GetNativeView();
@@ -1314,7 +1337,7 @@ TEST_F(RenderWidgetHostViewAuraTest, PopupClosesWhenParentLosesFocus) {
parent_view_->Focus();
EXPECT_TRUE(parent_view_->HasFocus());
- view_->SetPopupType(blink::kWebPopupTypePage);
+ view_->SetWidgetType(WidgetType::kPopup);
view_->InitAsPopup(parent_view_, gfx::Rect(10, 10, 100, 100));
aura::Window* popup_window = view_->GetNativeView();
@@ -1526,6 +1549,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventState) {
EXPECT_TRUE(press.synchronous_handling_disabled());
EXPECT_EQ(ui::MotionEvent::Action::DOWN, pointer_state().GetAction());
EXPECT_EQ(1U, pointer_state().GetPointerCount());
+ widget_host_->input_router()->OnSetTouchAction(cc::kTouchActionAuto);
view_->OnTouchEvent(&move);
base::RunLoop().RunUntilIdle();
@@ -1741,8 +1765,7 @@ TEST_F(RenderWidgetHostViewAuraTest,
parent_view_->Focus();
ASSERT_TRUE(parent_view_->HasFocus());
- // kWebPopupTypePage means the child view (popup) will receive input.
- view_->SetPopupType(blink::kWebPopupTypePage);
+ view_->SetWidgetType(WidgetType::kPopup);
view_->InitAsPopup(parent_view_, gfx::Rect(10, 10, 100, 100));
ASSERT_NE(nullptr, view_->GetNativeView());
view_->Show();
@@ -1800,66 +1823,6 @@ TEST_F(RenderWidgetHostViewAuraTest,
}
}
-TEST_F(RenderWidgetHostViewAuraTest,
- KeyEventRoutingKeyboardLockAndChildPopupWithoutInputGrab) {
- parent_view_->SetBounds(gfx::Rect(10, 10, 400, 400));
- parent_view_->Focus();
- ASSERT_TRUE(parent_view_->HasFocus());
-
- // kWebPopupTypeNone means the child view (popup) will not receive input.
- view_->SetPopupType(blink::kWebPopupTypeNone);
- view_->InitAsPopup(parent_view_, gfx::Rect(10, 10, 100, 100));
- ASSERT_NE(nullptr, view_->GetNativeView());
- view_->Show();
-
- // The parent view owns the KeyboardLock for this test.
- auto test_hook = std::make_unique<TestScopedKeyboardHook>();
- test_hook->LockAllKeys();
- parent_view_->event_handler()->scoped_keyboard_hook_ = std::move(test_hook);
-
- // These keys will be handled by the parent view and will not be sent through
- // the prehandler input pipeline.
- std::vector<ui::DomCode> dom_codes = {ui::DomCode::US_A, ui::DomCode::ENTER,
- ui::DomCode::TAB, ui::DomCode::ALT_LEFT,
- ui::DomCode::US_Z};
- MockRenderWidgetHostImpl* parent_host =
- static_cast<MockRenderWidgetHostImpl*>(parent_host_);
- for (ui::DomCode dom_code : dom_codes) {
- ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
- ui::DomCodeToUsLayoutKeyboardCode(dom_code),
- dom_code, ui::EF_NONE);
- parent_view_->OnKeyEvent(&key_event);
- const NativeWebKeyboardEvent* child_event =
- render_widget_host_delegate()->last_event();
- ASSERT_FALSE(child_event)
- << "Failed for DomCode: "
- << ui::KeycodeConverter::DomCodeToCodeString(dom_code);
- // Run the runloop to ensure input messages are dispatched. Otherwise the
- // result of GetAndResetDispatchedMessages() will not be valid.
- base::RunLoop().RunUntilIdle();
- auto child_events = GetAndResetDispatchedMessages();
- ASSERT_TRUE(child_events.empty())
- << "Failed for DomCode: "
- << ui::KeycodeConverter::DomCodeToCodeString(dom_code);
-
- const NativeWebKeyboardEvent* parent_event = delegates_[0]->last_event();
- ASSERT_FALSE(parent_event)
- << "Failed for DomCode: "
- << ui::KeycodeConverter::DomCodeToCodeString(dom_code);
- auto events = parent_host->input_handler()->GetAndResetDispatchedMessages();
- ASSERT_FALSE(events.empty());
- const NativeWebKeyboardEvent* native_key_event =
- static_cast<const NativeWebKeyboardEvent*>(
- events.back()->ToEvent()->Event()->web_event.get());
- ASSERT_TRUE(native_key_event)
- << "Failed for DomCode: "
- << ui::KeycodeConverter::DomCodeToCodeString(dom_code);
- ASSERT_EQ(key_event.key_code(), native_key_event->windows_key_code);
- ASSERT_EQ(ui::KeycodeConverter::DomCodeToNativeKeycode(key_event.code()),
- native_key_event->native_key_code);
- }
-}
-
TEST_F(RenderWidgetHostViewAuraTest, TimerBasedWheelEventPhaseInfo) {
view_->InitAsChild(nullptr);
view_->Show();
@@ -2657,14 +2620,14 @@ TEST_F(RenderWidgetHostViewAuraTest, CompositorViewportPixelSizeWithScale) {
view_->SetSize(gfx::Size(100, 100));
EXPECT_EQ("100x100", view_->GetCompositorViewportPixelSize().ToString());
EXPECT_EQ(1u, sink_->message_count());
- EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SynchronizeVisualProperties::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetMsg_SynchronizeVisualProperties::ID),
sink_->GetMessageAt(0)->type());
{
const IPC::Message* msg = sink_->GetMessageAt(0);
- EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SynchronizeVisualProperties::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetMsg_SynchronizeVisualProperties::ID),
msg->type());
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(msg, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(msg, &params);
EXPECT_EQ("100x100", std::get<0>(params).new_size.ToString()); // dip size
EXPECT_EQ("100x100",
std::get<0>(params)
@@ -2679,10 +2642,10 @@ TEST_F(RenderWidgetHostViewAuraTest, CompositorViewportPixelSizeWithScale) {
// Extra ScreenInfoChanged message for |parent_view_|.
// Changing the device scale factor triggers the
// RenderWidgetHostViewAura::OnDisplayMetricsChanged() observer callback,
- // which sends a ViewMsg_SynchronizeVisualProperties::ID message to the
+ // which sends a WidgetMsg_SynchronizeVisualProperties::ID message to the
// renderer.
EXPECT_EQ(1u, sink_->message_count());
- EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SynchronizeVisualProperties::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetMsg_SynchronizeVisualProperties::ID),
sink_->GetMessageAt(0)->type());
widget_host_->ResetSentVisualProperties();
@@ -2691,13 +2654,13 @@ TEST_F(RenderWidgetHostViewAuraTest, CompositorViewportPixelSizeWithScale) {
aura_test_helper_->test_screen()->SetDeviceScaleFactor(1.0f);
// Extra ScreenInfoChanged message for |parent_view_|.
EXPECT_EQ(1u, sink_->message_count());
- EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SynchronizeVisualProperties::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetMsg_SynchronizeVisualProperties::ID),
sink_->GetMessageAt(0)->type());
EXPECT_EQ("100x100", view_->GetCompositorViewportPixelSize().ToString());
}
// This test verifies that in AutoResize mode a new
-// ViewMsg_SynchronizeVisualProperties message is sent when ScreenInfo
+// WidgetMsg_SynchronizeVisualProperties message is sent when ScreenInfo
// changes and that message contains the latest ScreenInfo.
TEST_F(RenderWidgetHostViewAuraTest, AutoResizeWithScale) {
view_->InitAsChild(nullptr);
@@ -2714,10 +2677,10 @@ TEST_F(RenderWidgetHostViewAuraTest, AutoResizeWithScale) {
ASSERT_EQ(1u, sink_->message_count());
{
const IPC::Message* msg = sink_->GetMessageAt(0);
- EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SynchronizeVisualProperties::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetMsg_SynchronizeVisualProperties::ID),
msg->type());
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(msg, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(msg, &params);
VisualProperties visual_properties = std::get<0>(params);
EXPECT_EQ("50x50", visual_properties.min_size_for_auto_resize.ToString());
EXPECT_EQ("100x100", visual_properties.max_size_for_auto_resize.ToString());
@@ -2745,11 +2708,11 @@ TEST_F(RenderWidgetHostViewAuraTest, AutoResizeWithScale) {
{
// TODO(samans): There should be only one message in the sink, but some
// testers are seeing two (crrev.com/c/839580). Investigate why.
- const IPC::Message* msg =
- sink_->GetFirstMessageMatching(ViewMsg_SynchronizeVisualProperties::ID);
+ const IPC::Message* msg = sink_->GetFirstMessageMatching(
+ WidgetMsg_SynchronizeVisualProperties::ID);
ASSERT_TRUE(msg);
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(msg, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(msg, &params);
VisualProperties visual_properties = std::get<0>(params);
EXPECT_EQ("50x50", visual_properties.min_size_for_auto_resize.ToString());
EXPECT_EQ("100x100", visual_properties.max_size_for_auto_resize.ToString());
@@ -2762,7 +2725,7 @@ TEST_F(RenderWidgetHostViewAuraTest, AutoResizeWithScale) {
}
// This test verifies that in AutoResize mode a new
-// ViewMsg_SynchronizeVisualProperties message is sent when size changes.
+// WidgetMsg_SynchronizeVisualProperties message is sent when size changes.
TEST_F(RenderWidgetHostViewAuraTest, AutoResizeWithBrowserInitiatedResize) {
view_->InitAsChild(nullptr);
aura::client::ParentWindowWithContext(
@@ -2778,10 +2741,10 @@ TEST_F(RenderWidgetHostViewAuraTest, AutoResizeWithBrowserInitiatedResize) {
ASSERT_EQ(1u, sink_->message_count());
{
const IPC::Message* msg = sink_->GetMessageAt(0);
- EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SynchronizeVisualProperties::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetMsg_SynchronizeVisualProperties::ID),
msg->type());
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(msg, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(msg, &params);
VisualProperties visual_properties = std::get<0>(params);
EXPECT_EQ("50x50", visual_properties.min_size_for_auto_resize.ToString());
EXPECT_EQ("100x100", visual_properties.max_size_for_auto_resize.ToString());
@@ -2810,10 +2773,10 @@ TEST_F(RenderWidgetHostViewAuraTest, AutoResizeWithBrowserInitiatedResize) {
ASSERT_EQ(1u, sink_->message_count());
{
const IPC::Message* msg = sink_->GetMessageAt(0);
- EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SynchronizeVisualProperties::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetMsg_SynchronizeVisualProperties::ID),
msg->type());
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(msg, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(msg, &params);
VisualProperties visual_properties = std::get<0>(params);
EXPECT_EQ("50x50", visual_properties.min_size_for_auto_resize.ToString());
EXPECT_EQ("100x100", visual_properties.max_size_for_auto_resize.ToString());
@@ -3042,7 +3005,7 @@ viz::CompositorFrame MakeDelegatedFrame(float scale_factor,
// This test verifies that returned resources do not require a pending ack.
TEST_F(RenderWidgetHostViewAuraTest, ReturnedResources) {
// TODO: fix for mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
gfx::Size view_size(100, 100);
@@ -3076,7 +3039,7 @@ TEST_F(RenderWidgetHostViewAuraTest, TwoOutputSurfaces) {
// TODO(jonross): Delete this test once Viz launches as it will be obsolete.
// https://crbug.com/844469
if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
- features::IsUsingWindowService()) {
+ features::IsMultiProcessMash()) {
return;
}
@@ -3143,10 +3106,10 @@ TEST_F(RenderWidgetHostViewAuraTest, DISABLED_FullscreenResize) {
{
// 0 is CreatingNew message.
const IPC::Message* msg = sink_->GetMessageAt(0);
- EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SynchronizeVisualProperties::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetMsg_SynchronizeVisualProperties::ID),
msg->type());
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(msg, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(msg, &params);
EXPECT_EQ(
"0,0 800x600",
std::get<0>(params).screen_info.available_rect.ToString());
@@ -3171,10 +3134,10 @@ TEST_F(RenderWidgetHostViewAuraTest, DISABLED_FullscreenResize) {
EXPECT_EQ(1u, sink_->message_count());
{
const IPC::Message* msg = sink_->GetMessageAt(0);
- EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SynchronizeVisualProperties::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetMsg_SynchronizeVisualProperties::ID),
msg->type());
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(msg, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(msg, &params);
EXPECT_EQ(
"0,0 1600x1200",
std::get<0>(params).screen_info.available_rect.ToString());
@@ -3206,10 +3169,10 @@ TEST_F(RenderWidgetHostViewAuraTest, ZeroSizeStillGetsLocalSurfaceId) {
EXPECT_EQ(2u, sink_->message_count());
{
const IPC::Message* msg = sink_->GetMessageAt(1);
- EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SynchronizeVisualProperties::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetMsg_SynchronizeVisualProperties::ID),
msg->type());
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(msg, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(msg, &params);
EXPECT_EQ(frame_size.ToString(), std::get<0>(params).new_size.ToString());
ASSERT_TRUE(std::get<0>(params).local_surface_id.has_value());
EXPECT_TRUE(std::get<0>(params).local_surface_id->is_valid());
@@ -3218,7 +3181,7 @@ TEST_F(RenderWidgetHostViewAuraTest, ZeroSizeStillGetsLocalSurfaceId) {
TEST_F(RenderWidgetHostViewAuraTest, BackgroundColorMatchesCompositorFrame) {
// TODO: fix for mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
gfx::Size frame_size(100, 100);
@@ -3300,10 +3263,10 @@ TEST_F(RenderWidgetHostViewAuraTest, DISABLED_Resize) {
EXPECT_EQ(1u, sink_->message_count());
{
const IPC::Message* msg = sink_->GetMessageAt(0);
- EXPECT_EQ(static_cast<uint32_t>(ViewMsg_SynchronizeVisualProperties::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetMsg_SynchronizeVisualProperties::ID),
msg->type());
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(msg, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(msg, &params);
EXPECT_EQ(size2.ToString(), std::get<0>(params).new_size.ToString());
}
// Send resize ack to observe new Resize messages.
@@ -3356,10 +3319,10 @@ TEST_F(RenderWidgetHostViewAuraTest, DISABLED_Resize) {
for (uint32_t i = 0; i < sink_->message_count(); ++i) {
const IPC::Message* msg = sink_->GetMessageAt(i);
switch (msg->type()) {
- case ViewMsg_SynchronizeVisualProperties::ID: {
+ case WidgetMsg_SynchronizeVisualProperties::ID: {
EXPECT_FALSE(has_resize);
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(msg, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(msg, &params);
EXPECT_EQ(size3.ToString(), std::get<0>(params).new_size.ToString());
has_resize = true;
break;
@@ -3383,7 +3346,7 @@ TEST_F(RenderWidgetHostViewAuraTest, OutputSurfaceIdChange) {
// TODO(jonross): Delete this test once Viz launches as it will be obsolete.
// https://crbug.com/844469
if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
- features::IsUsingWindowService()) {
+ features::IsMultiProcessMash()) {
return;
}
@@ -3444,7 +3407,7 @@ TEST_F(RenderWidgetHostViewAuraTest, OutputSurfaceIdChange) {
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
DropFallbackWhenHidden) {
// Early out because DelegatedFrameHost is not used in mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
view_->InitAsChild(nullptr);
@@ -3468,11 +3431,10 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
EXPECT_FALSE(view_->HasFallbackSurface());
}
-// This test verifies that the primary SurfaceId is populated on resize and
-// the fallback SurfaceId is populated in OnFirstSurfaceActivation.
+// This test verifies that the primary SurfaceId is populated on resize.
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest, SurfaceChanges) {
// Early out because DelegatedFrameHost is not used in mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
view_->InitAsChild(nullptr);
@@ -3485,25 +3447,8 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest, SurfaceChanges) {
view_->SetSize(gfx::Size(300, 300));
ASSERT_TRUE(view_->HasPrimarySurface());
EXPECT_EQ(gfx::Size(300, 300), view_->window_->layer()->size());
- EXPECT_FALSE(view_->HasFallbackSurface());
EXPECT_EQ(gfx::Size(300, 300),
view_->delegated_frame_host_->CurrentFrameSizeInDipForTesting());
-
- // Resizing should update the primary SurfaceId.
- view_->SetSize(gfx::Size(400, 400));
- EXPECT_EQ(gfx::Size(400, 400), view_->window_->layer()->size());
- EXPECT_EQ(nullptr, view_->window_->layer()->GetFallbackSurfaceId());
- EXPECT_EQ(gfx::Size(400, 400),
- view_->delegated_frame_host_->CurrentFrameSizeInDipForTesting());
-
- // Fallback SurfaceId should be updated in OnFirstSurfaceActivation.
- // Submitting a CompositorFrame should update the fallback SurfaceId
- viz::SurfaceId surface_id(view_->GetFrameSinkId(),
- view_->GetLocalSurfaceId());
- view_->delegated_frame_host_->OnFirstSurfaceActivation(
- viz::SurfaceInfo(surface_id, 1.f, gfx::Size(400, 400)));
- EXPECT_EQ(gfx::Size(400, 400), view_->window_->layer()->size());
- EXPECT_EQ(surface_id, *view_->window_->layer()->GetFallbackSurfaceId());
}
// This test verifies that the primary SurfaceId is updated on device scale
@@ -3511,7 +3456,7 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest, SurfaceChanges) {
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
DeviceScaleFactorChanges) {
// TODO: fix for mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
view_->InitAsChild(nullptr);
@@ -3541,7 +3486,7 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
// TODO(jonross): Delete this test once Viz launches as it will be obsolete.
// https://crbug.com/844469
if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
- features::IsUsingWindowService()) {
+ features::IsMultiProcessMash()) {
return;
}
@@ -3576,7 +3521,7 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
DiscardDelegatedFrames) {
// Early out because DelegatedFrameHost is not used in mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
view_->InitAsChild(nullptr);
@@ -3612,40 +3557,41 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
parent_view_->GetNativeView()->GetRootWindow(), gfx::Rect());
views[i]->SetSize(view_rect.size());
ASSERT_TRUE(views[i]->HasPrimarySurface());
+ ASSERT_FALSE(views[i]->HasSavedFrame());
}
// Make each renderer visible, and swap a frame on it, then make it invisible.
for (size_t i = 0; i < renderer_count; ++i) {
views[i]->Show();
ASSERT_TRUE(views[i]->HasPrimarySurface());
- ASSERT_FALSE(views[i]->HasFallbackSurface());
+ ASSERT_FALSE(views[i]->HasSavedFrame());
viz::SurfaceId surface_id(views[i]->GetFrameSinkId(),
views[i]->GetLocalSurfaceId());
views[i]->delegated_frame_host_->OnFirstSurfaceActivation(
viz::SurfaceInfo(surface_id, 1.f, frame_size));
- ASSERT_TRUE(views[i]->HasPrimarySurface());
- EXPECT_TRUE(views[i]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[i]);
views[i]->Hide();
}
// There should be max_renderer_frames with a frame in it, and one without it.
// Since the logic is LRU eviction, the first one should be without.
- EXPECT_FALSE(views[0]->HasFallbackSurface());
+ EXPECT_EVICTED(views[0]);
for (size_t i = 1; i < renderer_count; ++i)
- EXPECT_TRUE(views[i]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[i]);
// LRU renderer is [0], make it visible, it shouldn't evict anything yet.
views[0]->Show();
- EXPECT_FALSE(views[0]->HasFallbackSurface());
- EXPECT_TRUE(views[1]->HasFallbackSurface());
+ EXPECT_TRUE(views[0]->HasPrimarySurface());
+ EXPECT_FALSE(views[0]->HasSavedFrame());
+ EXPECT_HAS_FRAME(views[1]);
// Swap a frame on it, it should evict the next LRU [1].
viz::SurfaceId surface_id0(views[0]->GetFrameSinkId(),
views[0]->GetLocalSurfaceId());
views[0]->delegated_frame_host_->OnFirstSurfaceActivation(
viz::SurfaceInfo(surface_id0, 1.f, frame_size));
- EXPECT_TRUE(views[0]->HasFallbackSurface());
- EXPECT_FALSE(views[1]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[0]);
+ EXPECT_EVICTED(views[1]);
views[0]->Hide();
// LRU renderer is [1], which is still hidden. Showing it and submitting a
@@ -3655,11 +3601,11 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
views[1]->GetLocalSurfaceId());
views[1]->delegated_frame_host_->OnFirstSurfaceActivation(
viz::SurfaceInfo(surface_id1, 1.f, frame_size));
- EXPECT_TRUE(views[0]->HasFallbackSurface());
- EXPECT_TRUE(views[1]->HasFallbackSurface());
- EXPECT_FALSE(views[2]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[0]);
+ EXPECT_HAS_FRAME(views[1]);
+ EXPECT_EVICTED(views[2]);
for (size_t i = 3; i < renderer_count; ++i)
- EXPECT_TRUE(views[i]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[i]);
// Make all renderers but [0] visible and swap a frame on them, keep [0]
// hidden, it becomes the LRU.
@@ -3671,14 +3617,14 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
views[i]->GetLocalSurfaceId());
views[i]->delegated_frame_host_->OnFirstSurfaceActivation(
viz::SurfaceInfo(surface_id, 1.f, frame_size));
- EXPECT_TRUE(views[i]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[i]);
}
- EXPECT_FALSE(views[0]->HasFallbackSurface());
+ EXPECT_EVICTED(views[0]);
// Swap a frame on [0], it should be evicted immediately.
views[0]->delegated_frame_host_->OnFirstSurfaceActivation(
viz::SurfaceInfo(surface_id0, 1.f, frame_size));
- EXPECT_FALSE(views[0]->HasFallbackSurface());
+ EXPECT_EVICTED(views[0]);
// Make [0] visible, and swap a frame on it. Nothing should be evicted
// although we're above the limit.
@@ -3686,25 +3632,26 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
views[0]->delegated_frame_host_->OnFirstSurfaceActivation(
viz::SurfaceInfo(surface_id0, 1.f, frame_size));
for (size_t i = 0; i < renderer_count; ++i)
- EXPECT_TRUE(views[i]->HasFallbackSurface()) << i;
+ EXPECT_HAS_FRAME(views[i]);
// Make [0] hidden, it should evict its frame.
views[0]->Hide();
- EXPECT_FALSE(views[0]->HasFallbackSurface());
+ EXPECT_EVICTED(views[0]);
// Make [0] visible, don't give it a frame, it should be waiting.
views[0]->Show();
// Make [0] hidden, it should stop waiting.
views[0]->Hide();
- // Make [1] hidden, resize it. It should drop its frame.
+ // Make [1] hidden, resize it. It should advance its fallback.
views[1]->Hide();
- EXPECT_TRUE(views[1]->HasFallbackSurface());
gfx::Size size2(200, 200);
views[1]->SetSize(size2);
- EXPECT_FALSE(views[1]->HasFallbackSurface());
// Show it, it should block until we give it a frame.
views[1]->Show();
+ ASSERT_TRUE(views[1]->window_->layer()->GetFallbackSurfaceId());
+ EXPECT_EQ(*views[1]->window_->layer()->GetFallbackSurfaceId(),
+ *views[1]->window_->layer()->GetPrimarySurfaceId());
views[1]->delegated_frame_host_->OnFirstSurfaceActivation(
viz::SurfaceInfo(surface_id1, 1.f, frame_size));
@@ -3716,7 +3663,7 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
// Early out because DelegatedFrameHost is not used in mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
view_->InitAsChild(nullptr);
@@ -3758,12 +3705,12 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
views[i]->GetLocalSurfaceId());
views[i]->delegated_frame_host_->OnFirstSurfaceActivation(
viz::SurfaceInfo(surface_id, 1.f, frame_size));
- EXPECT_TRUE(views[i]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[i]);
}
// If we hide [0], then [0] should be evicted.
views[0]->Hide();
- EXPECT_FALSE(views[0]->HasFallbackSurface());
+ EXPECT_EVICTED(views[0]);
// If we lock [0] before hiding it, then [0] should not be evicted.
views[0]->Show();
@@ -3771,14 +3718,14 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
views[0]->GetLocalSurfaceId());
views[0]->delegated_frame_host_->OnFirstSurfaceActivation(
viz::SurfaceInfo(surface_id, 1.f, frame_size));
- EXPECT_TRUE(views[0]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[0]);
views[0]->GetDelegatedFrameHost()->LockResources();
views[0]->Hide();
- EXPECT_TRUE(views[0]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[0]);
// If we unlock [0] now, then [0] should be evicted.
views[0]->GetDelegatedFrameHost()->UnlockResources();
- EXPECT_FALSE(views[0]->HasFallbackSurface());
+ EXPECT_EVICTED(views[0]);
for (size_t i = 0; i < renderer_count; ++i) {
views[i]->Destroy();
@@ -3790,7 +3737,7 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
// only applies to ChromeOS.
TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithMemoryPressure) {
// Early out because DelegatedFrameHost is not used in mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
view_->InitAsChild(nullptr);
@@ -3837,27 +3784,27 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithMemoryPressure) {
kArbitraryLocalSurfaceId);
views[i]->delegated_frame_host_->OnFirstSurfaceActivation(
viz::SurfaceInfo(surface_id, 1.f, frame_size));
- EXPECT_TRUE(views[i]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[i]);
}
// If we hide one, it should not get evicted.
views[0]->Hide();
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(views[0]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[0]);
// Using a lesser memory pressure event however, should evict.
SimulateMemoryPressure(
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(views[0]->HasFallbackSurface());
+ EXPECT_EVICTED(views[0]);
// Check the same for a higher pressure event.
views[1]->Hide();
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(views[1]->HasFallbackSurface());
+ EXPECT_HAS_FRAME(views[1]);
SimulateMemoryPressure(
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(views[1]->HasFallbackSurface());
+ EXPECT_EVICTED(views[1]);
for (size_t i = 0; i < renderer_count; ++i) {
views[i]->Destroy();
@@ -3897,7 +3844,7 @@ TEST_F(RenderWidgetHostViewAuraTest, ForwardsBeginFrameAcks) {
// TODO(jonross): Delete this test once Viz launches as it will be obsolete.
// https://crbug.com/844469
if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
- features::IsUsingWindowService()) {
+ features::IsMultiProcessMash()) {
return;
}
@@ -3964,11 +3911,11 @@ TEST_F(RenderWidgetHostViewAuraTest, VisibleViewportTest) {
EXPECT_EQ(60, view_->GetVisibleViewportSize().height());
const IPC::Message* message =
- sink_->GetFirstMessageMatching(ViewMsg_SynchronizeVisualProperties::ID);
+ sink_->GetFirstMessageMatching(WidgetMsg_SynchronizeVisualProperties::ID);
ASSERT_TRUE(message != nullptr);
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(message, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(message, &params);
EXPECT_EQ(60, std::get<0>(params).visible_viewport_size.height());
}
@@ -5527,7 +5474,8 @@ TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) {
events[0]->ToEvent()->Event()->web_event.get());
// Check if scroll is caused when ctrl-scroll is generated from
// mouse wheel event.
- EXPECT_FALSE(WebInputEventTraits::CanCauseScroll(*wheel_event));
+ EXPECT_EQ(blink::WebMouseWheelEvent::EventAction::kPageZoom,
+ wheel_event->event_action);
// Ack'ing the outstanding event should flush the pending event queue.
events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
@@ -5551,7 +5499,8 @@ TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) {
// mouse wheel event.
wheel_event = static_cast<const WebMouseWheelEvent*>(
events[1]->ToEvent()->Event()->web_event.get());
- EXPECT_TRUE(WebInputEventTraits::CanCauseScroll(*wheel_event));
+ EXPECT_NE(blink::WebMouseWheelEvent::EventAction::kPageZoom,
+ wheel_event->event_action);
events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
@@ -5572,7 +5521,8 @@ TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) {
// from scroll event.
wheel_event = static_cast<const WebMouseWheelEvent*>(
events[1]->ToEvent()->Event()->web_event.get());
- EXPECT_TRUE(WebInputEventTraits::CanCauseScroll(*wheel_event));
+ EXPECT_NE(blink::WebMouseWheelEvent::EventAction::kPageZoom,
+ wheel_event->event_action);
}
// Ensures that the mapping from ui::TouchEvent to blink::WebTouchEvent doesn't
@@ -5838,7 +5788,7 @@ TEST_F(RenderWidgetHostViewAuraTest, HitTestRegionListSubmitted) {
// TODO(jonross): Delete this test once Viz launches as it will be obsolete.
// https://crbug.com/844469
if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
- features::IsUsingWindowService()) {
+ features::IsMultiProcessMash()) {
return;
}
@@ -5880,7 +5830,7 @@ TEST_F(RenderWidgetHostViewAuraTest, HitTestRegionListSubmitted) {
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
NewContentRenderingTimeout) {
// TODO: fix for mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
constexpr base::TimeDelta kTimeout = base::TimeDelta::FromMicroseconds(10);
@@ -5935,7 +5885,7 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
AllocateLocalSurfaceIdOnEviction) {
// TODO: fix for mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
view_->InitAsChild(nullptr);
@@ -5958,7 +5908,7 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
DropFallbackIfResizedWhileHidden) {
// Early out because DelegatedFrameHost is not used in mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
view_->InitAsChild(nullptr);
@@ -5969,11 +5919,12 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
viz::LocalSurfaceId id1 = view_->GetLocalSurfaceId();
view_->delegated_frame_host_->OnFirstSurfaceActivation(viz::SurfaceInfo(
viz::SurfaceId(view_->GetFrameSinkId(), id1), 1, gfx::Size(20, 20)));
- EXPECT_TRUE(view_->window_->layer()->GetFallbackSurfaceId()->is_valid());
view_->Hide();
view_->SetSize(gfx::Size(54, 32));
view_->Show();
- EXPECT_EQ(nullptr, view_->window_->layer()->GetFallbackSurfaceId());
+ ASSERT_TRUE(view_->window_->layer()->GetFallbackSurfaceId());
+ EXPECT_EQ(*view_->window_->layer()->GetFallbackSurfaceId(),
+ *view_->window_->layer()->GetPrimarySurfaceId());
}
// If a tab is hidden and shown without being resized in the meantime, the
@@ -5981,7 +5932,7 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
DontDropFallbackIfNotResizedWhileHidden) {
// Early out because DelegatedFrameHost is not used in mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
view_->InitAsChild(nullptr);
@@ -5990,12 +5941,15 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
gfx::Rect());
view_->Show();
viz::LocalSurfaceId id1 = view_->GetLocalSurfaceId();
- view_->delegated_frame_host_->OnFirstSurfaceActivation(viz::SurfaceInfo(
- viz::SurfaceId(view_->GetFrameSinkId(), id1), 1, gfx::Size(20, 20)));
- EXPECT_TRUE(view_->window_->layer()->GetFallbackSurfaceId()->is_valid());
+ // Force fallback being set.
+ view_->DidNavigate();
+ view_->ResetFallbackToFirstNavigationSurface();
+ ASSERT_TRUE(view_->window_->layer()->GetFallbackSurfaceId());
+ viz::SurfaceId fallback = *view_->window_->layer()->GetFallbackSurfaceId();
view_->Hide();
view_->Show();
- EXPECT_TRUE(view_->window_->layer()->GetFallbackSurfaceId()->is_valid());
+ ASSERT_TRUE(view_->window_->layer()->GetFallbackSurfaceId());
+ EXPECT_EQ(fallback, *view_->window_->layer()->GetPrimarySurfaceId());
}
// Check that TakeFallbackContentFrom() copies the fallback SurfaceId and
@@ -6003,7 +5957,7 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
TakeFallbackContent) {
// Early out because DelegatedFrameHost is not used in mash.
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
// Initialize the first view.
@@ -6020,16 +5974,10 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
view2->GetNativeView(), parent_view_->GetNativeView()->GetRootWindow(),
gfx::Rect());
- // Set fallback for the first view.
- viz::LocalSurfaceId id = view_->GetLocalSurfaceId();
- view_->delegated_frame_host_->OnFirstSurfaceActivation(viz::SurfaceInfo(
- viz::SurfaceId(view_->GetFrameSinkId(), id), 1, gfx::Size(20, 20)));
- EXPECT_TRUE(view_->window_->layer()->GetFallbackSurfaceId()->is_valid());
-
- // Call TakeFallbackContentFrom(). The second view should now have the same
- // fallback as the first view.
+ // Call TakeFallbackContentFrom(). The second view should obtain a fallback
+ // from the first view.
view2->TakeFallbackContentFrom(view_);
- EXPECT_EQ(*view_->window_->layer()->GetFallbackSurfaceId(),
+ EXPECT_EQ(view_->window_->layer()->GetPrimarySurfaceId()->ToSmallestId(),
*view2->window_->layer()->GetFallbackSurfaceId());
DestroyView(view2);
@@ -6430,7 +6378,7 @@ TEST_F(InputMethodResultAuraTest, ChangeTextDirectionAndLayoutAlignment) {
ActivateViewForTextInputManager(views_[index], ui::TEXT_INPUT_TYPE_TEXT);
EXPECT_TRUE(!!RunAndReturnIPCSent(ime_finish_session_call,
processes_[index],
- ViewMsg_SetTextDirection::ID));
+ WidgetMsg_SetTextDirection::ID));
}
}
@@ -6465,7 +6413,7 @@ class InputMethodStateAuraTest : public InputMethodAuraTestBase {
// This test is for caret bounds which are calculated based on the tracked value
// for selection bounds.
TEST_F(InputMethodStateAuraTest, GetCaretBounds) {
- ViewHostMsg_SelectionBounds_Params params;
+ WidgetHostMsg_SelectionBounds_Params params;
params.is_anchor_first = true;
params.anchor_dir = blink::kWebTextDirectionLeftToRight;
params.focus_dir = blink::kWebTextDirectionLeftToRight;
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_base.cc b/chromium/content/browser/renderer_host/render_widget_host_view_base.cc
index fae4c74c977..e155153ec1e 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -16,6 +16,7 @@
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
+#include "content/browser/renderer_host/delegated_frame_host.h"
#include "content/browser/renderer_host/display_util.h"
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
#include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
@@ -45,16 +46,8 @@
namespace content {
RenderWidgetHostViewBase::RenderWidgetHostViewBase(RenderWidgetHost* host)
- : host_(RenderWidgetHostImpl::From(host)),
- is_fullscreen_(false),
- popup_type_(blink::kWebPopupTypeNone),
- current_device_scale_factor_(0),
- current_display_rotation_(display::Display::ROTATE_0),
- text_input_manager_(nullptr),
- web_contents_accessibility_(nullptr),
- is_currently_scrolling_viewport_(false),
- use_viz_hit_test_(features::IsVizHitTestingEnabled()),
- renderer_frame_number_(0),
+ : use_viz_hit_test_(features::IsVizHitTestingEnabled()),
+ host_(RenderWidgetHostImpl::From(host)),
weak_factory_(this) {
host_->render_frame_metadata_provider()->AddObserver(this);
}
@@ -132,7 +125,7 @@ gfx::Size RenderWidgetHostViewBase::GetCompositorViewportPixelSize() const {
GetDeviceScaleFactor());
}
-bool RenderWidgetHostViewBase::DoBrowserControlsShrinkBlinkSize() const {
+bool RenderWidgetHostViewBase::DoBrowserControlsShrinkRendererSize() const {
return false;
}
@@ -141,7 +134,7 @@ float RenderWidgetHostViewBase::GetTopControlsHeight() const {
}
void RenderWidgetHostViewBase::SelectionBoundsChanged(
- const ViewHostMsg_SelectionBounds_Params& params) {
+ const WidgetHostMsg_SelectionBounds_Params& params) {
#if !defined(OS_ANDROID)
if (GetTextInputManager())
GetTextInputManager()->SelectionBoundsChanged(this, params);
@@ -203,6 +196,87 @@ bool RenderWidgetHostViewBase::IsSurfaceAvailableForCopy() const {
return false;
}
+void RenderWidgetHostViewBase::CopyMainAndPopupFromSurface(
+ base::WeakPtr<RenderWidgetHostImpl> main_host,
+ base::WeakPtr<DelegatedFrameHost> main_frame_host,
+ base::WeakPtr<RenderWidgetHostImpl> popup_host,
+ base::WeakPtr<DelegatedFrameHost> popup_frame_host,
+ const gfx::Rect& src_subrect,
+ const gfx::Size& dst_size,
+ float scale_factor,
+ base::OnceCallback<void(const SkBitmap&)> callback) {
+ if (!main_host || !main_frame_host)
+ return;
+
+#if defined(OS_ANDROID)
+ NOTREACHED()
+ << "RenderWidgetHostViewAndroid::CopyFromSurface calls "
+ "DelegatedFrameHostAndroid::CopyFromCompositingSurface directly, "
+ "and popups are not supported.";
+ return;
+#else
+ if (!popup_host || !popup_frame_host) {
+ // No popup - just call CopyFromCompositingSurface once.
+ main_frame_host->CopyFromCompositingSurface(src_subrect, dst_size,
+ std::move(callback));
+ return;
+ }
+
+ // First locate the popup relative to the main page, in DIPs
+ const gfx::Point parent_location =
+ main_host->GetView()->GetBoundsInRootWindow().origin();
+ const gfx::Point popup_location =
+ popup_host->GetView()->GetBoundsInRootWindow().origin();
+ const gfx::Point offset_dips =
+ PointAtOffsetFromOrigin(popup_location - parent_location);
+ const gfx::Vector2d offset_physical =
+ ScaleToFlooredPoint(offset_dips, scale_factor).OffsetFromOrigin();
+
+ // Queue up the request for the MAIN frame image first, but with a
+ // callback that launches a second request for the popup image.
+ // 1. Call CopyFromCompositingSurface for the main frame, with callback
+ // |main_image_done_callback|. Inside |main_image_done_callback|:
+ // a. Call CopyFromCompositingSurface again, this time on the popup
+ // frame. For this call, build a new callback, |popup_done_callback|,
+ // which:
+ // i. Takes the main image as a parameter, combines the main image with
+ // the just-acquired popup image, and then calls the original
+ // (outer) callback with the combined image.
+ auto main_image_done_callback = base::BindOnce(
+ [](base::OnceCallback<void(const SkBitmap&)> final_callback,
+ const gfx::Vector2d offset,
+ base::WeakPtr<DelegatedFrameHost> popup_frame_host,
+ const gfx::Rect src_subrect, const gfx::Size dst_size,
+ const SkBitmap& main_image) {
+ if (!popup_frame_host)
+ return;
+
+ // Build a new callback that actually combines images.
+ auto popup_done_callback = base::BindOnce(
+ [](base::OnceCallback<void(const SkBitmap&)> final_callback,
+ const gfx::Vector2d offset, const SkBitmap& main_image,
+ const SkBitmap& popup_image) {
+ // Draw popup_image into main_image.
+ SkCanvas canvas(main_image);
+ canvas.drawBitmap(popup_image, offset.x(), offset.y());
+ std::move(final_callback).Run(main_image);
+ },
+ std::move(final_callback), offset, std::move(main_image));
+
+ // Second, request the popup image.
+ gfx::Rect popup_subrect(src_subrect - offset);
+ popup_frame_host->CopyFromCompositingSurface(
+ popup_subrect, dst_size, std::move(popup_done_callback));
+ },
+ std::move(callback), offset_physical, popup_frame_host, src_subrect,
+ dst_size);
+
+ // Request the main image (happens first).
+ main_frame_host->CopyFromCompositingSurface(
+ src_subrect, dst_size, std::move(main_image_done_callback));
+#endif
+}
+
void RenderWidgetHostViewBase::CopyFromSurface(
const gfx::Rect& src_rect,
const gfx::Size& output_size,
@@ -361,12 +435,12 @@ bool RenderWidgetHostViewBase::HasFallbackSurface() const {
return false;
}
-void RenderWidgetHostViewBase::SetPopupType(blink::WebPopupType popup_type) {
- popup_type_ = popup_type;
+void RenderWidgetHostViewBase::SetWidgetType(WidgetType widget_type) {
+ widget_type_ = widget_type;
}
-blink::WebPopupType RenderWidgetHostViewBase::GetPopupType() {
- return popup_type_;
+WidgetType RenderWidgetHostViewBase::GetWidgetType() {
+ return widget_type_;
}
BrowserAccessibilityManager*
@@ -811,6 +885,8 @@ void RenderWidgetHostViewBase::DidNavigate() {
host()->SynchronizeVisualProperties();
}
+// TODO(wjmaclean): Would it simplify this function if we re-implemented it
+// using GetTransformToViewCoordSpace()?
bool RenderWidgetHostViewBase::TransformPointToTargetCoordSpace(
RenderWidgetHostViewBase* original_view,
RenderWidgetHostViewBase* target_view,
@@ -866,6 +942,64 @@ bool RenderWidgetHostViewBase::TransformPointToTargetCoordSpace(
return true;
}
+bool RenderWidgetHostViewBase::GetTransformToViewCoordSpace(
+ RenderWidgetHostViewBase* target_view,
+ gfx::Transform* transform) {
+ DCHECK(transform);
+ if (target_view == this) {
+ transform->MakeIdentity();
+ return true;
+ }
+
+ if (!use_viz_hit_test_)
+ return false;
+ viz::FrameSinkId root_frame_sink_id = GetRootFrameSinkId();
+ if (!root_frame_sink_id.is_valid())
+ return false;
+
+ const auto& display_hit_test_query_map =
+ GetHostFrameSinkManager()->display_hit_test_query();
+ const auto iter = display_hit_test_query_map.find(root_frame_sink_id);
+ if (iter == display_hit_test_query_map.end())
+ return false;
+ viz::HitTestQuery* query = iter->second.get();
+
+ gfx::Transform transform_this_to_root;
+ if (GetFrameSinkId() != root_frame_sink_id) {
+ gfx::Transform transform_root_to_this;
+ if (!query->GetTransformToTarget(GetFrameSinkId(), &transform_root_to_this))
+ return false;
+ if (!transform_root_to_this.GetInverse(&transform_this_to_root))
+ return false;
+ }
+ gfx::Transform transform_root_to_target;
+ if (!query->GetTransformToTarget(target_view->GetFrameSinkId(),
+ &transform_root_to_target)) {
+ return false;
+ }
+
+ // TODO(wjmaclean): In TransformPointToTargetCoordSpace the device scale
+ // factor is taken from the original view ... does that matter? Presumably
+ // all the views have the same dsf.
+ float device_scale_factor = GetDeviceScaleFactor();
+ gfx::Transform transform_to_pixel;
+ transform_to_pixel.Scale(device_scale_factor, device_scale_factor);
+ gfx::Transform transform_from_pixel;
+ transform_from_pixel.Scale(1.f / device_scale_factor,
+ 1.f / device_scale_factor);
+
+ // Note: gfx::Transform includes optimizations to early-out for scale = 1 or
+ // concatenating an identity matrix, so we don't add those checks here.
+ transform->MakeIdentity();
+
+ transform->ConcatTransform(transform_to_pixel);
+ transform->ConcatTransform(transform_this_to_root);
+ transform->ConcatTransform(transform_root_to_target);
+ transform->ConcatTransform(transform_from_pixel);
+
+ return true;
+}
+
bool RenderWidgetHostViewBase::TransformPointToLocalCoordSpaceViz(
const gfx::PointF& point,
const viz::SurfaceId& original_surface,
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_base.h b/chromium/content/browser/renderer_host/render_widget_host_view_base.h
index 08454f68a01..c48b0aa86d8 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_base.h
@@ -27,11 +27,11 @@
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/common/input_event_ack_state.h"
#include "content/public/common/screen_info.h"
+#include "content/public/common/widget_type.h"
#include "ipc/ipc_listener.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
#include "services/viz/public/interfaces/hit_test/hit_test_region_list.mojom.h"
#include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h"
-#include "third_party/blink/public/web/web_popup_type.h"
#include "third_party/blink/public/web/web_text_direction.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "ui/accessibility/ax_tree_id_registry.h"
@@ -49,7 +49,7 @@
#include "services/ws/public/mojom/window_tree.mojom.h"
#endif
-struct ViewHostMsg_SelectionBounds_Params;
+struct WidgetHostMsg_SelectionBounds_Params;
namespace base {
class UnguessableToken;
@@ -88,6 +88,7 @@ class TextInputManager;
class TouchSelectionControllerClientManager;
class WebContentsAccessibility;
class WebCursor;
+class DelegatedFrameHost;
struct TextInputState;
// Basic implementation shared by concrete RenderWidgetHostView subclasses.
@@ -162,9 +163,19 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
void OnLocalSurfaceIdChanged(
const cc::RenderFrameMetadata& metadata) override;
- void SetPopupType(blink::WebPopupType popup_type);
+ static void CopyMainAndPopupFromSurface(
+ base::WeakPtr<RenderWidgetHostImpl> main_host,
+ base::WeakPtr<DelegatedFrameHost> main_frame_host,
+ base::WeakPtr<RenderWidgetHostImpl> popup_host,
+ base::WeakPtr<DelegatedFrameHost> popup_frame_host,
+ const gfx::Rect& src_subrect,
+ const gfx::Size& dst_size,
+ float scale_factor,
+ base::OnceCallback<void(const SkBitmap&)> callback);
- blink::WebPopupType GetPopupType();
+ void SetWidgetType(WidgetType widget_type);
+
+ WidgetType GetWidgetType();
// Return a value that is incremented each time the renderer swaps a new frame
// to the view.
@@ -218,9 +229,9 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// The size of the view's backing surface in non-DPI-adjusted pixels.
virtual gfx::Size GetCompositorViewportPixelSize() const;
- // Whether or not Blink's viewport size should be shrunk by the height of the
- // URL-bar.
- virtual bool DoBrowserControlsShrinkBlinkSize() const;
+ // Whether or not the renderer's viewport size should be shrunk by the height
+ // of the URL-bar.
+ virtual bool DoBrowserControlsShrinkRendererSize() const;
// The height of the URL-bar browser controls.
virtual float GetTopControlsHeight() const;
@@ -269,7 +280,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
virtual gfx::Point AccessibilityOriginInScreen(const gfx::Rect& bounds);
virtual gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget();
virtual gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible();
- virtual void SetMainFrameAXTreeID(ui::AXTreeIDRegistry::AXTreeID id) {}
+ virtual void SetMainFrameAXTreeID(ui::AXTreeID id) {}
// Informs that the focused DOM node has changed.
virtual void FocusedNodeChanged(bool is_editable_node,
const gfx::Rect& node_bounds_in_screen) {}
@@ -391,6 +402,18 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
gfx::PointF* transformed_point,
viz::EventSource source = viz::EventSource::ANY);
+ // On success, returns true and modifies |*transform| to represent the
+ // transformation mapping a point in the coordinate space of this view
+ // into the coordinate space of the target view.
+ // On Failure, returns false, and leaves |*transform| unchanged.
+ // This function will fail if viz hit testing is not enabled, or if either
+ // this view or the target view has no current FrameSinkId. The latter may
+ // happen if either view is not currently visible in the viewport.
+ // This function is useful if there are multiple points to transform between
+ // the same two views. |target_view| must be non-null.
+ bool GetTransformToViewCoordSpace(RenderWidgetHostViewBase* target_view,
+ gfx::Transform* transform);
+
// TODO(kenrb, wjmaclean): This is a temporary subclass identifier for
// RenderWidgetHostViewGuests that is needed for special treatment during
// input event routing. It can be removed either when RWHVGuests properly
@@ -450,7 +473,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// RenderWidget's window's origin. Focus and anchor bound are represented as
// gfx::Rect.
virtual void SelectionBoundsChanged(
- const ViewHostMsg_SelectionBounds_Params& params);
+ const WidgetHostMsg_SelectionBounds_Params& params);
// Updates the range of the marked text in an IME composition.
virtual void ImeCompositionRangeChanged(
@@ -613,16 +636,18 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
virtual bool HasFallbackSurface() const;
+ // Cached bool to test if the VizHitTesting feature is enabled.
+ const bool use_viz_hit_test_;
+
// The model object. Members will become private when
// RenderWidgetHostViewGuest is removed.
RenderWidgetHostImpl* host_;
// Is this a fullscreen view?
- bool is_fullscreen_;
+ bool is_fullscreen_ = false;
- // Whether this view is a popup and what kind of popup it is (select,
- // autofill...).
- blink::WebPopupType popup_type_;
+ // Whether this view is a frame or a popup.
+ WidgetType widget_type_ = WidgetType::kFrame;
// Indicates whether keyboard lock is active for this view.
bool keyboard_locked_ = false;
@@ -632,19 +657,20 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
bool is_scroll_offset_at_top_ = true;
// The scale factor of the display the renderer is currently on.
- float current_device_scale_factor_;
+ float current_device_scale_factor_ = 0;
// The color space of the display the renderer is currently on.
gfx::ColorSpace current_display_color_space_;
// The orientation of the display the renderer is currently on.
- display::Display::Rotation current_display_rotation_;
+ display::Display::Rotation current_display_rotation_ =
+ display::Display::ROTATE_0;
// A reference to current TextInputManager instance this RWHV is registered
// with. This is initially nullptr until the first time the view calls
// GetTextInputManager(). It also becomes nullptr when TextInputManager is
// destroyed before the RWHV is destroyed.
- TextInputManager* text_input_manager_;
+ TextInputManager* text_input_manager_ = nullptr;
// The background color used in the current renderer.
base::Optional<SkColor> content_background_color_;
@@ -653,11 +679,9 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// |content_background_color|.
base::Optional<SkColor> default_background_color_;
- WebContentsAccessibility* web_contents_accessibility_;
-
- bool is_currently_scrolling_viewport_;
+ WebContentsAccessibility* web_contents_accessibility_ = nullptr;
- bool use_viz_hit_test_ = false;
+ bool is_currently_scrolling_viewport_ = false;
private:
void SynchronizeVisualProperties();
@@ -693,7 +717,7 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
gfx::Rect current_display_area_;
- uint32_t renderer_frame_number_;
+ uint32_t renderer_frame_number_ = 0;
base::ObserverList<RenderWidgetHostViewBaseObserver>::Unchecked observers_;
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc
index ef607a087cd..99d980ac4ca 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -36,7 +36,7 @@
#include "content/browser/renderer_host/render_widget_host_view_event_handler.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "content/common/text_input_state.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/browser/guest_mode.h"
#include "content/public/browser/render_process_host.h"
#include "gpu/ipc/common/gpu_messages.h"
@@ -74,7 +74,7 @@ RenderWidgetHostViewChildFrame::RenderWidgetHostViewChildFrame(
enable_viz_(
base::FeatureList::IsEnabled(features::kVizDisplayCompositor)),
weak_factory_(this) {
- if (features::IsUsingWindowService()) {
+ if (features::IsMultiProcessMash()) {
// In Mus the RenderFrameProxy will eventually assign a viz::FrameSinkId
// until then set ours invalid, as operations using it will be disregarded.
frame_sink_id_ = viz::FrameSinkId();
@@ -93,7 +93,7 @@ RenderWidgetHostViewChildFrame::~RenderWidgetHostViewChildFrame() {
if (frame_connector_)
DetachFromTouchSelectionClientManagerIfNecessary();
- if (!features::IsUsingWindowService()) {
+ if (!features::IsMultiProcessMash()) {
ResetCompositorFrameSinkSupport();
if (GetHostFrameSinkManager())
GetHostFrameSinkManager()->InvalidateFrameSinkId(frame_sink_id_);
@@ -147,7 +147,7 @@ void RenderWidgetHostViewChildFrame::SetFrameConnectorDelegate(
if (parent_view) {
DCHECK(parent_view->GetFrameSinkId().is_valid() ||
- features::IsUsingWindowService());
+ features::IsMultiProcessMash());
SetParentFrameSinkId(parent_view->GetFrameSinkId());
}
@@ -168,7 +168,7 @@ void RenderWidgetHostViewChildFrame::SetFrameConnectorDelegate(
}
#if defined(USE_AURA)
- if (features::IsUsingWindowService()) {
+ if (features::IsMultiProcessMash()) {
frame_connector_->EmbedRendererWindowTreeClientInParent(
GetWindowTreeClientFromRenderer());
}
@@ -180,7 +180,7 @@ void RenderWidgetHostViewChildFrame::SetFrameConnectorDelegate(
#if defined(USE_AURA)
void RenderWidgetHostViewChildFrame::SetFrameSinkId(
const viz::FrameSinkId& frame_sink_id) {
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
frame_sink_id_ = frame_sink_id;
}
#endif // defined(USE_AURA)
@@ -189,7 +189,7 @@ bool RenderWidgetHostViewChildFrame::OnMessageReceived(
const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewChildFrame, msg)
- IPC_MESSAGE_HANDLER(ViewHostMsg_IntrinsicSizingInfoChanged,
+ IPC_MESSAGE_HANDLER(WidgetHostMsg_IntrinsicSizingInfoChanged,
OnIntrinsicSizingInfoChanged)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -348,9 +348,12 @@ gfx::NativeView RenderWidgetHostViewChildFrame::GetNativeView() const {
// OOPIF-webview, we need to return the native view to be used by
// RenderWidgetHostViewGuest. Remove this once https://crbug.com/642826 is
// fixed.
- if (frame_connector_)
- return frame_connector_->GetParentRenderWidgetHostView()->GetNativeView();
- return nullptr;
+ if (!frame_connector_)
+ return nullptr;
+
+ RenderWidgetHostView* parent_view =
+ frame_connector_->GetParentRenderWidgetHostView();
+ return parent_view ? parent_view->GetNativeView() : nullptr;
}
gfx::NativeViewAccessible
@@ -481,7 +484,7 @@ void RenderWidgetHostViewChildFrame::UpdateViewportIntersection(
bool occluded_or_obscured) {
if (host()) {
host()->SetIntersectsViewport(!viewport_intersection.IsEmpty());
- host()->Send(new ViewMsg_SetViewportIntersection(
+ host()->Send(new WidgetMsg_SetViewportIntersection(
host()->GetRoutingID(), viewport_intersection, compositor_visible_rect,
occluded_or_obscured));
}
@@ -489,14 +492,14 @@ void RenderWidgetHostViewChildFrame::UpdateViewportIntersection(
void RenderWidgetHostViewChildFrame::SetIsInert() {
if (host() && frame_connector_) {
- host()->Send(new ViewMsg_SetIsInert(host()->GetRoutingID(),
- frame_connector_->IsInert()));
+ host()->Send(new WidgetMsg_SetIsInert(host()->GetRoutingID(),
+ frame_connector_->IsInert()));
}
}
void RenderWidgetHostViewChildFrame::UpdateInheritedEffectiveTouchAction() {
if (host_ && frame_connector_) {
- host_->Send(new ViewMsg_SetInheritedEffectiveTouchAction(
+ host_->Send(new WidgetMsg_SetInheritedEffectiveTouchAction(
host_->GetRoutingID(),
frame_connector_->InheritedEffectiveTouchAction()));
}
@@ -504,7 +507,7 @@ void RenderWidgetHostViewChildFrame::UpdateInheritedEffectiveTouchAction() {
void RenderWidgetHostViewChildFrame::UpdateRenderThrottlingStatus() {
if (host() && frame_connector_) {
- host()->Send(new ViewMsg_UpdateRenderThrottlingStatus(
+ host()->Send(new WidgetMsg_UpdateRenderThrottlingStatus(
host()->GetRoutingID(), frame_connector_->IsThrottled(),
frame_connector_->IsSubtreeThrottled()));
}
@@ -619,7 +622,7 @@ void RenderWidgetHostViewChildFrame::DidCreateNewRendererCompositorFrameSink(
void RenderWidgetHostViewChildFrame::SetParentFrameSinkId(
const viz::FrameSinkId& parent_frame_sink_id) {
if (parent_frame_sink_id_ == parent_frame_sink_id ||
- features::IsUsingWindowService())
+ features::IsMultiProcessMash())
return;
auto* host_frame_sink_manager = GetHostFrameSinkManager();
@@ -640,7 +643,7 @@ void RenderWidgetHostViewChildFrame::SetParentFrameSinkId(
}
void RenderWidgetHostViewChildFrame::SendSurfaceInfoToEmbedder() {
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
return;
if (!last_activated_surface_info_.is_valid())
return;
@@ -872,12 +875,6 @@ void RenderWidgetHostViewChildFrame::CopyFromSurface(
const gfx::Rect& src_subrect,
const gfx::Size& output_size,
base::OnceCallback<void(const SkBitmap&)> callback) {
- // TODO(crbug.com/812059): Need a "copy from surface" VIZ API.
- if (enable_viz_) {
- std::move(callback).Run(SkBitmap());
- return;
- }
-
if (!IsSurfaceAvailableForCopy()) {
// Defer submitting the copy request until after a frame is drawn, at which
// point we should be guaranteed that the surface is available.
@@ -1098,7 +1095,7 @@ RenderWidgetHostViewChildFrame::DidUpdateVisualProperties(
}
void RenderWidgetHostViewChildFrame::CreateCompositorFrameSinkSupport() {
- if (features::IsUsingWindowService() || enable_viz_)
+ if (features::IsMultiProcessMash() || enable_viz_)
return;
DCHECK(!support_);
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc
index 96d0d44860b..650fb3130da 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc
@@ -160,7 +160,7 @@ IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest,
IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest, ChildFrameSinkId) {
// Only when mus hosts viz do we expect a RenderFrameProxy to provide the
// FrameSinkId.
- if (!features::IsUsingWindowService())
+ if (!features::IsMultiProcessMash())
return;
GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
index 4eff713dfc4..b9a41007d19 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
@@ -29,7 +29,7 @@
#include "content/browser/renderer_host/render_widget_host_delegate.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/frame_visual_properties.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
@@ -228,11 +228,11 @@ TEST_F(RenderWidgetHostViewChildFrameTest, ViewportIntersectionUpdated) {
const IPC::Message* intersection_update =
process->sink().GetUniqueMessageMatching(
- ViewMsg_SetViewportIntersection::ID);
+ WidgetMsg_SetViewportIntersection::ID);
ASSERT_TRUE(intersection_update);
std::tuple<gfx::Rect, gfx::Rect, bool> sent_rects;
- ViewMsg_SetViewportIntersection::Read(intersection_update, &sent_rects);
+ WidgetMsg_SetViewportIntersection::Read(intersection_update, &sent_rects);
EXPECT_EQ(intersection_rect, std::get<0>(sent_rects));
EXPECT_EQ(intersection_rect, std::get<1>(sent_rects));
}
@@ -298,10 +298,10 @@ TEST_F(RenderWidgetHostViewChildFrameTest, WasResizedOncePerChange) {
ASSERT_EQ(1u, process->sink().message_count());
const IPC::Message* resize_msg = process->sink().GetUniqueMessageMatching(
- ViewMsg_SynchronizeVisualProperties::ID);
+ WidgetMsg_SynchronizeVisualProperties::ID);
ASSERT_NE(nullptr, resize_msg);
- ViewMsg_SynchronizeVisualProperties::Param params;
- ViewMsg_SynchronizeVisualProperties::Read(resize_msg, &params);
+ WidgetMsg_SynchronizeVisualProperties::Param params;
+ WidgetMsg_SynchronizeVisualProperties::Read(resize_msg, &params);
EXPECT_EQ(compositor_viewport_pixel_size,
std::get<0>(params).compositor_viewport_pixel_size);
EXPECT_EQ(screen_space_rect.size(), std::get<0>(params).new_size);
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.h b/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.h
index 83af25a5814..fc0105d96d3 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.h
@@ -31,7 +31,7 @@ namespace mojom {
class RenderWidgetHostNSViewClient;
}
-class RenderWidgetHostNSViewLocalClient;
+class RenderWidgetHostNSViewClientHelper;
class RenderWidgetHostViewMac;
class RenderWidgetHostViewMacEditCommandHelper;
}
@@ -68,15 +68,13 @@ struct DidOverscrollParams;
// This includes events (where the extra translation is unnecessary or loses
// information) and access to accessibility structures (only present in the
// browser process).
- content::RenderWidgetHostNSViewLocalClient* localClient_;
+ content::RenderWidgetHostNSViewClientHelper* clientHelper_;
- // An implementation of the in-process interface that will translate and
- // forward messages through |client_|.
- std::unique_ptr<content::RenderWidgetHostNSViewLocalClient>
- forwardingLocalClient_;
-
- // Dummy client that is always valid (see above comments about client_).
+ // Dummy client and client helper that are always valid (see above comments
+ // about client_).
content::mojom::RenderWidgetHostNSViewClientPtr dummyClient_;
+ std::unique_ptr<content::RenderWidgetHostNSViewClientHelper>
+ dummyClientHelper_;
// This ivar is the cocoa delegate of the NSResponder.
base::scoped_nsobject<NSObject<RenderWidgetHostViewMacDelegate>>
@@ -251,7 +249,7 @@ struct DidOverscrollParams;
// Methods previously marked as private.
- (id)initWithClient:(content::mojom::RenderWidgetHostNSViewClient*)client
- withLocalClient:(content::RenderWidgetHostNSViewLocalClient*)localClient;
+ withClientHelper:(content::RenderWidgetHostNSViewClientHelper*)clientHelper;
- (void)setResponderDelegate:
(NSObject<RenderWidgetHostViewMacDelegate>*)delegate;
- (void)processedGestureScrollEvent:(const blink::WebGestureEvent&)event
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.mm b/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.mm
index 92f940ef023..ee6cde8137b 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.mm
@@ -8,6 +8,7 @@
#include <utility>
#include "base/debug/crash_logging.h"
+#import "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/stl_util.h"
#include "base/strings/sys_string_conversions.h"
@@ -37,7 +38,7 @@ using content::EditCommand;
using content::InputEvent;
using content::NativeWebKeyboardEvent;
using content::mojom::RenderWidgetHostNSViewClient;
-using content::RenderWidgetHostNSViewLocalClient;
+using content::RenderWidgetHostNSViewClientHelper;
using content::RenderWidgetHostViewMacEditCommandHelper;
using content::WebGestureEventBuilder;
using content::WebMouseEventBuilder;
@@ -51,82 +52,6 @@ using blink::WebTouchEvent;
namespace {
-class ForwardingLocalClient : public RenderWidgetHostNSViewLocalClient {
- public:
- explicit ForwardingLocalClient(RenderWidgetHostNSViewClient* client)
- : client_(client) {}
-
- private:
- std::unique_ptr<InputEvent> TranslateEvent(
- const blink::WebInputEvent& web_event) {
- return std::make_unique<InputEvent>(web_event, ui::LatencyInfo());
- }
-
- // RenderWidgetHostNSViewLocalClient implementation.
- BrowserAccessibilityManager* GetRootBrowserAccessibilityManager() override {
- return nullptr;
- }
- void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info) override {
- const blink::WebKeyboardEvent* web_event =
- static_cast<const blink::WebKeyboardEvent*>(&key_event);
- std::unique_ptr<InputEvent> input_event =
- std::make_unique<InputEvent>(*web_event, latency_info);
- client_->ForwardKeyboardEvent(std::move(input_event),
- key_event.skip_in_browser);
- }
- void ForwardKeyboardEventWithCommands(
- const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info,
- const std::vector<EditCommand>& commands) override {
- const blink::WebKeyboardEvent* web_event =
- static_cast<const blink::WebKeyboardEvent*>(&key_event);
- std::unique_ptr<InputEvent> input_event =
- std::make_unique<InputEvent>(*web_event, latency_info);
- client_->ForwardKeyboardEventWithCommands(
- std::move(input_event), key_event.skip_in_browser, commands);
- }
- void RouteOrProcessMouseEvent(
- const blink::WebMouseEvent& web_event) override {
- client_->RouteOrProcessMouseEvent(TranslateEvent(web_event));
- }
- void RouteOrProcessTouchEvent(
- const blink::WebTouchEvent& web_event) override {
- client_->RouteOrProcessTouchEvent(TranslateEvent(web_event));
- }
- void RouteOrProcessWheelEvent(
- const blink::WebMouseWheelEvent& web_event) override {
- client_->RouteOrProcessWheelEvent(TranslateEvent(web_event));
- }
- void ForwardMouseEvent(const blink::WebMouseEvent& web_event) override {
- client_->ForwardMouseEvent(TranslateEvent(web_event));
- }
- void ForwardWheelEvent(const blink::WebMouseWheelEvent& web_event) override {
- client_->ForwardWheelEvent(TranslateEvent(web_event));
- }
- void GestureBegin(blink::WebGestureEvent begin_event,
- bool is_synthetically_injected) override {
- // The gesture type is not yet known, but assign a type to avoid
- // serialization asserts (the type will be stripped on the other side).
- begin_event.SetType(blink::WebInputEvent::kGestureScrollBegin);
- client_->GestureBegin(TranslateEvent(begin_event),
- is_synthetically_injected);
- }
- void GestureUpdate(blink::WebGestureEvent update_event) override {
- client_->GestureUpdate(TranslateEvent(update_event));
- }
- void GestureEnd(blink::WebGestureEvent end_event) override {
- client_->GestureEnd(TranslateEvent(end_event));
- }
- void SmartMagnify(const blink::WebGestureEvent& web_event) override {
- client_->SmartMagnify(TranslateEvent(web_event));
- }
-
- RenderWidgetHostNSViewClient* client_ = nullptr;
-
- DISALLOW_COPY_AND_ASSIGN(ForwardingLocalClient);
-};
-
// Whether a keyboard event has been reserved by OSX.
BOOL EventIsReservedBySystem(NSEvent* event) {
content::SystemHotkeyHelperMac* helper =
@@ -212,7 +137,7 @@ void ExtractUnderlines(NSAttributedString* string,
@synthesize textInputType = textInputType_;
- (id)initWithClient:(RenderWidgetHostNSViewClient*)client
- withLocalClient:(RenderWidgetHostNSViewLocalClient*)localClient {
+ withClientHelper:(RenderWidgetHostNSViewClientHelper*)clientHelper {
self = [super initWithFrame:NSZeroRect];
if (self) {
self.acceptsTouchEvents = YES;
@@ -220,12 +145,7 @@ void ExtractUnderlines(NSAttributedString* string,
editCommandHelper_->AddEditingSelectorsToClass([self class]);
client_ = client;
- if (localClient) {
- localClient_ = localClient;
- } else {
- forwardingLocalClient_ = std::make_unique<ForwardingLocalClient>(client_);
- localClient_ = forwardingLocalClient_.get();
- }
+ clientHelper_ = clientHelper;
canBeKeyView_ = YES;
isStylusEnteringProximity_ = false;
keyboardLockActive_ = false;
@@ -372,13 +292,14 @@ void ExtractUnderlines(NSAttributedString* string,
}
- (void)setClientDisconnected {
- // Set the client to be an abandoned message pipe, and set the localClient
+ // Set the client to be an abandoned message pipe, and set the clientHelper
// to forward messages to that client.
content::mojom::RenderWidgetHostNSViewClientRequest dummyClientRequest =
mojo::MakeRequest(&dummyClient_);
+ dummyClientHelper_ = RenderWidgetHostNSViewClientHelper::CreateForMojoClient(
+ dummyClient_.get());
client_ = dummyClient_.get();
- forwardingLocalClient_ = std::make_unique<ForwardingLocalClient>(client_);
- localClient_ = forwardingLocalClient_.get();
+ clientHelper_ = dummyClientHelper_.get();
// |responderDelegate_| may attempt to access the RenderWidgetHostViewMac
// through its internal pointers, so detach it here.
@@ -421,7 +342,7 @@ void ExtractUnderlines(NSAttributedString* string,
WebMouseEvent web_event = WebMouseEventBuilder::Build(event, self);
web_event.SetModifiers(web_event.GetModifiers() |
WebInputEvent::kRelativeMotionEvent);
- localClient_->ForwardMouseEvent(web_event);
+ clientHelper_->ForwardMouseEvent(web_event);
}
- (BOOL)shouldIgnoreMouseEvent:(NSEvent*)theEvent {
@@ -511,7 +432,7 @@ void ExtractUnderlines(NSAttributedString* string,
WebMouseEventBuilder::Build(theEvent, self, pointerType_);
exitEvent.SetType(WebInputEvent::kMouseLeave);
exitEvent.button = WebMouseEvent::Button::kNoButton;
- localClient_->ForwardMouseEvent(exitEvent);
+ clientHelper_->ForwardMouseEvent(exitEvent);
}
mouseEventWasIgnored_ = YES;
return;
@@ -524,7 +445,7 @@ void ExtractUnderlines(NSAttributedString* string,
WebMouseEventBuilder::Build(theEvent, self, pointerType_);
enterEvent.SetType(WebInputEvent::kMouseMove);
enterEvent.button = WebMouseEvent::Button::kNoButton;
- localClient_->RouteOrProcessMouseEvent(enterEvent);
+ clientHelper_->RouteOrProcessMouseEvent(enterEvent);
}
mouseEventWasIgnored_ = NO;
@@ -578,10 +499,10 @@ void ExtractUnderlines(NSAttributedString* string,
if (!send_touch) {
WebMouseEvent event =
WebMouseEventBuilder::Build(theEvent, self, pointerType_);
- localClient_->RouteOrProcessMouseEvent(event);
+ clientHelper_->RouteOrProcessMouseEvent(event);
} else {
WebTouchEvent event = WebTouchEventBuilder::Build(theEvent, self);
- localClient_->RouteOrProcessTouchEvent(event);
+ clientHelper_->RouteOrProcessTouchEvent(event);
}
}
@@ -728,7 +649,7 @@ void ExtractUnderlines(NSAttributedString* string,
// We only handle key down events and just simply forward other events.
if (eventType != NSKeyDown) {
- localClient_->ForwardKeyboardEvent(event, latency_info);
+ clientHelper_->ForwardKeyboardEvent(event, latency_info);
// Possibly autohide the cursor.
if (shouldAutohideCursor) {
@@ -786,7 +707,7 @@ void ExtractUnderlines(NSAttributedString* string,
NativeWebKeyboardEvent fakeEvent = event;
fakeEvent.windows_key_code = 0xE5; // VKEY_PROCESSKEY
fakeEvent.skip_in_browser = true;
- localClient_->ForwardKeyboardEvent(fakeEvent, latency_info);
+ clientHelper_->ForwardKeyboardEvent(fakeEvent, latency_info);
// If this key event was handled by the input method, but
// -doCommandBySelector: (invoked by the call to -interpretKeyEvents: above)
// enqueued edit commands, then in order to let webkit handle them
@@ -797,8 +718,8 @@ void ExtractUnderlines(NSAttributedString* string,
if (hasEditCommands_ && !hasMarkedText_)
delayEventUntilAfterImeCompostion = YES;
} else {
- localClient_->ForwardKeyboardEventWithCommands(event, latency_info,
- editCommands_);
+ clientHelper_->ForwardKeyboardEventWithCommands(event, latency_info,
+ editCommands_);
}
// Then send keypress and/or composition related events.
@@ -856,8 +777,8 @@ void ExtractUnderlines(NSAttributedString* string,
fakeEvent.skip_in_browser = true;
ui::LatencyInfo fake_event_latency_info = latency_info;
fake_event_latency_info.set_source_event_type(ui::SourceEventType::OTHER);
- localClient_->ForwardKeyboardEvent(fakeEvent, fake_event_latency_info);
- localClient_->ForwardKeyboardEventWithCommands(
+ clientHelper_->ForwardKeyboardEvent(fakeEvent, fake_event_latency_info);
+ clientHelper_->ForwardKeyboardEventWithCommands(
event, fake_event_latency_info, editCommands_);
}
@@ -871,7 +792,7 @@ void ExtractUnderlines(NSAttributedString* string,
event.text[0] = textToBeInserted_[0];
event.text[1] = 0;
event.skip_in_browser = true;
- localClient_->ForwardKeyboardEvent(event, latency_info);
+ clientHelper_->ForwardKeyboardEvent(event, latency_info);
} else if ((!textInserted || delayEventUntilAfterImeCompostion) &&
event.text[0] != '\0' &&
((modifierFlags & kCtrlCmdKeyMask) ||
@@ -881,7 +802,7 @@ void ExtractUnderlines(NSAttributedString* string,
// cases, unless the key event generated any other command.
event.SetType(blink::WebInputEvent::kChar);
event.skip_in_browser = true;
- localClient_->ForwardKeyboardEvent(event, latency_info);
+ clientHelper_->ForwardKeyboardEvent(event, latency_info);
}
}
@@ -912,7 +833,7 @@ void ExtractUnderlines(NSAttributedString* string,
// History-swiping is not possible if the logic reaches this point.
WebMouseWheelEvent webEvent = WebMouseWheelEventBuilder::Build(event, self);
webEvent.rails_mode = mouseWheelFilter_.UpdateRailsMode(webEvent);
- localClient_->ForwardWheelEvent(webEvent);
+ clientHelper_->ForwardWheelEvent(webEvent);
if (endWheelMonitor_) {
[NSEvent removeMonitor:endWheelMonitor_];
@@ -926,7 +847,7 @@ void ExtractUnderlines(NSAttributedString* string,
WebGestureEvent gestureBeginEvent(WebGestureEventBuilder::Build(event, self));
- localClient_->GestureBegin(gestureBeginEvent, isSyntheticallyInjected);
+ clientHelper_->GestureBegin(gestureBeginEvent, isSyntheticallyInjected);
}
- (void)handleEndGestureWithEvent:(NSEvent*)event {
@@ -942,7 +863,7 @@ void ExtractUnderlines(NSAttributedString* string,
endEvent.SetSourceDevice(
blink::WebGestureDevice::kWebGestureDeviceTouchpad);
endEvent.SetNeedsWheelEvent(true);
- localClient_->GestureEnd(endEvent);
+ clientHelper_->GestureEnd(endEvent);
}
}
@@ -997,7 +918,7 @@ void ExtractUnderlines(NSAttributedString* string,
- (void)smartMagnifyWithEvent:(NSEvent*)event {
const WebGestureEvent& smartMagnifyEvent =
WebGestureEventBuilder::Build(event, self);
- localClient_->SmartMagnify(smartMagnifyEvent);
+ clientHelper_->SmartMagnify(smartMagnifyEvent);
}
- (void)showLookUpDictionaryOverlayFromRange:(NSRange)range {
@@ -1079,7 +1000,7 @@ void ExtractUnderlines(NSAttributedString* string,
// This is responsible for content scrolling!
WebMouseWheelEvent webEvent = WebMouseWheelEventBuilder::Build(event, self);
webEvent.rails_mode = mouseWheelFilter_.UpdateRailsMode(webEvent);
- localClient_->RouteOrProcessWheelEvent(webEvent);
+ clientHelper_->RouteOrProcessWheelEvent(webEvent);
}
// Called repeatedly during a pinch gesture, with incremental change values.
@@ -1112,7 +1033,7 @@ void ExtractUnderlines(NSAttributedString* string,
}
WebGestureEvent updateEvent = WebGestureEventBuilder::Build(event, self);
- localClient_->GestureUpdate(updateEvent);
+ clientHelper_->GestureUpdate(updateEvent);
}
- (void)viewWillMoveToWindow:(NSWindow*)newWindow {
@@ -1360,7 +1281,7 @@ void ExtractUnderlines(NSAttributedString* string,
- (id)accessibilityAttributeValue:(NSString*)attribute {
BrowserAccessibilityManager* manager =
- localClient_->GetRootBrowserAccessibilityManager();
+ clientHelper_->GetRootBrowserAccessibilityManager();
// Contents specifies document view of RenderWidgetHostViewCocoa provided by
// BrowserAccessibilityManager. Children includes all subviews in addition to
@@ -1386,7 +1307,7 @@ void ExtractUnderlines(NSAttributedString* string,
- (id)accessibilityHitTest:(NSPoint)point {
BrowserAccessibilityManager* manager =
- localClient_->GetRootBrowserAccessibilityManager();
+ clientHelper_->GetRootBrowserAccessibilityManager();
if (!manager)
return self;
NSPoint pointInWindow =
@@ -1401,13 +1322,13 @@ void ExtractUnderlines(NSAttributedString* string,
- (BOOL)accessibilityIsIgnored {
BrowserAccessibilityManager* manager =
- localClient_->GetRootBrowserAccessibilityManager();
+ clientHelper_->GetRootBrowserAccessibilityManager();
return !manager;
}
- (NSUInteger)accessibilityGetIndexOf:(id)child {
BrowserAccessibilityManager* manager =
- localClient_->GetRootBrowserAccessibilityManager();
+ clientHelper_->GetRootBrowserAccessibilityManager();
// Only child is root.
if (manager && ToBrowserAccessibilityCocoa(manager->GetRoot()) == child) {
return 0;
@@ -1428,7 +1349,7 @@ void ExtractUnderlines(NSAttributedString* string,
return popup_focus_override;
BrowserAccessibilityManager* manager =
- localClient_->GetRootBrowserAccessibilityManager();
+ clientHelper_->GetRootBrowserAccessibilityManager();
if (manager) {
BrowserAccessibility* focused_item = manager->GetFocus();
DCHECK(focused_item);
@@ -1790,7 +1711,7 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
WebMouseEvent event(WebInputEvent::kMouseUp, WebInputEvent::kNoModifiers,
ui::EventTimeForNow());
event.button = WebMouseEvent::Button::kLeft;
- localClient_->ForwardMouseEvent(event);
+ clientHelper_->ForwardMouseEvent(event);
hasOpenMouseDown_ = NO;
}
}
@@ -1926,29 +1847,36 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
//
// Supporting application services
//
+
+@interface RenderWidgetHostViewCocoa (
+ NSServicesRequests)<NSServicesMenuRequestor>
+@end
+
@implementation RenderWidgetHostViewCocoa (NSServicesRequests)
- (BOOL)writeSelectionToPasteboard:(NSPasteboard*)pboard types:(NSArray*)types {
- if (textSelectionRange_.is_empty() ||
- ![types containsObject:NSStringPboardType]) {
+ // NB: The NSServicesMenuRequestor protocol has not (as of 10.14) been
+ // upgraded to request UTIs rather than obsolete PboardType constants. Handle
+ // either for when it is upgraded.
+ DCHECK([types containsObject:NSStringPboardType] ||
+ [types containsObject:base::mac::CFToNSCast(kUTTypeUTF8PlainText)]);
+ if (textSelectionRange_.is_empty())
return NO;
- }
NSString* text = base::SysUTF16ToNSString([self selectedText]);
- NSArray* toDeclare = [NSArray arrayWithObject:NSStringPboardType];
- [pboard declareTypes:toDeclare owner:nil];
- return [pboard setString:text forType:NSStringPboardType];
+ return [pboard writeObjects:@[ text ]];
}
- (BOOL)readSelectionFromPasteboard:(NSPasteboard*)pboard {
- NSString* string = [pboard stringForType:NSStringPboardType];
- if (!string)
+ NSArray* objects =
+ [pboard readObjectsForClasses:@[ [NSString class] ] options:0];
+ if (![objects count])
return NO;
// If the user is currently using an IME, confirm the IME input,
// and then insert the text from the service, the same as TextEdit and Safari.
[self finishComposingText];
- [self insertText:string];
+ [self insertText:[objects lastObject]];
return YES;
}
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc b/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc
index 940d9c10766..caea824f874 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc
@@ -4,8 +4,11 @@
#include "content/browser/renderer_host/render_widget_host_view_event_handler.h"
+#include "base/command_line.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
+#include "components/viz/common/features.h"
+#include "content/browser/renderer_host/hit_test_debug_key_event_observer.h"
#include "content/browser/renderer_host/input/touch_selection_controller_client_aura.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
@@ -20,7 +23,6 @@
#include "content/public/common/content_features.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/client/focus_client.h"
-#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/scoped_keyboard_hook.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
@@ -65,19 +67,6 @@ BOOL CALLBACK DismissOwnedPopups(HWND window, LPARAM arg) {
}
#endif // defined(OS_WIN)
-gfx::PointF GetScreenLocationFromEvent(const ui::LocatedEvent& event) {
- aura::Window* root =
- static_cast<aura::Window*>(event.target())->GetRootWindow();
- aura::client::ScreenPositionClient* spc =
- aura::client::GetScreenPositionClient(root);
- if (!spc)
- return event.root_location_f();
-
- gfx::PointF screen_location(event.root_location_f());
- spc->ConvertPointToScreen(root, &screen_location);
- return screen_location;
-}
-
bool IsFractionalScaleFactor(float scale_factor) {
return (scale_factor - static_cast<int>(scale_factor)) > 0;
}
@@ -112,7 +101,16 @@ void MarkUnchangedTouchPointsAsStationary(blink::WebTouchEvent* event,
bool NeedsInputGrab(content::RenderWidgetHostViewBase* view) {
if (!view)
return false;
- return view->GetPopupType() == blink::kWebPopupTypePage;
+ return view->GetWidgetType() == content::WidgetType::kPopup;
+}
+
+// Enables hit-test debug logging.
+const char kEnableVizHitTestDebug[] = "enable-viz-hit-test-debug";
+
+inline bool IsVizHitTestingDebugEnabled() {
+ return features::IsVizHitTestingEnabled() &&
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ kEnableVizHitTestDebug);
}
} // namespace
@@ -142,7 +140,10 @@ RenderWidgetHostViewEventHandler::RenderWidgetHostViewEventHandler(
popup_child_event_handler_(nullptr),
delegate_(delegate),
window_(nullptr),
- mouse_wheel_phase_handler_(host_view) {}
+ mouse_wheel_phase_handler_(host_view),
+ debug_observer_(IsVizHitTestingDebugEnabled()
+ ? std::make_unique<HitTestDebugKeyEventObserver>(host)
+ : nullptr) {}
RenderWidgetHostViewEventHandler::~RenderWidgetHostViewEventHandler() {}
@@ -363,8 +364,7 @@ void RenderWidgetHostViewEventHandler::OnMouseEvent(ui::MouseEvent* event) {
}
#endif
blink::WebMouseWheelEvent mouse_wheel_event =
- ui::MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent&>(*event),
- base::Bind(&GetScreenLocationFromEvent));
+ ui::MakeWebMouseWheelEvent(*event->AsMouseWheelEvent());
if (mouse_wheel_event.delta_x != 0 || mouse_wheel_event.delta_y != 0) {
bool should_route_event = ShouldRouteEvent(event);
@@ -390,8 +390,7 @@ void RenderWidgetHostViewEventHandler::OnMouseEvent(ui::MouseEvent* event) {
if (event->type() == ui::ET_MOUSE_PRESSED)
FinishImeCompositionSession();
- blink::WebMouseEvent mouse_event = ui::MakeWebMouseEvent(
- *event, base::Bind(&GetScreenLocationFromEvent));
+ blink::WebMouseEvent mouse_event = ui::MakeWebMouseEvent(*event);
ModifyEventMovementAndCoords(*event, &mouse_event);
if (ShouldRouteEvent(event)) {
host_->delegate()->GetInputEventRouter()->RouteMouseEvent(
@@ -433,8 +432,8 @@ void RenderWidgetHostViewEventHandler::OnScrollEvent(ui::ScrollEvent* event) {
if (event->finger_count() != 2)
return;
#endif
- blink::WebMouseWheelEvent mouse_wheel_event = ui::MakeWebMouseWheelEvent(
- *event, base::Bind(&GetScreenLocationFromEvent));
+ blink::WebMouseWheelEvent mouse_wheel_event =
+ ui::MakeWebMouseWheelEvent(*event);
mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
mouse_wheel_event, should_route_event);
@@ -461,8 +460,7 @@ void RenderWidgetHostViewEventHandler::OnScrollEvent(ui::ScrollEvent* event) {
}
} else if (event->type() == ui::ET_SCROLL_FLING_START ||
event->type() == ui::ET_SCROLL_FLING_CANCEL) {
- blink::WebGestureEvent gesture_event = ui::MakeWebGestureEvent(
- *event, base::Bind(&GetScreenLocationFromEvent));
+ blink::WebGestureEvent gesture_event = ui::MakeWebGestureEvent(*event);
if (should_route_event) {
host_->delegate()->GetInputEventRouter()->RouteGestureEvent(
host_view_, &gesture_event,
@@ -552,8 +550,7 @@ void RenderWidgetHostViewEventHandler::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() == ui::ET_GESTURE_TAP)
FinishImeCompositionSession();
- blink::WebGestureEvent gesture =
- ui::MakeWebGestureEvent(*event, base::Bind(&GetScreenLocationFromEvent));
+ blink::WebGestureEvent gesture = ui::MakeWebGestureEvent(*event);
if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
// Webkit does not stop a fling-scroll on tap-down. So explicitly send an
// event to stop any in-progress flings.
@@ -741,8 +738,7 @@ void RenderWidgetHostViewEventHandler::HandleMouseEventWhileLocked(
if (event->type() == ui::ET_MOUSEWHEEL) {
blink::WebMouseWheelEvent mouse_wheel_event =
- ui::MakeWebMouseWheelEvent(static_cast<ui::MouseWheelEvent&>(*event),
- base::Bind(&GetScreenLocationFromEvent));
+ ui::MakeWebMouseWheelEvent(*event->AsMouseWheelEvent());
if (mouse_wheel_event.delta_x != 0 || mouse_wheel_event.delta_y != 0) {
if (ShouldRouteEvent(event)) {
host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(
@@ -764,8 +760,7 @@ void RenderWidgetHostViewEventHandler::HandleMouseEventWhileLocked(
return;
}
- blink::WebMouseEvent mouse_event =
- ui::MakeWebMouseEvent(*event, base::Bind(&GetScreenLocationFromEvent));
+ blink::WebMouseEvent mouse_event = ui::MakeWebMouseEvent(*event);
bool is_move_to_center_event =
(event->type() == ui::ET_MOUSE_MOVED ||
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.h b/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.h
index 5db1ce0507a..8b28ee3030a 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_event_handler.h
@@ -42,6 +42,7 @@ class OverscrollController;
class RenderWidgetHostImpl;
class RenderWidgetHostViewBase;
class TouchSelectionControllerClientAura;
+class HitTestDebugKeyEventObserver;
// Provides an implementation of ui::EventHandler for use with
// RenderWidgetHostViewBase. A delegate is required in order to provide platform
@@ -290,6 +291,8 @@ class CONTENT_EXPORT RenderWidgetHostViewEventHandler
aura::Window* window_;
MouseWheelPhaseHandler mouse_wheel_phase_handler_;
+ std::unique_ptr<HitTestDebugKeyEventObserver> debug_observer_;
+
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewEventHandler);
};
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac.h b/chromium/content/browser/renderer_host/render_widget_host_view_mac.h
index e25f39d32e7..bae1f369841 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -17,12 +17,13 @@
#include "components/viz/common/surfaces/surface_id.h"
#include "content/browser/renderer_host/browser_compositor_view_mac.h"
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
-#include "content/browser/renderer_host/render_widget_host_ns_view_client.h"
+#include "content/browser/renderer_host/render_widget_host_ns_view_client_helper.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "content/common/content_export.h"
#include "content/common/render_widget_host_ns_view.mojom.h"
#include "ipc/ipc_sender.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#include "ui/accelerated_widget_mac/ca_transaction_observer.h"
#include "ui/accelerated_widget_mac/display_link_mac.h"
@@ -41,6 +42,7 @@ class ScopedPasswordInputEnabler;
namespace content {
class CursorManager;
+class NSViewBridgeFactoryHost;
class RenderWidgetHost;
class RenderWidgetHostNSViewBridgeLocal;
class RenderWidgetHostViewMac;
@@ -65,7 +67,7 @@ class WebCursor;
// RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
class CONTENT_EXPORT RenderWidgetHostViewMac
: public RenderWidgetHostViewBase,
- public RenderWidgetHostNSViewLocalClient,
+ public RenderWidgetHostNSViewClientHelper,
public mojom::RenderWidgetHostNSViewClient,
public BrowserCompositorMacClient,
public TextInputManager::Observer,
@@ -91,7 +93,6 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// |delegate| should be set at most once.
CONTENT_EXPORT void SetDelegate(
NSObject<RenderWidgetHostViewMacDelegate>* delegate);
- void SetAllowPauseForResizeOrRepaint(bool allow);
// RenderWidgetHostView implementation.
void InitAsChild(gfx::NativeView parent_view) override;
@@ -300,7 +301,7 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// RenderWidgetHostImpl as well.
void UpdateNSViewAndDisplayProperties();
- // RenderWidgetHostNSViewLocalClient implementation.
+ // RenderWidgetHostNSViewClientHelper implementation.
BrowserAccessibilityManager* GetRootBrowserAccessibilityManager() override;
void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event,
const ui::LatencyInfo& latency_info) override;
@@ -447,6 +448,12 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// https://crbug.com/831843
RenderWidgetHostImpl* GetWidgetForKeyboardEvent();
+ // Migrate the NSView for this RenderWidgetHostView to be in the process
+ // hosted by |bridge_factory_host|, and make it a child view of the NSView
+ // referred to by |parent_ns_view_id|.
+ void MigrateNSViewBridge(NSViewBridgeFactoryHost* bridge_factory_host,
+ uint64_t parent_ns_view_id);
+
protected:
// This class is to be deleted through the Destroy method.
~RenderWidgetHostViewMac() override;
@@ -507,6 +514,13 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// not work when the RenderWidgetHostViewCocoa is hosted in an app process.
std::unique_ptr<RenderWidgetHostNSViewBridgeLocal> ns_view_bridge_local_;
+ // If the NSView is hosted in a remote process and accessed via mojo then
+ // - |ns_view_bridge_| will point to |ns_view_bridge_remote_|
+ // - |ns_view_client_binding_| is the binding provided to the bridge.
+ mojom::RenderWidgetHostNSViewBridgeAssociatedPtr ns_view_bridge_remote_;
+ mojo::AssociatedBinding<mojom::RenderWidgetHostNSViewClient>
+ ns_view_client_binding_;
+
// State tracked by Show/Hide/IsShowing.
bool is_visible_ = false;
@@ -535,6 +549,12 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// RenderWidgetHostViewGuest.
bool is_guest_view_hack_;
+ // Our parent host view, if this is a popup. NULL otherwise.
+ RenderWidgetHostViewMac* popup_parent_host_view_;
+
+ // Our child popup host. NULL if we do not have a child popup.
+ RenderWidgetHostViewMac* popup_child_host_view_;
+
// Display link for getting vsync info.
scoped_refptr<ui::DisplayLinkMac> display_link_;
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm
index 7e3a9aa6adc..94d6e79377d 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -36,6 +36,7 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
#include "content/public/browser/native_web_keyboard_event.h"
+#include "content/public/browser/ns_view_bridge_factory_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents.h"
#include "skia/ext/platform_canvas.h"
@@ -151,8 +152,11 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget,
: RenderWidgetHostViewBase(widget),
page_at_minimum_scale_(true),
mouse_wheel_phase_handler_(this),
+ ns_view_client_binding_(this),
is_loading_(false),
is_guest_view_hack_(is_guest_view_hack),
+ popup_parent_host_view_(nullptr),
+ popup_child_host_view_(nullptr),
gesture_provider_(ui::GetGestureProviderConfig(
ui::GestureProviderConfigType::CURRENT_PLATFORM),
this),
@@ -211,13 +215,56 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget,
// startup raciness and decrease latency.
needs_begin_frames_ = needs_begin_frames;
UpdateNeedsBeginFramesInternal();
- if (features::IsViewsBrowserCocoa())
- ui::CATransactionCoordinator::Get().AddPreCommitObserver(this);
}
RenderWidgetHostViewMac::~RenderWidgetHostViewMac() {
- if (features::IsViewsBrowserCocoa())
- ui::CATransactionCoordinator::Get().RemovePreCommitObserver(this);
+ if (popup_parent_host_view_) {
+ DCHECK(!popup_parent_host_view_->popup_child_host_view_ ||
+ popup_parent_host_view_->popup_child_host_view_ == this);
+ popup_parent_host_view_->popup_child_host_view_ = nullptr;
+ }
+ if (popup_child_host_view_) {
+ DCHECK(!popup_child_host_view_->popup_parent_host_view_ ||
+ popup_child_host_view_->popup_parent_host_view_ == this);
+ popup_child_host_view_->popup_parent_host_view_ = nullptr;
+ }
+}
+
+void RenderWidgetHostViewMac::MigrateNSViewBridge(
+ NSViewBridgeFactoryHost* bridge_factory_host,
+ uint64_t parent_ns_view_id) {
+ // Disconnect from the previous bridge (this will have the effect of
+ // destroying the associated bridge), and close the binding (to allow it
+ // to be re-bound). Note that |ns_view_bridge_local_| remains valid.
+ ns_view_client_binding_.Close();
+ ns_view_bridge_remote_.reset();
+
+ // If no host is specified, then use the locally hosted NSView.
+ if (!bridge_factory_host) {
+ ns_view_bridge_ = ns_view_bridge_local_.get();
+ return;
+ }
+
+ mojom::RenderWidgetHostNSViewClientAssociatedPtr client;
+ ns_view_client_binding_.Bind(mojo::MakeRequest(&client));
+ mojom::RenderWidgetHostNSViewBridgeAssociatedRequest bridge_request =
+ mojo::MakeRequest(&ns_view_bridge_remote_);
+
+ // Cast from mojom::RenderWidgetHostNSViewClientPtr and
+ // mojom::RenderWidgetHostNSViewBridgeRequest to the public interfaces
+ // accepted by the factory.
+ // TODO(ccameron): Remove the need for this cast.
+ // https://crbug.com/888290
+ mojo::AssociatedInterfacePtrInfo<mojom::StubInterface> stub_client(
+ client.PassInterface().PassHandle(), 0);
+ mojom::StubInterfaceAssociatedRequest stub_bridge_request(
+ bridge_request.PassHandle());
+
+ bridge_factory_host->GetFactory()->CreateRenderWidgetHostNSViewBridge(
+ std::move(stub_client), std::move(stub_bridge_request));
+
+ ns_view_bridge_ = ns_view_bridge_remote_.get();
+ ns_view_bridge_remote_->SetParentWebContentsNSView(parent_ns_view_id);
}
void RenderWidgetHostViewMac::SetParentUiLayer(ui::Layer* parent_ui_layer) {
@@ -246,11 +293,6 @@ void RenderWidgetHostViewMac::SetDelegate(
[cocoa_view() setResponderDelegate:delegate];
}
-void RenderWidgetHostViewMac::SetAllowPauseForResizeOrRepaint(bool allow) {
- // TODO: Remove SetAllowPauseForResizeOrRepaint and SetAllowOtherViews, since
- // they aren't used anymore.
-}
-
ui::TextInputType RenderWidgetHostViewMac::GetTextInputType() {
if (!GetActiveWidget())
return ui::TEXT_INPUT_TYPE_NONE;
@@ -279,13 +321,27 @@ RenderWidgetHostViewMac::GetTextSelection() {
void RenderWidgetHostViewMac::InitAsChild(
gfx::NativeView parent_view) {
+ DCHECK_EQ(widget_type_, WidgetType::kFrame);
}
void RenderWidgetHostViewMac::InitAsPopup(
RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos) {
+ DCHECK_EQ(widget_type_, WidgetType::kPopup);
+
+ popup_parent_host_view_ =
+ static_cast<RenderWidgetHostViewMac*>(parent_host_view);
+
+ RenderWidgetHostViewMac* old_child =
+ popup_parent_host_view_->popup_child_host_view_;
+ if (old_child) {
+ DCHECK(old_child->popup_parent_host_view_ == popup_parent_host_view_);
+ old_child->popup_parent_host_view_ = nullptr;
+ }
+ popup_parent_host_view_->popup_child_host_view_ = this;
+
// This path is used by the time/date picker.
- ns_view_bridge_->InitAsPopup(pos, popup_type_);
+ ns_view_bridge_->InitAsPopup(pos);
}
void RenderWidgetHostViewMac::InitAsFullscreen(
@@ -333,9 +389,6 @@ void RenderWidgetHostViewMac::UpdateNSViewAndDisplayProperties() {
LOG(ERROR) << "Failed to create display link.";
}
- if (features::IsViewsBrowserCocoa())
- ui::CATransactionCoordinator::Get().Synchronize();
-
// During auto-resize it is the responsibility of the caller to ensure that
// the NSView and RenderWidgetHostImpl are kept in sync.
if (host()->auto_resize_enabled())
@@ -624,10 +677,12 @@ void RenderWidgetHostViewMac::Destroy() {
ns_view_bridge_->SetCursorLocked(false);
}
- // Destroy the brige to the NSView. Note that the NSView on the other side
- // of |ns_view_bridge_| may outlive us due to other retains.
+ // Destroy the local and remote briges to the NSView. Note that the NSView on
+ // the other side of |ns_view_bridge_| may outlive us due to other retains.
ns_view_bridge_ = nullptr;
ns_view_bridge_local_.reset();
+ ns_view_client_binding_.Close();
+ ns_view_bridge_remote_.reset();
// Delete the delegated frame state, which will reach back into
// host().
@@ -763,8 +818,19 @@ void RenderWidgetHostViewMac::CopyFromSurface(
const gfx::Rect& src_subrect,
const gfx::Size& dst_size,
base::OnceCallback<void(const SkBitmap&)> callback) {
- browser_compositor_->GetDelegatedFrameHost()->CopyFromCompositingSurface(
- src_subrect, dst_size, std::move(callback));
+ base::WeakPtr<RenderWidgetHostImpl> popup_host;
+ base::WeakPtr<DelegatedFrameHost> popup_frame_host;
+ if (popup_child_host_view_) {
+ popup_host = popup_child_host_view_->host()->GetWeakPtr();
+ popup_frame_host = popup_child_host_view_->BrowserCompositor()
+ ->GetDelegatedFrameHost()
+ ->GetWeakPtr();
+ }
+ RenderWidgetHostViewBase::CopyMainAndPopupFromSurface(
+ host()->GetWeakPtr(),
+ browser_compositor_->GetDelegatedFrameHost()->GetWeakPtr(), popup_host,
+ popup_frame_host, src_subrect, dst_size, display_.device_scale_factor(),
+ std::move(callback));
}
void RenderWidgetHostViewMac::EnsureSurfaceSynchronizedForLayoutTest() {
@@ -1222,8 +1288,6 @@ bool RenderWidgetHostViewMac::TransformPointToCoordSpaceForView(
return true;
}
- if (!HasFallbackSurface())
- return false;
return target_view->TransformPointToLocalCoordSpace(
point, GetCurrentSurfaceId(), transformed_point, source);
}
@@ -1344,7 +1408,7 @@ MouseWheelPhaseHandler* RenderWidgetHostViewMac::GetMouseWheelPhaseHandler() {
}
///////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostNSViewLocalClient and mojom::RenderWidgetHostNSViewClient
+// RenderWidgetHostNSViewClientHelper and mojom::RenderWidgetHostNSViewClient
// implementation:
BrowserAccessibilityManager*
@@ -1824,7 +1888,7 @@ void RenderWidgetHostViewMac::StopSpeaking() {
///////////////////////////////////////////////////////////////////////////////
// mojom::RenderWidgetHostNSViewClient functions that translate events and
-// forward them to the RenderWidgetHostNSViewLocalClient implementation:
+// forward them to the RenderWidgetHostNSViewClientHelper implementation:
void RenderWidgetHostViewMac::ForwardKeyboardEvent(
std::unique_ptr<InputEvent> input_event,
@@ -2000,10 +2064,7 @@ void RenderWidgetHostViewMac::OnGotStringForDictionaryOverlay(
if ([ns_selected_text length] == 0)
return;
scoped_refptr<ui::UniquePasteboard> pasteboard = new ui::UniquePasteboard;
- NSArray* types = [NSArray arrayWithObject:NSStringPboardType];
- [pasteboard->get() declareTypes:types owner:nil];
- if ([pasteboard->get() setString:ns_selected_text
- forType:NSStringPboardType]) {
+ if ([pasteboard->get() writeObjects:@[ ns_selected_text ]]) {
NSPerformService(@"Look Up in Dictionary", pasteboard->get());
}
}
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
index 26c6b9e09d3..f27cb7c69cf 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
@@ -9,7 +9,7 @@
#include <stdint.h>
#include "base/mac/scoped_nsautorelease_pool.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/compositor/test/test_image_transport_factory.h"
#include "content/browser/gpu/compositor_util.h"
@@ -104,7 +104,7 @@ class RenderWidgetHostViewMacEditCommandHelperTest : public PlatformTest {
void TearDown() override { ImageTransportFactory::Terminate(); }
private:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
};
class RenderWidgetHostViewMacEditCommandHelperWithTaskEnvTest
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index 8e31dddeb00..ed5984e8d1f 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -17,6 +17,7 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
@@ -30,7 +31,8 @@
#include "content/browser/renderer_host/text_input_manager.h"
#include "content/common/input_messages.h"
#include "content/common/text_input_state.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_view_mac_delegate.h"
@@ -531,7 +533,7 @@ TEST_F(RenderWidgetHostViewMacTest, GetFirstRectForCharacterRangeCaretCase) {
gfx::Rect caret_rect(10, 11, 0, 10);
gfx::Range caret_range(0, 0);
- ViewHostMsg_SelectionBounds_Params params;
+ WidgetHostMsg_SelectionBounds_Params params;
gfx::Rect rect;
gfx::Range actual_range;
@@ -1132,8 +1134,8 @@ TEST_F(RenderWidgetHostViewMacTest, GuestViewDoesNotLeak) {
// Let |guest_rwhv_weak| have a chance to delete itself.
base::RunLoop run_loop;
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE, run_loop.QuitClosure());
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ run_loop.QuitClosure());
run_loop.Run();
ASSERT_FALSE(guest_rwhv_weak.get());
@@ -1155,7 +1157,7 @@ TEST_F(RenderWidgetHostViewMacTest, Background) {
EXPECT_EQ(static_cast<unsigned>(SK_ColorRED),
*rwhv_mac_->GetBackgroundColor());
set_background = process_host_->sink().GetUniqueMessageMatching(
- ViewMsg_SetBackgroundOpaque::ID);
+ WidgetMsg_SetBackgroundOpaque::ID);
ASSERT_FALSE(set_background);
// Set the color to blue. This should not send an opacity message.
@@ -1163,7 +1165,7 @@ TEST_F(RenderWidgetHostViewMacTest, Background) {
EXPECT_EQ(static_cast<unsigned>(SK_ColorBLUE),
*rwhv_mac_->GetBackgroundColor());
set_background = process_host_->sink().GetUniqueMessageMatching(
- ViewMsg_SetBackgroundOpaque::ID);
+ WidgetMsg_SetBackgroundOpaque::ID);
ASSERT_FALSE(set_background);
// Set the color back to transparent. The background color should now be
@@ -1174,9 +1176,9 @@ TEST_F(RenderWidgetHostViewMacTest, Background) {
EXPECT_EQ(static_cast<unsigned>(SK_ColorWHITE),
*rwhv_mac_->GetBackgroundColor());
set_background = process_host_->sink().GetUniqueMessageMatching(
- ViewMsg_SetBackgroundOpaque::ID);
+ WidgetMsg_SetBackgroundOpaque::ID);
ASSERT_TRUE(set_background);
- ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
+ WidgetMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
EXPECT_FALSE(std::get<0>(sent_background));
// Set the color to red. This should send an opacity message.
@@ -1185,9 +1187,9 @@ TEST_F(RenderWidgetHostViewMacTest, Background) {
EXPECT_EQ(static_cast<unsigned>(SK_ColorBLUE),
*rwhv_mac_->GetBackgroundColor());
set_background = process_host_->sink().GetUniqueMessageMatching(
- ViewMsg_SetBackgroundOpaque::ID);
+ WidgetMsg_SetBackgroundOpaque::ID);
ASSERT_TRUE(set_background);
- ViewMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
+ WidgetMsg_SetBackgroundOpaque::Read(set_background, &sent_background);
EXPECT_TRUE(std::get<0>(sent_background));
}
diff --git a/chromium/content/browser/renderer_host/render_widget_targeter.cc b/chromium/content/browser/renderer_host/render_widget_targeter.cc
index eef715fc681..daa6078f311 100644
--- a/chromium/content/browser/renderer_host/render_widget_targeter.cc
+++ b/chromium/content/browser/renderer_host/render_widget_targeter.cc
@@ -6,6 +6,8 @@
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
+#include "base/rand_util.h"
+#include "components/viz/common/features.h"
#include "content/browser/renderer_host/input/one_shot_timeout_monitor.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
@@ -59,7 +61,6 @@ class TracingUmaTracker {
}
~TracingUmaTracker() = default;
TracingUmaTracker(TracingUmaTracker&& tracker) = default;
- TracingUmaTracker& operator=(TracingUmaTracker&& tracker) = default;
void Stop() {
TRACE_EVENT_ASYNC_END0(
@@ -93,11 +94,13 @@ RenderWidgetTargetResult::RenderWidgetTargetResult(
RenderWidgetHostViewBase* in_view,
bool in_should_query_view,
base::Optional<gfx::PointF> in_location,
- bool in_latched_target)
+ bool in_latched_target,
+ bool in_should_verify_result)
: view(in_view),
should_query_view(in_should_query_view),
target_location(in_location),
- latched_target(in_latched_target) {}
+ latched_target(in_latched_target),
+ should_verify_result(in_should_verify_result) {}
RenderWidgetTargetResult::~RenderWidgetTargetResult() = default;
@@ -112,7 +115,9 @@ operator=(TargetingRequest&&) = default;
RenderWidgetTargeter::TargetingRequest::~TargetingRequest() = default;
RenderWidgetTargeter::RenderWidgetTargeter(Delegate* delegate)
- : delegate_(delegate), weak_ptr_factory_(this) {
+ : trace_id_(base::RandUint64()),
+ delegate_(delegate),
+ weak_ptr_factory_(this) {
DCHECK(delegate_);
}
@@ -150,21 +155,37 @@ void RenderWidgetTargeter::FindTargetAndDispatch(
RenderWidgetTargetResult result =
delegate_->FindTargetSynchronously(root_view, event);
+ const gfx::PointF event_location = ComputeEventLocation(event);
+
RenderWidgetHostViewBase* target = result.view;
auto* event_ptr = &event;
async_depth_ = 0;
if (result.should_query_view) {
+ TRACE_EVENT_WITH_FLOW2(
+ "viz,benchmark", "Event.Pipeline", TRACE_ID_GLOBAL(trace_id_),
+ TRACE_EVENT_FLAG_FLOW_OUT, "step", "QueryClient(Start)",
+ "event_location", event_location.ToString());
+
// TODO(kenrb, sadrul): When all event types support asynchronous hit
// testing, we should be able to have FindTargetSynchronously return the
// view and location to use for the renderer hit test query.
// Currently it has to return the surface hit test target, for event types
// that ignore |result.should_query_view|, and therefore we have to use
// root_view and the original event location for the initial query.
- QueryClient(root_view, root_view, *event_ptr, latency,
- ComputeEventLocation(event), nullptr, gfx::PointF());
+ // Do not compare hit test results if we are forced to do async hit testing
+ // by HitTestQuery.
+ QueryClient(root_view, root_view, *event_ptr, latency, event_location,
+ nullptr, gfx::PointF());
} else {
FoundTarget(root_view, target, *event_ptr, latency, result.target_location,
- result.latched_target);
+ result.latched_target, viz::FrameSinkId());
+ // Verify the event targeting results from surface layer viz hit testing if
+ // --use-viz-hit-test-surface-layer is enabled.
+ if (result.should_verify_result && !target->IsRenderWidgetHostViewGuest()) {
+ QueryAndVerifyClient(root_view, root_view, *event_ptr, latency,
+ event_location, nullptr, gfx::PointF(),
+ target->GetFrameSinkId());
+ }
}
}
@@ -172,66 +193,135 @@ void RenderWidgetTargeter::ViewWillBeDestroyed(RenderWidgetHostViewBase* view) {
unresponsive_views_.erase(view);
}
-void RenderWidgetTargeter::QueryClient(
+void RenderWidgetTargeter::QueryClientInternal(
RenderWidgetHostViewBase* root_view,
RenderWidgetHostViewBase* target,
const blink::WebInputEvent& event,
const ui::LatencyInfo& latency,
const gfx::PointF& target_location,
RenderWidgetHostViewBase* last_request_target,
- const gfx::PointF& last_target_location) {
- DCHECK(!request_in_flight_);
+ const gfx::PointF& last_target_location,
+ const viz::FrameSinkId& expected_frame_sink_id) {
+ // Async event targeting and verifying use two different queues, so they don't
+ // block each other.
+ bool is_verifying = expected_frame_sink_id.is_valid();
+ DCHECK((!is_verifying && !request_in_flight_) ||
+ (is_verifying && !verify_request_in_flight_));
auto* target_client = target->host()->input_target_client();
// |target_client| may not be set yet for this |target| on Mac, need to
- // understand why this happens. https://crbug.com/859492
+ // understand why this happens. https://crbug.com/859492.
+ // We do not verify hit testing result under this circumstance.
if (!target_client) {
- FoundTarget(root_view, target, event, latency, target_location, false);
+ FoundTarget(root_view, target, event, latency, target_location, false,
+ viz::FrameSinkId());
return;
}
- request_in_flight_ = true;
- async_depth_++;
+ if (is_verifying) {
+ verify_request_in_flight_ = true;
+ } else {
+ request_in_flight_ = true;
+ async_depth_++;
+ }
TracingUmaTracker tracker("Event.AsyncTargeting.ResponseTime",
"input,latency");
- async_hit_test_timeout_.reset(new OneShotTimeoutMonitor(
+ auto& hit_test_timeout =
+ is_verifying ? async_verify_hit_test_timeout_ : async_hit_test_timeout_;
+ hit_test_timeout.reset(new OneShotTimeoutMonitor(
base::BindOnce(
&RenderWidgetTargeter::AsyncHitTestTimedOut,
weak_ptr_factory_.GetWeakPtr(), root_view->GetWeakPtr(),
target->GetWeakPtr(), target_location,
last_request_target ? last_request_target->GetWeakPtr() : nullptr,
- last_target_location, ui::WebInputEventTraits::Clone(event), latency),
+ last_target_location, ui::WebInputEventTraits::Clone(event), latency,
+ expected_frame_sink_id),
async_hit_test_timeout_delay_));
+
+ TRACE_EVENT_WITH_FLOW2(
+ "viz,benchmark", "Event.Pipeline", TRACE_ID_GLOBAL(trace_id_),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
+ "QueryClient", "event", blink::WebInputEvent::GetName(event.GetType()));
+
target_client->FrameSinkIdAt(
- gfx::ToCeiledPoint(target_location),
- base::BindOnce(&RenderWidgetTargeter::FoundFrameSinkId,
- weak_ptr_factory_.GetWeakPtr(), root_view->GetWeakPtr(),
- target->GetWeakPtr(),
- ui::WebInputEventTraits::Clone(event), latency,
- ++last_request_id_, target_location, std::move(tracker)));
+ gfx::ToCeiledPoint(target_location), trace_id_,
+ base::BindOnce(
+ &RenderWidgetTargeter::FoundFrameSinkId,
+ weak_ptr_factory_.GetWeakPtr(), root_view->GetWeakPtr(),
+ target->GetWeakPtr(), ui::WebInputEventTraits::Clone(event), latency,
+ is_verifying ? ++last_verify_request_id_ : ++last_request_id_,
+ target_location, std::move(tracker), expected_frame_sink_id));
}
-void RenderWidgetTargeter::FlushEventQueue() {
+void RenderWidgetTargeter::QueryClient(
+ RenderWidgetHostViewBase* root_view,
+ RenderWidgetHostViewBase* target,
+ const blink::WebInputEvent& event,
+ const ui::LatencyInfo& latency,
+ const gfx::PointF& target_location,
+ RenderWidgetHostViewBase* last_request_target,
+ const gfx::PointF& last_target_location) {
+ QueryClientInternal(root_view, target, event, latency, target_location,
+ last_request_target, last_target_location,
+ viz::FrameSinkId());
+}
+
+void RenderWidgetTargeter::QueryAndVerifyClient(
+ RenderWidgetHostViewBase* root_view,
+ RenderWidgetHostViewBase* target,
+ const blink::WebInputEvent& event,
+ const ui::LatencyInfo& latency,
+ const gfx::PointF& target_location,
+ RenderWidgetHostViewBase* last_request_target,
+ const gfx::PointF& last_target_location,
+ const viz::FrameSinkId& expected_frame_sink_id) {
+ if (verify_request_in_flight_) {
+ TargetingRequest request;
+ request.root_view = root_view->GetWeakPtr();
+ request.event = ui::WebInputEventTraits::Clone(event);
+ request.latency = latency;
+ request.expected_frame_sink_id = expected_frame_sink_id;
+ verify_requests_.push(std::move(request));
+ return;
+ }
+ QueryClientInternal(root_view, target, event, latency, target_location,
+ last_request_target, last_target_location,
+ expected_frame_sink_id);
+}
+
+void RenderWidgetTargeter::FlushEventQueue(bool is_verifying) {
bool events_being_flushed = false;
- while (!request_in_flight_ && !requests_.empty()) {
- auto request = std::move(requests_.front());
- requests_.pop();
+ bool& request_in_flight =
+ is_verifying ? verify_request_in_flight_ : request_in_flight_;
+ auto* requests = is_verifying ? &verify_requests_ : &requests_;
+ while (!request_in_flight && !requests->empty()) {
+ auto request = std::move(requests->front());
+ requests->pop();
// The root-view has gone away. Ignore this event, and try to process the
// next event.
if (!request.root_view) {
continue;
}
- request.tracker->Stop();
+ if (request.tracker)
+ request.tracker->Stop();
// Only notify the delegate once that the current event queue is being
// flushed. Once all the events are flushed, notify the delegate again.
- if (!events_being_flushed) {
+ if (!is_verifying && !events_being_flushed) {
delegate_->SetEventsBeingFlushed(true);
events_being_flushed = true;
}
- FindTargetAndDispatch(request.root_view.get(), *request.event,
- request.latency);
+ if (is_verifying) {
+ QueryAndVerifyClient(request.root_view.get(), request.root_view.get(),
+ *request.event, request.latency,
+ ComputeEventLocation(*request.event), nullptr,
+ gfx::PointF(), request.expected_frame_sink_id);
+ } else {
+ FindTargetAndDispatch(request.root_view.get(), *request.event,
+ request.latency);
+ }
}
- delegate_->SetEventsBeingFlushed(false);
+ if (!is_verifying)
+ delegate_->SetEventsBeingFlushed(false);
}
void RenderWidgetTargeter::FoundFrameSinkId(
@@ -242,10 +332,15 @@ void RenderWidgetTargeter::FoundFrameSinkId(
uint32_t request_id,
const gfx::PointF& target_location,
TracingUmaTracker tracker,
+ const viz::FrameSinkId& expected_frame_sink_id,
const viz::FrameSinkId& frame_sink_id,
const gfx::PointF& transformed_location) {
tracker.Stop();
- if (request_id != last_request_id_ || !request_in_flight_) {
+ uint32_t last_id = expected_frame_sink_id.is_valid() ? last_verify_request_id_
+ : last_request_id_;
+ bool in_flight = expected_frame_sink_id.is_valid() ? verify_request_in_flight_
+ : request_in_flight_;
+ if (request_id != last_id || !in_flight) {
// This is a response to a request that already timed out, so the event
// should have already been dispatched. Mark the renderer as responsive
// and otherwise ignore this response.
@@ -253,8 +348,13 @@ void RenderWidgetTargeter::FoundFrameSinkId(
return;
}
- request_in_flight_ = false;
- async_hit_test_timeout_.reset(nullptr);
+ if (expected_frame_sink_id.is_valid()) {
+ verify_request_in_flight_ = false;
+ async_verify_hit_test_timeout_.reset(nullptr);
+ } else {
+ request_in_flight_ = false;
+ async_hit_test_timeout_.reset(nullptr);
+ }
auto* view = delegate_->FindViewFromFrameSinkId(frame_sink_id);
if (!view)
view = target.get();
@@ -263,10 +363,20 @@ void RenderWidgetTargeter::FoundFrameSinkId(
// asking the clients until a client claims an event for itself.
if (view == target.get() ||
unresponsive_views_.find(view) != unresponsive_views_.end()) {
- FoundTarget(root_view.get(), view, *event, latency, target_location, false);
+ // Reduced scope is required since FoundTarget can trigger another query
+ // which would end up linked to the current query.
+ {
+ TRACE_EVENT_WITH_FLOW1("viz,benchmark", "Event.Pipeline",
+ TRACE_ID_GLOBAL(trace_id_),
+ TRACE_EVENT_FLAG_FLOW_IN, "step", "FoundTarget");
+ }
+
+ FoundTarget(root_view.get(), view, *event, latency, target_location, false,
+ expected_frame_sink_id);
} else {
- QueryClient(root_view.get(), view, *event, latency, transformed_location,
- target.get(), target_location);
+ QueryClientInternal(root_view.get(), view, *event, latency,
+ transformed_location, target.get(), target_location,
+ expected_frame_sink_id);
}
}
@@ -276,19 +386,27 @@ void RenderWidgetTargeter::FoundTarget(
const blink::WebInputEvent& event,
const ui::LatencyInfo& latency,
const base::Optional<gfx::PointF>& target_location,
- bool latched_target) {
+ bool latched_target,
+ const viz::FrameSinkId& expected_frame_sink_id) {
if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites() &&
- !latched_target) {
+ !latched_target && !expected_frame_sink_id.is_valid()) {
UMA_HISTOGRAM_COUNTS_100("Event.AsyncTargeting.AsyncClientDepth",
async_depth_);
}
+ if (features::IsVizHitTestingSurfaceLayerEnabled() &&
+ expected_frame_sink_id.is_valid()) {
+ UMA_HISTOGRAM_BOOLEAN("Event.VizHitTestSurfaceLayer.ResultsMatch",
+ target->GetFrameSinkId() == expected_frame_sink_id);
+ FlushEventQueue(true);
+ return;
+ }
// RenderWidgetHostViewMac can be deleted asynchronously, in which case the
// View will be valid but there will no longer be a RenderWidgetHostImpl.
if (!root_view || !root_view->GetRenderWidgetHost())
return;
delegate_->DispatchEventToTarget(root_view, target, event, latency,
target_location);
- FlushEventQueue();
+ FlushEventQueue(false);
}
void RenderWidgetTargeter::AsyncHitTestTimedOut(
@@ -298,9 +416,17 @@ void RenderWidgetTargeter::AsyncHitTestTimedOut(
base::WeakPtr<RenderWidgetHostViewBase> last_request_target,
const gfx::PointF& last_target_location,
ui::WebScopedInputEvent event,
- const ui::LatencyInfo& latency) {
- DCHECK(request_in_flight_);
- request_in_flight_ = false;
+ const ui::LatencyInfo& latency,
+ const viz::FrameSinkId& expected_frame_sink_id) {
+ DCHECK(request_in_flight_ || verify_request_in_flight_);
+ // If we time out during a verification, we early out to avoid dispatching
+ // event to root frame.
+ if (expected_frame_sink_id.is_valid()) {
+ verify_request_in_flight_ = false;
+ return;
+ } else {
+ request_in_flight_ = false;
+ }
if (!current_request_root_view)
return;
@@ -315,10 +441,11 @@ void RenderWidgetTargeter::AsyncHitTestTimedOut(
// renderer fails to process it.
FoundTarget(current_request_root_view.get(),
current_request_root_view.get(), *event, latency,
- current_target_location, false);
+ current_target_location, false, viz::FrameSinkId());
} else {
FoundTarget(current_request_root_view.get(), last_request_target.get(),
- *event, latency, last_target_location, false);
+ *event, latency, last_target_location, false,
+ viz::FrameSinkId());
}
}
diff --git a/chromium/content/browser/renderer_host/render_widget_targeter.h b/chromium/content/browser/renderer_host/render_widget_targeter.h
index 5e6dda1dbc3..8994fcfa873 100644
--- a/chromium/content/browser/renderer_host/render_widget_targeter.h
+++ b/chromium/content/browser/renderer_host/render_widget_targeter.h
@@ -11,6 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/time/time.h"
+#include "components/viz/common/surfaces/frame_sink_id.h"
#include "content/common/content_constants_internal.h"
#include "content/common/content_export.h"
#include "ui/events/blink/web_input_event_traits.h"
@@ -24,22 +25,22 @@ namespace gfx {
class PointF;
}
-namespace viz {
-class FrameSinkId;
-}
-
namespace content {
class RenderWidgetHostViewBase;
class OneShotTimeoutMonitor;
+// TODO(sunxd): Make |RenderWidgetTargetResult| a class. Merge the booleans into
+// a mask to reduce the size. Make the constructor take in enums for better
+// readability.
struct CONTENT_EXPORT RenderWidgetTargetResult {
RenderWidgetTargetResult();
RenderWidgetTargetResult(const RenderWidgetTargetResult&);
RenderWidgetTargetResult(RenderWidgetHostViewBase* view,
bool should_query_view,
base::Optional<gfx::PointF> location,
- bool latched_target);
+ bool latched_target,
+ bool should_verify_result);
~RenderWidgetTargetResult();
RenderWidgetHostViewBase* view = nullptr;
@@ -48,6 +49,11 @@ struct CONTENT_EXPORT RenderWidgetTargetResult {
// When |latched_target| is false, we explicitly hit-tested events instead of
// using a known target.
bool latched_target = false;
+ // When |should_verify_result| is true, RenderWidgetTargeter will do async hit
+ // testing and compare the target with the result of synchronous hit testing.
+ // |should_verify_result| will always be false if we are doing draw quad based
+ // hit testing.
+ bool should_verify_result = false;
};
class TracingUmaTracker;
@@ -99,7 +105,7 @@ class RenderWidgetTargeter {
private:
// Attempts to target and dispatch all events in the queue. It stops if it has
// to query a client, or if the queue becomes empty.
- void FlushEventQueue();
+ void FlushEventQueue(bool is_verifying);
// Queries |target| to find the correct target for |event|.
// |event| is in the coordinate space of |root_view|.
@@ -107,6 +113,22 @@ class RenderWidgetTargeter {
// |last_request_target| and |last_target_location| provide a fallback target
// the case that the query times out. These should be null values when
// querying the root view, and the target's immediate parent view otherwise.
+ // |expected_frame_sink_id| is temporarily added for v2 viz hit testing.
+ // V2 uses cc generated hit test data and we need to verify its correctness.
+ // The variable is the target frame sink id v2 finds in synchronous hit
+ // testing. It should be the same as the async hit testing target if v2 works
+ // correctly.
+ // TODO(sunxd): Remove |expected_frame_sink_id| after verifying synchronous
+ // hit testing correctness. See https://crbug.com/871996.
+ void QueryClientInternal(RenderWidgetHostViewBase* root_view,
+ RenderWidgetHostViewBase* target,
+ const blink::WebInputEvent& event,
+ const ui::LatencyInfo& latency,
+ const gfx::PointF& target_location,
+ RenderWidgetHostViewBase* last_request_target,
+ const gfx::PointF& last_target_location,
+ const viz::FrameSinkId& expected_frame_sink_id);
+
void QueryClient(RenderWidgetHostViewBase* root_view,
RenderWidgetHostViewBase* target,
const blink::WebInputEvent& event,
@@ -115,6 +137,15 @@ class RenderWidgetTargeter {
RenderWidgetHostViewBase* last_request_target,
const gfx::PointF& last_target_location);
+ void QueryAndVerifyClient(RenderWidgetHostViewBase* root_view,
+ RenderWidgetHostViewBase* target,
+ const blink::WebInputEvent& event,
+ const ui::LatencyInfo& latency,
+ const gfx::PointF& target_location,
+ RenderWidgetHostViewBase* last_request_target,
+ const gfx::PointF& last_target_location,
+ const viz::FrameSinkId& expected_frame_sink_id);
+
// |event| is in the coordinate space of |root_view|. |target_location|, if
// set, is the location in |target|'s coordinate space.
// |target| is the current target that will be queried using its
@@ -122,6 +153,8 @@ class RenderWidgetTargeter {
// |frame_sink_id| is returned from the InputTargetClient to indicate where
// the event should be routed, and |transformed_location| is the point in
// that new target's coordinate space.
+ // |expected_frame_sink_id| is the expected hit test result based on
+ // synchronous event targeting with cc generated data.
void FoundFrameSinkId(base::WeakPtr<RenderWidgetHostViewBase> root_view,
base::WeakPtr<RenderWidgetHostViewBase> target,
ui::WebScopedInputEvent event,
@@ -129,6 +162,7 @@ class RenderWidgetTargeter {
uint32_t request_id,
const gfx::PointF& target_location,
TracingUmaTracker tracker,
+ const viz::FrameSinkId& expected_frame_sink_id,
const viz::FrameSinkId& frame_sink_id,
const gfx::PointF& transformed_location);
@@ -141,7 +175,8 @@ class RenderWidgetTargeter {
const blink::WebInputEvent& event,
const ui::LatencyInfo& latency,
const base::Optional<gfx::PointF>& target_location,
- bool latched_target);
+ bool latched_target,
+ const viz::FrameSinkId& expected_frame_sink_id);
// Callback when the hit testing timer fires, to resume event processing
// without further waiting for a response to the last targeting request.
@@ -152,7 +187,8 @@ class RenderWidgetTargeter {
base::WeakPtr<RenderWidgetHostViewBase> last_request_target,
const gfx::PointF& last_target_location,
ui::WebScopedInputEvent event,
- const ui::LatencyInfo& latency);
+ const ui::LatencyInfo& latency,
+ const viz::FrameSinkId& expected_frame_sink_id);
base::TimeDelta async_hit_test_timeout_delay() {
return async_hit_test_timeout_delay_;
@@ -167,6 +203,7 @@ class RenderWidgetTargeter {
base::WeakPtr<RenderWidgetHostViewBase> root_view;
ui::WebScopedInputEvent event;
ui::LatencyInfo latency;
+ viz::FrameSinkId expected_frame_sink_id;
std::unique_ptr<TracingUmaTracker> tracker;
};
@@ -174,6 +211,13 @@ class RenderWidgetTargeter {
uint32_t last_request_id_ = 0;
std::queue<TargetingRequest> requests_;
+ // With viz-hit-testing-surface-layer being enabled, we do async hit testing
+ // for already dispatched events for verification. These verification requests
+ // should not block normal hit testing requests.
+ bool verify_request_in_flight_ = false;
+ uint32_t last_verify_request_id_ = 0;
+ std::queue<TargetingRequest> verify_requests_;
+
std::unordered_set<RenderWidgetHostViewBase*> unresponsive_views_;
// This value keeps track of the number of clients we have asked in order to
@@ -186,6 +230,9 @@ class RenderWidgetTargeter {
base::TimeDelta::FromMilliseconds(kAsyncHitTestTimeoutMs);
std::unique_ptr<OneShotTimeoutMonitor> async_hit_test_timeout_;
+ std::unique_ptr<OneShotTimeoutMonitor> async_verify_hit_test_timeout_;
+
+ uint64_t trace_id_;
Delegate* const delegate_;
base::WeakPtrFactory<RenderWidgetTargeter> weak_ptr_factory_;
diff --git a/chromium/content/browser/renderer_host/text_input_manager.cc b/chromium/content/browser/renderer_host/text_input_manager.cc
index ce3a5ff83cf..ea4a2725997 100644
--- a/chromium/content/browser/renderer_host/text_input_manager.cc
+++ b/chromium/content/browser/renderer_host/text_input_manager.cc
@@ -6,7 +6,7 @@
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/range/range.h"
@@ -152,7 +152,7 @@ void TextInputManager::ImeCancelComposition(RenderWidgetHostViewBase* view) {
void TextInputManager::SelectionBoundsChanged(
RenderWidgetHostViewBase* view,
- const ViewHostMsg_SelectionBounds_Params& params) {
+ const WidgetHostMsg_SelectionBounds_Params& params) {
DCHECK(IsRegistered(view));
// Converting the anchor point to root's coordinate space (for child frame
// views).
diff --git a/chromium/content/browser/renderer_host/text_input_manager.h b/chromium/content/browser/renderer_host/text_input_manager.h
index b715544c7a2..ff2aac26c4f 100644
--- a/chromium/content/browser/renderer_host/text_input_manager.h
+++ b/chromium/content/browser/renderer_host/text_input_manager.h
@@ -16,7 +16,7 @@
#include "ui/gfx/range/range.h"
#include "ui/gfx/selection_bound.h"
-struct ViewHostMsg_SelectionBounds_Params;
+struct WidgetHostMsg_SelectionBounds_Params;
namespace content {
@@ -181,8 +181,9 @@ class CONTENT_EXPORT TextInputManager {
// Updates the selection bounds for the |view|. In Aura, selection bounds are
// used to provide the InputMethod with the position of the caret, e.g., in
// setting the position of the ui::ImeWindow.
- void SelectionBoundsChanged(RenderWidgetHostViewBase* view,
- const ViewHostMsg_SelectionBounds_Params& params);
+ void SelectionBoundsChanged(
+ RenderWidgetHostViewBase* view,
+ const WidgetHostMsg_SelectionBounds_Params& params);
// Notify observers that the selection bounds have been updated. This is also
// called when a view with a selection is reactivated.
diff --git a/chromium/content/browser/renderer_host/ui_events_helper.cc b/chromium/content/browser/renderer_host/ui_events_helper.cc
index 8b3330f22c9..1ca84152326 100644
--- a/chromium/content/browser/renderer_host/ui_events_helper.cc
+++ b/chromium/content/browser/renderer_host/ui_events_helper.cc
@@ -78,8 +78,9 @@ bool MakeUITouchEventsFromWebTouchEvents(
auto uievent = std::make_unique<ui::TouchEvent>(
type, gfx::Point(), timestamp,
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, point.id,
- point.radius_x, point.radius_y, point.force),
- flags, point.rotation_angle);
+ point.radius_x, point.radius_y, point.force,
+ point.rotation_angle),
+ flags);
uievent->set_location_f(location);
uievent->set_root_location_f(location);
uievent->set_latency(touch_with_latency.latency);
diff --git a/chromium/content/browser/renderer_host/web_database_host_impl.cc b/chromium/content/browser/renderer_host/web_database_host_impl.cc
index da7a48e8903..65af343c3f2 100644
--- a/chromium/content/browser/renderer_host/web_database_host_impl.cc
+++ b/chromium/content/browser/renderer_host/web_database_host_impl.cc
@@ -9,7 +9,9 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "content/browser/child_process_security_policy_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/origin_util.h"
@@ -359,8 +361,8 @@ blink::mojom::WebDatabase& WebDatabaseHostImpl::GetWebDatabase() {
if (!database_provider_) {
// The interface binding needs to occur on the UI thread, as we can
// only call RenderProcessHost::FromID() on the UI thread.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
[](int process_id, blink::mojom::WebDatabaseRequest request) {
RenderProcessHost* host = RenderProcessHost::FromID(process_id);
@@ -374,7 +376,7 @@ blink::mojom::WebDatabase& WebDatabaseHostImpl::GetWebDatabase() {
}
bool WebDatabaseHostImpl::ValidateOrigin(const url::Origin& origin) {
- if (origin.unique()) {
+ if (origin.opaque()) {
mojo::ReportBadMessage("Invalid origin.");
return false;
}
diff --git a/chromium/content/browser/renderer_interface_binders.cc b/chromium/content/browser/renderer_interface_binders.cc
index c3a8bdc572d..5a6e7ed1611 100644
--- a/chromium/content/browser/renderer_interface_binders.cc
+++ b/chromium/content/browser/renderer_interface_binders.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/no_destructor.h"
#include "content/browser/background_fetch/background_fetch_service_impl.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/cookie_store/cookie_store_context.h"
@@ -149,6 +150,13 @@ void RendererInterfaceBinders::InitializeParameterizedBinderRegistry() {
static_cast<RenderProcessHostImpl*>(host)->BindCacheStorage(
std::move(request), origin);
}));
+ // TODO(https://crbug.com/873661): Pass origin to FileSystemMananger.
+ parameterized_binder_registry_.AddInterface(base::BindRepeating(
+ [](blink::mojom::FileSystemManagerRequest request,
+ RenderProcessHost* host, const url::Origin& origin) {
+ static_cast<RenderProcessHostImpl*>(host)->BindFileSystemManager(
+ std::move(request));
+ }));
parameterized_binder_registry_.AddInterface(
base::Bind([](blink::mojom::PermissionServiceRequest request,
RenderProcessHost* host, const url::Origin& origin) {
@@ -186,8 +194,8 @@ void RendererInterfaceBinders::InitializeParameterizedBinderRegistry() {
}
RendererInterfaceBinders& GetRendererInterfaceBinders() {
- CR_DEFINE_STATIC_LOCAL(RendererInterfaceBinders, binders, ());
- return binders;
+ static base::NoDestructor<RendererInterfaceBinders> binders;
+ return *binders;
}
void RendererInterfaceBinders::CreateWebSocket(
diff --git a/chromium/content/browser/resources/gpu/info_view.js b/chromium/content/browser/resources/gpu/info_view.js
index 122f2e874be..780b52a28b3 100644
--- a/chromium/content/browser/resources/gpu/info_view.js
+++ b/chromium/content/browser/resources/gpu/info_view.js
@@ -235,6 +235,7 @@ cr.define('gpu', function() {
'native_gpu_memory_buffers': 'Native GpuMemoryBuffers',
'protected_video_decode': 'Hardware Protected Video Decode',
'surface_synchronization': 'Surface Synchronization',
+ 'surface_control': 'Surface Control',
'vpx_decode': 'VPx Video Decode',
'webgl2': 'WebGL2',
'viz_display_compositor': 'Viz Service Display Compositor',
diff --git a/chromium/content/browser/resources/media/client_renderer.js b/chromium/content/browser/resources/media/client_renderer.js
index 5d04e38d678..894cdd6766f 100644
--- a/chromium/content/browser/resources/media/client_renderer.js
+++ b/chromium/content/browser/resources/media/client_renderer.js
@@ -4,20 +4,24 @@
var ClientRenderer = (function() {
var ClientRenderer = function() {
- this.playerListElement = document.getElementById('player-list');
- var audioTableElement = document.getElementById('audio-property-table');
+ this.playerListElement = $('player-list');
+ var audioTableElement = $('audio-property-table');
if (audioTableElement)
this.audioPropertiesTable = audioTableElement.querySelector('tbody');
- var playerTableElement = document.getElementById('player-property-table');
+ var playerTableElement = $('player-property-table');
if (playerTableElement)
this.playerPropertiesTable = playerTableElement.querySelector('tbody');
- var logElement = document.getElementById('log');
+ var logElement = $('log');
if (logElement)
this.logTable = logElement.querySelector('tbody');
- this.graphElement = document.getElementById('graphs');
- this.audioPropertyName = document.getElementById('audio-property-name');
- this.audioFocusSessionListElement_ =
- document.getElementById('audio-focus-session-list');
+ this.graphElement = $('graphs');
+ this.audioPropertyName = $('audio-property-name');
+ this.audioFocusSessionListElement_ = $('audio-focus-session-list');
+ var generalAudioInformationTableElement = $('general-audio-info-table');
+ if (generalAudioInformationTableElement) {
+ this.generalAudioInformationTable =
+ generalAudioInformationTableElement.querySelector('tbody');
+ }
this.players = null;
this.selectedPlayer = null;
@@ -28,12 +32,12 @@ var ClientRenderer = (function() {
this.selectedPlayerLogIndex = 0;
this.filterFunction = function() { return true; };
- this.filterText = document.getElementById('filter-text');
+ this.filterText = $('filter-text');
if (this.filterText)
this.filterText.onkeyup = this.onTextChange_.bind(this);
- this.clipboardDialog = document.getElementById('clipboard-dialog');
+ this.clipboardDialog = $('clipboard-dialog');
- this.clipboardTextarea = document.getElementById('clipboard-textarea');
+ this.clipboardTextarea = $('clipboard-textarea');
if (this.clipboardTextarea)
this.clipboardTextarea.onblur = this.hideClipboard_.bind(this);
var clipboardButtons = document.getElementsByClassName('copy-button');
@@ -43,7 +47,7 @@ var ClientRenderer = (function() {
}
}
- this.saveLogButton = document.getElementById('save-log-button');
+ this.saveLogButton = $('save-log-button');
if (this.saveLogButton)
this.saveLogButton.onclick = this.saveLog_.bind(this);
@@ -99,7 +103,7 @@ var ClientRenderer = (function() {
}
function selectSelectableButton(id) {
- var element = document.getElementById(id);
+ var element = $(id);
if (!element) {
console.error('failed to select button with id: ' + id);
return;
@@ -118,6 +122,14 @@ var ClientRenderer = (function() {
ClientRenderer.prototype = {
/**
+ * Called to set general audio information.
+ @param audioInfo The map of information.
+ */
+ generalAudioInformationSet: function(audioInfo) {
+ this.drawProperties_(audioInfo, this.generalAudioInformationTable);
+ },
+
+ /**
* Called when an audio component is added to the collection.
* @param componentType Integer AudioComponent enum value; must match values
* from the AudioLogFactory::AudioComponent enum.
@@ -237,14 +249,12 @@ var ClientRenderer = (function() {
},
redrawVideoCaptureCapabilities: function(videoCaptureCapabilities, keys) {
- var copyButtonElement =
- document.getElementById('video-capture-capabilities-copy-button');
+ var copyButtonElement = $('video-capture-capabilities-copy-button');
copyButtonElement.onclick = function() {
this.showClipboard(JSON.stringify(videoCaptureCapabilities, null, 2));
}.bind(this);
- var videoTableBodyElement =
- document.getElementById('video-capture-capabilities-tbody');
+ var videoTableBodyElement = $('video-capture-capabilities-tbody');
removeChildren(videoTableBodyElement);
for (var component in videoCaptureCapabilities) {
@@ -289,16 +299,13 @@ var ClientRenderer = (function() {
var listElement;
switch (componentType) {
case 0:
- listElement = document.getElementById(
- 'audio-input-controller-list');
+ listElement = $('audio-input-controller-list');
break;
case 1:
- listElement = document.getElementById(
- 'audio-output-controller-list');
+ listElement = $('audio-output-controller-list');
break;
case 2:
- listElement = document.getElementById(
- 'audio-output-stream-list');
+ listElement = $('audio-output-stream-list');
break;
default:
console.error('Unrecognized component type: ' + componentType);
@@ -323,13 +330,13 @@ var ClientRenderer = (function() {
var fragment = document.createDocumentFragment();
for (var id in components) {
var li = document.createElement('li');
- var button_cb = this.selectAudioComponent_.bind(
+ var buttonCb = this.selectAudioComponent_.bind(
this, componentType, id, components[id]);
var friendlyName = this.getAudioComponentName_(componentType, id);
var label = document.createElement('label');
label.appendChild(document.createTextNode(friendlyName));
- li.appendChild(createSelectableButton(
- id, buttonGroupName, label, button_cb));
+ li.appendChild(
+ createSelectableButton(id, buttonGroupName, label, buttonCb));
fragment.appendChild(li);
}
removeChildren(listElement);
@@ -372,23 +379,23 @@ var ClientRenderer = (function() {
var p = player.properties;
var label = document.createElement('label');
- var name_text = p.url || 'Player ' + player.id;
- var name_node = document.createElement('div');
- name_node.appendChild(document.createTextNode(name_text));
- name_node.className = 'player-name';
- label.appendChild(name_node);
+ var nameText = p.url || 'Player ' + player.id;
+ var nameNode = document.createElement('div');
+ nameNode.appendChild(document.createTextNode(nameText));
+ nameNode.className = 'player-name';
+ label.appendChild(nameNode);
var frame = [];
if (p.frame_title)
frame.push(p.frame_title);
if (p.frame_url)
frame.push(p.frame_url);
- var frame_text = frame.join(' - ');
- if (frame_text) {
- var frame_node = document.createElement('div');
- frame_node.className = 'player-frame';
- frame_node.appendChild(document.createTextNode(frame_text));
- label.appendChild(frame_node);
+ var frameText = frame.join(' - ');
+ if (frameText) {
+ var frameNode = document.createElement('div');
+ frameNode.className = 'player-frame';
+ frameNode.appendChild(document.createTextNode(frameText));
+ label.appendChild(frameNode);
}
var desc = [];
@@ -402,18 +409,18 @@ var ClientRenderer = (function() {
desc.push(p.audio_codec_name);
if (p.event)
desc.push('(' + p.event + ')');
- var desc_text = desc.join(' ');
- if (desc_text) {
- var desc_node = document.createElement('div');
- desc_node.className = 'player-desc';
- desc_node.appendChild(document.createTextNode(desc_text));
- label.appendChild(desc_node);
+ var descText = desc.join(' ');
+ if (descText) {
+ var descNode = document.createElement('div');
+ descNode.className = 'player-desc';
+ descNode.appendChild(document.createTextNode(descText));
+ label.appendChild(descNode);
}
var li = document.createElement('li');
- var button_cb = this.selectPlayer_.bind(this, player);
+ var buttonCb = this.selectPlayer_.bind(this, player);
li.appendChild(createSelectableButton(
- id, buttonGroupName, label, button_cb, player.destructed));
+ id, buttonGroupName, label, buttonCb, player.destructed));
fragment.appendChild(li);
}
removeChildren(this.playerListElement);
diff --git a/chromium/content/browser/resources/media/main.js b/chromium/content/browser/resources/media/main.js
index 9a25be49b7e..082b336a997 100644
--- a/chromium/content/browser/resources/media/main.js
+++ b/chromium/content/browser/resources/media/main.js
@@ -17,6 +17,10 @@ var media = (function() {
manager = theManager;
};
+ media.updateGeneralAudioInformation = function(audioInfo) {
+ manager.updateGeneralAudioInformation(audioInfo);
+ };
+
media.onReceiveAudioStreamData = function(audioStreamData) {
for (var component in audioStreamData) {
media.updateAudioComponent(audioStreamData[component]);
diff --git a/chromium/content/browser/resources/media/manager.js b/chromium/content/browser/resources/media/manager.js
index 994df2b5bfe..cc75fe75d47 100644
--- a/chromium/content/browser/resources/media/manager.js
+++ b/chromium/content/browser/resources/media/manager.js
@@ -14,12 +14,13 @@ var Manager = (function() {
function Manager(clientRenderer) {
this.players_ = {};
+ this.audioInfo_ = {};
this.audioComponents_ = [];
this.clientRenderer_ = clientRenderer;
- var copyAllPlayerButton = document.getElementById('copy-all-player-button');
- var copyAllAudioButton = document.getElementById('copy-all-audio-button');
- var hidePlayersButton = document.getElementById('hide-players-button');
+ var copyAllPlayerButton = $('copy-all-player-button');
+ var copyAllAudioButton = $('copy-all-audio-button');
+ var hidePlayersButton = $('hide-players-button');
// In tests we may not have these buttons.
if (copyAllPlayerButton) {
@@ -31,7 +32,8 @@ var Manager = (function() {
if (copyAllAudioButton) {
copyAllAudioButton.onclick = function() {
this.clientRenderer_.showClipboard(
- JSON.stringify(this.audioComponents_, null, 2));
+ JSON.stringify(this.audioInfo_, null, 2) + '\n\n' +
+ JSON.stringify(this.audioComponents_, null, 2));
}.bind(this);
}
if (hidePlayersButton) {
@@ -49,6 +51,15 @@ var Manager = (function() {
},
/**
+ * Updates the general audio information.
+ * @param audioInfo The map of information.
+ */
+ updateGeneralAudioInformation: function(audioInfo) {
+ this.audioInfo_ = audioInfo;
+ this.clientRenderer_.generalAudioInformationSet(this.audioInfo_);
+ },
+
+ /**
* Updates an audio-component.
* @param componentType Integer AudioComponent enum value; must match values
* from the AudioLogFactory::AudioComponent enum.
diff --git a/chromium/content/browser/resources/media/media_internals.html b/chromium/content/browser/resources/media/media_internals.html
index 6df11b93b5c..57c84338fd0 100644
--- a/chromium/content/browser/resources/media/media_internals.html
+++ b/chromium/content/browser/resources/media/media_internals.html
@@ -72,6 +72,18 @@ found in the LICENSE file.
</tabpanel>
<tabpanel id="audio">
<button id="copy-all-audio-button">Copy all to clipboard</button>
+ <div>
+ <h2>General Information</h2>
+ <table id="general-audio-info-table">
+ <thead>
+ <tr>
+ <th>Property</th>
+ <th>Value</th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
<div id="audio-component-list-wrapper">
<h2>Input Controllers</h2>
<ul id="audio-input-controller-list" class="show-none-if-empty"></ul>
diff --git a/chromium/content/browser/resources/media/stats_graph_helper.js b/chromium/content/browser/resources/media/stats_graph_helper.js
index daa28866f6a..30cdf0ee298 100644
--- a/chromium/content/browser/resources/media/stats_graph_helper.js
+++ b/chromium/content/browser/resources/media/stats_graph_helper.js
@@ -36,8 +36,8 @@ var totalToPerSecond = function(srcDataSeries) {
if (length >= 2) {
var lastDataPoint = srcDataSeries.dataPoints_[length - 1];
var secondLastDataPoint = srcDataSeries.dataPoints_[length - 2];
- return (lastDataPoint.value - secondLastDataPoint.value) * 1000 /
- (lastDataPoint.time - secondLastDataPoint.time);
+ return Math.floor((lastDataPoint.value - secondLastDataPoint.value) * 1000 /
+ (lastDataPoint.time - secondLastDataPoint.time));
}
return 0;
diff --git a/chromium/content/browser/resources/media/util.js b/chromium/content/browser/resources/media/util.js
index 29cc1b152e3..3ab7da77a2b 100644
--- a/chromium/content/browser/resources/media/util.js
+++ b/chromium/content/browser/resources/media/util.js
@@ -30,17 +30,19 @@ var util = (function() {
}
};
util.millisecondsToString = function(timeMillis) {
- function pad(num) {
+ function pad(num, len) {
num = num.toString();
- if (num.length < 2) {
- return '0' + num;
+ while (num.length < len) {
+ num = '0' + num;
}
return num;
}
var date = new Date(timeMillis);
- return pad(date.getUTCHours()) + ':' + pad(date.getUTCMinutes()) + ':' +
- pad(date.getUTCSeconds()) + ' ' + pad((date.getMilliseconds()) % 1000);
+ return pad(date.getUTCHours(), 2) + ':' +
+ pad(date.getUTCMinutes(), 2) + ':' +
+ pad(date.getUTCSeconds(), 2) + '.' +
+ pad((date.getMilliseconds()) % 1000, 3);
};
return util;
diff --git a/chromium/content/browser/resources/process/process_internals.css b/chromium/content/browser/resources/process/process_internals.css
new file mode 100644
index 00000000000..ce59e9da8c7
--- /dev/null
+++ b/chromium/content/browser/resources/process/process_internals.css
@@ -0,0 +1,86 @@
+/* Copyright 2018 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file. */
+
+* {
+ box-sizing: border-box;
+}
+
+html {
+ height: 100%;
+}
+
+body {
+ color: rgb(48, 57, 66);
+ display: flex;
+ flex-direction: column;
+ font-size: 13px;
+ height: 100%;
+ margin: 0;
+ overflow: auto;
+}
+
+#container {
+ display: flex;
+ height: 100%
+}
+
+#navigation {
+ flex-shrink: 0;
+ padding-top: 20px;
+ width: 200px;
+}
+
+#content {
+ flex-grow: 1;
+}
+
+#caption {
+ color: rgb(92, 97, 102);
+ font-size: 1.5rem;
+ padding-bottom: 10px;
+ padding-inline-start: 20px;
+}
+
+.tab-header {
+ border-inline-start: 6px solid transparent;
+ padding-left: 15px;
+}
+
+.tab-header.selected {
+ border-inline-start-color: rgb(78, 87, 100);
+}
+
+.tab-header > button {
+ background-color: white;
+ border: 0;
+ cursor: pointer;
+ font: inherit;
+ line-height: 17px;
+ margin: 6px 0;
+ padding: 0 2px;
+}
+
+.tab-header:not(.selected) > button {
+ color: #999;
+}
+
+#content > div {
+ min-width: 32em;
+ padding: 0 20px 65px 0;
+}
+#content > div:not(.selected) {
+ display: none;
+}
+
+.content-header {
+ background: linear-gradient(white, white 40%, rgba(255, 255, 255, 0.92));
+ border-bottom: 1px solid #eee;
+ font-size: 150%;
+ padding: 20px 0 10px 0;
+ z-index: 1;
+}
+
+.tree-label {
+ user-select: text;
+}
diff --git a/chromium/content/browser/resources/process/process_internals.html b/chromium/content/browser/resources/process/process_internals.html
index 9b63631e817..595fbdcdaae 100644
--- a/chromium/content/browser/resources/process/process_internals.html
+++ b/chromium/content/browser/resources/process/process_internals.html
@@ -6,11 +6,50 @@
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
+ <script src="chrome://resources/js/util.js"></script>
+ <script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/mojo_bindings.js"></script>
+
+ <link rel="stylesheet" href="chrome://resources/css/tree.css">
+ <script src="chrome://resources/js/cr/ui.js"></script>
+ <script src="chrome://resources/js/cr/ui/tree.js"></script>
+
+ <link rel="stylesheet" href="process_internals.css">
+ <script src="url.mojom.js"></script>
<script src="process_internals.mojom.js"></script>
<script src='process_internals.js'></script>
<title>Process Model Internals</title>
</head>
-<div id="site-isolation-mode">Site Isolation mode: <span id='isolation-mode'>unknown</span></div>
-<div id="isolated-origins-container">Number of isolated origins: <span id='isolated-origins'></span></div>
+<body>
+
+<div id="container">
+ <div id="navigation">
+ <div id="caption">Process Internals</div>
+ </div>
+ <div id="content">
+ <div id="general">
+ <div class="content-header">General info</div>
+ <div id="general-info">
+ <div id="site-isolation-mode">Site Isolation mode: <span id='isolation-mode'>unknown</span></div>
+ <div id="isolated-origins-container">Number of isolated origins: <span id='isolated-origins'></span></div>
+ </div>
+ </div>
+ <div id="web-contents">
+ <div class="content-header">Frame Trees</div>
+ <div id="wc-list" class="list pages"></div>
+ <div id="tree-view-container">
+ <button id="refresh-button">Refresh</button>
+ <div>Legend:</div>
+ <div>Frame[<i>process_id</i>:<i>routing_id</i>]:
+ SI:<i>site_instance_id</i>, <i>whether process is locked to a
+ site</i>, site: <i>site_url</i> | url:
+ <i>last_committed_url</i>
+ </div>
+ <tree id="tree-view"></tree>
+ </div>
+ </div>
+ </div>
+</div>
+
+</body>
</html>
diff --git a/chromium/content/browser/resources/process/process_internals.js b/chromium/content/browser/resources/process/process_internals.js
index 155847443a7..c299e9a8c02 100644
--- a/chromium/content/browser/resources/process/process_internals.js
+++ b/chromium/content/browser/resources/process/process_internals.js
@@ -2,16 +2,169 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-console.log('process internals initializing');
-
(function() {
'use strict';
/**
- * Reference to the backend.
+ * Reference to the backend providing all the data.
* @type {mojom.ProcessInternalsHandlerPtr}
*/
-var uiHandler = null;
+let uiHandler = null;
+
+/**
+ * @param {string} id Tab id.
+ * @return {boolean} True if successful.
+ */
+function selectTab(id) {
+ const tabContents = document.querySelectorAll('#content > div');
+ const tabHeaders = $('navigation').querySelectorAll('.tab-header');
+ let found = false;
+ for (let i = 0; i < tabContents.length; i++) {
+ const tabContent = tabContents[i];
+ const tabHeader = tabHeaders[i];
+ const isTargetTab = tabContent.id == id;
+
+ found = found || isTargetTab;
+ tabContent.classList.toggle('selected', isTargetTab);
+ tabHeader.classList.toggle('selected', isTargetTab);
+ }
+ if (!found)
+ return false;
+ window.location.hash = id;
+ return true;
+}
+
+function onHashChange() {
+ let hash = window.location.hash.slice(1).toLowerCase();
+ if (!selectTab(hash))
+ selectTab('general');
+}
+
+function setupTabs() {
+ const tabContents = document.querySelectorAll('#content > div');
+ for (let i = 0; i < tabContents.length; i++) {
+ const tabContent = tabContents[i];
+ const tabName = tabContent.querySelector('.content-header').textContent;
+
+ let tabHeader = document.createElement('div');
+ tabHeader.className = 'tab-header';
+ let button = document.createElement('button');
+ button.textContent = tabName;
+ tabHeader.appendChild(button);
+ tabHeader.addEventListener('click', selectTab.bind(null, tabContent.id));
+ $('navigation').appendChild(tabHeader);
+ }
+ onHashChange();
+}
+
+/**
+ * Root of the WebContents tree.
+ * @type {cr.ui.Tree|null}
+ */
+let treeViewRoot = null;
+
+/**
+ * Initialize and return |treeViewRoot|.
+ * @return {cr.ui.Tree} Initialized |treeViewRoot|.
+ */
+function getTreeViewRoot() {
+ if (!treeViewRoot) {
+ cr.ui.decorate('#tree-view', cr.ui.Tree);
+
+ treeViewRoot = /** @type {cr.ui.Tree} */ ($('tree-view'));
+ treeViewRoot.detail = {payload: {}, children: {}};
+ }
+ return treeViewRoot;
+}
+
+/**
+ * Initialize and return a tree item representing a FrameInfo object and
+ * recursively creates its subframe objects.
+ * @param {mojom.FrameInfo} frame
+ * @return {Array}
+ */
+function frameToTreeItem(frame) {
+ // Compose the string which will appear in the entry for this frame.
+ let itemLabel = `Frame[${frame.processId}:${frame.routingId}]:`;
+ itemLabel += ` SI:${frame.siteInstance.id}`;
+ if (frame.siteInstance.locked)
+ itemLabel += ', locked';
+ if (frame.siteInstance.siteUrl)
+ itemLabel += `, site:${frame.siteInstance.siteUrl.url}`;
+ if (frame.lastCommittedUrl)
+ itemLabel += ` | url: ${frame.lastCommittedUrl.url}`;
+
+ let item = new cr.ui.TreeItem(
+ {label: itemLabel, detail: {payload: {}, children: {}}});
+ item.mayHaveChildren_ = true;
+ item.expanded = true;
+ item.icon = '';
+
+ let frameCount = 1;
+ for (const subframe of frame.subframes) {
+ let result = frameToTreeItem(subframe);
+ const subItem = result[0];
+ const count = result[1];
+
+ frameCount += count;
+ item.add(subItem);
+ }
+
+ return [item, frameCount];
+}
+
+/**
+ * Initialize and return a tree item representing the WebContentsInfo object
+ * and contains all frames in it as a subtree.
+ * @param {mojom.WebContentsInfo} webContents
+ * @return {cr.ui.TreeItem}
+ */
+function webContentsToTreeItem(webContents) {
+ let itemLabel = 'WebContents: ';
+ if (webContents.title.length > 0)
+ itemLabel += webContents.title + ', ';
+
+ let item = new cr.ui.TreeItem(
+ {label: itemLabel, detail: {payload: {}, children: {}}});
+ item.mayHaveChildren_ = true;
+ item.expanded = true;
+ item.icon = '';
+
+ let result = frameToTreeItem(webContents.rootFrame);
+ const rootItem = result[0];
+ const count = result[1];
+
+ itemLabel += `${count} frame` + (count > 1 ? 's.' : '.');
+ item.label = itemLabel;
+
+ item.add(rootItem);
+ return item;
+}
+
+/**
+ * This is a callback which is invoked when the data for WebContents
+ * associated with the browser profile is received from the browser process.
+ * @param {mojom.ProcessInternalsHandler_GetAllWebContentsInfo_ResponseParams} input
+ */
+function populateWebContentsTab(input) {
+ let tree = getTreeViewRoot();
+
+ // Clear the tree first before populating it with the new content.
+ tree.innerText = '';
+
+ for (const webContents of input.infos) {
+ const item = webContentsToTreeItem(webContents);
+ tree.add(item);
+ }
+}
+
+/**
+ * Function which retrieves the data for all WebContents associated with the
+ * current browser profile. The result is passed to populateWebContentsTab.
+ */
+function loadWebContentsInfo() {
+ uiHandler.getAllWebContentsInfo().then(populateWebContentsTab);
+}
document.addEventListener('DOMContentLoaded', function() {
// Setup Mojo interface to the backend.
@@ -22,11 +175,19 @@ document.addEventListener('DOMContentLoaded', function() {
// Get the Site Isolation mode and populate it.
uiHandler.getIsolationMode().then((response) => {
- document.getElementById('isolation-mode').innerText = response.mode;
+ $('isolation-mode').innerText = response.mode;
});
uiHandler.getIsolatedOriginsSize().then((response) => {
- document.getElementById('isolated-origins').innerText = response.size;
+ $('isolated-origins').innerText = response.size;
});
+
+ // Setup the tabbed UI
+ setupTabs();
+
+ // Start loading the information about WebContents.
+ loadWebContentsInfo();
+
+ $('refresh-button').addEventListener('click', loadWebContentsInfo);
});
})();
diff --git a/chromium/content/browser/scheduler/OWNERS b/chromium/content/browser/scheduler/OWNERS
new file mode 100644
index 00000000000..970514cb53e
--- /dev/null
+++ b/chromium/content/browser/scheduler/OWNERS
@@ -0,0 +1,4 @@
+altimin@chromium.org
+alexclarke@chromium.org
+eseckler@chromium.org
+skyostil@chromium.org
diff --git a/chromium/content/browser/scheduler/browser_task_executor.cc b/chromium/content/browser/scheduler/browser_task_executor.cc
new file mode 100644
index 00000000000..e96642469fc
--- /dev/null
+++ b/chromium/content/browser/scheduler/browser_task_executor.cc
@@ -0,0 +1,153 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/scheduler/browser_task_executor.h"
+
+#include "base/no_destructor.h"
+#include "content/browser/browser_thread_impl.h"
+
+namespace content {
+namespace {
+
+// |g_browser_task_executor| is intentionally leaked on shutdown.
+BrowserTaskExecutor* g_browser_task_executor = nullptr;
+
+// An implementation of SingleThreadTaskRunner to be used in conjunction with
+// BrowserThread. BrowserThreadTaskRunners are vended by
+// base::Create*TaskRunnerWithTraits({BrowserThread::UI/IO}).
+//
+// TODO(gab): Consider replacing this with direct calls to task runners obtained
+// via |BrowserThreadImpl::GetTaskRunnerForThread()| -- only works if none are
+// requested before starting the threads.
+class BrowserThreadTaskRunner : public base::SingleThreadTaskRunner {
+ public:
+ explicit BrowserThreadTaskRunner(BrowserThread::ID identifier)
+ : id_(identifier) {}
+
+ // SingleThreadTaskRunner implementation.
+ bool PostDelayedTask(const base::Location& from_here,
+ base::OnceClosure task,
+ base::TimeDelta delay) override {
+ return BrowserThreadImpl::GetTaskRunnerForThread(id_)->PostDelayedTask(
+ from_here, std::move(task), delay);
+ }
+
+ bool PostNonNestableDelayedTask(const base::Location& from_here,
+ base::OnceClosure task,
+ base::TimeDelta delay) override {
+ return BrowserThreadImpl::GetTaskRunnerForThread(id_)
+ ->PostNonNestableDelayedTask(from_here, std::move(task), delay);
+ }
+
+ bool RunsTasksInCurrentSequence() const override {
+ return BrowserThread::CurrentlyOn(id_);
+ }
+
+ private:
+ ~BrowserThreadTaskRunner() override {}
+
+ const BrowserThread::ID id_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserThreadTaskRunner);
+};
+
+} // namespace
+
+BrowserTaskExecutor::BrowserTaskExecutor() = default;
+BrowserTaskExecutor::~BrowserTaskExecutor() = default;
+
+// static
+void BrowserTaskExecutor::Create() {
+ DCHECK(!g_browser_task_executor);
+ g_browser_task_executor = new BrowserTaskExecutor();
+ base::RegisterTaskExecutor(BrowserTaskTraitsExtension::kExtensionId,
+ g_browser_task_executor);
+}
+
+// static
+void BrowserTaskExecutor::ResetForTesting() {
+ if (g_browser_task_executor) {
+ base::UnregisterTaskExecutorForTesting(
+ BrowserTaskTraitsExtension::kExtensionId);
+ delete g_browser_task_executor;
+ g_browser_task_executor = nullptr;
+ }
+}
+
+bool BrowserTaskExecutor::PostDelayedTaskWithTraits(
+ const base::Location& from_here,
+ const base::TaskTraits& traits,
+ base::OnceClosure task,
+ base::TimeDelta delay) {
+ DCHECK_EQ(BrowserTaskTraitsExtension::kExtensionId, traits.extension_id());
+ const BrowserTaskTraitsExtension& extension =
+ traits.GetExtension<BrowserTaskTraitsExtension>();
+ if (extension.nestable()) {
+ return GetTaskRunner(extension)->PostDelayedTask(from_here, std::move(task),
+ delay);
+ } else {
+ return GetTaskRunner(extension)->PostNonNestableDelayedTask(
+ from_here, std::move(task), delay);
+ }
+}
+
+scoped_refptr<base::TaskRunner> BrowserTaskExecutor::CreateTaskRunnerWithTraits(
+ const base::TaskTraits& traits) {
+ return GetTaskRunner(traits);
+}
+
+scoped_refptr<base::SequencedTaskRunner>
+BrowserTaskExecutor::CreateSequencedTaskRunnerWithTraits(
+ const base::TaskTraits& traits) {
+ return GetTaskRunner(traits);
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+BrowserTaskExecutor::CreateSingleThreadTaskRunnerWithTraits(
+ const base::TaskTraits& traits,
+ base::SingleThreadTaskRunnerThreadMode thread_mode) {
+ return GetTaskRunner(traits);
+}
+
+#if defined(OS_WIN)
+scoped_refptr<base::SingleThreadTaskRunner>
+BrowserTaskExecutor::CreateCOMSTATaskRunnerWithTraits(
+ const base::TaskTraits& traits,
+ base::SingleThreadTaskRunnerThreadMode thread_mode) {
+ return GetTaskRunner(traits);
+}
+#endif // defined(OS_WIN)
+
+scoped_refptr<base::SingleThreadTaskRunner> BrowserTaskExecutor::GetTaskRunner(
+ const base::TaskTraits& traits) {
+ DCHECK_EQ(BrowserTaskTraitsExtension::kExtensionId, traits.extension_id());
+ const BrowserTaskTraitsExtension& extension =
+ traits.GetExtension<BrowserTaskTraitsExtension>();
+ return GetTaskRunner(extension);
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> BrowserTaskExecutor::GetTaskRunner(
+ const BrowserTaskTraitsExtension& extension) {
+ BrowserThread::ID thread_id = extension.browser_thread();
+ DCHECK_GE(thread_id, 0);
+ DCHECK_LT(thread_id, BrowserThread::ID::ID_COUNT);
+ return GetProxyTaskRunnerForThread(thread_id);
+}
+
+// static
+scoped_refptr<base::SingleThreadTaskRunner>
+BrowserTaskExecutor::GetProxyTaskRunnerForThread(BrowserThread::ID id) {
+ using TaskRunnerMap = std::array<scoped_refptr<base::SingleThreadTaskRunner>,
+ BrowserThread::ID_COUNT>;
+ static const base::NoDestructor<TaskRunnerMap> task_runners([] {
+ TaskRunnerMap task_runners;
+ for (int i = 0; i < BrowserThread::ID_COUNT; ++i)
+ task_runners[i] = base::MakeRefCounted<BrowserThreadTaskRunner>(
+ static_cast<BrowserThread::ID>(i));
+ return task_runners;
+ }());
+ return (*task_runners)[id];
+}
+
+} // namespace content
diff --git a/chromium/content/browser/scheduler/browser_task_executor.h b/chromium/content/browser/scheduler/browser_task_executor.h
new file mode 100644
index 00000000000..418d6176f04
--- /dev/null
+++ b/chromium/content/browser/scheduler/browser_task_executor.h
@@ -0,0 +1,74 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SCHEDULER_BROWSER_TASK_EXECUTOR_H_
+#define CONTENT_BROWSER_SCHEDULER_BROWSER_TASK_EXECUTOR_H_
+
+#include "base/gtest_prod_util.h"
+#include "base/task/task_executor.h"
+#include "build/build_config.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/browser_task_traits.h"
+
+namespace content {
+
+// This class's job is to map base::TaskTraits to actual task queues for the
+// browser process.
+class CONTENT_EXPORT BrowserTaskExecutor : public base::TaskExecutor {
+ public:
+ // Creates and registers a BrowserTaskExecutor that facilitates posting tasks
+ // to a BrowserThread via //base/task/post_task.h.
+ static void Create();
+
+ // Unregister and delete the TaskExecutor after a test.
+ static void ResetForTesting();
+
+ // base::TaskExecutor implementation.
+ bool PostDelayedTaskWithTraits(const base::Location& from_here,
+ const base::TaskTraits& traits,
+ base::OnceClosure task,
+ base::TimeDelta delay) override;
+
+ scoped_refptr<base::TaskRunner> CreateTaskRunnerWithTraits(
+ const base::TaskTraits& traits) override;
+
+ scoped_refptr<base::SequencedTaskRunner> CreateSequencedTaskRunnerWithTraits(
+ const base::TaskTraits& traits) override;
+
+ scoped_refptr<base::SingleThreadTaskRunner>
+ CreateSingleThreadTaskRunnerWithTraits(
+ const base::TaskTraits& traits,
+ base::SingleThreadTaskRunnerThreadMode thread_mode) override;
+
+#if defined(OS_WIN)
+ scoped_refptr<base::SingleThreadTaskRunner> CreateCOMSTATaskRunnerWithTraits(
+ const base::TaskTraits& traits,
+ base::SingleThreadTaskRunnerThreadMode thread_mode) override;
+#endif // defined(OS_WIN)
+
+ private:
+ // For GetProxyTaskRunnerForThread().
+ FRIEND_TEST_ALL_PREFIXES(BrowserTaskExecutorTest,
+ EnsureUIThreadTraitPointsToExpectedQueue);
+ FRIEND_TEST_ALL_PREFIXES(BrowserTaskExecutorTest,
+ EnsureIOThreadTraitPointsToExpectedQueue);
+
+ BrowserTaskExecutor();
+ ~BrowserTaskExecutor() override;
+
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(
+ const base::TaskTraits& traits);
+
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(
+ const BrowserTaskTraitsExtension& extension);
+
+ static scoped_refptr<base::SingleThreadTaskRunner>
+ GetProxyTaskRunnerForThread(BrowserThread::ID id);
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserTaskExecutor);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SCHEDULER_BROWSER_TASK_EXECUTOR_H_
diff --git a/chromium/content/browser/scheduler/browser_task_executor_unittest.cc b/chromium/content/browser/scheduler/browser_task_executor_unittest.cc
new file mode 100644
index 00000000000..7f283afecab
--- /dev/null
+++ b/chromium/content/browser/scheduler/browser_task_executor_unittest.cc
@@ -0,0 +1,51 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/scheduler/browser_task_executor.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/task/post_task.h"
+#include "base/task/task_scheduler/task_scheduler.h"
+#include "content/browser/browser_thread_impl.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class BrowserTaskExecutorTest : public testing::Test {
+ public:
+ void SetUp() override {
+ base::TaskScheduler::CreateAndStartWithDefaultParams("Test");
+ BrowserTaskExecutor::Create();
+ message_loop_ = std::make_unique<base::MessageLoop>();
+ }
+
+ void TearDown() override {
+ BrowserTaskExecutor::ResetForTesting();
+ base::TaskScheduler::GetInstance()->Shutdown();
+ base::TaskScheduler::GetInstance()->JoinForTesting();
+ base::TaskScheduler::SetInstance(nullptr);
+ message_loop_.reset();
+ }
+
+ static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
+
+ protected:
+ std::unique_ptr<base::MessageLoop> message_loop_;
+};
+
+TEST_F(BrowserTaskExecutorTest, EnsureUIThreadTraitPointsToExpectedQueue) {
+ EXPECT_EQ(
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI}),
+ BrowserTaskExecutor::GetProxyTaskRunnerForThread(BrowserThread::UI));
+}
+
+TEST_F(BrowserTaskExecutorTest, EnsureIOThreadTraitPointsToExpectedQueue) {
+ EXPECT_EQ(
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
+ BrowserTaskExecutor::GetProxyTaskRunnerForThread(BrowserThread::IO));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/scheduler/responsiveness/README b/chromium/content/browser/scheduler/responsiveness/README
index 68ee4d93be7..96429ebb75a 100644
--- a/chromium/content/browser/scheduler/responsiveness/README
+++ b/chromium/content/browser/scheduler/responsiveness/README
@@ -3,7 +3,7 @@ execution latency on the UI and IO threads of the browser process.
There are four types of work executed on the UI and IO threads.
1) Both the UI and IO threads can have tasks posted to them via the Task
- Scheduler [e.g. via content::BrowserThread::PostTask].
+ Scheduler [e.g. via base::PostTaskWithTraits with a BrowserThread::ID].
2) The UI thread processes native events directly from the message loop
[NSEvents on macOS, MSGs on Windows, InputEvents on Android, XEvents on
X11, etc.]
diff --git a/chromium/content/browser/scheduler/responsiveness/native_event_observer.cc b/chromium/content/browser/scheduler/responsiveness/native_event_observer.cc
index 4225e9aa6df..0aa5e6e69fa 100644
--- a/chromium/content/browser/scheduler/responsiveness/native_event_observer.cc
+++ b/chromium/content/browser/scheduler/responsiveness/native_event_observer.cc
@@ -17,14 +17,9 @@
#include "ui/events/platform/platform_event_source.h"
-#if defined(USE_X11)
-#include "ui/events/platform/x11/x11_event_source.h" // nogncheck
-#elif defined(USE_OZONE)
-#include "ui/events/event.h"
-#endif
-
#if defined(OS_LINUX)
-#include "ui/events/platform_event.h"
+#include "ui/aura/env.h"
+#include "ui/events/event.h"
#endif
#if defined(OS_WIN)
@@ -71,41 +66,25 @@ NativeEventObserver::~NativeEventObserver() {
#if defined(OS_LINUX)
void NativeEventObserver::RegisterObserver() {
- ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
+ aura::Env::GetInstance()->AddWindowEventDispatcherObserver(this);
}
void NativeEventObserver::DeregisterObserver() {
- ui::PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
+ aura::Env::GetInstance()->RemoveWindowEventDispatcherObserver(this);
}
-void NativeEventObserver::WillProcessEvent(const ui::PlatformEvent& event) {
+void NativeEventObserver::OnWindowEventDispatcherStartedProcessing(
+ aura::WindowEventDispatcher* dispatcher,
+ const ui::Event& event) {
+ EventInfo info{&event, event.time_stamp()};
+ events_being_processed_.push_back(info);
will_run_event_callback_.Run(&event);
}
-void NativeEventObserver::DidProcessEvent(const ui::PlatformEvent& event) {
-#if defined(USE_OZONE)
- did_run_event_callback_.Run(&event, event->time_stamp());
-#elif defined(USE_X11)
- // X11 uses a uint32_t on the wire protocol. Xlib casts this to an unsigned
- // long by prepending with 0s. We cast back to a uint32_t so that subtraction
- // works properly when the timestamp overflows back to 0.
- uint32_t event_server_time_ms =
- static_cast<uint32_t>(ui::X11EventSource::GetInstance()->GetTimestamp());
- uint32_t current_server_time_ms = static_cast<uint32_t>(
- ui::X11EventSource::GetInstance()->GetCurrentServerTime());
-
- // On X11, event times are in X11 Server time. To convert to base::TimeTicks,
- // we perform a round-trip to the X11 Server, subtract the two times to get a
- // TimeDelta, and then subtract that from base::TimeTicks::Now(). Since we're
- // working with units of time from an external source, we clamp the TimeDelta
- // to reasonable values.
- uint32_t delta_ms = current_server_time_ms - event_server_time_ms;
- base::TimeDelta delta = base::TimeDelta::FromMilliseconds(delta_ms);
- base::TimeDelta sanitized = ClampDeltaFromExternalSource(delta);
-
- did_run_event_callback_.Run(&event, base::TimeTicks::Now() - sanitized);
-#else
-#error
-#endif
+void NativeEventObserver::OnWindowEventDispatcherFinishedProcessingEvent(
+ aura::WindowEventDispatcher* dispatcher) {
+ EventInfo& info = events_being_processed_.back();
+ did_run_event_callback_.Run(info.unique_id, info.creation_time);
+ events_being_processed_.pop_back();
}
#endif // defined(OS_LINUX)
diff --git a/chromium/content/browser/scheduler/responsiveness/native_event_observer.h b/chromium/content/browser/scheduler/responsiveness/native_event_observer.h
index 5aaefd3daf5..cf2ef28d0d0 100644
--- a/chromium/content/browser/scheduler/responsiveness/native_event_observer.h
+++ b/chromium/content/browser/scheduler/responsiveness/native_event_observer.h
@@ -7,6 +7,7 @@
#include "base/callback.h"
#include "base/macros.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
@@ -15,7 +16,7 @@
#endif
#if defined(OS_LINUX)
-#include "ui/events/platform/platform_event_observer.h"
+#include "ui/aura/window_event_dispatcher_observer.h"
#endif
#if defined(OS_WIN)
@@ -40,7 +41,7 @@ class CONTENT_EXPORT NativeEventObserver
#if defined(OS_MACOSX)
: public NativeEventProcessorObserver
#elif defined(OS_LINUX)
- : public ui::PlatformEventObserver
+ : public aura::WindowEventDispatcherObserver
#elif defined(OS_WIN)
: public base::MessagePumpForUI::Observer
#endif
@@ -73,10 +74,12 @@ class CONTENT_EXPORT NativeEventObserver
void DidRunNativeEvent(const void* opaque_identifier,
base::TimeTicks creation_time) override;
#elif defined(OS_LINUX)
- // PlatformEventObserver overrides:
- // Exposed for tests.
- void WillProcessEvent(const ui::PlatformEvent& event) override;
- void DidProcessEvent(const ui::PlatformEvent& event) override;
+ // aura::WindowEventDispatcherObserver overrides:
+ void OnWindowEventDispatcherStartedProcessing(
+ aura::WindowEventDispatcher* dispatcher,
+ const ui::Event& event) override;
+ void OnWindowEventDispatcherFinishedProcessingEvent(
+ aura::WindowEventDispatcher* dispatcher) override;
#elif defined(OS_WIN)
// base::MessagePumpForUI::Observer overrides:
void WillDispatchMSG(const MSG& msg) override;
@@ -87,6 +90,14 @@ class CONTENT_EXPORT NativeEventObserver
void RegisterObserver();
void DeregisterObserver();
+#if defined(OS_LINUX)
+ struct EventInfo {
+ const void* unique_id;
+ base::TimeTicks creation_time;
+ };
+ std::vector<EventInfo> events_being_processed_;
+#endif
+
WillRunEventCallback will_run_event_callback_;
DidRunEventCallback did_run_event_callback_;
diff --git a/chromium/content/browser/scheduler/responsiveness/watcher.cc b/chromium/content/browser/scheduler/responsiveness/watcher.cc
index 2e61f5db182..2cee5678737 100644
--- a/chromium/content/browser/scheduler/responsiveness/watcher.cc
+++ b/chromium/content/browser/scheduler/responsiveness/watcher.cc
@@ -5,9 +5,11 @@
#include "content/browser/scheduler/responsiveness/watcher.h"
#include "base/pending_task.h"
+#include "base/task/post_task.h"
#include "content/browser/scheduler/responsiveness/calculator.h"
#include "content/browser/scheduler/responsiveness/message_loop_observer.h"
#include "content/browser/scheduler/responsiveness/native_event_observer.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@@ -30,11 +32,12 @@ void Watcher::SetUp() {
calculator_ = CreateCalculator();
native_event_observer_ui_ = CreateNativeEventObserver();
+ currently_running_metadata_ui_.reserve(5);
RegisterMessageLoopObserverUI();
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&Watcher::SetUpOnIOThread, base::Unretained(this),
calculator_.get()));
}
@@ -48,8 +51,8 @@ void Watcher::Destroy() {
message_loop_observer_ui_.reset();
native_event_observer_ui_.reset();
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&Watcher::TearDownOnIOThread, base::Unretained(this)));
}
@@ -96,6 +99,7 @@ void Watcher::RegisterMessageLoopObserverIO() {
void Watcher::SetUpOnIOThread(Calculator* calculator) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ currently_running_metadata_io_.reserve(5);
RegisterMessageLoopObserverIO();
calculator_io_ = calculator;
}
@@ -106,8 +110,8 @@ void Watcher::TearDownOnIOThread() {
message_loop_observer_io_.reset();
calculator_io_ = nullptr;
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&Watcher::TearDownOnUIThread, base::Unretained(this)));
}
@@ -156,23 +160,23 @@ void Watcher::DidRunTaskOnIOThread(const base::PendingTask* task) {
}
void Watcher::WillRunTask(const base::PendingTask* task,
- std::stack<Metadata>* currently_running_metadata) {
+ std::vector<Metadata>* currently_running_metadata) {
// Reentrancy should be rare.
if (UNLIKELY(!currently_running_metadata->empty())) {
- currently_running_metadata->top().caused_reentrancy = true;
+ currently_running_metadata->back().caused_reentrancy = true;
}
- currently_running_metadata->emplace(task);
+ currently_running_metadata->emplace_back(task);
// For delayed tasks, record the time right before the task is run.
if (!task->delayed_run_time.is_null()) {
- currently_running_metadata->top().delayed_task_start =
+ currently_running_metadata->back().delayed_task_start =
base::TimeTicks::Now();
}
}
void Watcher::DidRunTask(const base::PendingTask* task,
- std::stack<Metadata>* currently_running_metadata,
+ std::vector<Metadata>* currently_running_metadata,
int* mismatched_task_identifiers,
TaskOrEventFinishedCallback callback) {
// Calls to DidRunTask should always be paired with WillRunTask. The only time
@@ -180,16 +184,16 @@ void Watcher::DidRunTask(const base::PendingTask* task,
// TaskRunner Observers may be added while a task is being run, which means
// that there was no corresponding WillRunTask.
if (UNLIKELY(currently_running_metadata->empty() ||
- (task != currently_running_metadata->top().identifier))) {
+ (task != currently_running_metadata->back().identifier))) {
*mismatched_task_identifiers += 1;
DCHECK_LE(*mismatched_task_identifiers, 1);
return;
}
- bool caused_reentrancy = currently_running_metadata->top().caused_reentrancy;
+ bool caused_reentrancy = currently_running_metadata->back().caused_reentrancy;
base::TimeTicks delayed_task_start =
- currently_running_metadata->top().delayed_task_start;
- currently_running_metadata->pop();
+ currently_running_metadata->back().delayed_task_start;
+ currently_running_metadata->pop_back();
// Ignore tasks that caused reentrancy, since their execution latency will
// be very large, but Chrome was still responsive.
@@ -218,10 +222,10 @@ void Watcher::WillRunEventOnUIThread(const void* opaque_identifier) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// Reentrancy should be rare.
if (UNLIKELY(!currently_running_metadata_ui_.empty())) {
- currently_running_metadata_ui_.top().caused_reentrancy = true;
+ currently_running_metadata_ui_.back().caused_reentrancy = true;
}
- currently_running_metadata_ui_.emplace(opaque_identifier);
+ currently_running_metadata_ui_.emplace_back(opaque_identifier);
}
void Watcher::DidRunEventOnUIThread(const void* opaque_identifier,
@@ -234,15 +238,15 @@ void Watcher::DidRunEventOnUIThread(const void* opaque_identifier,
// task is being run, which means that there was no corresponding WillRunTask.
if (UNLIKELY(currently_running_metadata_ui_.empty() ||
(opaque_identifier !=
- currently_running_metadata_ui_.top().identifier))) {
+ currently_running_metadata_ui_.back().identifier))) {
mismatched_event_identifiers_ui_ += 1;
DCHECK_LE(mismatched_event_identifiers_ui_, 1);
return;
}
bool caused_reentrancy =
- currently_running_metadata_ui_.top().caused_reentrancy;
- currently_running_metadata_ui_.pop();
+ currently_running_metadata_ui_.back().caused_reentrancy;
+ currently_running_metadata_ui_.pop_back();
// Ignore events that caused reentrancy, since their execution latency will
// be very large, but Chrome was still responsive.
diff --git a/chromium/content/browser/scheduler/responsiveness/watcher.h b/chromium/content/browser/scheduler/responsiveness/watcher.h
index 0e6d3edfce7..b8f516de6ad 100644
--- a/chromium/content/browser/scheduler/responsiveness/watcher.h
+++ b/chromium/content/browser/scheduler/responsiveness/watcher.h
@@ -6,7 +6,7 @@
#define CONTENT_BROWSER_SCHEDULER_RESPONSIVENESS_WATCHER_H_
#include <memory>
-#include <stack>
+#include <vector>
#include "base/callback.h"
#include "base/gtest_prod_util.h"
@@ -98,13 +98,13 @@ class CONTENT_EXPORT Watcher : public base::RefCounted<Watcher> {
// Common implementations for the thread-specific methods.
void WillRunTask(const base::PendingTask* task,
- std::stack<Metadata>* currently_running_metadata);
+ std::vector<Metadata>* currently_running_metadata);
// |callback| will either be synchronously invoked, or else never invoked.
using TaskOrEventFinishedCallback =
base::OnceCallback<void(base::TimeTicks, base::TimeTicks)>;
void DidRunTask(const base::PendingTask* task,
- std::stack<Metadata>* currently_running_metadata,
+ std::vector<Metadata>* currently_running_metadata,
int* mismatched_task_identifiers,
TaskOrEventFinishedCallback callback);
@@ -120,7 +120,7 @@ class CONTENT_EXPORT Watcher : public base::RefCounted<Watcher> {
std::unique_ptr<NativeEventObserver> native_event_observer_ui_;
// Metadata for currently running tasks and events on the UI thread.
- std::stack<Metadata> currently_running_metadata_ui_;
+ std::vector<Metadata> currently_running_metadata_ui_;
// Task identifiers should only be mismatched once, since the Watcher may
// register itself during a Task execution, and thus doesn't capture the
@@ -133,7 +133,7 @@ class CONTENT_EXPORT Watcher : public base::RefCounted<Watcher> {
int mismatched_event_identifiers_ui_ = 0;
// The following members are all affine to the IO thread.
- std::stack<Metadata> currently_running_metadata_io_;
+ std::vector<Metadata> currently_running_metadata_io_;
int mismatched_task_identifiers_io_ = 0;
std::unique_ptr<MessageLoopObserver> message_loop_observer_io_;
diff --git a/chromium/content/browser/scheduler/responsiveness/watcher_unittest.cc b/chromium/content/browser/scheduler/responsiveness/watcher_unittest.cc
index c80be85babb..fd6ded28069 100644
--- a/chromium/content/browser/scheduler/responsiveness/watcher_unittest.cc
+++ b/chromium/content/browser/scheduler/responsiveness/watcher_unittest.cc
@@ -8,9 +8,11 @@
#include "base/pending_task.h"
#include "base/run_loop.h"
#include "base/synchronization/lock.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/scheduler/responsiveness/calculator.h"
#include "content/browser/scheduler/responsiveness/native_event_observer.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -206,24 +208,24 @@ class ResponsivenessWatcherRealIOThreadTest : public testing::Test {
#endif
TEST_F(ResponsivenessWatcherRealIOThreadTest, MAYBE_MessageLoopObserver) {
// Post a do-nothing task onto the UI thread.
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- base::BindOnce([]() {}));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce([]() {}));
// Post a do-nothing task onto the IO thread.
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::BindOnce([]() {}));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce([]() {}));
// Post a task onto the IO thread that hops back to the UI thread. This
// guarantees that both of the do-nothing tasks have already been processed.
base::RunLoop run_loop;
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- [](base::OnceClosure quit_closure) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE, std::move(quit_closure));
- },
- run_loop.QuitClosure()));
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::IO},
+ base::BindOnce(
+ [](base::OnceClosure quit_closure) {
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
+ std::move(quit_closure));
+ },
+ run_loop.QuitClosure()));
run_loop.Run();
ASSERT_GE(watcher_->NumTasksOnUIThread(), 1);
diff --git a/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc b/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc
index 45bd8008d22..199b8cd580c 100644
--- a/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc
+++ b/chromium/content/browser/screen_orientation/screen_orientation_browsertest.cc
@@ -346,7 +346,7 @@ IN_PROC_BROWSER_TEST_F(ScreenOrientationOOPIFBrowserTest, ScreenOrientation) {
// Regression test for triggering a screen orientation change for a pending
// main frame RenderFrameHost. See https://crbug.com/764202. In the bug, this
// was triggered via the DevTools audit panel and
-// ViewMsg_EnableDeviceEmulation, which calls RenderWidget::Resize on the
+// WidgetMsg_EnableDeviceEmulation, which calls RenderWidget::Resize on the
// renderer side. The test fakes this by directly sending the resize message
// to the widget.
IN_PROC_BROWSER_TEST_F(ScreenOrientationOOPIFBrowserTest,
diff --git a/chromium/content/browser/screenlock_monitor/OWNERS b/chromium/content/browser/screenlock_monitor/OWNERS
new file mode 100644
index 00000000000..f32afb48692
--- /dev/null
+++ b/chromium/content/browser/screenlock_monitor/OWNERS
@@ -0,0 +1 @@
+braveyao@chromium.org \ No newline at end of file
diff --git a/chromium/content/browser/screenlock_monitor/screenlock_monitor.cc b/chromium/content/browser/screenlock_monitor/screenlock_monitor.cc
new file mode 100644
index 00000000000..f15322babe6
--- /dev/null
+++ b/chromium/content/browser/screenlock_monitor/screenlock_monitor.cc
@@ -0,0 +1,56 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/screenlock_monitor/screenlock_monitor.h"
+
+#include "base/trace_event/trace_event.h"
+#include "content/browser/screenlock_monitor/screenlock_monitor_source.h"
+
+namespace content {
+
+static ScreenlockMonitor* g_screenlock_monitor = nullptr;
+
+ScreenlockMonitor::ScreenlockMonitor(
+ std::unique_ptr<ScreenlockMonitorSource> source)
+ : observers_(new base::ObserverListThreadSafe<ScreenlockObserver>()),
+ source_(std::move(source)) {
+ DCHECK(!g_screenlock_monitor);
+ g_screenlock_monitor = this;
+}
+
+ScreenlockMonitor::~ScreenlockMonitor() {
+ DCHECK_EQ(this, g_screenlock_monitor);
+ g_screenlock_monitor = nullptr;
+}
+
+// static
+ScreenlockMonitor* ScreenlockMonitor::Get() {
+ return g_screenlock_monitor;
+}
+
+void ScreenlockMonitor::AddObserver(ScreenlockObserver* obs) {
+ observers_->AddObserver(obs);
+}
+
+void ScreenlockMonitor::RemoveObserver(ScreenlockObserver* obs) {
+ observers_->RemoveObserver(obs);
+}
+
+void ScreenlockMonitor::NotifyScreenLocked() {
+ TRACE_EVENT_INSTANT0("screenlock_monitor",
+ "ScreenlockMonitor::NotifyScreenLocked",
+ TRACE_EVENT_SCOPE_GLOBAL);
+ DVLOG(1) << "Screen Locked";
+ observers_->Notify(FROM_HERE, &ScreenlockObserver::OnScreenLocked);
+}
+
+void ScreenlockMonitor::NotifyScreenUnlocked() {
+ TRACE_EVENT_INSTANT0("screenlock_monitor",
+ "ScreenlockMonitor::NotifyScreenUnlocked",
+ TRACE_EVENT_SCOPE_GLOBAL);
+ DVLOG(1) << "Screen Unlocked";
+ observers_->Notify(FROM_HERE, &ScreenlockObserver::OnScreenUnlocked);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/screenlock_monitor/screenlock_monitor.h b/chromium/content/browser/screenlock_monitor/screenlock_monitor.h
new file mode 100644
index 00000000000..81b1e7c867c
--- /dev/null
+++ b/chromium/content/browser/screenlock_monitor/screenlock_monitor.h
@@ -0,0 +1,53 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SCREENLOCK_MONITOR_SCREENLOCK_MONITOR_H_
+#define CONTENT_BROWSER_SCREENLOCK_MONITOR_SCREENLOCK_MONITOR_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/observer_list_threadsafe.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/screenlock_observer.h"
+
+namespace content {
+
+class ScreenlockMonitorSource;
+
+// A class used to monitor the screenlock state change and notify the observers
+// about the change event.
+// Currently available on Win/MacOSX/ChromOS only.
+// TODO(crbug.com/887585): Keep studying for a solid way to do this on Linux.
+class CONTENT_EXPORT ScreenlockMonitor {
+ public:
+ ScreenlockMonitor(std::unique_ptr<ScreenlockMonitorSource> source);
+ ~ScreenlockMonitor();
+
+ // Get the process-wide ScreenlockMonitor (if not present, returns NULL).
+ static ScreenlockMonitor* Get();
+
+ // Add and remove an observer.
+ // Can be called from any thread. |observer| is notified on the sequence
+ // from which it was registered.
+ // Must not be called from within a notification callback.
+ void AddObserver(ScreenlockObserver* observer);
+ void RemoveObserver(ScreenlockObserver* observer);
+
+ private:
+ friend class ScreenlockMonitorSource;
+
+ void NotifyScreenLocked();
+ void NotifyScreenUnlocked();
+
+ scoped_refptr<base::ObserverListThreadSafe<ScreenlockObserver>> observers_;
+ std::unique_ptr<ScreenlockMonitorSource> source_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScreenlockMonitor);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SCREENLOCK_MONITOR_SCREENLOCK_MONITOR_H_ \ No newline at end of file
diff --git a/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source.cc b/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source.cc
new file mode 100644
index 00000000000..0a5bdeea5be
--- /dev/null
+++ b/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source.cc
@@ -0,0 +1,21 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/screenlock_monitor/screenlock_monitor_device_source.h"
+
+namespace content {
+
+ScreenlockMonitorDeviceSource::ScreenlockMonitorDeviceSource() {
+#if defined(OS_MACOSX)
+ StartListeningForScreenlock();
+#endif // OS_MACOSX
+}
+
+ScreenlockMonitorDeviceSource::~ScreenlockMonitorDeviceSource() {
+#if defined(OS_MACOSX)
+ StopListeningForScreenlock();
+#endif // OS_MACOSX
+}
+
+} // namespace content
diff --git a/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source.h b/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source.h
new file mode 100644
index 00000000000..8d70faea1dc
--- /dev/null
+++ b/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source.h
@@ -0,0 +1,89 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SCREENLOCK_MONITOR_SCREENLOCK_MONITOR_DEVICE_SOURCE_H_
+#define CONTENT_BROWSER_SCREENLOCK_MONITOR_SCREENLOCK_MONITOR_DEVICE_SOURCE_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "build/build_config.h"
+#include "content/browser/screenlock_monitor/screenlock_monitor_source.h"
+#include "content/common/content_export.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#include <wtsapi32.h>
+#endif // OS_WIN
+
+#if defined(OS_CHROMEOS)
+#include "components/session_manager/core/session_manager_observer.h"
+#endif // OS_CHROMEOS
+
+#if defined(OS_WIN)
+namespace base {
+namespace win {
+class MessageWindow;
+}
+} // namespace base
+#endif // OS_WIN
+
+namespace content {
+
+// A class used to monitor the screenlock state change on each supported
+// platform and notify the change event to monitor.
+class CONTENT_EXPORT ScreenlockMonitorDeviceSource
+ : public ScreenlockMonitorSource {
+ public:
+ ScreenlockMonitorDeviceSource();
+ ~ScreenlockMonitorDeviceSource() override;
+
+ private:
+#if defined(OS_WIN)
+ // Represents a message-only window for screenlock message handling on Win.
+ // Only allow ScreenlockMonitor to create it.
+ class SessionMessageWindow {
+ public:
+ SessionMessageWindow();
+ ~SessionMessageWindow();
+
+ private:
+ bool OnWndProc(UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result);
+ void ProcessWTSSessionLockMessage(WPARAM event_id);
+
+ std::unique_ptr<base::win::MessageWindow> window_;
+
+ DISALLOW_COPY_AND_ASSIGN(SessionMessageWindow);
+ };
+
+ SessionMessageWindow session_message_window_;
+#endif // OS_WIN
+
+#if defined(OS_MACOSX)
+ void StartListeningForScreenlock();
+ void StopListeningForScreenlock();
+#endif // OS_MACOSX
+
+#if defined(OS_CHROMEOS)
+ class ScreenLockListener : public session_manager::SessionManagerObserver {
+ public:
+ ScreenLockListener();
+ ~ScreenLockListener() override;
+
+ // session_manager::SessionManagerObserver:
+ void OnSessionStateChanged() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScreenLockListener);
+ };
+
+ ScreenLockListener screenlock_listener_;
+#endif // OS_CHROMEOS
+
+ DISALLOW_COPY_AND_ASSIGN(ScreenlockMonitorDeviceSource);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SCREENLOCK_MONITOR_SCREENLOCK_MONITOR_DEVICE_SOURCE_H_
diff --git a/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_chromeos.cc b/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_chromeos.cc
new file mode 100644
index 00000000000..3cbd2441bf7
--- /dev/null
+++ b/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_chromeos.cc
@@ -0,0 +1,35 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/screenlock_monitor/screenlock_monitor_device_source.h"
+
+#include "components/session_manager/core/session_manager.h"
+
+namespace content {
+
+ScreenlockMonitorDeviceSource::ScreenLockListener::ScreenLockListener() {
+ if (session_manager::SessionManager::Get()) {
+ session_manager::SessionManager::Get()->AddObserver(this);
+ }
+}
+
+ScreenlockMonitorDeviceSource::ScreenLockListener::~ScreenLockListener() {
+ if (session_manager::SessionManager::Get()) {
+ session_manager::SessionManager::Get()->RemoveObserver(this);
+ }
+}
+
+void ScreenlockMonitorDeviceSource::ScreenLockListener::
+ OnSessionStateChanged() {
+ ScreenlockEvent screenlock_event;
+ if (session_manager::SessionManager::Get()->IsScreenLocked()) {
+ screenlock_event = SCREEN_LOCK_EVENT;
+ } else {
+ screenlock_event = SCREEN_UNLOCK_EVENT;
+ }
+
+ ProcessScreenlockEvent(screenlock_event);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_mac.mm b/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_mac.mm
new file mode 100644
index 00000000000..883372720ce
--- /dev/null
+++ b/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_mac.mm
@@ -0,0 +1,52 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/screenlock_monitor/screenlock_monitor_device_source.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+namespace content {
+
+namespace {
+
+CFStringRef kScreenLockedEvent = CFSTR("com.apple.screenIsLocked");
+CFStringRef kScreenUnlockedEvent = CFSTR("com.apple.screenIsUnlocked");
+
+void OnScreenlockNotificationReceived(CFNotificationCenterRef center,
+ void* observer,
+ CFStringRef name,
+ const void* object,
+ CFDictionaryRef userInfo) {
+ ScreenlockMonitorSource::ScreenlockEvent screenlock_event;
+ if (CFEqual(name, kScreenLockedEvent)) {
+ screenlock_event = ScreenlockMonitorSource::SCREEN_LOCK_EVENT;
+ } else if (CFEqual(name, kScreenUnlockedEvent)) {
+ screenlock_event = ScreenlockMonitorSource::SCREEN_UNLOCK_EVENT;
+ } else {
+ return;
+ }
+
+ ScreenlockMonitorSource::ProcessScreenlockEvent(screenlock_event);
+}
+
+} // namespace
+
+void ScreenlockMonitorDeviceSource::StartListeningForScreenlock() {
+ CFNotificationCenterAddObserver(
+ CFNotificationCenterGetDistributedCenter(), this,
+ &OnScreenlockNotificationReceived, kScreenLockedEvent, nullptr,
+ CFNotificationSuspensionBehaviorDeliverImmediately);
+
+ CFNotificationCenterAddObserver(
+ CFNotificationCenterGetDistributedCenter(), this,
+ &OnScreenlockNotificationReceived, kScreenUnlockedEvent, nullptr,
+ CFNotificationSuspensionBehaviorDeliverImmediately);
+}
+
+void ScreenlockMonitorDeviceSource::StopListeningForScreenlock() {
+ CFNotificationCenterRemoveEveryObserver(
+ CFNotificationCenterGetDistributedCenter(), this);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_win.cc b/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_win.cc
new file mode 100644
index 00000000000..486470e3d64
--- /dev/null
+++ b/chromium/content/browser/screenlock_monitor/screenlock_monitor_device_source_win.cc
@@ -0,0 +1,70 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/screenlock_monitor/screenlock_monitor_device_source.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/task/post_task.h"
+#include "base/win/message_window.h"
+
+namespace content {
+
+ScreenlockMonitorDeviceSource::SessionMessageWindow::SessionMessageWindow() {
+ // Create a window for receiving session change notifications.
+ window_.reset(new base::win::MessageWindow());
+ if (!window_->Create(base::BindRepeating(&SessionMessageWindow::OnWndProc,
+ base::Unretained(this)))) {
+ DLOG(ERROR) << "Failed to create the screenlock monitor window.";
+ window_.reset();
+ return;
+ }
+
+ base::OnceClosure wts_register =
+ base::BindOnce(base::IgnoreResult(&::WTSRegisterSessionNotification),
+ window_->hwnd(), NOTIFY_FOR_ALL_SESSIONS);
+
+ base::CreateCOMSTATaskRunnerWithTraits({})->PostTask(FROM_HERE,
+ std::move(wts_register));
+}
+
+ScreenlockMonitorDeviceSource::SessionMessageWindow::~SessionMessageWindow() {
+ // There should be no race condition between this code and the worker thread.
+ // WTSUnRegisterSessionNotification is only called from destruction as we are
+ // in shutdown, which means no other worker threads can be running.
+ if (window_) {
+ ::WTSUnRegisterSessionNotification(window_->hwnd());
+ window_.reset();
+ }
+}
+
+bool ScreenlockMonitorDeviceSource::SessionMessageWindow::OnWndProc(
+ UINT message,
+ WPARAM wparam,
+ LPARAM lparam,
+ LRESULT* result) {
+ if (message == WM_WTSSESSION_CHANGE) {
+ ProcessWTSSessionLockMessage(wparam);
+ }
+ return true;
+}
+
+void ScreenlockMonitorDeviceSource::SessionMessageWindow::
+ ProcessWTSSessionLockMessage(WPARAM event_id) {
+ ScreenlockEvent screenlock_event;
+ switch (event_id) {
+ case WTS_SESSION_LOCK:
+ screenlock_event = SCREEN_LOCK_EVENT;
+ break;
+ case WTS_SESSION_UNLOCK:
+ screenlock_event = SCREEN_UNLOCK_EVENT;
+ break;
+ default:
+ return;
+ }
+
+ ProcessScreenlockEvent(screenlock_event);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/screenlock_monitor/screenlock_monitor_source.cc b/chromium/content/browser/screenlock_monitor/screenlock_monitor_source.cc
new file mode 100644
index 00000000000..ef61bd3cf5e
--- /dev/null
+++ b/chromium/content/browser/screenlock_monitor/screenlock_monitor_source.cc
@@ -0,0 +1,31 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/screenlock_monitor/screenlock_monitor_source.h"
+
+#include "content/browser/screenlock_monitor/screenlock_monitor.h"
+
+namespace content {
+
+ScreenlockMonitorSource::ScreenlockMonitorSource() = default;
+ScreenlockMonitorSource::~ScreenlockMonitorSource() = default;
+
+// static
+void ScreenlockMonitorSource::ProcessScreenlockEvent(ScreenlockEvent event_id) {
+ ScreenlockMonitor* monitor = ScreenlockMonitor::Get();
+ if (!monitor) {
+ return;
+ }
+
+ switch (event_id) {
+ case SCREEN_LOCK_EVENT:
+ monitor->NotifyScreenLocked();
+ break;
+ case SCREEN_UNLOCK_EVENT:
+ monitor->NotifyScreenUnlocked();
+ break;
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/browser/screenlock_monitor/screenlock_monitor_source.h b/chromium/content/browser/screenlock_monitor/screenlock_monitor_source.h
new file mode 100644
index 00000000000..6a7f5dcc608
--- /dev/null
+++ b/chromium/content/browser/screenlock_monitor/screenlock_monitor_source.h
@@ -0,0 +1,31 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SCREENLOCK_MONITOR_SCREENLOCK_MONITOR_SOURCE_H_
+#define CONTENT_BROWSER_SCREENLOCK_MONITOR_SCREENLOCK_MONITOR_SOURCE_H_
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// A class to communicate screenlock state changes from each platform-specific
+// sub-class source implementation to the screenlock monitor.
+class CONTENT_EXPORT ScreenlockMonitorSource {
+ public:
+ ScreenlockMonitorSource();
+ virtual ~ScreenlockMonitorSource();
+
+ enum ScreenlockEvent { SCREEN_LOCK_EVENT, SCREEN_UNLOCK_EVENT };
+
+ // ProcessScreenlockEvent should only be called from a single thread.
+ static void ProcessScreenlockEvent(ScreenlockEvent event_id);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScreenlockMonitorSource);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SCREENLOCK_MONITOR_SCREENLOCK_MONITOR_SOURCE_H_
diff --git a/chromium/content/browser/screenlock_monitor/screenlock_monitor_unittest.cc b/chromium/content/browser/screenlock_monitor/screenlock_monitor_unittest.cc
new file mode 100644
index 00000000000..5f2da1f620b
--- /dev/null
+++ b/chromium/content/browser/screenlock_monitor/screenlock_monitor_unittest.cc
@@ -0,0 +1,89 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/screenlock_monitor/screenlock_monitor.h"
+
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_loop_current.h"
+#include "base/run_loop.h"
+#include "content/browser/screenlock_monitor/screenlock_monitor_source.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class ScreenlockMonitorTestSource : public ScreenlockMonitorSource {
+ public:
+ ScreenlockMonitorTestSource() {
+ DCHECK(base::MessageLoopCurrent::Get())
+ << "ScreenlocMonitorTestSource requires a MessageLoop.";
+ }
+ ~ScreenlockMonitorTestSource() override = default;
+
+ void GenerateScreenLockedEvent() {
+ ProcessScreenlockEvent(SCREEN_LOCK_EVENT);
+ base::RunLoop().RunUntilIdle();
+ }
+
+ void GenerateScreenUnlockedEvent() {
+ ProcessScreenlockEvent(SCREEN_UNLOCK_EVENT);
+ base::RunLoop().RunUntilIdle();
+ }
+};
+
+class ScreenlockMonitorTestObserver : public ScreenlockObserver {
+ public:
+ ScreenlockMonitorTestObserver() : is_screen_locked_(false) {}
+ ~ScreenlockMonitorTestObserver() override = default;
+
+ // ScreenlockObserver callbacks.
+ void OnScreenLocked() override { is_screen_locked_ = true; }
+ void OnScreenUnlocked() override { is_screen_locked_ = false; }
+
+ bool IsScreenLocked() { return is_screen_locked_; }
+
+ private:
+ bool is_screen_locked_;
+};
+
+class ScreenlockMonitorTest : public testing::Test {
+ protected:
+ ScreenlockMonitorTest() {
+ screenlock_monitor_source_ = new ScreenlockMonitorTestSource();
+ screenlock_monitor_ = std::make_unique<ScreenlockMonitor>(
+ std::unique_ptr<ScreenlockMonitorSource>(screenlock_monitor_source_));
+ }
+ ~ScreenlockMonitorTest() override = default;
+
+ protected:
+ ScreenlockMonitorTestSource* screenlock_monitor_source_;
+ std::unique_ptr<ScreenlockMonitor> screenlock_monitor_;
+
+ private:
+ base::MessageLoop message_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScreenlockMonitorTest);
+};
+
+TEST_F(ScreenlockMonitorTest, ScreenlockNotifications) {
+ const int kObservers = 5;
+
+ ScreenlockMonitorTestObserver observers[kObservers];
+ for (int index = 0; index < kObservers; ++index)
+ screenlock_monitor_->AddObserver(&observers[index]);
+
+ // Pretend screen is locked.
+ screenlock_monitor_source_->GenerateScreenLockedEvent();
+ // Ensure all observers were notified of the event
+ for (int index = 0; index < kObservers; ++index)
+ EXPECT_TRUE(observers[index].IsScreenLocked());
+
+ // Pretend screen is unlocked.
+ screenlock_monitor_source_->GenerateScreenUnlockedEvent();
+ // Ensure all observers were notified of the event
+ for (int index = 0; index < kObservers; ++index)
+ EXPECT_FALSE(observers[index].IsScreenLocked());
+}
+
+} // namespace content \ No newline at end of file
diff --git a/chromium/content/browser/security_exploit_browsertest.cc b/chromium/content/browser/security_exploit_browsertest.cc
index e9cb49ebc81..82af6087231 100644
--- a/chromium/content/browser/security_exploit_browsertest.cc
+++ b/chromium/content/browser/security_exploit_browsertest.cc
@@ -9,12 +9,15 @@
#include "base/feature_list.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/frame_host/render_frame_proxy_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -23,7 +26,9 @@
#include "content/common/frame_messages.h"
#include "content/common/render_message_filter.mojom.h"
#include "content/common/view_messages.h"
+#include "content/public/browser/blob_handle.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/interstitial_page.h"
@@ -34,7 +39,6 @@
#include "content/public/common/appcache_info.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_switches.h"
-#include "content/public/common/file_chooser_params.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
@@ -46,6 +50,7 @@
#include "content/test/mock_widget_impl.h"
#include "content/test/test_content_browser_client.h"
#include "ipc/ipc_security_test_util.h"
+#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/url_request/url_request_slow_download_job.h"
@@ -55,6 +60,8 @@
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/test/test_url_loader_client.h"
+#include "storage/browser/blob/blob_registry_impl.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/web/web_triggering_event_info.h"
using IPC::IpcSecurityTestUtil;
@@ -145,6 +152,55 @@ network::ResourceRequest CreateXHRRequestWithOrigin(const char* origin) {
return request;
}
+std::unique_ptr<content::BlobHandle> CreateMemoryBackedBlob(
+ BrowserContext* browser_context,
+ const std::string& contents,
+ const std::string& content_type) {
+ std::unique_ptr<content::BlobHandle> result;
+ base::RunLoop loop;
+ BrowserContext::CreateMemoryBackedBlob(
+ browser_context, contents.c_str(), contents.length(), content_type,
+ base::BindOnce(
+ [](std::unique_ptr<content::BlobHandle>* out_blob,
+ base::OnceClosure done,
+ std::unique_ptr<content::BlobHandle> blob) {
+ *out_blob = std::move(blob);
+ std::move(done).Run();
+ },
+ &result, loop.QuitClosure()));
+ loop.Run();
+ EXPECT_TRUE(result);
+ return result;
+}
+
+// Helper class to interpose on Blob URL registrations, replacing the URL
+// contained in incoming registration requests with the specified URL.
+class BlobURLStoreInterceptor
+ : public blink::mojom::BlobURLStoreInterceptorForTesting {
+ public:
+ explicit BlobURLStoreInterceptor(GURL target_url) : target_url_(target_url) {}
+
+ void Intercept(
+ mojo::StrongAssociatedBindingPtr<blink::mojom::BlobURLStore> binding) {
+ url_store_ = binding->SwapImplForTesting(this);
+ }
+
+ blink::mojom::BlobURLStore* GetForwardingInterface() override {
+ return url_store_;
+ }
+
+ void Register(blink::mojom::BlobPtr blob,
+ const GURL& url,
+ RegisterCallback callback) override {
+ GetForwardingInterface()->Register(std::move(blob), target_url_,
+ std::move(callback));
+ }
+
+ private:
+ blink::mojom::BlobURLStore* url_store_;
+ GURL target_url_;
+};
+
} // namespace
// The goal of these tests will be to "simulate" exploited renderer processes,
@@ -178,32 +234,33 @@ class SecurityExploitBrowserTest : public ContentBrowserTest {
// initialization, ref. comment on InitializeAndListen() above.
embedded_test_server()->StartAcceptingConnections();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&net::URLRequestSlowDownloadJob::AddUrlHandler));
}
static void CreateLoaderAndStart(
- RenderProcessHost* process,
+ RenderFrameHost* frame,
int route_id,
int request_id,
const network::ResourceRequest& resource_request) {
network::mojom::URLLoaderPtr loader;
network::TestURLLoaderClient client;
- CreateLoaderAndStart(process, mojo::MakeRequest(&loader), route_id,
+ CreateLoaderAndStart(frame, mojo::MakeRequest(&loader), route_id,
request_id, resource_request,
client.CreateInterfacePtr().PassInterface());
}
static void CreateLoaderAndStart(
- RenderProcessHost* process,
+ RenderFrameHost* frame,
network::mojom::URLLoaderRequest request,
int route_id,
int request_id,
const network::ResourceRequest& resource_request,
network::mojom::URLLoaderClientPtrInfo client) {
network::mojom::URLLoaderFactoryPtr factory;
- process->CreateURLLoaderFactory(mojo::MakeRequest(&factory));
+ frame->GetProcess()->CreateURLLoaderFactory(frame->GetLastCommittedOrigin(),
+ mojo::MakeRequest(&factory));
factory->CreateLoaderAndStart(
std::move(request), route_id, request_id,
network::mojom::kURLLoadOptionNone, resource_request,
@@ -234,12 +291,12 @@ class SecurityExploitBrowserTest : public ContentBrowserTest {
network::mojom::URLLoaderPtr loader1, loader2;
network::TestURLLoaderClient client1, client2;
- CreateLoaderAndStart(rfh->GetProcess(), mojo::MakeRequest(&loader1),
- rfh->GetRoutingID(), kRequestIdNotPreviouslyUsed,
- request, client1.CreateInterfacePtr().PassInterface());
- CreateLoaderAndStart(rfh->GetProcess(), mojo::MakeRequest(&loader2),
- rfh->GetRoutingID(), kRequestIdNotPreviouslyUsed,
- request, client2.CreateInterfacePtr().PassInterface());
+ CreateLoaderAndStart(rfh, mojo::MakeRequest(&loader1), rfh->GetRoutingID(),
+ kRequestIdNotPreviouslyUsed, request,
+ client1.CreateInterfacePtr().PassInterface());
+ CreateLoaderAndStart(rfh, mojo::MakeRequest(&loader2), rfh->GetRoutingID(),
+ kRequestIdNotPreviouslyUsed, request,
+ client2.CreateInterfacePtr().PassInterface());
EXPECT_EQ(bad_message::RDH_INVALID_REQUEST_ID, kill_waiter.Wait());
}
@@ -259,7 +316,7 @@ void SecurityExploitBrowserTest::TestFileChooserWithPath(
shell()->web_contents()->GetMainFrame();
RenderProcessHostKillWaiter kill_waiter(compromised_renderer->GetProcess());
- FileChooserParams params;
+ blink::mojom::FileChooserParams params;
params.default_file_name = path;
FrameHostMsg_RunFileChooser evil(compromised_renderer->GetRoutingID(),
@@ -331,8 +388,8 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
// different timing in the test, let's simulate a CreateNewWidget call coming
// from the IO thread. Use the existing window routing id to cause a
// deliberate collision.
- pending_rfh->render_view_host()->CreateNewWidget(
- duplicate_routing_id, std::move(widget), blink::kWebPopupTypePage);
+ pending_rfh->render_view_host()->CreateNewWidget(duplicate_routing_id,
+ std::move(widget));
// If the above operation doesn't crash, the test has succeeded!
}
@@ -476,7 +533,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) {
{
RenderProcessHostKillWaiter kill_waiter(web_rfh->GetProcess());
- CreateLoaderAndStart(web_rfh->GetProcess(), web_rfh->GetRoutingID(),
+ CreateLoaderAndStart(web_rfh, web_rfh->GetRoutingID(),
kRequestIdNotPreviouslyUsed, chrome_origin_msg);
EXPECT_EQ(bad_message::RDH_ILLEGAL_ORIGIN, kill_waiter.Wait());
}
@@ -491,7 +548,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) {
"Origin", "", base::Bind(&OnHttpHeaderReceived));
RenderProcessHostKillWaiter kill_waiter(web_rfh->GetProcess());
- CreateLoaderAndStart(web_rfh->GetProcess(), web_rfh->GetRoutingID(),
+ CreateLoaderAndStart(web_rfh, web_rfh->GetRoutingID(),
kRequestIdNotPreviouslyUsed,
embedder_isolated_origin_msg);
EXPECT_EQ(bad_message::RDH_ILLEGAL_ORIGIN, kill_waiter.Wait());
@@ -501,7 +558,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) {
NavigateToURL(shell(), web_url);
{
RenderProcessHostKillWaiter kill_waiter(web_rfh->GetProcess());
- CreateLoaderAndStart(web_rfh->GetProcess(), web_rfh->GetRoutingID(),
+ CreateLoaderAndStart(web_rfh, web_rfh->GetRoutingID(),
kRequestIdNotPreviouslyUsed, invalid_origin_msg);
EXPECT_EQ(bad_message::RDH_ILLEGAL_ORIGIN, kill_waiter.Wait());
}
@@ -510,7 +567,7 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) {
NavigateToURL(shell(), web_url);
{
RenderProcessHostKillWaiter kill_waiter(web_rfh->GetProcess());
- CreateLoaderAndStart(web_rfh->GetProcess(), web_rfh->GetRoutingID(),
+ CreateLoaderAndStart(web_rfh, web_rfh->GetRoutingID(),
kRequestIdNotPreviouslyUsed,
invalid_scheme_origin_msg);
EXPECT_EQ(bad_message::RDH_ILLEGAL_ORIGIN, kill_waiter.Wait());
@@ -768,4 +825,231 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, PageStateToWrongEntry) {
ASSERT_EQ(child1_url, child1->current_url());
}
+// Check that when site isolation is enabled, an origin can't create a blob URL
+// for a different origin. See https://crbug.com/886976.
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
+ CreateBlobURLInDifferentOrigin) {
+ IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());
+
+ GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ RenderFrameHost* rfh = shell()->web_contents()->GetMainFrame();
+
+ // All these are attacker controlled values.
+ std::string blob_type = "text/html";
+ std::string blob_contents = "<html><body>pwned.</body></html>";
+ std::string blob_path = "5881f76e-10d2-410d-8c61-ef210502acfd";
+
+ // Target a different origin.
+ std::string target_origin = "http://b.com";
+
+ // Set up a blob ID and populate it with attacker-controlled value. This
+ // is just using the blob APIs directly since creating arbitrary blobs is not
+ // what is prohibited; this data is not in any origin.
+ std::unique_ptr<BlobHandle> blob = CreateMemoryBackedBlob(
+ rfh->GetSiteInstance()->GetBrowserContext(), blob_contents, blob_type);
+ std::string blob_id = blob->GetUUID();
+
+ base::HistogramTester histograms;
+ // Try registering a blob URL for b.com. This IPC should result
+ // in a kill because a.com should not be abllowed to create blob URLs outside
+ // of its own origin.
+ RenderProcessHostWatcher crash_observer(
+ rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ PwnMessageHelper::RegisterBlobURL(
+ rfh->GetProcess(), GURL("blob:" + target_origin + "/" + blob_path),
+ blob_id);
+ // If the process is killed, this test passes.
+ crash_observer.Wait();
+ histograms.ExpectUniqueSample("Stability.BadMessageTerminated.Content",
+ 139 /* BDH_DISALLOWED_ORIGIN */, 1);
+}
+
+class SecurityExploitBrowserTestMojoBlobURLs
+ : public SecurityExploitBrowserTest {
+ public:
+ SecurityExploitBrowserTestMojoBlobURLs() {
+ scoped_feature_list_.InitAndEnableFeature(blink::features::kMojoBlobURLs);
+ }
+
+ void TearDown() override {
+ storage::BlobRegistryImpl::SetURLStoreCreationHookForTesting(nullptr);
+ }
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+// Check that when site isolation is enabled, an origin can't create a blob URL
+// for a different origin. Similar to the test above, but checks the
+// mojo-based Blob URL implementation. See https://crbug.com/886976.
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTestMojoBlobURLs,
+ CreateMojoBlobURLInDifferentOrigin) {
+ IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());
+
+ GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ RenderFrameHost* rfh = shell()->web_contents()->GetMainFrame();
+
+ // Intercept future blob URL registrations and overwrite the blob URL origin
+ // with b.com.
+ std::string target_origin = "http://b.com";
+ std::string blob_path = "5881f76e-10d2-410d-8c61-ef210502acfd";
+ BlobURLStoreInterceptor interceptor(
+ GURL("blob:" + target_origin + "/" + blob_path));
+ auto intercept_hook = base::BindRepeating(&BlobURLStoreInterceptor::Intercept,
+ base::Unretained(&interceptor));
+ storage::BlobRegistryImpl::SetURLStoreCreationHookForTesting(&intercept_hook);
+
+ // Register a blob URL from the a.com main frame, which will go through the
+ // interceptor above and be rewritten to register the blob URL with the b.com
+ // origin. This should result in a kill because a.com should not be allowed
+ // to create blob URLs outside of its own origin.
+ base::HistogramTester histograms;
+ RenderProcessHostWatcher crash_observer(
+ rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+
+ // The renderer should always get killed, but sometimes ExecuteScript returns
+ // true anyway, so just ignore the result.
+ ignore_result(
+ content::ExecuteScript(rfh, "URL.createObjectURL(new Blob(['foo']))"));
+
+ // If the process is killed, this test passes.
+ crash_observer.Wait();
+ histograms.ExpectUniqueSample("Stability.BadMessageTerminated.Content", 123,
+ 1);
+}
+
+// Check that with site isolation enabled, an origin can't create a filesystem
+// URL for a different origin. See https://crbug.com/888001.
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
+ CreateFilesystemURLInDifferentOrigin) {
+ IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());
+
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ RenderFrameHost* rfh = shell()->web_contents()->GetMainFrame();
+
+ // Block the renderer on operation that never completes, to shield it from
+ // receiving unexpected browser->renderer IPCs that might CHECK.
+ rfh->ExecuteJavaScriptWithUserGestureForTests(
+ base::ASCIIToUTF16("var r = new XMLHttpRequest();"
+ "r.open('GET', '/slow?99999', false);"
+ "r.send(null);"
+ "while (1);"));
+
+ // Set up a blob ID and populate it with attacker-controlled value. This
+ // is just using the blob APIs directly since creating arbitrary blobs is not
+ // what is prohibited; this data is not in any origin.
+ std::string payload = "<html><body>pwned.</body></html>";
+ std::string payload_type = "text/html";
+ std::unique_ptr<content::BlobHandle> blob = CreateMemoryBackedBlob(
+ rfh->GetSiteInstance()->GetBrowserContext(), payload, payload_type);
+ std::string blob_id = blob->GetUUID();
+
+ // Target a different origin.
+ std::string target_origin = "http://b.com";
+ GURL target_url =
+ GURL("filesystem:" + target_origin + "/temporary/exploit.html");
+
+ // Note: a well-behaved renderer would always call Open first before calling
+ // Create and Write, but it's actually not necessary for the original attack
+ // to succeed, so we omit it. As a result there are some log warnings from the
+ // quota observer.
+
+ PwnMessageHelper::FileSystemCreate(rfh->GetProcess(), 23, target_url, false,
+ false, false);
+
+ // Write the blob into the file. If successful, this places an
+ // attacker-controlled value in a resource on the target origin.
+ PwnMessageHelper::FileSystemWrite(rfh->GetProcess(), 24, target_url, blob_id,
+ 0);
+
+ // Now navigate to |target_url| in a subframe. It should not succeed, and the
+ // subframe should not contain |payload|.
+ TestNavigationObserver observer(shell()->web_contents());
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ NavigateFrameToURL(root->child_at(0), target_url);
+ EXPECT_FALSE(observer.last_navigation_succeeded());
+ EXPECT_EQ(net::ERR_FILE_NOT_FOUND, observer.last_net_error_code());
+
+ RenderFrameHost* attacked_rfh = root->child_at(0)->current_frame_host();
+ std::string body =
+ EvalJs(attacked_rfh, "document.body.innerText").ExtractString();
+ EXPECT_TRUE(base::StartsWith(body, "Could not load the requested resource",
+ base::CompareCase::INSENSITIVE_ASCII))
+ << " body=" << body;
+}
+
+// Verify that when a compromised renderer tries to navigate a remote frame to
+// a disallowed URL (e.g., file URL), that navigation is blocked.
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
+ BlockIllegalOpenURLFromRemoteFrame) {
+ // This test is only valid in site-per-process mode, where a cross-site
+ // iframe will have a proxy in the main frame's process.
+ if (!AreAllSitesIsolatedForTesting())
+ return;
+
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ FrameTreeNode* child = root->child_at(0);
+
+ // Simulate an IPC message where the top frame asks the remote subframe to
+ // navigate to a file: URL.
+ GURL file_url("file:///");
+ FrameHostMsg_OpenURL_Params params;
+ params.url = file_url;
+ params.uses_post = false;
+ params.disposition = WindowOpenDisposition::CURRENT_TAB;
+ params.should_replace_current_entry = false;
+ params.user_gesture = true;
+ params.is_history_navigation_in_new_child = false;
+
+ SiteInstance* a_com_instance = root->current_frame_host()->GetSiteInstance();
+ RenderFrameProxyHost* proxy =
+ child->render_manager()->GetRenderFrameProxyHost(a_com_instance);
+ EXPECT_TRUE(proxy);
+
+ {
+ FrameHostMsg_OpenURL msg(proxy->GetRoutingID(), params);
+ IPC::IpcSecurityTestUtil::PwnMessageReceived(
+ proxy->GetProcess()->GetChannel(), msg);
+ }
+
+ // Verify that the malicious navigation was blocked. Currently, this happens
+ // by rewriting the target URL to about:blank.
+ //
+ // TODO(alexmos): Consider killing the renderer process in this case, since
+ // this security check is already enforced in the renderer process.
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+ EXPECT_EQ(GURL(url::kAboutBlankURL),
+ child->current_frame_host()->GetLastCommittedURL());
+
+ // Navigate to the starting page again to recreate the proxy, then try the
+ // same malicious navigation with a chrome:// URL.
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ child = root->child_at(0);
+ proxy = child->render_manager()->GetRenderFrameProxyHost(a_com_instance);
+ EXPECT_TRUE(proxy);
+
+ GURL chrome_url(std::string(kChromeUIScheme) + "://" +
+ std::string(kChromeUIGpuHost));
+ params.url = chrome_url;
+ {
+ FrameHostMsg_OpenURL msg(proxy->GetRoutingID(), params);
+ IPC::IpcSecurityTestUtil::PwnMessageReceived(
+ proxy->GetProcess()->GetChannel(), msg);
+ }
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+ EXPECT_EQ(GURL(url::kAboutBlankURL),
+ child->current_frame_host()->GetLastCommittedURL());
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_manager/common_browser_interfaces.cc b/chromium/content/browser/service_manager/common_browser_interfaces.cc
index f537f90fa48..631c58056b6 100644
--- a/chromium/content/browser/service_manager/common_browser_interfaces.cc
+++ b/chromium/content/browser/service_manager/common_browser_interfaces.cc
@@ -19,6 +19,7 @@
#include "content/browser/browser_main_loop.h"
#include "content/browser/gpu/browser_gpu_client_delegate.h"
#include "content/common/child_process_host_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/connection_filter.h"
#include "content/public/common/service_manager_connection.h"
@@ -51,7 +52,7 @@ class ConnectionFilterImpl : public ConnectionFilter {
#elif defined(OS_MACOSX)
registry_.AddInterface(base::BindRepeating(&FontLoaderDispatcher::Create));
#endif
- if (!features::IsUsingWindowService()) {
+ if (!features::IsMultiProcessMash()) {
// For mus, the mojom::discardable_memory::DiscardableSharedMemoryManager
// is exposed from ui::Service. So we don't need bind the interface here.
auto* browser_main_loop = BrowserMainLoop::GetInstance();
@@ -106,7 +107,7 @@ class ConnectionFilterImpl : public ConnectionFilter {
auto gpu_client = std::make_unique<viz::GpuClient>(
std::make_unique<BrowserGpuClientDelegate>(), gpu_client_id,
gpu_client_tracing_id,
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}));
gpu_client->SetConnectionErrorHandler(
base::BindOnce(&ConnectionFilterImpl::OnGpuConnectionClosed,
base::Unretained(this), source_info.identity));
diff --git a/chromium/content/browser/service_manager/service_manager_context.cc b/chromium/content/browser/service_manager/service_manager_context.cc
index f35734b66d0..5119d521cd2 100644
--- a/chromium/content/browser/service_manager/service_manager_context.cc
+++ b/chromium/content/browser/service_manager/service_manager_context.cc
@@ -59,12 +59,14 @@
#include "services/data_decoder/public/mojom/constants.mojom.h"
#include "services/device/device_service.h"
#include "services/device/public/mojom/constants.mojom.h"
+#include "services/media_session/media_session_service.h"
+#include "services/media_session/public/cpp/switches.h"
+#include "services/media_session/public/mojom/constants.mojom.h"
#include "services/metrics/metrics_mojo_service.h"
#include "services/metrics/public/mojom/constants.mojom.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/network_service_test.mojom.h"
-#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
#include "services/resource_coordinator/public/mojom/service_constants.mojom.h"
#include "services/resource_coordinator/resource_coordinator_service.h"
#include "services/service_manager/connect_params.h"
@@ -548,12 +550,18 @@ ServiceManagerContext::ServiceManagerContext(
packaged_services_connection_->AddEmbeddedService(device::mojom::kServiceName,
device_info);
- if (base::FeatureList::IsEnabled(features::kGlobalResourceCoordinator)) {
- service_manager::EmbeddedServiceInfo resource_coordinator_info;
- resource_coordinator_info.factory =
- base::Bind(&resource_coordinator::ResourceCoordinatorService::Create);
+ service_manager::EmbeddedServiceInfo resource_coordinator_info;
+ resource_coordinator_info.factory =
+ base::Bind(&resource_coordinator::ResourceCoordinatorService::Create);
+ packaged_services_connection_->AddEmbeddedService(
+ resource_coordinator::mojom::kServiceName, resource_coordinator_info);
+
+ if (media_session::IsMediaSessionEnabled()) {
+ service_manager::EmbeddedServiceInfo media_session_info;
+ media_session_info.factory =
+ base::BindRepeating(&media_session::MediaSessionService::Create);
packaged_services_connection_->AddEmbeddedService(
- resource_coordinator::mojom::kServiceName, resource_coordinator_info);
+ media_session::mojom::kServiceName, media_session_info);
}
{
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance.cc b/chromium/content/browser/service_worker/embedded_worker_instance.cc
index 597aba71671..05e0bcd55cd 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_instance.cc
@@ -7,9 +7,13 @@
#include <utility>
#include "base/bind_helpers.h"
+#include "base/callback.h"
#include "base/feature_list.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
+#include "base/optional.h"
+#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/bad_message.h"
#include "content/browser/devtools/service_worker_devtools_manager.h"
@@ -24,6 +28,7 @@
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/url_loader_factory_bundle.mojom.h"
#include "content/common/url_schemes.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/child_process_host.h"
@@ -42,6 +47,14 @@ namespace content {
namespace {
+base::Optional<EmbeddedWorkerInstance::CreateNetworkFactoryCallback>&
+GetNetworkFactoryCallbackForTest() {
+ static base::NoDestructor<
+ base::Optional<EmbeddedWorkerInstance::CreateNetworkFactoryCallback>>
+ callback;
+ return *callback;
+}
+
// When a service worker version's failure count exceeds
// |kMaxSameProcessFailureCount|, the embedded worker is forced to start in a
// new process.
@@ -54,10 +67,12 @@ const char kServiceWorkerTerminationCanceledMesage[] =
void NotifyWorkerReadyForInspectionOnUI(
int worker_process_id,
int worker_route_id,
+ blink::mojom::DevToolsAgentHostAssociatedRequest host_request,
blink::mojom::DevToolsAgentAssociatedPtrInfo devtools_agent_ptr_info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
ServiceWorkerDevToolsManager::GetInstance()->WorkerReadyForInspection(
- worker_process_id, worker_route_id, std::move(devtools_agent_ptr_info));
+ worker_process_id, worker_route_id, std::move(host_request),
+ std::move(devtools_agent_ptr_info));
}
void NotifyWorkerDestroyedOnUI(int worker_process_id, int worker_route_id) {
@@ -79,36 +94,49 @@ void NotifyWorkerVersionDoomedOnUI(int worker_process_id, int worker_route_id) {
worker_process_id, worker_route_id);
}
+// Returns a factory bundle for doing loads on behalf of the specified |rph| and
+// |origin|. The returned bundle has a default factory that goes to network and
+// it may also include scheme-specific factories that don't go to network.
+//
+// The network factory does not support reconnection to the network service.
std::unique_ptr<URLLoaderFactoryBundleInfo> CreateFactoryBundle(
RenderProcessHost* rph,
- bool use_non_network_factories) {
+ const url::Origin& origin) {
auto factory_bundle = std::make_unique<URLLoaderFactoryBundleInfo>();
network::mojom::URLLoaderFactoryPtrInfo default_factory_info;
- rph->CreateURLLoaderFactory(mojo::MakeRequest(&default_factory_info));
+ if (!GetNetworkFactoryCallbackForTest()) {
+ rph->CreateURLLoaderFactory(origin,
+ mojo::MakeRequest(&default_factory_info));
+ } else {
+ network::mojom::URLLoaderFactoryPtr original_factory;
+ rph->CreateURLLoaderFactory(origin, mojo::MakeRequest(&original_factory));
+ GetNetworkFactoryCallbackForTest()->Run(
+ mojo::MakeRequest(&default_factory_info), rph->GetID(),
+ original_factory.PassInterface());
+ }
factory_bundle->default_factory_info() = std::move(default_factory_info);
- if (use_non_network_factories) {
- ContentBrowserClient::NonNetworkURLLoaderFactoryMap factories;
- GetContentClient()
- ->browser()
- ->RegisterNonNetworkSubresourceURLLoaderFactories(
- rph->GetID(), MSG_ROUTING_NONE, &factories);
-
- for (auto& pair : factories) {
- const std::string& scheme = pair.first;
- std::unique_ptr<network::mojom::URLLoaderFactory> factory =
- std::move(pair.second);
-
- // To be safe, ignore schemes that aren't allowed to register service
- // workers. We assume that importScripts should fail on such schemes.
- if (!base::ContainsValue(GetServiceWorkerSchemes(), scheme))
- continue;
- network::mojom::URLLoaderFactoryPtr factory_ptr;
- mojo::MakeStrongBinding(std::move(factory),
- mojo::MakeRequest(&factory_ptr));
- factory_bundle->factories_info().emplace(scheme,
- factory_ptr.PassInterface());
- }
+ ContentBrowserClient::NonNetworkURLLoaderFactoryMap non_network_factories;
+ GetContentClient()
+ ->browser()
+ ->RegisterNonNetworkSubresourceURLLoaderFactories(
+ rph->GetID(), MSG_ROUTING_NONE, &non_network_factories);
+
+ for (auto& pair : non_network_factories) {
+ const std::string& scheme = pair.first;
+ std::unique_ptr<network::mojom::URLLoaderFactory> factory =
+ std::move(pair.second);
+
+ // To be safe, ignore schemes that aren't allowed to register service
+ // workers. We assume that importScripts and fetch() should fail on such
+ // schemes.
+ if (!base::ContainsValue(GetServiceWorkerSchemes(), scheme))
+ continue;
+ network::mojom::URLLoaderFactoryPtr factory_ptr;
+ mojo::MakeStrongBinding(std::move(factory),
+ mojo::MakeRequest(&factory_ptr));
+ factory_bundle->scheme_specific_factory_infos().emplace(
+ scheme, factory_ptr.PassInterface());
}
return factory_bundle;
}
@@ -148,8 +176,8 @@ void SetupOnUIThread(base::WeakPtr<ServiceWorkerProcessManager> process_manager,
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_for_renderer;
if (!process_manager) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
std::move(callback), blink::ServiceWorkerStatusCode::kErrorAbort,
std::move(params), std::move(process_info),
@@ -165,8 +193,8 @@ void SetupOnUIThread(base::WeakPtr<ServiceWorkerProcessManager> process_manager,
params->embedded_worker_id, params->scope, params->script_url,
can_use_existing_process, process_info.get());
if (status != blink::ServiceWorkerStatusCode::kOk) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), status, std::move(params),
std::move(process_info), std::move(devtools_proxy),
std::move(factory_bundle_for_browser),
@@ -202,23 +230,26 @@ void SetupOnUIThread(base::WeakPtr<ServiceWorkerProcessManager> process_manager,
std::move(request));
}
- // S13nServiceWorker:
- // Create a default loader for network fallback.
- // The factory from RPH::CreateURLLoaderFactory() doesn't support
- // reconnection to the network service after a crash, but it's probably OK
- // since it's used for a single service worker startup until installation
- // finishes (with the exception of https://crbug.com/719052).
+ // S13nServiceWorker: Create factory bundles for this worker to do loading.
+ // These bundles don't support reconnection to the network service, see
+ // below comments.
if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
- // For performance, we only create the loader factories for non-http(s)
- // URLs (e.g. chrome-extension://) when the main script URL is
- // non-http(s). We assume an http(s) service worker cannot
- // importScripts a non-http(s) URL.
- bool use_non_network_factories = !params->script_url.SchemeIsHTTPOrHTTPS();
-
- factory_bundle_for_browser =
- CreateFactoryBundle(rph, use_non_network_factories);
- factory_bundle_for_renderer =
- CreateFactoryBundle(rph, use_non_network_factories);
+ const url::Origin origin = url::Origin::Create(params->script_url);
+
+ // The bundle for the browser is passed to ServiceWorkerScriptLoaderFactory
+ // and used to request non-installed service worker scripts. It's OK to not
+ // support reconnection to then network service because it can only used
+ // until the service worker reaches the 'installed' state.
+ //
+ // TODO(falken): Only make this bundle for non-installed service workers.
+ factory_bundle_for_browser = CreateFactoryBundle(rph, origin);
+
+ // The bundle for the renderer is passed to the service worker, and
+ // used for subresource loading from the service worker (i.e., fetch()).
+ // It's OK to not support reconnection to the network service because the
+ // service worker terminates itself when the connection breaks, so a new
+ // instance can be started.
+ factory_bundle_for_renderer = CreateFactoryBundle(rph, origin);
}
// Register to DevTools and update params accordingly.
@@ -248,8 +279,8 @@ void SetupOnUIThread(base::WeakPtr<ServiceWorkerProcessManager> process_manager,
process_manager->browser_context(), std::move(watcher_ptr));
// Continue to OnSetupCompleted on the IO thread.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), status, std::move(params),
std::move(process_info), std::move(devtools_proxy),
std::move(factory_bundle_for_browser),
@@ -288,32 +319,34 @@ class EmbeddedWorkerInstance::DevToolsProxy {
~DevToolsProxy() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(NotifyWorkerDestroyedOnUI,
- process_id_, agent_route_id_));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(NotifyWorkerDestroyedOnUI,
+ process_id_, agent_route_id_));
}
void NotifyWorkerReadyForInspection(
+ blink::mojom::DevToolsAgentHostAssociatedRequest host_request,
blink::mojom::DevToolsAgentAssociatedPtrInfo devtools_agent_ptr_info) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(NotifyWorkerReadyForInspectionOnUI, process_id_,
- agent_route_id_, std::move(devtools_agent_ptr_info)));
+ agent_route_id_, std::move(host_request),
+ std::move(devtools_agent_ptr_info)));
}
void NotifyWorkerVersionInstalled() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(NotifyWorkerVersionInstalledOnUI,
- process_id_, agent_route_id_));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(NotifyWorkerVersionInstalledOnUI,
+ process_id_, agent_route_id_));
}
void NotifyWorkerVersionDoomed() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(NotifyWorkerVersionDoomedOnUI,
- process_id_, agent_route_id_));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(NotifyWorkerVersionDoomedOnUI,
+ process_id_, agent_route_id_));
}
bool ShouldNotifyWorkerStopIgnored() const {
@@ -349,8 +382,8 @@ class EmbeddedWorkerInstance::WorkerProcessHandle {
~WorkerProcessHandle() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ServiceWorkerProcessManager::ReleaseWorkerProcess,
process_manager_, embedded_worker_id_));
}
@@ -414,8 +447,8 @@ class EmbeddedWorkerInstance::StartTask {
break;
case ProcessAllocationState::ALLOCATING:
// Abort half-baked process allocation on the UI thread.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ServiceWorkerProcessManager::ReleaseWorkerProcess,
instance_->context_->process_manager()->AsWeakPtr(),
instance_->embedded_worker_id()));
@@ -475,8 +508,8 @@ class EmbeddedWorkerInstance::StartTask {
// Hop to the UI thread for process allocation and setup. We will continue
// on the IO thread in StartTask::OnSetupCompleted().
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&SetupOnUIThread, process_manager, can_use_existing_process,
std::move(params), std::move(request_), context.get(), context,
@@ -777,15 +810,7 @@ void EmbeddedWorkerInstance::RequestTermination(
return;
}
- if (status() == EmbeddedWorkerStatus::STOPPING) {
- std::move(callback).Run(true /* will_be_terminated */);
- return;
- }
- owner_version_->StopWorkerIfIdle(true /* requested_from_renderer */);
-
- // If DevTools is attached and the worker won't be stopped, the worker needs
- // to continue to work.
- std::move(callback).Run(status() != EmbeddedWorkerStatus::RUNNING);
+ std::move(callback).Run(owner_version_->OnRequestTermination());
}
void EmbeddedWorkerInstance::CountFeature(blink::mojom::WebFeature feature) {
@@ -793,12 +818,16 @@ void EmbeddedWorkerInstance::CountFeature(blink::mojom::WebFeature feature) {
}
void EmbeddedWorkerInstance::OnReadyForInspection() {
- if (devtools_proxy_) {
- blink::mojom::DevToolsAgentAssociatedPtrInfo devtools_agent_ptr_info;
- client_->BindDevToolsAgent(mojo::MakeRequest(&devtools_agent_ptr_info));
- devtools_proxy_->NotifyWorkerReadyForInspection(
- std::move(devtools_agent_ptr_info));
- }
+ if (!devtools_proxy_)
+ return;
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host_ptr_info;
+ blink::mojom::DevToolsAgentHostAssociatedRequest host_request =
+ mojo::MakeRequest(&host_ptr_info);
+ blink::mojom::DevToolsAgentAssociatedPtrInfo devtools_agent_ptr_info;
+ client_->BindDevToolsAgent(std::move(host_ptr_info),
+ mojo::MakeRequest(&devtools_agent_ptr_info));
+ devtools_proxy_->NotifyWorkerReadyForInspection(
+ std::move(host_request), std::move(devtools_agent_ptr_info));
}
void EmbeddedWorkerInstance::OnScriptReadStarted() {
@@ -1047,4 +1076,10 @@ std::string EmbeddedWorkerInstance::StartingPhaseToString(StartingPhase phase) {
return std::string();
}
+// static
+void EmbeddedWorkerInstance::SetNetworkFactoryForTesting(
+ const CreateNetworkFactoryCallback& create_network_factory_callback) {
+ GetNetworkFactoryCallbackForTest() = create_network_factory_callback;
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance.h b/chromium/content/browser/service_worker/embedded_worker_instance.h
index 261425d2f41..e0202212b8f 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance.h
+++ b/chromium/content/browser/service_worker/embedded_worker_instance.h
@@ -200,6 +200,16 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
static std::string StatusToString(EmbeddedWorkerStatus status);
static std::string StartingPhaseToString(StartingPhase phase);
+ using CreateNetworkFactoryCallback = base::RepeatingCallback<void(
+ network::mojom::URLLoaderFactoryRequest request,
+ int process_id,
+ network::mojom::URLLoaderFactoryPtrInfo original_factory)>;
+ // Allows overriding the URLLoaderFactory creation for loading subresources
+ // from service workers (i.e., fetch()) and for loading non-installed service
+ // worker scripts.
+ static void SetNetworkFactoryForTesting(
+ const CreateNetworkFactoryCallback& url_loader_factory_callback);
+
// Forces this instance into STOPPED status and releases any state about the
// running worker. Called when connection with the renderer died or the
// renderer is unresponsive. Essentially, it throws away any information
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc b/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
index 5dac55e4405..eb96a7337ab 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -125,8 +125,8 @@ class EmbeddedWorkerInstanceTest : public testing::TestWithParam<bool>,
options, context()->storage()->NewRegistrationId(),
context()->AsWeakPtr());
pair.second = base::MakeRefCounted<ServiceWorkerVersion>(
- pair.first.get(), script_url, context()->storage()->NewVersionId(),
- context()->AsWeakPtr());
+ pair.first.get(), script_url, blink::mojom::ScriptType::kClassic,
+ context()->storage()->NewVersionId(), context()->AsWeakPtr());
return pair;
}
diff --git a/chromium/content/browser/service_worker/embedded_worker_registry.cc b/chromium/content/browser/service_worker/embedded_worker_registry.cc
index 34287d99034..896a7240d6d 100644
--- a/chromium/content/browser/service_worker/embedded_worker_registry.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_registry.cc
@@ -44,9 +44,7 @@ std::unique_ptr<EmbeddedWorkerInstance> EmbeddedWorkerRegistry::CreateWorker(
}
void EmbeddedWorkerRegistry::Shutdown() {
- for (WorkerInstanceMap::iterator it = worker_map_.begin();
- it != worker_map_.end();
- ++it) {
+ for (auto it = worker_map_.begin(); it != worker_map_.end(); ++it) {
it->second->Stop();
}
}
@@ -74,7 +72,7 @@ void EmbeddedWorkerRegistry::AbortLifetimeTracking(int embedded_worker_id) {
EmbeddedWorkerInstance* EmbeddedWorkerRegistry::GetWorker(
int embedded_worker_id) {
- WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
+ auto found = worker_map_.find(embedded_worker_id);
if (found == worker_map_.end())
return nullptr;
return found->second;
diff --git a/chromium/content/browser/service_worker/embedded_worker_test_helper.cc b/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
index 92fcf8b5fe8..7c41d084e3b 100644
--- a/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -48,10 +48,11 @@ void OnFetchEventCommon(
response->status_code = 200;
response->status_text = "OK";
response->response_type = network::mojom::FetchResponseType::kDefault;
- response_callback->OnResponse(std::move(response), base::Time::Now());
+ response_callback->OnResponse(
+ std::move(response), blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
} // namespace
@@ -266,7 +267,7 @@ class EmbeddedWorkerTestHelper::MockServiceWorker
void DispatchNotificationClickEvent(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
DispatchNotificationClickEventCallback callback) override {
@@ -279,7 +280,7 @@ class EmbeddedWorkerTestHelper::MockServiceWorker
void DispatchNotificationCloseEvent(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
DispatchNotificationCloseEventCallback callback) override {
if (!helper_)
return;
@@ -581,28 +582,28 @@ void EmbeddedWorkerTestHelper::OnActivateEvent(
mojom::ServiceWorker::DispatchActivateEventCallback callback) {
dispatched_events()->push_back(Event::Activate);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent(
const BackgroundFetchRegistration& registration,
mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent(
const BackgroundFetchRegistration& registration,
mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent(
const BackgroundFetchRegistration& registration,
mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnBackgroundFetchSuccessEvent(
@@ -610,7 +611,7 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchSuccessEvent(
mojom::ServiceWorker::DispatchBackgroundFetchSuccessEventCallback
callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnCookieChangeEvent(
@@ -618,21 +619,21 @@ void EmbeddedWorkerTestHelper::OnCookieChangeEvent(
::network::mojom::CookieChangeCause cause,
mojom::ServiceWorker::DispatchCookieChangeEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnExtendableMessageEvent(
mojom::ExtendableMessageEventPtr event,
mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnInstallEvent(
mojom::ServiceWorker::DispatchInstallEventCallback callback) {
dispatched_events()->push_back(Event::Install);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- true /* has_fetch_handler */, base::Time::Now());
+ true /* has_fetch_handler */, base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnFetchEvent(
@@ -649,33 +650,33 @@ void EmbeddedWorkerTestHelper::OnPushEvent(
base::Optional<std::string> payload,
mojom::ServiceWorker::DispatchPushEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnNotificationClickEvent(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
mojom::ServiceWorker::DispatchNotificationClickEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnNotificationCloseEvent(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnAbortPaymentEvent(
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback) {
- response_callback->OnResponseForAbortPayment(true, base::Time::Now());
+ response_callback->OnResponseForAbortPayment(true, base::TimeTicks::Now());
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnCanMakePaymentEvent(
@@ -690,9 +691,9 @@ void EmbeddedWorkerTestHelper::OnCanMakePaymentEvent(
}
}
response_callback->OnResponseForCanMakePayment(can_make_payment,
- base::Time::Now());
+ base::TimeTicks::Now());
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnPaymentRequestEvent(
@@ -700,9 +701,9 @@ void EmbeddedWorkerTestHelper::OnPaymentRequestEvent(
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback) {
response_callback->OnResponseForPaymentRequest(
- payments::mojom::PaymentHandlerResponse::New(), base::Time::Now());
+ payments::mojom::PaymentHandlerResponse::New(), base::TimeTicks::Now());
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void EmbeddedWorkerTestHelper::OnSetIdleTimerDelayToZero(
@@ -933,7 +934,7 @@ void EmbeddedWorkerTestHelper::OnFetchEventStub(
void EmbeddedWorkerTestHelper::OnNotificationClickEventStub(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
mojom::ServiceWorker::DispatchNotificationClickEventCallback callback) {
@@ -946,7 +947,7 @@ void EmbeddedWorkerTestHelper::OnNotificationClickEventStub(
void EmbeddedWorkerTestHelper::OnNotificationCloseEventStub(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
diff --git a/chromium/content/browser/service_worker/embedded_worker_test_helper.h b/chromium/content/browser/service_worker/embedded_worker_test_helper.h
index 04943106abf..e3c8fc90669 100644
--- a/chromium/content/browser/service_worker/embedded_worker_test_helper.h
+++ b/chromium/content/browser/service_worker/embedded_worker_test_helper.h
@@ -33,6 +33,10 @@
class GURL;
+namespace blink {
+struct PlatformNotificationData;
+}
+
namespace content {
struct BackgroundFetchRegistration;
@@ -42,7 +46,6 @@ class MockRenderProcessHost;
class ServiceWorkerContextCore;
class ServiceWorkerContextWrapper;
class TestBrowserContext;
-struct PlatformNotificationData;
// In-Process EmbeddedWorker test helper.
//
@@ -80,7 +83,8 @@ class EmbeddedWorkerTestHelper {
void AddMessageToConsole(blink::WebConsoleMessage::Level level,
const std::string& message) override;
void BindDevToolsAgent(
- blink::mojom::DevToolsAgentAssociatedRequest request) override {}
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo,
+ blink::mojom::DevToolsAgentAssociatedRequest) override {}
base::WeakPtr<EmbeddedWorkerTestHelper> helper_;
mojo::Binding<mojom::EmbeddedWorkerInstanceClient> binding_;
@@ -196,13 +200,13 @@ class EmbeddedWorkerTestHelper {
mojom::ServiceWorker::DispatchFetchEventCallback finish_callback);
virtual void OnNotificationClickEvent(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
mojom::ServiceWorker::DispatchNotificationClickEventCallback callback);
virtual void OnNotificationCloseEvent(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback);
virtual void OnPushEvent(
base::Optional<std::string> payload,
@@ -290,13 +294,13 @@ class EmbeddedWorkerTestHelper {
mojom::ServiceWorker::DispatchFetchEventCallback finish_callback);
void OnNotificationClickEventStub(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
mojom::ServiceWorker::DispatchNotificationClickEventCallback callback);
void OnNotificationCloseEventStub(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback);
void OnPushEventStub(
base::Optional<std::string> payload,
diff --git a/chromium/content/browser/service_worker/payment_handler_support.cc b/chromium/content/browser/service_worker/payment_handler_support.cc
index ccf233ffddc..c98173fd292 100644
--- a/chromium/content/browser/service_worker/payment_handler_support.cc
+++ b/chromium/content/browser/service_worker/payment_handler_support.cc
@@ -4,9 +4,11 @@
#include "content/browser/service_worker/payment_handler_support.h"
+#include "base/task/post_task.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/storage_partition_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
@@ -47,16 +49,16 @@ class ShowPaymentHandlerWindowReplier {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (response_callback_) {
DCHECK(fallback_);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(fallback_), std::move(response_callback_)));
}
}
void Run(bool success, int render_process_id, int render_frame_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback_), std::move(response_callback_),
success, render_process_id, render_frame_id));
}
@@ -97,8 +99,8 @@ void PaymentHandlerSupport::ShowPaymentHandlerWindow(
response_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(context);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ShowPaymentHandlerWindowOnUI,
base::WrapRefCounted(context->wrapper()), url,
std::move(callback), std::move(fallback),
diff --git a/chromium/content/browser/service_worker/service_worker_browsertest.cc b/chromium/content/browser/service_worker/service_worker_browsertest.cc
index 7e129e81e95..a62f6839ac5 100644
--- a/chromium/content/browser/service_worker/service_worker_browsertest.cc
+++ b/chromium/content/browser/service_worker/service_worker_browsertest.cc
@@ -47,6 +47,7 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/navigation_entry.h"
@@ -122,8 +123,8 @@ void RunAndQuit(base::OnceClosure closure,
void RunOnIOThreadWithDelay(base::OnceClosure closure, base::TimeDelta delay) {
base::RunLoop run_loop;
- BrowserThread::PostDelayedTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&RunAndQuit, std::move(closure), run_loop.QuitClosure(),
base::RetainedRef(base::ThreadTaskRunnerHandle::Get())),
delay);
@@ -135,16 +136,16 @@ void RunOnIOThread(base::OnceClosure closure) {
}
void RunOnIOThread(
- const base::Callback<void(const base::Closure& continuation)>& closure) {
+ base::OnceCallback<void(base::OnceClosure continuation)> callback) {
base::RunLoop run_loop;
- base::Closure quit_on_original_thread =
- base::Bind(base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
- base::ThreadTaskRunnerHandle::Get().get(),
- FROM_HERE,
- run_loop.QuitClosure());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(closure, std::move(quit_on_original_thread)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(
+ std::move(callback),
+ base::BindOnce(
+ base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
+ base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
+ run_loop.QuitClosure())));
run_loop.Run();
}
@@ -164,7 +165,7 @@ void ReceiveFindRegistrationStatus(
scoped_refptr<ServiceWorkerRegistration> registration) {
*out_status = status;
if (!quit.is_null())
- BrowserThread::PostTask(run_quit_thread, FROM_HERE, std::move(quit));
+ base::PostTaskWithTraits(FROM_HERE, {run_quit_thread}, std::move(quit));
}
ServiceWorkerStorage::FindRegistrationCallback CreateFindRegistrationReceiver(
@@ -212,8 +213,8 @@ class WorkerActivatedObserver
context_->RemoveObserver(this);
version_id_ = version_id;
registration_id_ = version->registration_id();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&WorkerActivatedObserver::Quit, this));
}
}
@@ -484,8 +485,8 @@ class ConsoleListener : public EmbeddedWorkerInstance::Listener {
int line_number,
const GURL& source_url) override {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&ConsoleListener::OnReportConsoleMessageOnUI,
base::Unretained(this), message));
}
@@ -509,14 +510,16 @@ class ConsoleListener : public EmbeddedWorkerInstance::Listener {
void OnReportConsoleMessageOnUI(const base::string16& message) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
messages_.push_back(message);
- if (!quit_.is_null() && messages_.size() == expected_message_count_)
- quit_.Run();
+ if (messages_.size() == expected_message_count_) {
+ DCHECK(quit_);
+ std::move(quit_).Run();
+ }
}
// These parameters must be accessed on the UI thread.
std::vector<base::string16> messages_;
size_t expected_message_count_ = 0;
- base::Closure quit_;
+ base::OnceClosure quit_;
};
// Listens to console messages on ServiceWorkerContextWrapper.
@@ -586,8 +589,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
// Dispatch install on a worker.
base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop install_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::InstallOnIOThread, base::Unretained(this),
install_run_loop.QuitClosure(), &status));
install_run_loop.Run();
@@ -595,8 +598,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
// Stop the worker.
base::RunLoop stop_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::StopOnIOThread, base::Unretained(this),
stop_run_loop.QuitClosure()));
stop_run_loop.Run();
@@ -606,8 +609,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
blink::ServiceWorkerStatusCode expected_status) {
base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::ActivateOnIOThread, base::Unretained(this),
run_loop.QuitClosure(), &status));
run_loop.Run();
@@ -624,8 +627,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
FetchResult fetch_result;
fetch_result.status = blink::ServiceWorkerStatusCode::kErrorFailed;
base::RunLoop fetch_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::FetchOnIOThread, base::Unretained(this),
fetch_run_loop.QuitClosure(), &prepare_result,
&fetch_result));
@@ -650,8 +653,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
registration_->set_last_update_check(base::Time::Now());
version_ = new ServiceWorkerVersion(
- registration_.get(),
- embedded_test_server()->GetURL(worker_url),
+ registration_.get(), embedded_test_server()->GetURL(worker_url),
+ blink::mojom::ScriptType::kClassic,
wrapper()->context()->storage()->NewVersionId(),
wrapper()->context()->AsWeakPtr());
@@ -686,6 +689,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
scoped_refptr<ServiceWorkerVersion> waiting_version(
new ServiceWorkerVersion(
registration_.get(), embedded_test_server()->GetURL(worker_url),
+ blink::mojom::ScriptType::kClassic,
wrapper()->context()->storage()->NewVersionId(),
wrapper()->context()->AsWeakPtr()));
waiting_version->set_fetch_handler_existence(
@@ -699,8 +703,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop start_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::StartOnIOThread, base::Unretained(this),
start_run_loop.QuitClosure(), &status));
start_run_loop.Run();
@@ -710,8 +714,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
void StopWorker() {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::RunLoop stop_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::StopOnIOThread, base::Unretained(this),
stop_run_loop.QuitClosure()));
stop_run_loop.Run();
@@ -722,8 +726,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop store_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::StoreOnIOThread, base::Unretained(this),
store_run_loop.QuitClosure(), &status, version_id));
store_run_loop.Run();
@@ -738,8 +742,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
blink::ServiceWorkerStatusCode* out_status,
bool* out_update_found) {
base::RunLoop update_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&self::UpdateOnIOThread, base::Unretained(this), registration_id,
base::BindOnce(
@@ -755,8 +759,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
blink::ServiceWorkerStatusCode status =
blink::ServiceWorkerStatusCode::kErrorFailed;
base::RunLoop run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::FindRegistrationForIdOnIOThread,
base::Unretained(this), run_loop.QuitClosure(), &status,
id, origin));
@@ -787,12 +791,13 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
wrapper()->context()->RemoveLiveRegistration(id);
}
- void StartOnIOThread(const base::Closure& done,
+ void StartOnIOThread(base::OnceClosure done,
base::Optional<blink::ServiceWorkerStatusCode>* result) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
version_->SetMainScriptHttpResponseInfo(CreateHttpResponseInfo());
- version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
- CreateReceiver(BrowserThread::UI, done, result));
+ version_->StartWorker(
+ ServiceWorkerMetrics::EventType::UNKNOWN,
+ CreateReceiver(BrowserThread::UI, std::move(done), result));
}
void InstallOnIOThread(
@@ -806,27 +811,29 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
}
void DispatchInstallEventOnIOThread(
- const base::Closure& done,
+ base::OnceClosure done,
base::Optional<blink::ServiceWorkerStatusCode>* result,
blink::ServiceWorkerStatusCode start_worker_status) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, start_worker_status);
version_->SetStatus(ServiceWorkerVersion::INSTALLING);
- int request_id =
- version_->StartRequest(ServiceWorkerMetrics::EventType::INSTALL,
- CreateReceiver(BrowserThread::UI, done, result));
- version_->endpoint()->DispatchInstallEvent(
- base::BindOnce(&self::ReceiveInstallEventOnIOThread,
- base::Unretained(this), done, result, request_id));
+
+ auto repeating_done = base::AdaptCallbackForRepeating(std::move(done));
+ int request_id = version_->StartRequest(
+ ServiceWorkerMetrics::EventType::INSTALL,
+ CreateReceiver(BrowserThread::UI, repeating_done, result));
+ version_->endpoint()->DispatchInstallEvent(base::BindOnce(
+ &self::ReceiveInstallEventOnIOThread, base::Unretained(this),
+ repeating_done, result, request_id));
}
void ReceiveInstallEventOnIOThread(
- const base::Closure& done,
+ base::OnceClosure done,
base::Optional<blink::ServiceWorkerStatusCode>* out_result,
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
bool has_fetch_handler,
- base::Time dispatch_event_time) {
+ base::TimeTicks dispatch_event_time) {
version_->FinishRequest(
request_id, status == blink::mojom::ServiceWorkerEventStatus::COMPLETED,
dispatch_event_time);
@@ -837,10 +844,10 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
*out_result = mojo::ConvertTo<blink::ServiceWorkerStatusCode>(status);
if (!done.is_null())
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(done));
}
- void StoreOnIOThread(const base::Closure& done,
+ void StoreOnIOThread(base::OnceClosure done,
base::Optional<blink::ServiceWorkerStatusCode>* result,
int64_t version_id) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -848,30 +855,30 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
wrapper()->context()->GetLiveVersion(version_id);
wrapper()->context()->storage()->StoreRegistration(
registration_.get(), version,
- CreateReceiver(BrowserThread::UI, done, result));
+ CreateReceiver(BrowserThread::UI, std::move(done), result));
}
void ActivateOnIOThread(
- const base::RepeatingClosure& done,
+ base::OnceClosure done,
base::Optional<blink::ServiceWorkerStatusCode>* result) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
version_->RunAfterStartWorker(
ServiceWorkerMetrics::EventType::ACTIVATE,
base::BindOnce(&self::DispatchActivateEventOnIOThread,
- base::Unretained(this), done, result));
+ base::Unretained(this), std::move(done), result));
}
void DispatchActivateEventOnIOThread(
- const base::Closure& done,
+ base::OnceClosure done,
base::Optional<blink::ServiceWorkerStatusCode>* result,
blink::ServiceWorkerStatusCode start_worker_status) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, start_worker_status);
version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
registration_->SetActiveVersion(version_.get());
- int request_id =
- version_->StartRequest(ServiceWorkerMetrics::EventType::INSTALL,
- CreateReceiver(BrowserThread::UI, done, result));
+ int request_id = version_->StartRequest(
+ ServiceWorkerMetrics::EventType::INSTALL,
+ CreateReceiver(BrowserThread::UI, std::move(done), result));
version_->endpoint()->DispatchActivateEvent(
version_->CreateSimpleEventCallback(request_id));
}
@@ -899,10 +906,10 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
*out_status = status;
*out_update_found = !!registration->installing_version();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done_on_ui);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, done_on_ui);
}
- void FetchOnIOThread(const base::Closure& done,
+ void FetchOnIOThread(base::OnceClosure done,
bool* prepare_result,
FetchResult* result) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -911,7 +918,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
ResourceType resource_type = RESOURCE_TYPE_MAIN_FRAME;
base::OnceClosure prepare_callback = CreatePrepareReceiver(prepare_result);
ServiceWorkerFetchDispatcher::FetchCallback fetch_callback =
- CreateResponseReceiver(done, blob_context_.get(), result);
+ CreateResponseReceiver(std::move(done), blob_context_.get(), result);
auto request = std::make_unique<network::ResourceRequest>();
request->url = url;
request->method = "GET";
@@ -927,8 +934,8 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
base::Time GetLastUpdateCheck(int64_t registration_id) {
base::Time last_update_time;
base::RunLoop time_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::GetLastUpdateCheckOnIOThread,
base::Unretained(this), registration_id,
&last_update_time, time_run_loop.QuitClosure()));
@@ -944,7 +951,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
wrapper()->context()->GetLiveRegistration(registration_id);
ASSERT_TRUE(registration);
*out_time = registration->last_update_check();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done_on_ui);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, done_on_ui);
}
void SetLastUpdateCheckOnIOThread(int64_t registration_id,
@@ -955,20 +962,21 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
wrapper()->context()->GetLiveRegistration(registration_id);
ASSERT_TRUE(registration);
registration->set_last_update_check(last_update_time);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done_on_ui);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, done_on_ui);
}
// Contrary to the style guide, the output parameter of this function comes
// before input parameters so Bind can be used on it to create a FetchCallback
// to pass to DispatchFetchEvent.
void ReceiveFetchResultOnIOThread(
- const base::Closure& quit,
+ base::OnceClosure quit,
ChromeBlobStorageContext* blob_context,
FetchResult* out_result,
blink::ServiceWorkerStatusCode actual_status,
ServiceWorkerFetchDispatcher::FetchEventResult actual_result,
blink::mojom::FetchAPIResponsePtr actual_response,
blink::mojom::ServiceWorkerStreamHandlePtr /* stream */,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr /* timing */,
scoped_refptr<ServiceWorkerVersion> worker) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
ASSERT_TRUE(fetch_dispatcher_);
@@ -983,21 +991,21 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
out_result->response->blob->uuid);
}
if (!quit.is_null())
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(quit));
}
ServiceWorkerFetchDispatcher::FetchCallback CreateResponseReceiver(
- const base::Closure& quit,
+ base::OnceClosure quit,
ChromeBlobStorageContext* blob_context,
FetchResult* result) {
return base::BindOnce(&self::ReceiveFetchResultOnIOThread,
- base::Unretained(this), quit,
+ base::Unretained(this), std::move(quit),
base::RetainedRef(blob_context), result);
}
- void StopOnIOThread(const base::Closure& done) {
+ void StopOnIOThread(base::OnceClosure done) {
ASSERT_TRUE(version_.get());
- version_->StopWorker(done);
+ version_->StopWorker(std::move(done));
}
protected:
@@ -1017,8 +1025,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, StartAndStop) {
// Start a worker.
base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop start_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::StartOnIOThread, base::Unretained(this),
start_run_loop.QuitClosure(), &status));
start_run_loop.Run();
@@ -1026,8 +1034,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, StartAndStop) {
// Stop the worker.
base::RunLoop stop_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::StopOnIOThread, base::Unretained(this),
stop_run_loop.QuitClosure()));
stop_run_loop.Run();
@@ -1044,8 +1052,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
// Start a worker.
base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop start_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::StartOnIOThread, base::Unretained(this),
start_run_loop.QuitClosure(), &status));
start_run_loop.Run();
@@ -1057,8 +1065,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
// Stop the worker.
base::RunLoop stop_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::StopOnIOThread, base::Unretained(this),
stop_run_loop.QuitClosure()));
stop_run_loop.Run();
@@ -1244,8 +1252,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
// Dispatch install on a worker.
base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop install_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::InstallOnIOThread, base::Unretained(this),
install_run_loop.QuitClosure(), &status));
install_run_loop.Run();
@@ -1264,15 +1272,16 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
class WaitForLoaded : public EmbeddedWorkerInstance::Listener {
public:
- explicit WaitForLoaded(const base::Closure& quit) : quit_(quit) {}
+ explicit WaitForLoaded(base::OnceClosure quit) : quit_(std::move(quit)) {}
void OnScriptEvaluationStart() override {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_);
+ DCHECK(quit_);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, std::move(quit_));
}
private:
- base::Closure quit_;
+ base::OnceClosure quit_;
};
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutStartingWorker) {
@@ -1289,8 +1298,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutStartingWorker) {
RunOnIOThread(base::BindOnce(&EmbeddedWorkerInstance::AddObserver,
base::Unretained(version_->embedded_worker()),
&wait_for_load));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::StartOnIOThread, base::Unretained(this),
start_run_loop.QuitClosure(), &status));
load_run_loop.Run();
@@ -1321,8 +1330,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutWorkerInEvent) {
// Start a worker.
base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop start_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::StartOnIOThread, base::Unretained(this),
start_run_loop.QuitClosure(), &status));
start_run_loop.Run();
@@ -1330,8 +1339,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutWorkerInEvent) {
// Dispatch an event.
base::RunLoop install_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::InstallOnIOThread, base::Unretained(this),
install_run_loop.QuitClosure(), &status));
@@ -1466,6 +1475,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
// Make options. Set to kAll so updating exercises the browser cache.
blink::mojom::ServiceWorkerRegistrationOptions options(
embedded_test_server()->GetURL(kScope),
+ blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kAll);
// Register and wait for activation.
@@ -1498,8 +1508,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
{
last_update_time = base::Time::Now() - base::TimeDelta::FromHours(24);
base::RunLoop time_run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&self::SetLastUpdateCheckOnIOThread,
base::Unretained(this), registration_id,
last_update_time, time_run_loop.QuitClosure()));
@@ -1598,6 +1608,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, FetchPageWithSaveData) {
observer->Init();
blink::mojom::ServiceWorkerRegistrationOptions options(
embedded_test_server()->GetURL(kPageUrl),
+ blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
embedded_test_server()->GetURL(kWorkerUrl), options,
@@ -1642,6 +1653,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, CrossOriginFetchWithSaveData) {
observer->Init();
blink::mojom::ServiceWorkerRegistrationOptions options(
embedded_test_server()->GetURL(kPageUrl),
+ blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
embedded_test_server()->GetURL(kWorkerUrl), options,
@@ -1687,6 +1699,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest,
blink::mojom::ServiceWorkerRegistrationOptions options(
embedded_test_server()->GetURL(kPageUrl),
+ blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
embedded_test_server()->GetURL(kWorkerUrl), options,
@@ -1715,6 +1728,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, Reload) {
observer->Init();
blink::mojom::ServiceWorkerRegistrationOptions options(
embedded_test_server()->GetURL(kPageUrl),
+ blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
embedded_test_server()->GetURL(kWorkerUrl), options,
@@ -1766,7 +1780,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, IdleTimerWithDevTools) {
"/service_worker/fetch_event_respond_with_fetch.js");
blink::mojom::ServiceWorkerRegistrationOptions options(
- scope, blink::mojom::ServiceWorkerUpdateViaCache::kNone);
+ scope, blink::mojom::ScriptType::kClassic,
+ blink::mojom::ServiceWorkerUpdateViaCache::kNone);
public_context()->RegisterServiceWorker(
worker_url, options,
base::BindOnce(&ExpectResultAndRun, true, base::DoNothing()));
@@ -1774,19 +1789,15 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, IdleTimerWithDevTools) {
// Navigate to a new page and request a sub resource. This should succeed
// normally.
- {
- const GURL url = embedded_test_server()->GetURL(
- "/service_worker/fetch_from_page.html?url=/service_worker/empty.html");
- EXPECT_TRUE(NavigateToURL(shell(), url));
- const base::string16 title = base::ASCIIToUTF16("DONE");
- TitleWatcher watcher(shell()->web_contents(), title);
- EXPECT_EQ(title, watcher.WaitAndGetTitle());
- }
+ EXPECT_TRUE(NavigateToURL(
+ shell(),
+ embedded_test_server()->GetURL("/service_worker/fetch_from_page.html")));
+ EXPECT_EQ("Echo", EvalJs(shell(), "fetch_from_page('/echo');"));
// Simulate to attach DevTools.
base::RunLoop loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
[](base::OnceClosure done, ServiceWorkerContextWrapper* wrapper,
int64_t version_id) {
@@ -1816,12 +1827,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, IdleTimerWithDevTools) {
// idle. However, the browser process notifies the renderer to let it continue
// to work because DevTools is attached, and it'll result in running all
// queued events.
- EXPECT_EQ(200, EvalJs(shell(), R"(
- (async () => {
- let response = await fetch(params.get('url'));
- return response.status;
- })()
- )"));
+ EXPECT_EQ("Echo", EvalJs(shell(), "fetch_from_page('/echo');"));
}
class ServiceWorkerNavigationPreloadTest : public ServiceWorkerBrowserTest {
@@ -1869,7 +1875,8 @@ class ServiceWorkerNavigationPreloadTest : public ServiceWorkerBrowserTest {
observer->Init();
blink::mojom::ServiceWorkerRegistrationOptions options(
- scope, blink::mojom::ServiceWorkerUpdateViaCache::kImports);
+ scope, blink::mojom::ScriptType::kClassic,
+ blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
worker_url, options,
base::BindOnce(&ExpectResultAndRun, true, base::DoNothing()));
@@ -2255,6 +2262,130 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, GetResponseText) {
EXPECT_EQ(1, GetRequestCount(kPageUrl));
}
+IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest,
+ GetLargeResponseText) {
+ const char kPageUrl[] = "/service_worker/navigation_preload.html";
+ const char kWorkerUrl[] = "/service_worker/navigation_preload.js";
+ std::string title = "<title>PASS</title>";
+ // A large body that exceeds the default size of a mojo::DataPipe.
+ constexpr size_t kBodySize = 128 * 1024;
+ // Randomly generate the body data
+ int index = 0;
+ std::string body;
+ for (size_t i = 0; i < kBodySize; ++i) {
+ body += static_cast<char>(index + 'a');
+ index = (37 * index + 11) % 26;
+ }
+ const std::string kScript =
+ kEnableNavigationPreloadScript +
+ "self.addEventListener('fetch', event => {\n"
+ " event.respondWith(\n"
+ " event.preloadResponse\n"
+ " .then(response => response.text())\n"
+ " .then(text =>\n"
+ " new Response(\n"
+ " text,\n"
+ " {headers: [['content-type', 'text/html']]})));\n"
+ " });";
+ const GURL page_url = embedded_test_server()->GetURL(kPageUrl);
+ const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl);
+ RegisterStaticFile(kPageUrl, title + body, "text/html");
+ RegisterStaticFile(kWorkerUrl, kScript, "text/javascript");
+
+ EXPECT_EQ(body, LoadNavigationPreloadTestPage(page_url, worker_url, "PASS"));
+
+ // The page request must be sent only once, since the worker responded with
+ // a synthetic Response.
+ EXPECT_EQ(1, GetRequestCount(kPageUrl));
+}
+
+IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest,
+ GetLargeResponseCloneText) {
+ const char kPageUrl[] = "/service_worker/navigation_preload.html";
+ const char kWorkerUrl[] = "/service_worker/navigation_preload.js";
+ std::string title = "<title>PASS</title>";
+ // A large body that exceeds the default size of a mojo::DataPipe.
+ constexpr size_t kBodySize = 128 * 1024;
+ // Randomly generate the body data
+ int index = 0;
+ std::string body;
+ for (size_t i = 0; i < kBodySize; ++i) {
+ body += static_cast<char>(index + 'a');
+ index = (37 * index + 11) % 26;
+ }
+ const std::string kScript =
+ kEnableNavigationPreloadScript +
+ "self.addEventListener('fetch', event => {\n"
+ " event.respondWith(\n"
+ " event.preloadResponse\n"
+ " .then(response => response.clone())\n"
+ " .then(response => response.text())\n"
+ " .then(text =>\n"
+ " new Response(\n"
+ " text,\n"
+ " {headers: [['content-type', 'text/html']]})));\n"
+ " });";
+ const GURL page_url = embedded_test_server()->GetURL(kPageUrl);
+ const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl);
+ RegisterStaticFile(kPageUrl, title + body, "text/html");
+ RegisterStaticFile(kWorkerUrl, kScript, "text/javascript");
+
+ EXPECT_EQ(body, LoadNavigationPreloadTestPage(page_url, worker_url, "PASS"));
+
+ // The page request must be sent only once, since the worker responded with
+ // a synthetic Response.
+ EXPECT_EQ(1, GetRequestCount(kPageUrl));
+}
+
+IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest,
+ GetLargeResponseReadableStream) {
+ const char kPageUrl[] = "/service_worker/navigation_preload.html";
+ const char kWorkerUrl[] = "/service_worker/navigation_preload.js";
+ std::string title = "<title>PASS</title>";
+ // A large body that exceeds the default size of a mojo::DataPipe.
+ constexpr size_t kBodySize = 128 * 1024;
+ // Randomly generate the body data
+ int index = 0;
+ std::string body;
+ for (size_t i = 0; i < kBodySize; ++i) {
+ body += static_cast<char>(index + 'a');
+ index = (37 * index + 11) % 26;
+ }
+ const std::string kScript =
+ kEnableNavigationPreloadScript +
+ "function drain(reader) {\n"
+ " var data = [];\n"
+ " var decoder = new TextDecoder();\n"
+ " function nextChunk(chunk) {\n"
+ " if (chunk.done)\n"
+ " return data.join();\n"
+ " data.push(decoder.decode(chunk.value));\n"
+ " return reader.read().then(nextChunk);\n"
+ " }\n"
+ " return reader.read().then(nextChunk);\n"
+ "}\n"
+ "self.addEventListener('fetch', event => {\n"
+ " event.respondWith(\n"
+ " event.preloadResponse\n"
+ " .then(response => response.body.getReader())\n"
+ " .then(reader => drain(reader))\n"
+ " .then(text =>\n"
+ " new Response(\n"
+ " text,\n"
+ " {headers: [['content-type', 'text/html']]})));\n"
+ " });";
+ const GURL page_url = embedded_test_server()->GetURL(kPageUrl);
+ const GURL worker_url = embedded_test_server()->GetURL(kWorkerUrl);
+ RegisterStaticFile(kPageUrl, title + body, "text/html");
+ RegisterStaticFile(kWorkerUrl, kScript, "text/javascript");
+
+ EXPECT_EQ(body, LoadNavigationPreloadTestPage(page_url, worker_url, "PASS"));
+
+ // The page request must be sent only once, since the worker responded with
+ // a synthetic Response.
+ EXPECT_EQ(1, GetRequestCount(kPageUrl));
+}
+
IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, NetworkError) {
const char kPageUrl[] = "/service_worker/navigation_preload.html";
const char kWorkerUrl[] = "/service_worker/navigation_preload.js";
@@ -2303,6 +2434,10 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest,
return;
}
+ auto console_observer =
+ base::MakeRefCounted<ConsoleMessageContextObserver>(wrapper());
+ console_observer->Init();
+
content::ResourceDispatcherHost::Get()->RegisterInterceptor(
kNavigationPreloadHeaderName, "",
base::Bind(&CancellingInterceptorCallback));
@@ -2317,6 +2452,11 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest,
EXPECT_EQ(kNavigationPreloadAbortError,
LoadNavigationPreloadTestPage(page_url, worker_url, "REJECTED"));
+
+ console_observer->WaitForConsoleMessages(1);
+ const base::string16 expected = base::ASCIIToUTF16("request was cancelled");
+ std::vector<base::string16> messages = console_observer->messages();
+ EXPECT_NE(base::string16::npos, messages[0].find(expected));
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest,
@@ -2615,7 +2755,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest,
new WorkerActivatedObserver(wrapper());
observer->Init();
blink::mojom::ServiceWorkerRegistrationOptions options(
- https_server.GetURL(kPageUrl),
+ https_server.GetURL(kPageUrl), blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
https_server.GetURL(kWorkerUrl), options,
@@ -2654,6 +2794,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest,
observer->Init();
blink::mojom::ServiceWorkerRegistrationOptions options(
embedded_test_server()->GetURL(kPageUrl),
+ blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
embedded_test_server()->GetURL(kWorkerUrl), options,
@@ -2705,16 +2846,19 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, ImportsBustMemcache) {
// An observer that waits for the version to stop.
class StopObserver : public ServiceWorkerVersion::Observer {
public:
- explicit StopObserver(const base::Closure& quit_closure)
- : quit_closure_(quit_closure) {}
+ explicit StopObserver(base::OnceClosure quit_closure)
+ : quit_closure_(std::move(quit_closure)) {}
void OnRunningStateChanged(ServiceWorkerVersion* version) override {
- if (version->running_status() == EmbeddedWorkerStatus::STOPPED)
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_closure_);
+ if (version->running_status() == EmbeddedWorkerStatus::STOPPED) {
+ DCHECK(quit_closure_);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ std::move(quit_closure_));
+ }
}
private:
- base::Closure quit_closure_;
+ base::OnceClosure quit_closure_;
};
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, RendererCrash) {
@@ -2745,22 +2889,23 @@ class ServiceWorkerBlackBoxBrowserTest : public ServiceWorkerBrowserTest {
void FindRegistrationOnIO(const GURL& document_url,
blink::ServiceWorkerStatusCode* status,
- const base::Closure& continuation) {
+ base::OnceClosure continuation) {
wrapper()->FindReadyRegistrationForDocument(
document_url,
- base::BindOnce(&ServiceWorkerBlackBoxBrowserTest::FindRegistrationOnIO2,
- base::Unretained(this), status, continuation));
+ base::BindOnce(
+ &ServiceWorkerBlackBoxBrowserTest::DidFindRegistrationOnIO,
+ base::Unretained(this), status, std::move(continuation)));
}
- void FindRegistrationOnIO2(
+ void DidFindRegistrationOnIO(
blink::ServiceWorkerStatusCode* out_status,
- const base::Closure& continuation,
+ base::OnceClosure continuation,
blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
*out_status = status;
if (!registration.get())
EXPECT_NE(blink::ServiceWorkerStatusCode::kOk, status);
- continuation.Run();
+ std::move(continuation).Run();
}
};
@@ -2791,6 +2936,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBlackBoxBrowserTest, Registration) {
base::RunLoop run_loop;
blink::mojom::ServiceWorkerRegistrationOptions options(
embedded_test_server()->GetURL(kScope),
+ blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
embedded_test_server()->GetURL("/does/not/exist"), options,
@@ -2804,6 +2950,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBlackBoxBrowserTest, Registration) {
base::RunLoop run_loop;
blink::mojom::ServiceWorkerRegistrationOptions options(
embedded_test_server()->GetURL(kScope),
+ blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
embedded_test_server()->GetURL(kWorkerUrl), options,
@@ -2818,6 +2965,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBlackBoxBrowserTest, Registration) {
base::RunLoop run_loop;
blink::mojom::ServiceWorkerRegistrationOptions options(
embedded_test_server()->GetURL(kScope),
+ blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
embedded_test_server()->GetURL(kWorkerUrl), options,
@@ -2911,28 +3059,45 @@ class ServiceWorkerVersionBrowserV8CacheTest
if (version_)
version_->RemoveObserver(this);
}
- void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitchASCII(switches::kV8CacheOptions, "code");
- }
void SetUpRegistrationAndListenerOnIOThread(const std::string& worker_url) {
SetUpRegistrationOnIOThread(worker_url);
version_->AddObserver(this);
}
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitchASCII(switches::kV8CacheOptions, "code");
+ }
+ void StartWorkerAndWaitUntilCachedMetadataUpdated(
+ blink::ServiceWorkerStatusCode status) {
+ DCHECK(!cache_updated_closure_);
+
+ base::RunLoop run_loop;
+ cache_updated_closure_ = run_loop.QuitClosure();
+
+ // Start a worker.
+ StartWorker(status);
+
+ // Wait for the metadata to be stored. This run loop should finish when
+ // OnCachedMetadataUpdated() is called.
+ run_loop.Run();
+ }
+ size_t metadata_size() { return metadata_size_; };
protected:
// ServiceWorkerVersion::Observer overrides
void OnCachedMetadataUpdated(ServiceWorkerVersion* version,
size_t size) override {
+ DCHECK(cache_updated_closure_);
+
metadata_size_ = size;
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- cache_updated_closure_);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ std::move(cache_updated_closure_));
}
- base::Closure cache_updated_closure_;
- size_t metadata_size_ = 0;
-
private:
base::test::ScopedFeatureList scoped_feature_list_;
+
+ base::OnceClosure cache_updated_closure_;
+ size_t metadata_size_ = 0;
};
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8CacheTest, Restart) {
@@ -2940,37 +3105,23 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8CacheTest, Restart) {
RunOnIOThread(base::BindOnce(&self::SetUpRegistrationAndListenerOnIOThread,
base::Unretained(this),
"/service_worker/worker.js"));
- {
- base::RunLoop cached_metadata_run_loop;
- cache_updated_closure_ = cached_metadata_run_loop.QuitClosure();
-
- // Start a worker.
- StartWorker(blink::ServiceWorkerStatusCode::kOk);
- // Wait for the metadata to be stored. This run loop should finish when
- // OnCachedMetadataUpdated() is called.
- cached_metadata_run_loop.Run();
- }
+ StartWorkerAndWaitUntilCachedMetadataUpdated(
+ blink::ServiceWorkerStatusCode::kOk);
// Time stamp data must be stored to the storage.
- EXPECT_EQ(kV8CacheTimeStampDataSize, static_cast<int>(metadata_size_));
+ EXPECT_EQ(kV8CacheTimeStampDataSize, static_cast<int>(metadata_size()));
// Stop the worker.
StopWorker();
- {
- base::RunLoop cached_metadata_run_loop;
- cache_updated_closure_ = cached_metadata_run_loop.QuitClosure();
- // Restart the worker.
- StartWorker(blink::ServiceWorkerStatusCode::kOk);
- // Wait for the matadata to be stored. This run loop should finish when
- // OnCachedMetadataUpdated() is called.
- cached_metadata_run_loop.Run();
- }
+ // Restart the worker.
+ StartWorkerAndWaitUntilCachedMetadataUpdated(
+ blink::ServiceWorkerStatusCode::kOk);
// The V8 code cache should be stored to the storage. It must have size
// greater than 16 bytes.
- EXPECT_GT(static_cast<int>(metadata_size_), kV8CacheTimeStampDataSize);
+ EXPECT_GT(static_cast<int>(metadata_size()), kV8CacheTimeStampDataSize);
// Stop the worker.
StopWorker();
@@ -2993,21 +3144,37 @@ class ServiceWorkerVersionBrowserV8FullCodeCacheTest
SetUpRegistrationOnIOThread(worker_url);
version_->AddObserver(this);
}
+ void StartWorkerAndWaitUntilCachedMetadataUpdated(
+ blink::ServiceWorkerStatusCode status) {
+ DCHECK(!cache_updated_closure_);
+
+ base::RunLoop run_loop;
+ cache_updated_closure_ = run_loop.QuitClosure();
+
+ // Start a worker.
+ StartWorker(status);
+
+ // Wait for the metadata to be stored. This run loop should finish when
+ // OnCachedMetadataUpdated() is called.
+ run_loop.Run();
+ }
+ size_t metadata_size() { return metadata_size_; };
protected:
// ServiceWorkerVersion::Observer overrides
void OnCachedMetadataUpdated(ServiceWorkerVersion* version,
size_t size) override {
+ DCHECK(cache_updated_closure_);
metadata_size_ = size;
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- cache_updated_closure_);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ std::move(cache_updated_closure_));
}
- base::Closure cache_updated_closure_;
- size_t metadata_size_ = 0;
-
private:
base::test::ScopedFeatureList scoped_feature_list_;
+
+ base::OnceClosure cache_updated_closure_;
+ size_t metadata_size_ = 0;
};
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8FullCodeCacheTest,
@@ -3016,19 +3183,13 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8FullCodeCacheTest,
RunOnIOThread(base::BindOnce(&self::SetUpRegistrationAndListenerOnIOThread,
base::Unretained(this),
"/service_worker/worker.js"));
- base::RunLoop cached_metadata_run_loop;
- cache_updated_closure_ = cached_metadata_run_loop.QuitClosure();
-
- // Start a worker.
- StartWorker(blink::ServiceWorkerStatusCode::kOk);
- // Wait for the metadata to be stored. This run loop should finish when
- // OnCachedMetadataUpdated() is called.
- cached_metadata_run_loop.Run();
+ StartWorkerAndWaitUntilCachedMetadataUpdated(
+ blink::ServiceWorkerStatusCode::kOk);
// The V8 code cache should be stored to the storage. It must have size
// greater than 16 bytes.
- EXPECT_GT(static_cast<int>(metadata_size_), kV8CacheTimeStampDataSize);
+ EXPECT_GT(static_cast<int>(metadata_size()), kV8CacheTimeStampDataSize);
// Stop the worker.
StopWorker();
@@ -3073,15 +3234,15 @@ class CacheStorageSideDataSizeChecker
return result;
}
- void OpenCacheOnIOThread(int* result, const base::Closure& continuation) {
+ void OpenCacheOnIOThread(int* result, base::OnceClosure continuation) {
cache_storage_context_->cache_manager()->OpenCache(
url::Origin::Create(origin_), CacheStorageOwner::kCacheAPI, cache_name_,
base::BindOnce(&self::OnCacheStorageOpenCallback, this, result,
- continuation));
+ std::move(continuation)));
}
void OnCacheStorageOpenCallback(int* result,
- const base::Closure& continuation,
+ base::OnceClosure continuation,
CacheStorageCacheHandle cache_handle,
CacheStorageError error) {
ASSERT_EQ(CacheStorageError::kSuccess, error);
@@ -3089,14 +3250,15 @@ class CacheStorageSideDataSizeChecker
new ServiceWorkerFetchRequest());
scoped_request->url = url_;
CacheStorageCache* cache = cache_handle.value();
- cache->Match(std::move(scoped_request), nullptr,
- base::BindOnce(&self::OnCacheStorageCacheMatchCallback, this,
- result, continuation, std::move(cache_handle)));
+ cache->Match(
+ std::move(scoped_request), nullptr,
+ base::BindOnce(&self::OnCacheStorageCacheMatchCallback, this, result,
+ std::move(continuation), std::move(cache_handle)));
}
void OnCacheStorageCacheMatchCallback(
int* result,
- const base::Closure& continuation,
+ base::OnceClosure continuation,
CacheStorageCacheHandle cache_handle,
CacheStorageError error,
blink::mojom::FetchAPIResponsePtr response) {
@@ -3105,13 +3267,15 @@ class CacheStorageSideDataSizeChecker
blink::mojom::BlobPtr blob_ptr(std::move(response->blob->blob));
auto blob_handle =
base::MakeRefCounted<storage::BlobHandle>(std::move(blob_ptr));
- blob_handle->get()->ReadSideData(base::BindLambdaForTesting(
- [blob_handle, result,
- continuation](const base::Optional<std::vector<uint8_t>>& data) {
+ blob_handle->get()->ReadSideData(base::BindOnce(
+ [](scoped_refptr<storage::BlobHandle> blob_handle, int* result,
+ base::OnceClosure continuation,
+ const base::Optional<std::vector<uint8_t>>& data) {
if (data)
*result = data->size();
- continuation.Run();
- }));
+ std::move(continuation).Run();
+ },
+ blob_handle, result, std::move(continuation)));
}
CacheStorageContextImpl* cache_storage_context_;
@@ -3140,6 +3304,7 @@ class ServiceWorkerV8CodeCacheForCacheStorageTest
observer->Init();
blink::mojom::ServiceWorkerRegistrationOptions options(
embedded_test_server()->GetURL(kPageUrl),
+ blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
embedded_test_server()->GetURL(kWorkerUrl), options,
@@ -3261,7 +3426,7 @@ class ServiceWorkerDisableWebSecurityTest : public ServiceWorkerBrowserTest {
new WorkerActivatedObserver(wrapper());
observer->Init();
blink::mojom::ServiceWorkerRegistrationOptions options(
- cross_origin_server_.GetURL(scope),
+ cross_origin_server_.GetURL(scope), blink::mojom::ScriptType::kClassic,
blink::mojom::ServiceWorkerUpdateViaCache::kImports);
public_context()->RegisterServiceWorker(
cross_origin_server_.GetURL(script), options,
@@ -3378,26 +3543,20 @@ class ServiceWorkerURLLoaderThrottleTest : public ServiceWorkerBrowserTest {
ServiceWorkerBrowserTest::TearDownOnMainThread();
}
- void NavigateAndWaitForDone(const GURL& url) {
- const base::string16 title = base::ASCIIToUTF16("DONE");
- TitleWatcher watcher(shell()->web_contents(), title);
- watcher.AlsoWaitForTitle(base::ASCIIToUTF16("ERROR"));
- EXPECT_TRUE(NavigateToURL(shell(), url));
- EXPECT_EQ(title, watcher.WaitAndGetTitle());
- }
-
void RegisterServiceWorker(const std::string& worker_url) {
- GURL url = embedded_test_server()->GetURL(
- "/service_worker/create_service_worker.html?worker_url=" + worker_url);
- NavigateAndWaitForDone(url);
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL(
+ "/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE", EvalJs(shell(), "register('" + worker_url + "');"));
}
void RegisterServiceWorkerWithScope(const std::string& worker_url,
const std::string& scope) {
- GURL url = embedded_test_server()->GetURL(
- "/service_worker/create_service_worker.html?worker_url=" + worker_url +
- "&scope=" + scope);
- NavigateAndWaitForDone(url);
+ EXPECT_TRUE(NavigateToURL(
+ shell(), embedded_test_server()->GetURL(
+ "/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE", EvalJs(shell(), "register('" + worker_url + "', '" +
+ scope + "');"));
}
};
@@ -3526,21 +3685,9 @@ IN_PROC_BROWSER_TEST_F(
EXPECT_EQ(true, EvalJs(shell()->web_contents()->GetMainFrame(),
"!!navigator.serviceWorker.controller"));
- if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- // The injected header should be present.
- EXPECT_EQ("injected value", EvalJs(shell()->web_contents()->GetMainFrame(),
- "document.body.textContent"));
- } else {
- // S13nServiceWorker: the injected header is not present. Throttle-modified
- // headers are not propagated to network requests through
- // ResourceDispatcherHost, because the legacy network code has its own code
- // path that applies the same throttling independent from the navigation's
- // URLLoaderThrottles.
- DCHECK(base::FeatureList::IsEnabled(
- blink::features::kServiceWorkerServicification));
- EXPECT_EQ("None", EvalJs(shell()->web_contents()->GetMainFrame(),
- "document.body.textContent"));
- }
+ // The injected header should be present.
+ EXPECT_EQ("injected value", EvalJs(shell()->web_contents()->GetMainFrame(),
+ "document.body.textContent"));
SetBrowserClientForTesting(old_content_browser_client);
}
diff --git a/chromium/content/browser/service_worker/service_worker_cache_writer.cc b/chromium/content/browser/service_worker/service_worker_cache_writer.cc
index 2d43b2ec095..7ff8cde2513 100644
--- a/chromium/content/browser/service_worker/service_worker_cache_writer.cc
+++ b/chromium/content/browser/service_worker/service_worker_cache_writer.cc
@@ -117,11 +117,12 @@ int ServiceWorkerCacheWriter::DoLoop(int status) {
ServiceWorkerCacheWriter::ServiceWorkerCacheWriter(
std::unique_ptr<ServiceWorkerResponseReader> compare_reader,
std::unique_ptr<ServiceWorkerResponseReader> copy_reader,
- std::unique_ptr<ServiceWorkerResponseWriter> writer)
+ std::unique_ptr<ServiceWorkerResponseWriter> writer,
+ bool pause_when_not_identical)
: state_(STATE_START),
io_pending_(false),
comparing_(false),
- did_replace_(false),
+ pause_when_not_identical_(pause_when_not_identical),
compare_reader_(std::move(compare_reader)),
copy_reader_(std::move(copy_reader)),
writer_(std::move(writer)),
@@ -136,12 +137,12 @@ net::Error ServiceWorkerCacheWriter::MaybeWriteHeaders(
headers_to_write_ = headers;
pending_callback_ = std::move(callback);
- DCHECK_EQ(state_, STATE_START);
+ DCHECK_EQ(STATE_START, state_);
int result = DoLoop(net::OK);
// Synchronous errors and successes always go to STATE_DONE.
if (result != net::ERR_IO_PENDING)
- DCHECK_EQ(state_, STATE_DONE);
+ DCHECK_EQ(STATE_DONE, state_);
// ERR_IO_PENDING has to have one of the STATE_*_DONE states as the next state
// (not STATE_DONE itself).
@@ -175,7 +176,7 @@ net::Error ServiceWorkerCacheWriter::MaybeWriteData(
// Synchronous completions are always STATE_DONE.
if (result != net::ERR_IO_PENDING)
- DCHECK_EQ(state_, STATE_DONE);
+ DCHECK_EQ(STATE_DONE, state_);
// Asynchronous completion means the state machine must be waiting in one of
// the Done states for an IO operation to complete:
@@ -185,6 +186,7 @@ net::Error ServiceWorkerCacheWriter::MaybeWriteData(
// STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE is excluded because that write
// is done by MaybeWriteHeaders.
DCHECK(state_ == STATE_READ_DATA_FOR_COMPARE_DONE ||
+ state_ == STATE_PAUSING ||
state_ == STATE_READ_HEADERS_FOR_COPY_DONE ||
state_ == STATE_READ_DATA_FOR_COPY_DONE ||
state_ == STATE_WRITE_HEADERS_FOR_COPY_DONE ||
@@ -192,6 +194,38 @@ net::Error ServiceWorkerCacheWriter::MaybeWriteData(
state_ == STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE)
<< "Unexpected state: " << state_;
}
+ return result >= 0 ? net::OK : static_cast<net::Error>(result);
+}
+
+net::Error ServiceWorkerCacheWriter::Resume(OnWriteCompleteCallback callback) {
+ DCHECK(pause_when_not_identical_);
+ DCHECK_EQ(STATE_PAUSING, state_);
+ DCHECK(io_pending_);
+
+ io_pending_ = false;
+ pending_callback_ = std::move(callback);
+ state_ = STATE_READ_HEADERS_FOR_COPY;
+
+ int result = DoLoop(net::OK);
+
+ // Synchronous completions are always STATE_DONE.
+ if (result != net::ERR_IO_PENDING)
+ DCHECK_EQ(STATE_DONE, state_);
+
+ // Asynchronous completion means the state machine must be waiting in one of
+ // the Done states for an IO operation to complete:
+ if (result == net::ERR_IO_PENDING) {
+ // Note that STATE_READ_HEADERS_FOR_COMPARE_DONE is excluded because the
+ // headers are compared in MaybeWriteHeaders, not here, and
+ // STATE_WRITE_HEADERS_FOR_PASSTHROUGH_DONE is excluded because that write
+ // is done by MaybeWriteHeaders.
+ DCHECK(state_ == STATE_READ_HEADERS_FOR_COPY_DONE ||
+ state_ == STATE_READ_DATA_FOR_COPY_DONE ||
+ state_ == STATE_WRITE_HEADERS_FOR_COPY_DONE ||
+ state_ == STATE_WRITE_DATA_FOR_COPY_DONE ||
+ state_ == STATE_WRITE_DATA_FOR_PASSTHROUGH_DONE)
+ << "Unexpected state: " << state_;
+ }
return result >= 0 ? net::OK : static_cast<net::Error>(result);
}
@@ -233,7 +267,7 @@ int ServiceWorkerCacheWriter::DoReadDataForCompare(int result) {
DCHECK_GE(result, 0);
DCHECK(data_to_write_);
- data_to_read_ = new net::IOBuffer(len_to_write_);
+ data_to_read_ = base::MakeRefCounted<net::IOBuffer>(len_to_write_);
len_to_read_ = len_to_write_;
state_ = STATE_READ_DATA_FOR_COMPARE_DONE;
compare_offset_ = 0;
@@ -259,8 +293,9 @@ int ServiceWorkerCacheWriter::DoReadDataForCompareDone(int result) {
// compare. Fail the comparison.
if (result == 0 && len_to_write_ != 0) {
comparing_ = false;
- state_ = STATE_READ_HEADERS_FOR_COPY;
- return net::OK;
+ state_ =
+ pause_when_not_identical_ ? STATE_PAUSING : STATE_READ_HEADERS_FOR_COPY;
+ return pause_when_not_identical_ ? net::ERR_IO_PENDING : net::OK;
}
// Compare the data from the ServiceWorker script cache to the data from the
@@ -271,8 +306,9 @@ int ServiceWorkerCacheWriter::DoReadDataForCompareDone(int result) {
// |bytes_compared_| were identical, so copy the first |bytes_compared_|
// over, then start writing network data back after the changed point.
comparing_ = false;
- state_ = STATE_READ_HEADERS_FOR_COPY;
- return net::OK;
+ state_ =
+ pause_when_not_identical_ ? STATE_PAUSING : STATE_READ_HEADERS_FOR_COPY;
+ return pause_when_not_identical_ ? net::ERR_IO_PENDING : net::OK;
}
compare_offset_ += result;
@@ -294,8 +330,9 @@ int ServiceWorkerCacheWriter::DoReadDataForCompareDone(int result) {
// just the prefix.
if (len_to_read_ == 0 && bytes_compared_ + compare_offset_ < cached_length_) {
comparing_ = false;
- state_ = STATE_READ_HEADERS_FOR_COPY;
- return net::OK;
+ state_ =
+ pause_when_not_identical_ ? STATE_PAUSING : STATE_READ_HEADERS_FOR_COPY;
+ return pause_when_not_identical_ ? net::ERR_IO_PENDING : net::OK;
}
bytes_compared_ += compare_offset_;
@@ -308,7 +345,7 @@ int ServiceWorkerCacheWriter::DoReadHeadersForCopy(int result) {
DCHECK(copy_reader_);
bytes_copied_ = 0;
headers_to_read_ = new HttpResponseInfoIOBuffer;
- data_to_copy_ = new net::IOBuffer(kCopyBufferSize);
+ data_to_copy_ = base::MakeRefCounted<net::IOBuffer>(kCopyBufferSize);
state_ = STATE_READ_HEADERS_FOR_COPY_DONE;
return ReadInfoHelper(copy_reader_, headers_to_read_.get());
}
@@ -492,10 +529,15 @@ void ServiceWorkerCacheWriter::AsyncDoLoop(int result) {
// later invocation of AsyncDoLoop.
if (result != net::ERR_IO_PENDING) {
OnWriteCompleteCallback callback = std::move(pending_callback_);
- pending_callback_.Reset();
net::Error error = result >= 0 ? net::OK : static_cast<net::Error>(result);
io_pending_ = false;
std::move(callback).Run(error);
+ return;
+ }
+ if (state_ == STATE_PAUSING) {
+ DCHECK(pause_when_not_identical_);
+ OnWriteCompleteCallback callback = std::move(pending_callback_);
+ std::move(callback).Run(net::ERR_IO_PENDING);
}
}
diff --git a/chromium/content/browser/service_worker/service_worker_cache_writer.h b/chromium/content/browser/service_worker/service_worker_cache_writer.h
index e357240657f..e8866e14f68 100644
--- a/chromium/content/browser/service_worker/service_worker_cache_writer.h
+++ b/chromium/content/browser/service_worker/service_worker_cache_writer.h
@@ -42,10 +42,16 @@ class CONTENT_EXPORT ServiceWorkerCacheWriter {
// The |compare_reader| may be null, in which case this instance will
// unconditionally write back data supplied to |MaybeWriteHeaders| and
// |MaybeWriteData|.
+ //
+ // When |pause_when_not_identical| is true and the cache writer detects a
+ // difference between bodies from the network and from the storage, the
+ // comparison stops immediately and the cache writer returns
+ // net::ERR_IO_PENDING, with nothing written to the storage.
ServiceWorkerCacheWriter(
std::unique_ptr<ServiceWorkerResponseReader> compare_reader,
std::unique_ptr<ServiceWorkerResponseReader> copy_reader,
- std::unique_ptr<ServiceWorkerResponseWriter> writer);
+ std::unique_ptr<ServiceWorkerResponseWriter> writer,
+ bool pause_when_not_identical);
~ServiceWorkerCacheWriter();
@@ -73,6 +79,13 @@ class CONTENT_EXPORT ServiceWorkerCacheWriter {
// Returns a count of bytes written back to the cache.
size_t bytes_written() const { return bytes_written_; }
bool did_replace() const { return did_replace_; }
+ bool is_pausing() const { return state_ == STATE_PAUSING; }
+
+ // Resumes a cache writer which were paused when a block of data from the
+ // network wasn't identical to the data in the storage. It is valid to call
+ // this method only when |pause_when_not_identical| is true in the constructor
+ // and |state_| is STATE_PAUSING.
+ net::Error Resume(OnWriteCompleteCallback callback);
private:
// States for the state machine.
@@ -102,6 +115,10 @@ class CONTENT_EXPORT ServiceWorkerCacheWriter {
STATE_READ_DATA_FOR_COMPARE,
STATE_READ_DATA_FOR_COMPARE_DONE,
+ // The cache writer is paused because the network data wasn't identical with
+ // the stored data, and |pause_when_not_identical| is true.
+ STATE_PAUSING,
+
// Control flows linearly through these states, with each pass from
// READ_DATA_FOR_COPY to WRITE_DATA_FOR_COPY_DONE copying one block of data
// at a time. Control loops from WRITE_DATA_FOR_COPY_DONE back to
@@ -219,7 +236,12 @@ class CONTENT_EXPORT ServiceWorkerCacheWriter {
// Count of bytes written back to |writer_|.
size_t bytes_written_;
- bool did_replace_;
+ bool did_replace_ = false;
+
+ // When the cache writer finds any differences between bodies from the network
+ // and from the storage, and the |pause_when_not_identical_| is true, the
+ // cache writer pauses immediately.
+ const bool pause_when_not_identical_;
std::unique_ptr<ServiceWorkerResponseReader> compare_reader_;
std::unique_ptr<ServiceWorkerResponseReader> copy_reader_;
diff --git a/chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc b/chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc
index 38d9f5c1f28..d37f40a4038 100644
--- a/chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc
@@ -19,306 +19,6 @@
namespace content {
namespace {
-// A test implementation of ServiceWorkerResponseReader.
-//
-// This class exposes the ability to expect reads (see ExpectRead*() below).
-// Each call to ReadInfo() or ReadData() consumes another expected read, in the
-// order those reads were expected, so:
-// reader->ExpectReadInfoOk(5, false);
-// reader->ExpectReadDataOk("abcdef", false);
-// reader->ExpectReadDataOk("ghijkl", false);
-// Expects these calls, in this order:
-// reader->ReadInfo(...); // reader writes 5 into
-// // |info_buf->response_data_size|
-// reader->ReadData(...); // reader writes "abcdef" into |buf|
-// reader->ReadData(...); // reader writes "ghijkl" into |buf|
-// If an unexpected call happens, this class DCHECKs.
-// If an expected read is marked "async", it will not complete immediately, but
-// must be completed by the test using CompletePendingRead().
-// These is a convenience method AllExpectedReadsDone() which returns whether
-// there are any expected reads that have not yet happened.
-class MockServiceWorkerResponseReader : public ServiceWorkerResponseReader {
- public:
- MockServiceWorkerResponseReader()
- : ServiceWorkerResponseReader(
- 0,
- base::WeakPtr<AppCacheDiskCacheInterface>()) {}
- ~MockServiceWorkerResponseReader() override {}
-
- // ServiceWorkerResponseReader overrides
- void ReadInfo(HttpResponseInfoIOBuffer* info_buf,
- OnceCompletionCallback callback) override;
- void ReadData(net::IOBuffer* buf,
- int buf_len,
- OnceCompletionCallback callback) override;
-
- // Test helpers. ExpectReadInfo() and ExpectReadData() give precise control
- // over both the data to be written and the result to return.
- // ExpectReadInfoOk() and ExpectReadDataOk() are convenience functions for
- // expecting successful reads, which always have their length as their result.
-
- // Expect a call to ReadInfo() on this reader. For these functions, |len| will
- // be used as |response_data_size|, not as the length of this particular read.
- void ExpectReadInfo(size_t len, bool async, int result);
- void ExpectReadInfoOk(size_t len, bool async);
-
- // Expect a call to ReadData() on this reader. For these functions, |len| is
- // the length of the data to be written back; in ExpectReadDataOk(), |len| is
- // implicitly the length of |data|.
- void ExpectReadData(const char* data, size_t len, bool async, int result);
- void ExpectReadDataOk(const std::string& data, bool async);
-
- // Complete a pending async read. It is an error to call this function without
- // a pending async read (ie, a previous call to ReadInfo() or ReadData()
- // having not run its callback yet).
- void CompletePendingRead();
-
- // Returns whether all expected reads have occurred.
- bool AllExpectedReadsDone() { return expected_reads_.size() == 0; }
-
- private:
- struct ExpectedRead {
- ExpectedRead(size_t len, bool async, int result)
- : data(nullptr), len(len), info(true), async(async), result(result) {}
- ExpectedRead(const char* data, size_t len, bool async, int result)
- : data(data), len(len), info(false), async(async), result(result) {}
- const char* data;
- size_t len;
- bool info;
- bool async;
- int result;
- };
-
- base::queue<ExpectedRead> expected_reads_;
- scoped_refptr<net::IOBuffer> pending_buffer_;
- size_t pending_buffer_len_;
- scoped_refptr<HttpResponseInfoIOBuffer> pending_info_;
- OnceCompletionCallback pending_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerResponseReader);
-};
-
-void MockServiceWorkerResponseReader::ReadInfo(
- HttpResponseInfoIOBuffer* info_buf,
- OnceCompletionCallback callback) {
- DCHECK(!expected_reads_.empty());
- ExpectedRead expected = expected_reads_.front();
- EXPECT_TRUE(expected.info);
- if (expected.async) {
- pending_info_ = info_buf;
- pending_callback_ = std::move(callback);
- } else {
- expected_reads_.pop();
- info_buf->response_data_size = expected.len;
- std::move(callback).Run(expected.result);
- }
-}
-
-void MockServiceWorkerResponseReader::ReadData(
- net::IOBuffer* buf,
- int buf_len,
- OnceCompletionCallback callback) {
- DCHECK(!expected_reads_.empty());
- ExpectedRead expected = expected_reads_.front();
- EXPECT_FALSE(expected.info);
- if (expected.async) {
- pending_callback_ = std::move(callback);
- pending_buffer_ = buf;
- pending_buffer_len_ = static_cast<size_t>(buf_len);
- } else {
- expected_reads_.pop();
- if (expected.len > 0) {
- size_t to_read = std::min(static_cast<size_t>(buf_len), expected.len);
- memcpy(buf->data(), expected.data, to_read);
- }
- std::move(callback).Run(expected.result);
- }
-}
-
-void MockServiceWorkerResponseReader::ExpectReadInfo(size_t len,
- bool async,
- int result) {
- expected_reads_.push(ExpectedRead(len, async, result));
-}
-
-void MockServiceWorkerResponseReader::ExpectReadInfoOk(size_t len, bool async) {
- expected_reads_.push(ExpectedRead(len, async, len));
-}
-
-void MockServiceWorkerResponseReader::ExpectReadData(const char* data,
- size_t len,
- bool async,
- int result) {
- expected_reads_.push(ExpectedRead(data, len, async, result));
-}
-
-void MockServiceWorkerResponseReader::ExpectReadDataOk(const std::string& data,
- bool async) {
- expected_reads_.push(
- ExpectedRead(data.data(), data.size(), async, data.size()));
-}
-
-void MockServiceWorkerResponseReader::CompletePendingRead() {
- DCHECK(!expected_reads_.empty());
- ExpectedRead expected = expected_reads_.front();
- expected_reads_.pop();
- EXPECT_TRUE(expected.async);
- if (expected.info) {
- pending_info_->response_data_size = expected.len;
- } else {
- size_t to_read = std::min(pending_buffer_len_, expected.len);
- if (to_read > 0)
- memcpy(pending_buffer_->data(), expected.data, to_read);
- }
- pending_info_ = nullptr;
- pending_buffer_ = nullptr;
- OnceCompletionCallback callback = std::move(pending_callback_);
- pending_callback_.Reset();
- std::move(callback).Run(expected.result);
-}
-
-// A test implementation of ServiceWorkerResponseWriter.
-//
-// This class exposes the ability to expect writes (see ExpectWrite*Ok() below).
-// Each write to this class via WriteInfo() or WriteData() consumes another
-// expected write, in the order they were added, so:
-// writer->ExpectWriteInfoOk(5, false);
-// writer->ExpectWriteDataOk(6, false);
-// writer->ExpectWriteDataOk(6, false);
-// Expects these calls, in this order:
-// writer->WriteInfo(...); // checks that |buf->response_data_size| == 5
-// writer->WriteData(...); // checks that 6 bytes are being written
-// writer->WriteData(...); // checks that another 6 bytes are being written
-// If this class receives an unexpected call to WriteInfo() or WriteData(), it
-// DCHECKs.
-// Expected writes marked async do not complete synchronously, but rather return
-// without running their callback and need to be completed with
-// CompletePendingWrite().
-// A convenience method AllExpectedWritesDone() is exposed so tests can ensure
-// that all expected writes have been consumed by matching calls to WriteInfo()
-// or WriteData().
-class MockServiceWorkerResponseWriter : public ServiceWorkerResponseWriter {
- public:
- MockServiceWorkerResponseWriter()
- : ServiceWorkerResponseWriter(
- 0,
- base::WeakPtr<AppCacheDiskCacheInterface>()),
- info_written_(0),
- data_written_(0) {}
- ~MockServiceWorkerResponseWriter() override {}
-
- // ServiceWorkerResponseWriter overrides
- void WriteInfo(HttpResponseInfoIOBuffer* info_buf,
- OnceCompletionCallback callback) override;
- void WriteData(net::IOBuffer* buf,
- int buf_len,
- OnceCompletionCallback callback) override;
-
- // Enqueue expected writes.
- void ExpectWriteInfoOk(size_t len, bool async);
- void ExpectWriteInfo(size_t len, bool async, int result);
- void ExpectWriteDataOk(size_t len, bool async);
- void ExpectWriteData(size_t len, bool async, int result);
-
- // Complete a pending asynchronous write. This method DCHECKs unless there is
- // a pending write (a write for which WriteInfo() or WriteData() has been
- // called but the callback has not yet been run).
- void CompletePendingWrite();
-
- // Returns whether all expected reads have been consumed.
- bool AllExpectedWritesDone() { return expected_writes_.size() == 0; }
-
- private:
- struct ExpectedWrite {
- ExpectedWrite(bool is_info, size_t length, bool async, int result)
- : is_info(is_info), length(length), async(async), result(result) {}
- bool is_info;
- size_t length;
- bool async;
- int result;
- };
-
- base::queue<ExpectedWrite> expected_writes_;
-
- size_t info_written_;
- size_t data_written_;
-
- OnceCompletionCallback pending_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerResponseWriter);
-};
-
-void MockServiceWorkerResponseWriter::WriteInfo(
- HttpResponseInfoIOBuffer* info_buf,
- OnceCompletionCallback callback) {
- DCHECK(!expected_writes_.empty());
- ExpectedWrite write = expected_writes_.front();
- EXPECT_TRUE(write.is_info);
- if (write.result > 0) {
- EXPECT_EQ(write.length, static_cast<size_t>(info_buf->response_data_size));
- info_written_ += info_buf->response_data_size;
- }
- if (!write.async) {
- expected_writes_.pop();
- std::move(callback).Run(write.result);
- } else {
- pending_callback_ = std::move(callback);
- }
-}
-
-void MockServiceWorkerResponseWriter::WriteData(
- net::IOBuffer* buf,
- int buf_len,
- OnceCompletionCallback callback) {
- DCHECK(!expected_writes_.empty());
- ExpectedWrite write = expected_writes_.front();
- EXPECT_FALSE(write.is_info);
- if (write.result > 0) {
- EXPECT_EQ(write.length, static_cast<size_t>(buf_len));
- data_written_ += buf_len;
- }
- if (!write.async) {
- expected_writes_.pop();
- std::move(callback).Run(write.result);
- } else {
- pending_callback_ = std::move(callback);
- }
-}
-
-void MockServiceWorkerResponseWriter::ExpectWriteInfoOk(size_t length,
- bool async) {
- ExpectWriteInfo(length, async, length);
-}
-
-void MockServiceWorkerResponseWriter::ExpectWriteDataOk(size_t length,
- bool async) {
- ExpectWriteData(length, async, length);
-}
-
-void MockServiceWorkerResponseWriter::ExpectWriteInfo(size_t length,
- bool async,
- int result) {
- DCHECK_NE(net::ERR_IO_PENDING, result);
- ExpectedWrite expected(true, length, async, result);
- expected_writes_.push(expected);
-}
-
-void MockServiceWorkerResponseWriter::ExpectWriteData(size_t length,
- bool async,
- int result) {
- DCHECK_NE(net::ERR_IO_PENDING, result);
- ExpectedWrite expected(false, length, async, result);
- expected_writes_.push(expected);
-}
-
-void MockServiceWorkerResponseWriter::CompletePendingWrite() {
- DCHECK(!expected_writes_.empty());
- ExpectedWrite write = expected_writes_.front();
- DCHECK(write.async);
- expected_writes_.pop();
- std::move(pending_callback_).Run(write.result);
-}
-
class ServiceWorkerCacheWriterTest : public ::testing::Test {
public:
ServiceWorkerCacheWriterTest() {}
@@ -341,12 +41,13 @@ class ServiceWorkerCacheWriterTest : public ::testing::Test {
}
// This should be called after ExpectReader() and ExpectWriter().
- void Initialize() {
+ void Initialize(bool pause_when_not_identical) {
std::unique_ptr<ServiceWorkerResponseReader> compare_reader(CreateReader());
std::unique_ptr<ServiceWorkerResponseReader> copy_reader(CreateReader());
std::unique_ptr<ServiceWorkerResponseWriter> writer(CreateWriter());
cache_writer_.reset(new ServiceWorkerCacheWriter(
- std::move(compare_reader), std::move(copy_reader), std::move(writer)));
+ std::move(compare_reader), std::move(copy_reader), std::move(writer),
+ pause_when_not_identical));
}
protected:
@@ -391,7 +92,8 @@ class ServiceWorkerCacheWriterTest : public ::testing::Test {
}
net::Error WriteData(const std::string& data) {
- scoped_refptr<net::IOBuffer> buf = new net::StringIOBuffer(data);
+ scoped_refptr<net::IOBuffer> buf =
+ base::MakeRefCounted<net::StringIOBuffer>(data);
return cache_writer_->MaybeWriteData(buf.get(), data.size(),
CreateWriteCallback());
}
@@ -410,7 +112,7 @@ TEST_F(ServiceWorkerCacheWriterTest, PassthroughHeadersSync) {
const size_t kHeaderSize = 16;
MockServiceWorkerResponseWriter* writer = ExpectWriter();
writer->ExpectWriteInfoOk(kHeaderSize, false);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(kHeaderSize);
EXPECT_EQ(net::OK, error);
@@ -423,7 +125,7 @@ TEST_F(ServiceWorkerCacheWriterTest, PassthroughHeadersAsync) {
size_t kHeaderSize = 16;
MockServiceWorkerResponseWriter* writer = ExpectWriter();
writer->ExpectWriteInfoOk(kHeaderSize, true);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(kHeaderSize);
EXPECT_EQ(net::ERR_IO_PENDING, error);
@@ -444,7 +146,7 @@ TEST_F(ServiceWorkerCacheWriterTest, PassthroughDataSync) {
writer->ExpectWriteInfoOk(response_size, false);
writer->ExpectWriteDataOk(data1.size(), false);
writer->ExpectWriteDataOk(data2.size(), false);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(response_size);
EXPECT_EQ(net::OK, error);
@@ -466,7 +168,7 @@ TEST_F(ServiceWorkerCacheWriterTest, PassthroughDataAsync) {
writer->ExpectWriteInfoOk(response_size, false);
writer->ExpectWriteDataOk(data1.size(), true);
writer->ExpectWriteDataOk(data2.size(), true);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(response_size);
EXPECT_EQ(net::OK, error);
@@ -489,7 +191,7 @@ TEST_F(ServiceWorkerCacheWriterTest, PassthroughHeadersFailSync) {
const size_t kHeaderSize = 16;
MockServiceWorkerResponseWriter* writer = ExpectWriter();
writer->ExpectWriteInfo(kHeaderSize, false, net::ERR_FAILED);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(kHeaderSize);
EXPECT_EQ(net::ERR_FAILED, error);
@@ -502,7 +204,7 @@ TEST_F(ServiceWorkerCacheWriterTest, PassthroughHeadersFailAsync) {
size_t kHeaderSize = 16;
MockServiceWorkerResponseWriter* writer = ExpectWriter();
writer->ExpectWriteInfo(kHeaderSize, true, net::ERR_FAILED);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(kHeaderSize);
EXPECT_EQ(net::ERR_IO_PENDING, error);
@@ -520,7 +222,7 @@ TEST_F(ServiceWorkerCacheWriterTest, PassthroughDataFailSync) {
MockServiceWorkerResponseWriter* writer = ExpectWriter();
writer->ExpectWriteInfoOk(data.size(), false);
writer->ExpectWriteData(data.size(), false, net::ERR_FAILED);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
EXPECT_EQ(net::OK, WriteHeaders(data.size()));
EXPECT_EQ(net::ERR_FAILED, WriteData(data));
@@ -533,7 +235,7 @@ TEST_F(ServiceWorkerCacheWriterTest, PassthroughDataFailAsync) {
MockServiceWorkerResponseWriter* writer = ExpectWriter();
writer->ExpectWriteInfoOk(data.size(), false);
writer->ExpectWriteData(data.size(), true, net::ERR_FAILED);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
EXPECT_EQ(net::OK, WriteHeaders(data.size()));
@@ -555,7 +257,7 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareHeadersSync) {
MockServiceWorkerResponseReader* reader = ExpectReader();
reader->ExpectReadInfoOk(response_size, false);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(response_size);
EXPECT_EQ(net::OK, error);
@@ -572,7 +274,7 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareDataOkSync) {
reader->ExpectReadInfoOk(response_size, false);
reader->ExpectReadDataOk(data1, false);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(response_size);
EXPECT_EQ(net::OK, error);
@@ -591,7 +293,7 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareHeadersFailSync) {
MockServiceWorkerResponseReader* reader = ExpectReader();
reader->ExpectReadInfo(response_size, false, net::ERR_FAILED);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
EXPECT_EQ(net::ERR_FAILED, WriteHeaders(response_size));
EXPECT_TRUE(writer->AllExpectedWritesDone());
@@ -607,7 +309,7 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareDataFailSync) {
reader->ExpectReadInfoOk(response_size, false);
reader->ExpectReadData(data1.c_str(), data1.length(), false, net::ERR_FAILED);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(response_size);
EXPECT_EQ(net::OK, error);
@@ -635,7 +337,7 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareShortCacheReads) {
reader->ExpectReadDataOk(cache_data3, false);
reader->ExpectReadDataOk(cache_data4, false);
reader->ExpectReadDataOk(data5, false);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(kHeaderSize);
EXPECT_EQ(net::OK, error);
@@ -657,7 +359,7 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareDataOkAsync) {
reader->ExpectReadInfoOk(response_size, true);
reader->ExpectReadDataOk(data1, true);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(response_size);
EXPECT_EQ(net::ERR_IO_PENDING, error);
@@ -685,7 +387,7 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareDataManyOkAsync) {
for (size_t i = 0; i < arraysize(expected_data); ++i) {
reader->ExpectReadDataOk(expected_data[i], true);
}
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(response_size);
EXPECT_EQ(net::ERR_IO_PENDING, error);
@@ -730,7 +432,7 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopySync) {
writer->ExpectWriteDataOk(net_data2.size(), false);
writer->ExpectWriteDataOk(data3.size(), false);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(net_response_size);
EXPECT_EQ(net::OK, error);
@@ -772,7 +474,7 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopyShort) {
writer->ExpectWriteDataOk(net_data2.size(), false);
writer->ExpectWriteDataOk(data3.size(), false);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(net_response_size);
EXPECT_EQ(net::OK, error);
@@ -816,7 +518,7 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopyLong) {
writer->ExpectWriteDataOk(data1.size(), false);
writer->ExpectWriteDataOk(net_data2.size(), false);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(net_size);
EXPECT_EQ(net::OK, error);
@@ -879,7 +581,7 @@ TEST_F(ServiceWorkerCacheWriterTest, MultipleComparisonInSingleWrite) {
for (const auto& data : data_expected)
writer->ExpectWriteDataOk(data.size(), false);
- Initialize();
+ Initialize(false /* pause_when_not_identical */);
net::Error error = WriteHeaders(bytes_from_net);
EXPECT_EQ(net::OK, error);
@@ -893,5 +595,175 @@ TEST_F(ServiceWorkerCacheWriterTest, MultipleComparisonInSingleWrite) {
EXPECT_TRUE(copy_reader->AllExpectedReadsDone());
}
+// Tests behavior when |pause_when_not_identical| is enabled and cache writer
+// finishes synchronously.
+TEST_F(ServiceWorkerCacheWriterTest, PauseWhenNotIdentical_SyncWriteData) {
+ // Data from |compare_reader|.
+ const std::vector<std::string> data_from_cache{"abcd"};
+
+ // Data for |writer|. The comparison should stop at the first block of the
+ // data.
+ const std::vector<std::string> data_from_net{"abxx"};
+
+ // We don't need |data_to_copy| because the network data and the cached data
+ // have no common blocks.
+
+ // The written data should be the same as |data_from_net|.
+ const std::vector<std::string> data_expected{"abxx"};
+
+ size_t bytes_cached = 0;
+ size_t bytes_from_net = 0;
+ size_t bytes_expected = 0;
+
+ for (const auto& data : data_from_cache)
+ bytes_cached += data.size();
+
+ for (const auto& data : data_from_net)
+ bytes_from_net += data.size();
+
+ for (const auto& data : data_expected)
+ bytes_expected += data.size();
+
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ MockServiceWorkerResponseReader* compare_reader = ExpectReader();
+ MockServiceWorkerResponseReader* copy_reader = ExpectReader();
+
+ compare_reader->ExpectReadInfoOk(bytes_cached, false);
+ for (const auto& data : data_from_cache)
+ compare_reader->ExpectReadDataOk(data, false);
+
+ copy_reader->ExpectReadInfoOk(bytes_cached, false);
+
+ writer->ExpectWriteInfoOk(bytes_expected, false);
+ for (const auto& data : data_expected)
+ writer->ExpectWriteDataOk(data.size(), false);
+
+ Initialize(true /* pause_when_not_identical */);
+
+ net::Error error = WriteHeaders(bytes_from_net);
+ EXPECT_EQ(net::OK, error);
+
+ // |cache_writer_| stops the comparison at the first block of the data.
+ // It should return net::ERR_IO_PENDING and |write_complete_| should remain
+ // false since |pause_when_not_identical| forbids proceeding to the next step.
+ write_complete_ = false;
+ error = WriteData(data_from_net[0]);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ EXPECT_FALSE(write_complete_);
+ EXPECT_EQ(0U, cache_writer_->bytes_written());
+
+ // Resume |cache_writer_| with a callback. The passed callback shouldn't be
+ // called because this is a synchronous write. This time, the result should be
+ // net::OK and the expected data should be written to the storage.
+ error =
+ cache_writer_->Resume(base::BindOnce([](net::Error) { NOTREACHED(); }));
+ EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(bytes_expected, cache_writer_->bytes_written());
+
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_TRUE(compare_reader->AllExpectedReadsDone());
+ EXPECT_TRUE(copy_reader->AllExpectedReadsDone());
+}
+
+// Tests behavior when |pause_when_not_identical| is enabled and cache writer
+// finishes asynchronously.
+TEST_F(ServiceWorkerCacheWriterTest, PauseWhenNotIdentical_AsyncWriteData) {
+ // Data from |compare_reader|.
+ const std::vector<std::string> data_from_cache{"abcd"};
+
+ // Data for |writer|. The comparison should stop at the first block of the
+ // data.
+ const std::vector<std::string> data_from_net{"abxx"};
+
+ // We don't need |data_to_copy| because the network data and the cached data
+ // have no common blocks.
+
+ // The written data should be the same as |data_from_net|.
+ const std::vector<std::string> data_expected{"abxx"};
+
+ size_t bytes_cached = 0;
+ size_t bytes_from_net = 0;
+ size_t bytes_expected = 0;
+
+ for (const auto& data : data_from_cache)
+ bytes_cached += data.size();
+
+ for (const auto& data : data_from_net)
+ bytes_from_net += data.size();
+
+ for (const auto& data : data_expected)
+ bytes_expected += data.size();
+
+ MockServiceWorkerResponseWriter* writer = ExpectWriter();
+ MockServiceWorkerResponseReader* compare_reader = ExpectReader();
+ MockServiceWorkerResponseReader* copy_reader = ExpectReader();
+
+ compare_reader->ExpectReadInfoOk(bytes_cached, true);
+ for (const auto& data : data_from_cache)
+ compare_reader->ExpectReadDataOk(data, true);
+
+ copy_reader->ExpectReadInfoOk(bytes_cached, true);
+
+ writer->ExpectWriteInfoOk(bytes_expected, true);
+ for (const auto& data : data_expected)
+ writer->ExpectWriteDataOk(data.size(), true);
+
+ Initialize(true /* pause_when_not_identical */);
+
+ write_complete_ = false;
+ net::Error error = WriteHeaders(bytes_from_net);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ EXPECT_FALSE(write_complete_);
+ compare_reader->CompletePendingRead();
+ EXPECT_TRUE(write_complete_);
+
+ // The comparison is suspended due to an asynchronous read of
+ // |compare_reader|, resulting in an early return. At this point, the callback
+ // shouldn't be called yet.
+ write_complete_ = false;
+ error = WriteData(data_from_net[0]);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ EXPECT_FALSE(write_complete_);
+
+ // When |compare_reader| succeeds in reading the stored data, |cache_writer_|
+ // then proceeds to the comparison phase.
+ // |cache_writer_| stops comparison at the first block of the data.
+ // Since |pause_when_not_identical| is enabled, it should subsequently trigger
+ // the callback and return net::ERR_IO_PENDING.
+ compare_reader->CompletePendingRead();
+ EXPECT_TRUE(write_complete_);
+ EXPECT_EQ(net::ERR_IO_PENDING, last_error_);
+ EXPECT_EQ(0U, cache_writer_->bytes_written());
+
+ // Resume |cache_writer_| with a callback which updates |write_complete_| and
+ // |last_error_| when it's called.
+ // |copy_reader| does an asynchronous read here.
+ write_complete_ = false;
+ error = cache_writer_->Resume(CreateWriteCallback());
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ EXPECT_FALSE(write_complete_);
+
+ // Complete the asynchronous read of the header. Since there's nothing to copy
+ // from the storage, |copy_reader| should finish all its jobs here.
+ copy_reader->CompletePendingRead();
+ EXPECT_TRUE(copy_reader->AllExpectedReadsDone());
+
+ // Complete the asynchronous write of the header. This doesn't finish all the
+ // write to the storage, so the callback isn't called yet.
+ writer->CompletePendingWrite();
+ EXPECT_FALSE(write_complete_);
+ EXPECT_EQ(net::ERR_IO_PENDING, last_error_);
+
+ // Complete the asynchronous write of the body. This completes all the work of
+ // |cache_writer|, so the callback is triggered.
+ writer->CompletePendingWrite();
+ EXPECT_TRUE(write_complete_);
+ EXPECT_EQ(net::OK, last_error_);
+ EXPECT_EQ(bytes_expected, cache_writer_->bytes_written());
+
+ EXPECT_TRUE(writer->AllExpectedWritesDone());
+ EXPECT_TRUE(compare_reader->AllExpectedReadsDone());
+}
+
} // namespace
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_client_utils.cc b/chromium/content/browser/service_worker/service_worker_client_utils.cc
index c2252ec96fa..c83bf9eafb9 100644
--- a/chromium/content/browser/service_worker/service_worker_client_utils.cc
+++ b/chromium/content/browser/service_worker/service_worker_client_utils.cc
@@ -10,6 +10,7 @@
#include "base/location.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
@@ -20,6 +21,7 @@
#include "content/browser/storage_partition_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/navigation_handle.h"
@@ -93,9 +95,10 @@ class OpenURLObserver : public WebContentsObserver {
DCHECK(web_contents());
DCHECK(callback_);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(std::move(callback_),
- render_process_id, render_frame_id));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(std::move(callback_), render_process_id,
+ render_frame_id));
Observe(nullptr);
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}
@@ -167,8 +170,8 @@ void DidOpenURLOnUI(WindowType type,
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!web_contents) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), ChildProcessHost::kInvalidUniqueID,
MSG_ROUTING_NONE));
return;
@@ -214,8 +217,8 @@ void OpenWindowOnUI(
RenderProcessHost* render_process_host =
RenderProcessHost::FromID(worker_process_id);
if (render_process_host->IsForGuestsOnly()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), ChildProcessHost::kInvalidUniqueID,
MSG_ROUTING_NONE));
return;
@@ -248,8 +251,8 @@ void NavigateClientOnUI(const GURL& url,
WebContents* web_contents = WebContents::FromRenderFrameHost(rfhi);
if (!rfhi || !web_contents) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), ChildProcessHost::kInvalidUniqueID,
MSG_ROUTING_NONE));
return;
@@ -333,8 +336,8 @@ void OnGetWindowClientsOnUI(
out_clients->push_back(std::move(info));
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), std::move(out_clients)));
}
@@ -432,8 +435,8 @@ void GetWindowClients(const base::WeakPtr<ServiceWorkerVersion>& controller,
return;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&OnGetWindowClientsOnUI, clients_info,
controller->script_url(),
base::BindOnce(&DidGetWindowClients, controller,
@@ -448,8 +451,8 @@ void FocusWindowClient(ServiceWorkerProviderHost* provider_host,
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK_EQ(blink::mojom::ServiceWorkerClientType::kWindow,
provider_host->client_type());
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&FocusOnUI, provider_host->process_id(),
provider_host->frame_id(), provider_host->create_time(),
provider_host->client_uuid()),
@@ -463,8 +466,8 @@ void OpenWindow(const GURL& url,
WindowType type,
NavigationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&OpenWindowOnUI, url, script_url, worker_process_id,
base::WrapRefCounted(context->wrapper()), type,
@@ -479,8 +482,8 @@ void NavigateClient(const GURL& url,
const base::WeakPtr<ServiceWorkerContextCore>& context,
NavigationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&NavigateClientOnUI, url, script_url, process_id, frame_id,
base::BindOnce(&DidNavigate, context, script_url.GetOrigin(),
@@ -498,8 +501,8 @@ void GetClient(const ServiceWorkerProviderHost* provider_host,
<< client_type;
if (client_type == blink::mojom::ServiceWorkerClientType::kWindow) {
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&GetWindowClientInfoOnUI, provider_host->process_id(),
provider_host->route_id(), provider_host->create_time(),
provider_host->client_uuid()),
@@ -513,8 +516,8 @@ void GetClient(const ServiceWorkerProviderHost* provider_host,
false, // is_focused
network::mojom::RequestContextFrameType::kNone, base::TimeTicks(),
provider_host->create_time());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), std::move(client_info)));
}
@@ -570,8 +573,8 @@ void DidNavigate(const base::WeakPtr<ServiceWorkerContextCore>& context,
provider_host->frame_id() != render_frame_id) {
continue;
}
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&GetWindowClientInfoOnUI, provider_host->process_id(),
provider_host->route_id(), provider_host->create_time(),
provider_host->client_uuid()),
diff --git a/chromium/content/browser/service_worker/service_worker_content_settings_proxy_impl.cc b/chromium/content/browser/service_worker/service_worker_content_settings_proxy_impl.cc
index 3ba2c39cc15..f7baefc57cc 100644
--- a/chromium/content/browser/service_worker/service_worker_content_settings_proxy_impl.cc
+++ b/chromium/content/browser/service_worker/service_worker_content_settings_proxy_impl.cc
@@ -36,7 +36,7 @@ void ServiceWorkerContentSettingsProxyImpl::AllowIndexedDB(
std::move(callback).Run(false);
return;
}
- if (origin_.unique()) {
+ if (origin_.opaque()) {
std::move(callback).Run(false);
return;
}
diff --git a/chromium/content/browser/service_worker/service_worker_context_core.cc b/chromium/content/browser/service_worker/service_worker_context_core.cc
index df3b6835062..e7e9dfa000b 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_core.cc
@@ -17,6 +17,7 @@
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
@@ -34,6 +35,7 @@
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/url_loader_factory_getter.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/child_process_host.h"
#include "ipc/ipc_message.h"
@@ -162,7 +164,8 @@ class ClearAllServiceWorkersHelper
friend class base::RefCounted<ClearAllServiceWorkersHelper>;
~ClearAllServiceWorkersHelper() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(callback_));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ std::move(callback_));
}
base::OnceClosure callback_;
@@ -412,8 +415,8 @@ void ServiceWorkerContextCore::HasMainFrameProviderHost(
provider_host_iterator.Advance();
}
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&FrameListContainsMainFrameOnUI, std::move(render_frames)),
std::move(callback));
}
@@ -604,7 +607,7 @@ bool ServiceWorkerContextCore::IsValidRegisterRequest(
ServiceWorkerRegistration* ServiceWorkerContextCore::GetLiveRegistration(
int64_t id) {
- RegistrationsMap::iterator it = live_registrations_.find(id);
+ auto it = live_registrations_.find(id);
return (it != live_registrations_.end()) ? it->second : nullptr;
}
@@ -622,7 +625,7 @@ void ServiceWorkerContextCore::RemoveLiveRegistration(int64_t id) {
}
ServiceWorkerVersion* ServiceWorkerContextCore::GetLiveVersion(int64_t id) {
- VersionMap::iterator it = live_versions_.find(id);
+ auto it = live_versions_.find(id);
return (it != live_versions_.end()) ? it->second : nullptr;
}
diff --git a/chromium/content/browser/service_worker/service_worker_context_request_handler.cc b/chromium/content/browser/service_worker/service_worker_context_request_handler.cc
index 1570948c6ef..32af334ed62 100644
--- a/chromium/content/browser/service_worker/service_worker_context_request_handler.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_request_handler.cc
@@ -101,17 +101,6 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJob(
// falling back to network. Otherwise the renderer may receive the response
// from network and start a service worker whose browser-side
// ServiceWorkerVersion is not properly initialized.
- //
- // As an exception, allow installed service workers to use importScripts()
- // to import non-installed scripts.
- // TODO(falken): This is a spec violation that should be deprecated and
- // removed. See https://github.com/w3c/ServiceWorker/issues/1021
- if (status == CreateJobStatus::ERROR_UNINSTALLED_SCRIPT_IMPORT) {
- // Fall back to network.
- ServiceWorkerMetrics::RecordUninstalledScriptImport(version_->script_url());
- return nullptr;
- }
-
std::string error_str(CreateJobStatusToString(status));
request->net_log().AddEvent(
net::NetLogEventType::SERVICE_WORKER_SCRIPT_LOAD_UNHANDLED_REQUEST_ERROR,
diff --git a/chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc b/chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
index 692d21dc1f8..086d9925e68 100644
--- a/chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
@@ -79,9 +79,9 @@ class ServiceWorkerContextRequestHandlerTest : public testing::Test {
options.scope = scope_;
registration_ = base::MakeRefCounted<ServiceWorkerRegistration>(
options, 1L, context()->AsWeakPtr());
- version_ = new ServiceWorkerVersion(registration_.get(), script_url_,
- context()->storage()->NewVersionId(),
- context()->AsWeakPtr());
+ version_ = new ServiceWorkerVersion(
+ registration_.get(), script_url_, blink::mojom::ScriptType::kClassic,
+ context()->storage()->NewVersionId(), context()->AsWeakPtr());
SetUpProvider();
std::unique_ptr<MockHttpProtocolHandler> handler(
@@ -131,7 +131,8 @@ class ServiceWorkerContextRequestHandlerTest : public testing::Test {
network::mojom::FetchCredentialsMode::kOmit,
network::mojom::FetchRedirectMode::kFollow,
std::string() /* integrity */, false /* keepalive */,
- RESOURCE_TYPE_SERVICE_WORKER, REQUEST_CONTEXT_TYPE_SERVICE_WORKER,
+ RESOURCE_TYPE_SERVICE_WORKER,
+ blink::mojom::RequestContextType::SERVICE_WORKER,
network::mojom::RequestContextFrameType::kNone, nullptr);
}
@@ -308,7 +309,7 @@ TEST_F(ServiceWorkerContextRequestHandlerTest,
network::mojom::FetchCredentialsMode::kOmit,
network::mojom::FetchRedirectMode::kFollow, std::string() /* integrity */,
false /* keepalive */, RESOURCE_TYPE_SERVICE_WORKER,
- REQUEST_CONTEXT_TYPE_SERVICE_WORKER,
+ blink::mojom::RequestContextType::SERVICE_WORKER,
network::mojom::RequestContextFrameType::kNone, nullptr);
// Verify a ServiceWorkerRequestHandler was created.
ServiceWorkerRequestHandler* handler =
@@ -398,8 +399,8 @@ TEST_F(ServiceWorkerContextRequestHandlerTest, InstalledWorker) {
TEST_F(ServiceWorkerContextRequestHandlerTest, Incumbent) {
// Make an incumbent version.
scoped_refptr<ServiceWorkerVersion> incumbent = new ServiceWorkerVersion(
- registration_.get(), script_url_, context()->storage()->NewVersionId(),
- context()->AsWeakPtr());
+ registration_.get(), script_url_, blink::mojom::ScriptType::kClassic,
+ context()->storage()->NewVersionId(), context()->AsWeakPtr());
incumbent->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
std::vector<ServiceWorkerDatabase::ResourceRecord> resources = {
diff --git a/chromium/content/browser/service_worker/service_worker_context_unittest.cc b/chromium/content/browser/service_worker/service_worker_context_unittest.cc
index 7ca85191c7b..acf4e1d44a2 100644
--- a/chromium/content/browser/service_worker/service_worker_context_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_unittest.cc
@@ -93,7 +93,8 @@ class RejectInstallTestHelper : public EmbeddedWorkerTestHelper {
mojom::ServiceWorker::DispatchInstallEventCallback callback) override {
dispatched_events()->push_back(Event::Install);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::REJECTED,
- true /* has_fetch_handler */, base::Time::Now());
+ true /* has_fetch_handler */,
+ base::TimeTicks::Now());
}
};
@@ -105,7 +106,7 @@ class RejectActivateTestHelper : public EmbeddedWorkerTestHelper {
mojom::ServiceWorker::DispatchActivateEventCallback callback) override {
dispatched_events()->push_back(Event::Activate);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::REJECTED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
};
@@ -307,8 +308,8 @@ TEST_F(ServiceWorkerContextTest, NoControlleesObserver) {
options, 1l /* dummy registration id */, context()->AsWeakPtr());
auto version = base::MakeRefCounted<ServiceWorkerVersion>(
- registration.get(), script_url, 2l /* dummy version id */,
- context()->AsWeakPtr());
+ registration.get(), script_url, blink::mojom::ScriptType::kClassic,
+ 2l /* dummy version id */, context()->AsWeakPtr());
ServiceWorkerRemoteProviderEndpoint endpoint;
std::unique_ptr<ServiceWorkerProviderHost> host =
@@ -341,8 +342,8 @@ TEST_F(ServiceWorkerContextTest, VersionActivatedObserver) {
options, 1l /* dummy registration id */, context()->AsWeakPtr());
auto version = base::MakeRefCounted<ServiceWorkerVersion>(
- registration.get(), script_url, 2l /* dummy version id */,
- context()->AsWeakPtr());
+ registration.get(), script_url, blink::mojom::ScriptType::kClassic,
+ 2l /* dummy version id */, context()->AsWeakPtr());
TestServiceWorkerContextObserver observer(context_wrapper());
@@ -368,8 +369,8 @@ TEST_F(ServiceWorkerContextTest, VersionRedundantObserver) {
options, 1l /* dummy registration id */, context()->AsWeakPtr());
auto version = base::MakeRefCounted<ServiceWorkerVersion>(
- registration.get(), script_url, 2l /* dummy version id */,
- context()->AsWeakPtr());
+ registration.get(), script_url, blink::mojom::ScriptType::kClassic,
+ 2l /* dummy version id */, context()->AsWeakPtr());
TestServiceWorkerContextObserver observer(context_wrapper());
@@ -850,7 +851,8 @@ TEST_F(ServiceWorkerContextTest, ProviderHostIterator) {
base::MakeRefCounted<ServiceWorkerVersion>(
registration.get(),
GURL("https://another-origin.example.net/test/script_url"),
- 1L /* version_id */, helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, 1L /* version_id */,
+ helper_->context()->AsWeakPtr());
remote_endpoints.emplace_back();
base::WeakPtr<ServiceWorkerProviderHost> host4 =
CreateProviderHostForServiceWorkerContext(
diff --git a/chromium/content/browser/service_worker/service_worker_context_watcher.cc b/chromium/content/browser/service_worker/service_worker_context_watcher.cc
index 93255031e6d..594ed900fba 100644
--- a/chromium/content/browser/service_worker/service_worker_context_watcher.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_watcher.cc
@@ -7,9 +7,11 @@
#include <utility>
#include "base/bind.h"
+#include "base/task/post_task.h"
#include "content/browser/service_worker/embedded_worker_status.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_version.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/console_message_level.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
@@ -40,8 +42,8 @@ ServiceWorkerContextWatcher::ServiceWorkerContextWatcher(
void ServiceWorkerContextWatcher::Start() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ServiceWorkerContextWatcher::GetStoredRegistrationsOnIOThread,
this));
@@ -50,8 +52,8 @@ void ServiceWorkerContextWatcher::Start() {
void ServiceWorkerContextWatcher::Stop() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
stop_called_ = true;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWatcher::StopOnIOThread, this));
}
@@ -99,13 +101,13 @@ void ServiceWorkerContextWatcher::OnStoredRegistrationsOnIOThread(
++version_it;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerRegistrationUpdatedCallback,
this, std::move(registrations)));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerVersionUpdatedCallback, this,
std::move(versions)));
@@ -159,8 +161,8 @@ void ServiceWorkerContextWatcher::SendRegistrationInfo(
registrations->push_back(
ServiceWorkerRegistrationInfo(pattern, registration_id, delete_flag));
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerRegistrationUpdatedCallback,
this, std::move(registrations)));
@@ -172,8 +174,8 @@ void ServiceWorkerContextWatcher::SendVersionInfo(
std::unique_ptr<std::vector<ServiceWorkerVersionInfo>> versions =
std::make_unique<std::vector<ServiceWorkerVersionInfo>>();
versions->push_back(version_info);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerVersionUpdatedCallback, this,
std::move(versions)));
@@ -304,8 +306,8 @@ void ServiceWorkerContextWatcher::OnErrorReported(int64_t version_id,
auto it = version_info_map_.find(version_id);
if (it != version_info_map_.end())
registration_id = it->second->registration_id;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerErrorReportedCallback, this,
registration_id, version_id, std::make_unique<ErrorInfo>(info)));
@@ -322,8 +324,8 @@ void ServiceWorkerContextWatcher::OnReportConsoleMessage(
if (it != version_info_map_.end())
registration_id = it->second->registration_id;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerErrorReportedCallback, this,
registration_id, version_id,
diff --git a/chromium/content/browser/service_worker/service_worker_context_wrapper.cc b/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
index 4203d20bd22..c0b46e12826 100644
--- a/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -28,6 +28,7 @@
#include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/service_worker_context_observer.h"
#include "content/public/common/content_features.h"
@@ -49,8 +50,8 @@ const int kActiveWorkerTimeoutDays = 999;
void WorkerStarted(ServiceWorkerContextWrapper::StatusCallback callback,
blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), status));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), status));
}
void StartActiveWorkerOnIO(
@@ -67,8 +68,8 @@ void StartActiveWorkerOnIO(
base::BindOnce(WorkerStarted, std::move(callback)));
return;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback),
blink::ServiceWorkerStatusCode::kErrorNotFound));
}
@@ -143,8 +144,8 @@ void FinishRegistrationOnIO(ServiceWorkerContext::ResultCallback callback,
const std::string& status_message,
int64_t registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback),
status == blink::ServiceWorkerStatusCode::kOk));
}
@@ -152,8 +153,8 @@ void FinishRegistrationOnIO(ServiceWorkerContext::ResultCallback callback,
void FinishUnregistrationOnIO(ServiceWorkerContext::ResultCallback callback,
blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback),
status == blink::ServiceWorkerStatusCode::kOk));
}
@@ -229,8 +230,8 @@ void ServiceWorkerContextWrapper::Shutdown() {
storage_partition_ = nullptr;
process_manager_->Shutdown();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::ShutdownOnIO, this));
}
@@ -310,19 +311,20 @@ void ServiceWorkerContextWrapper::RegisterServiceWorker(
const blink::mojom::ServiceWorkerRegistrationOptions& options,
ResultCallback callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::RegisterServiceWorker,
this, script_url, options, std::move(callback)));
return;
}
if (!context_core_) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), false));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), false));
return;
}
blink::mojom::ServiceWorkerRegistrationOptions options_to_pass(
- net::SimplifyUrlForRequest(options.scope), options.update_via_cache);
+ net::SimplifyUrlForRequest(options.scope), options.type,
+ options.update_via_cache);
context()->RegisterServiceWorker(
net::SimplifyUrlForRequest(script_url), options_to_pass,
base::BindOnce(&FinishRegistrationOnIO, std::move(callback)));
@@ -332,15 +334,15 @@ void ServiceWorkerContextWrapper::UnregisterServiceWorker(
const GURL& pattern,
ResultCallback callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::UnregisterServiceWorker,
this, pattern, std::move(callback)));
return;
}
if (!context_core_) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), false));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), false));
return;
}
@@ -375,8 +377,8 @@ void ServiceWorkerContextWrapper::CountExternalRequestsForTest(
const GURL& origin,
CountExternalRequestsCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::CountExternalRequests, this,
origin, std::move(callback)));
}
@@ -385,8 +387,8 @@ void ServiceWorkerContextWrapper::GetAllOriginsInfo(
GetUsageInfoCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback),
std::vector<ServiceWorkerUsageInfo>()));
return;
@@ -399,15 +401,15 @@ void ServiceWorkerContextWrapper::GetAllOriginsInfo(
void ServiceWorkerContextWrapper::DeleteForOrigin(const GURL& origin,
ResultCallback callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::DeleteForOrigin, this,
origin, std::move(callback)));
return;
}
if (!context_core_) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(std::move(callback), false));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(std::move(callback), false));
return;
}
context()->DeleteForOrigin(
@@ -420,15 +422,15 @@ void ServiceWorkerContextWrapper::CheckHasServiceWorker(
const GURL& other_url,
CheckHasServiceWorkerCallback callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::CheckHasServiceWorker,
this, url, other_url, std::move(callback)));
return;
}
if (!context_core_) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback),
ServiceWorkerCapability::NO_SERVICE_WORKER));
return;
@@ -442,15 +444,16 @@ void ServiceWorkerContextWrapper::CheckHasServiceWorker(
void ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest(
base::OnceClosure callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest, this,
std::move(callback)));
return;
}
if (!context_core_) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(callback));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ std::move(callback));
return;
}
context_core_->ClearAllServiceWorkersForTest(std::move(callback));
@@ -485,7 +488,7 @@ void ServiceWorkerContextWrapper::
return;
}
- context_core_->storage()->FindRegistrationForPattern(
+ FindReadyRegistrationForPattern(
net::SimplifyUrlForRequest(pattern),
base::BindOnce(&ServiceWorkerContextWrapper::
DidFindRegistrationForLongRunningMessage,
@@ -552,8 +555,8 @@ void ServiceWorkerContextWrapper::StartServiceWorkerForNavigationHint(
"document_url", document_url.spec());
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ServiceWorkerContextWrapper::StartServiceWorkerForNavigationHintOnIO,
this, document_url,
@@ -565,8 +568,8 @@ void ServiceWorkerContextWrapper::StartServiceWorkerForNavigationHint(
void ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin(
const GURL& origin) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin, this,
origin));
@@ -586,8 +589,8 @@ void ServiceWorkerContextWrapper::StopAllServiceWorkersForOrigin(
void ServiceWorkerContextWrapper::StopAllServiceWorkers(
base::OnceClosure callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::StopAllServiceWorkersOnIO,
this, std::move(callback),
base::ThreadTaskRunnerHandle::Get()));
@@ -742,6 +745,22 @@ void ServiceWorkerContextWrapper::GetAllRegistrations(
context_core_->storage()->GetAllRegistrationsInfos(std::move(callback));
}
+void ServiceWorkerContextWrapper::GetRegistrationsForOrigin(
+ const url::Origin& origin,
+ GetRegistrationsCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (!context_core_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ std::move(callback), blink::ServiceWorkerStatusCode::kErrorAbort,
+ std::vector<scoped_refptr<ServiceWorkerRegistration>>()));
+ return;
+ }
+ context_core_->storage()->GetRegistrationsForOrigin(origin.GetURL(),
+ std::move(callback));
+}
+
void ServiceWorkerContextWrapper::GetRegistrationUserData(
int64_t registration_id,
const std::vector<std::string>& keys,
@@ -871,15 +890,15 @@ void ServiceWorkerContextWrapper::GetUserDataForAllRegistrationsByKeyPrefix(
void ServiceWorkerContextWrapper::StartServiceWorker(const GURL& pattern,
StatusCallback callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::StartServiceWorker, this,
pattern, std::move(callback)));
return;
}
if (!context_core_) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback),
blink::ServiceWorkerStatusCode::kErrorAbort));
return;
@@ -891,8 +910,8 @@ void ServiceWorkerContextWrapper::StartServiceWorker(const GURL& pattern,
void ServiceWorkerContextWrapper::SkipWaitingWorker(const GURL& pattern) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::SkipWaitingWorker, this,
pattern));
return;
@@ -906,8 +925,8 @@ void ServiceWorkerContextWrapper::SkipWaitingWorker(const GURL& pattern) {
void ServiceWorkerContextWrapper::UpdateRegistration(const GURL& pattern) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::UpdateRegistration, this,
pattern));
return;
@@ -923,8 +942,8 @@ void ServiceWorkerContextWrapper::UpdateRegistration(const GURL& pattern) {
void ServiceWorkerContextWrapper::SetForceUpdateOnPageLoad(
bool force_update_on_page_load) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::SetForceUpdateOnPageLoad,
this, force_update_on_page_load));
return;
@@ -970,8 +989,8 @@ void ServiceWorkerContextWrapper::InitInternal(
ChromeBlobStorageContext* blob_context,
URLLoaderFactoryGetter* loader_factory_getter) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::InitInternal, this,
user_data_directory, std::move(database_task_runner),
base::RetainedRef(quota_manager_proxy),
@@ -1124,8 +1143,8 @@ void ServiceWorkerContextWrapper::DidCheckHasServiceWorker(
ServiceWorkerCapability capability) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), capability));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), capability));
}
void ServiceWorkerContextWrapper::DidFindRegistrationForUpdate(
@@ -1164,8 +1183,8 @@ void ServiceWorkerContextWrapper::CountExternalRequests(
}
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(callback), pending_external_request_count));
}
@@ -1244,8 +1263,8 @@ void ServiceWorkerContextWrapper::
StartServiceWorkerForNavigationHintResult result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
ServiceWorkerMetrics::RecordStartServiceWorkerForNavigationHintResult(result);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), result));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), result));
}
void ServiceWorkerContextWrapper::StopAllServiceWorkersOnIO(
diff --git a/chromium/content/browser/service_worker/service_worker_context_wrapper.h b/chromium/content/browser/service_worker/service_worker_context_wrapper.h
index 7766bd2311a..a137985a0f1 100644
--- a/chromium/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/chromium/content/browser/service_worker/service_worker_context_wrapper.h
@@ -31,6 +31,10 @@ class QuotaManagerProxy;
class SpecialStoragePolicy;
}
+namespace url {
+class Origin;
+} // namespace url
+
namespace content {
class BrowserContext;
@@ -54,6 +58,8 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
using BoolCallback = base::OnceCallback<void(bool)>;
using FindRegistrationCallback =
ServiceWorkerStorage::FindRegistrationCallback;
+ using GetRegistrationsCallback =
+ ServiceWorkerStorage::GetRegistrationsCallback;
using GetRegistrationsInfosCallback =
ServiceWorkerStorage::GetRegistrationsInfosCallback;
using GetUserDataCallback = ServiceWorkerStorage::GetUserDataCallback;
@@ -225,6 +231,8 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
// All these methods must be called from the IO thread.
void GetAllRegistrations(GetRegistrationsInfosCallback callback);
+ void GetRegistrationsForOrigin(const url::Origin& origin,
+ GetRegistrationsCallback callback);
void GetRegistrationUserData(int64_t registration_id,
const std::vector<std::string>& keys,
GetUserDataCallback callback);
diff --git a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc
index 8c7859bfbe6..f777411dc46 100644
--- a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc
+++ b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -148,7 +148,7 @@ ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler(
const std::string& integrity,
bool keepalive,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
scoped_refptr<network::ResourceRequestBody> body)
: ServiceWorkerRequestHandler(std::move(context),
@@ -243,10 +243,10 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
// It's for original request (A) or redirect case (B-a or B-b).
auto job = std::make_unique<ServiceWorkerURLRequestJob>(
- request, network_delegate, provider_host_->client_uuid(),
- blob_storage_context_, resource_context, request_mode_, credentials_mode_,
- redirect_mode_, integrity_, keepalive_, resource_type_,
- request_context_type_, frame_type_, body_, this);
+ request, network_delegate, provider_host_, blob_storage_context_,
+ resource_context, request_mode_, credentials_mode_, redirect_mode_,
+ integrity_, keepalive_, resource_type_, request_context_type_,
+ frame_type_, body_, this);
url_job_ = std::make_unique<ServiceWorkerURLJobWrapper>(job->GetWeakPtr());
resource_context_ = resource_context;
@@ -310,7 +310,7 @@ void ServiceWorkerControlleeRequestHandler::MaybeCreateLoader(
url_job_ = std::make_unique<ServiceWorkerURLJobWrapper>(
std::make_unique<ServiceWorkerNavigationLoader>(
std::move(callback), std::move(fallback_callback), this,
- tentative_resource_request,
+ tentative_resource_request, provider_host_,
base::WrapRefCounted(context_->loader_factory_getter())));
resource_context_ = resource_context;
@@ -319,9 +319,7 @@ void ServiceWorkerControlleeRequestHandler::MaybeCreateLoader(
tentative_resource_request.site_for_cookies);
if (url_job_->ShouldFallbackToNetwork()) {
- // We're falling back to the next NavigationLoaderInterceptor, forward
- // the request and clear job now.
- url_job_->FallbackToNetwork();
+ // The job already fell back to network. Clear the job now.
ClearJob();
return;
}
@@ -356,6 +354,10 @@ ServiceWorkerControlleeRequestHandler::MaybeCreateSubresourceLoaderParams() {
controller_info->endpoint =
provider_host_->GetControllerServiceWorkerPtr().PassInterface();
controller_info->client_id = provider_host_->client_uuid();
+ if (provider_host_->fetch_request_window_id()) {
+ controller_info->fetch_request_window_id =
+ base::make_optional(provider_host_->fetch_request_window_id());
+ }
base::WeakPtr<ServiceWorkerObjectHost> object_host =
provider_host_->GetOrCreateServiceWorkerObjectHost(
provider_host_->controller());
@@ -370,15 +372,15 @@ ServiceWorkerControlleeRequestHandler::MaybeCreateSubresourceLoaderParams() {
void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
const GURL& url,
const GURL& site_for_cookies) {
- DCHECK(!JobWasCanceled());
+ DCHECK(IsJobAlive());
DCHECK(context_);
DCHECK(provider_host_);
tracker_ = std::make_unique<MainResourceRequestTracker>();
TRACE_EVENT_ASYNC_BEGIN1(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "URL", url.spec());
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "URL", url.spec());
// The provider host may already have set a controller in redirect case,
// unset it now.
provider_host_->SetControllerRegistration(
@@ -405,8 +407,8 @@ void ServiceWorkerControlleeRequestHandler::
disallow_controller,
blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
- // The job may have been canceled before this was invoked.
- if (JobWasCanceled())
+ // The job may have been destroyed before this was invoked.
+ if (!IsJobAlive())
return;
if (status != blink::ServiceWorkerStatusCode::kOk) {
@@ -416,8 +418,8 @@ void ServiceWorkerControlleeRequestHandler::
url_job_->FallbackToNetwork();
TRACE_EVENT_ASYNC_END1(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Status", blink::ServiceWorkerStatusToString(status));
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "Status", blink::ServiceWorkerStatusToString(status));
return;
}
DCHECK(registration);
@@ -429,8 +431,8 @@ void ServiceWorkerControlleeRequestHandler::
url_job_->FallbackToNetwork();
TRACE_EVENT_ASYNC_END1(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Info", "No Provider");
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "Info", "No Provider");
return;
}
provider_host_->AddMatchingRegistration(registration.get());
@@ -442,8 +444,8 @@ void ServiceWorkerControlleeRequestHandler::
url_job_->FallbackToNetwork();
TRACE_EVENT_ASYNC_END1(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Info", "No Context");
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "Info", "No Context");
return;
}
@@ -456,8 +458,8 @@ void ServiceWorkerControlleeRequestHandler::
url_job_->FallbackToNetwork();
TRACE_EVENT_ASYNC_END1(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Info", "ServiceWorker is blocked");
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "Info", "ServiceWorker is blocked");
return;
}
@@ -470,8 +472,8 @@ void ServiceWorkerControlleeRequestHandler::
url_job_->FallbackToNetwork();
TRACE_EVENT_ASYNC_END1(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Info", "Insecure context");
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "Info", "Insecure context");
return;
}
@@ -504,9 +506,8 @@ void ServiceWorkerControlleeRequestHandler::
url_job_->FallbackToNetwork();
TRACE_EVENT_ASYNC_END1(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Info",
- "No active version, so falling back to network");
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "Info", "No active version, so falling back to network");
return;
}
@@ -522,8 +523,8 @@ void ServiceWorkerControlleeRequestHandler::
std::move(disallow_controller)));
TRACE_EVENT_ASYNC_END1(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Info", "Wait until finished SW activation");
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "Info", "Wait until finished SW activation");
return;
}
@@ -538,15 +539,15 @@ void ServiceWorkerControlleeRequestHandler::
scoped_refptr<ServiceWorkerVersion> active_version,
std::unique_ptr<ScopedDisallowSetControllerRegistration>
disallow_controller) {
- // The job may have been canceled before this was invoked. In that
+ // The job may have been destroyed before this was invoked. In that
// case, |url_job_| can't be used, so return.
- if (JobWasCanceled()) {
+ if (!IsJobAlive()) {
tracker_->RecordDestination(
- ServiceWorkerMetrics::MainResourceRequestDestination::kJobWasCancelled);
+ ServiceWorkerMetrics::MainResourceRequestDestination::kJobWasDestroyed);
TRACE_EVENT_ASYNC_END1(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Info", "The job was canceled");
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "Info", "The job was destroyed");
return;
}
@@ -557,9 +558,8 @@ void ServiceWorkerControlleeRequestHandler::
url_job_->FallbackToNetwork();
TRACE_EVENT_ASYNC_END1(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Info",
- "The provider host is gone, so falling back to network");
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "Info", "The provider host is gone, so falling back to network");
return;
}
@@ -588,8 +588,8 @@ void ServiceWorkerControlleeRequestHandler::
url_job_->FallbackToNetwork();
TRACE_EVENT_ASYNC_END2(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Info",
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "Info",
"The expected active version is not ACTIVATED, so falling back to "
"network",
"Status",
@@ -622,8 +622,8 @@ void ServiceWorkerControlleeRequestHandler::
}
TRACE_EVENT_ASYNC_END1(
"ServiceWorker",
- "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Info",
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource", this,
+ "Info",
(is_forwarded) ? "Forwarded to the ServiceWorker"
: "Skipped the ServiceWorker which has no fetch handler");
}
@@ -637,8 +637,8 @@ void ServiceWorkerControlleeRequestHandler::DidUpdateRegistration(
int64_t registration_id) {
DCHECK(force_update_started_);
- // The job may have been canceled before this was invoked.
- if (JobWasCanceled())
+ // The job may have been destroyed before this was invoked.
+ if (!IsJobAlive())
return;
if (!context_) {
@@ -672,8 +672,8 @@ void ServiceWorkerControlleeRequestHandler::OnUpdatedVersionStatusChanged(
scoped_refptr<ServiceWorkerVersion> version,
std::unique_ptr<ScopedDisallowSetControllerRegistration>
disallow_controller) {
- // The job may have been canceled before this was invoked.
- if (JobWasCanceled())
+ // The job may have been destroyed before this was invoked.
+ if (!IsJobAlive())
return;
if (!context_) {
@@ -699,7 +699,7 @@ void ServiceWorkerControlleeRequestHandler::OnUpdatedVersionStatusChanged(
}
void ServiceWorkerControlleeRequestHandler::PrepareForSubResource() {
- DCHECK(!JobWasCanceled());
+ DCHECK(IsJobAlive());
DCHECK(context_);
// When this request handler was created, the provider host had a controller
@@ -776,8 +776,8 @@ void ServiceWorkerControlleeRequestHandler::ClearJob() {
url_job_.reset();
}
-bool ServiceWorkerControlleeRequestHandler::JobWasCanceled() const {
- return !url_job_ || url_job_->WasCanceled();
+bool ServiceWorkerControlleeRequestHandler::IsJobAlive() const {
+ return url_job_ && url_job_->IsAlive();
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h
index 0ad6eed9b4b..d8ed84cd241 100644
--- a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h
+++ b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h
@@ -19,10 +19,10 @@
#include "content/browser/service_worker/service_worker_url_job_wrapper.h"
#include "content/browser/service_worker/service_worker_url_request_job.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "url/gurl.h"
namespace net {
@@ -58,7 +58,7 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
const std::string& integrity,
bool keepalive,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
scoped_refptr<network::ResourceRequestBody> body);
~ServiceWorkerControlleeRequestHandler() override;
@@ -144,7 +144,7 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
// that job, except for timing information.
void ClearJob();
- bool JobWasCanceled() const;
+ bool IsJobAlive() const;
// Schedules a service worker update to occur shortly after the page and its
// initial subresources load, if this handler was for a navigation.
@@ -158,7 +158,7 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
network::mojom::FetchRedirectMode redirect_mode_;
std::string integrity_;
const bool keepalive_;
- RequestContextType request_context_type_;
+ blink::mojom::RequestContextType request_context_type_;
network::mojom::RequestContextFrameType frame_type_;
scoped_refptr<network::ResourceRequestBody> body_;
ResourceContext* resource_context_;
diff --git a/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc b/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
index 930165c99aa..e929e0d6884 100644
--- a/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
@@ -23,7 +23,6 @@
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/resource_context.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "content/public/test/mock_resource_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -36,6 +35,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
namespace content {
namespace service_worker_controllee_request_handler_unittest {
@@ -70,7 +70,7 @@ class ServiceWorkerControlleeRequestHandlerTest
std::string() /* integrity */,
false /* keepalive */,
type,
- REQUEST_CONTEXT_TYPE_HYPERLINK,
+ blink::mojom::RequestContextType::HYPERLINK,
network::mojom::RequestContextFrameType::kTopLevel,
scoped_refptr<network::ResourceRequestBody>())),
job_(nullptr) {}
@@ -145,8 +145,9 @@ class ServiceWorkerControlleeRequestHandlerTest
options.scope = scope_;
registration_ =
new ServiceWorkerRegistration(options, 1L, context()->AsWeakPtr());
- version_ = new ServiceWorkerVersion(
- registration_.get(), script_url_, 1L, context()->AsWeakPtr());
+ version_ = new ServiceWorkerVersion(registration_.get(), script_url_,
+ blink::mojom::ScriptType::kClassic, 1L,
+ context()->AsWeakPtr());
context()->storage()->LazyInitializeForTest(base::DoNothing());
base::RunLoop().RunUntilIdle();
diff --git a/chromium/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc b/chromium/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc
index 4b9a1d71457..33490cb1dc8 100644
--- a/chromium/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc
@@ -33,7 +33,7 @@ class MockServiceWorkerURLRequestJob : public ServiceWorkerURLRequestJob {
: ServiceWorkerURLRequestJob(
nullptr,
nullptr,
- "",
+ nullptr,
nullptr,
nullptr,
network::mojom::FetchRequestMode::kNoCORS,
@@ -42,7 +42,7 @@ class MockServiceWorkerURLRequestJob : public ServiceWorkerURLRequestJob {
std::string() /* integrity */,
false /* keepalive */,
RESOURCE_TYPE_MAIN_FRAME,
- REQUEST_CONTEXT_TYPE_HYPERLINK,
+ blink::mojom::RequestContextType::HYPERLINK,
network::mojom::RequestContextFrameType::kTopLevel,
scoped_refptr<network::ResourceRequestBody>(),
delegate),
@@ -86,7 +86,8 @@ class ServiceWorkerDataPipeReaderTest
registration_ = new ServiceWorkerRegistration(
options, 1L, helper_->context()->AsWeakPtr());
version_ = new ServiceWorkerVersion(
- registration_.get(), GURL("https://example.com/service_worker.js"), 1L,
+ registration_.get(), GURL("https://example.com/service_worker.js"),
+ blink::mojom::ScriptType::kClassic, 1L,
helper_->context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
records.push_back(
@@ -182,7 +183,8 @@ TEST_P(ServiceWorkerDataPipeReaderTestP, SyncRead) {
data_pipe_reader->Start();
EXPECT_TRUE(mock_url_request_job()->is_response_started());
const int buffer_size = sizeof(kTestData);
- scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(buffer_size);
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(buffer_size);
buffer->data()[buffer_size - 1] = '\0';
// Read successfully.
@@ -238,7 +240,8 @@ TEST_P(ServiceWorkerDataPipeReaderTestP, SyncAbort) {
data_pipe_reader->Start();
EXPECT_TRUE(mock_url_request_job()->is_response_started());
const int buffer_size = sizeof(kTestData);
- scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(buffer_size);
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(buffer_size);
buffer->data()[buffer_size - 1] = '\0';
// Read successfully.
@@ -276,7 +279,8 @@ TEST_P(ServiceWorkerDataPipeReaderTestP, AsyncRead) {
// Start to read.
data_pipe_reader->Start();
EXPECT_TRUE(mock_url_request_job()->is_response_started());
- scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(sizeof(kTestData));
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(sizeof(kTestData));
buffer->data()[sizeof(kTestData) - 1] = '\0';
std::string expected_response;
std::string retrieved_response;
@@ -349,7 +353,8 @@ TEST_P(ServiceWorkerDataPipeReaderTestP, AsyncAbort) {
// Start to read.
data_pipe_reader->Start();
EXPECT_TRUE(mock_url_request_job()->is_response_started());
- scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(sizeof(kTestData));
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(sizeof(kTestData));
buffer->data()[sizeof(kTestData) - 1] = '\0';
std::string expected_response;
std::string retrieved_response;
diff --git a/chromium/content/browser/service_worker/service_worker_database.cc b/chromium/content/browser/service_worker/service_worker_database.cc
index c7610f12b60..4f39ee07144 100644
--- a/chromium/content/browser/service_worker/service_worker_database.cc
+++ b/chromium/content/browser/service_worker/service_worker_database.cc
@@ -275,6 +275,7 @@ const char* ServiceWorkerDatabase::StatusToString(
ServiceWorkerDatabase::RegistrationData::RegistrationData()
: registration_id(blink::mojom::kInvalidServiceWorkerRegistrationId),
+ script_type(blink::mojom::ScriptType::kClassic),
update_via_cache(blink::mojom::ServiceWorkerUpdateViaCache::kImports),
version_id(blink::mojom::kInvalidServiceWorkerVersionId),
is_active(false),
@@ -575,8 +576,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration(
// Used for avoiding multiple writes for the same resource id or url.
std::set<int64_t> pushed_resources;
std::set<GURL> pushed_urls;
- for (std::vector<ResourceRecord>::const_iterator itr = resources.begin();
- itr != resources.end(); ++itr) {
+ for (auto itr = resources.begin(); itr != resources.end(); ++itr) {
if (!itr->url.is_valid())
return STATUS_ERROR_FAILED;
@@ -1410,6 +1410,15 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ParseRegistrationData(
for (uint32_t feature : data.used_features())
out->used_features.insert(feature);
+ if (data.has_script_type()) {
+ auto value = data.script_type();
+ if (!ServiceWorkerRegistrationData_ServiceWorkerScriptType_IsValid(value)) {
+ DLOG(ERROR) << "Worker script type '" << value << "' is not valid.";
+ return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
+ }
+ out->script_type = static_cast<blink::mojom::ScriptType>(value);
+ }
+
if (data.has_update_via_cache()) {
auto value = data.update_via_cache();
if (!ServiceWorkerRegistrationData_ServiceWorkerUpdateViaCacheType_IsValid(
@@ -1461,6 +1470,9 @@ void ServiceWorkerDatabase::WriteRegistrationDataInBatch(
for (uint32_t feature : registration.used_features)
data.add_used_features(feature);
+ data.set_script_type(
+ static_cast<ServiceWorkerRegistrationData_ServiceWorkerScriptType>(
+ registration.script_type));
data.set_update_via_cache(
static_cast<
ServiceWorkerRegistrationData_ServiceWorkerUpdateViaCacheType>(
@@ -1669,8 +1681,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteResourceIdsInBatch(
if (ids.empty())
return STATUS_OK;
- for (std::set<int64_t>::const_iterator itr = ids.begin(); itr != ids.end();
- ++itr) {
+ for (auto itr = ids.begin(); itr != ids.end(); ++itr) {
// Value should be empty.
batch->Put(CreateResourceIdKey(id_key_prefix, *itr), "");
}
@@ -1692,8 +1703,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceIdsInBatch(
if (status != STATUS_OK)
return status;
- for (std::set<int64_t>::const_iterator itr = ids.begin(); itr != ids.end();
- ++itr) {
+ for (auto itr = ids.begin(); itr != ids.end(); ++itr) {
batch->Delete(CreateResourceIdKey(id_key_prefix, *itr));
}
return STATUS_OK;
diff --git a/chromium/content/browser/service_worker/service_worker_database.h b/chromium/content/browser/service_worker/service_worker_database.h
index c99a3d88f66..31fee1851b2 100644
--- a/chromium/content/browser/service_worker/service_worker_database.h
+++ b/chromium/content/browser/service_worker/service_worker_database.h
@@ -72,6 +72,7 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
// the waiting version. Then transition to the active version. The stored
// version may be in the ACTIVATED state or in the INSTALLED state.
GURL script;
+ blink::mojom::ScriptType script_type;
blink::mojom::ServiceWorkerUpdateViaCache update_via_cache;
int64_t version_id;
bool is_active;
diff --git a/chromium/content/browser/service_worker/service_worker_database.proto b/chromium/content/browser/service_worker/service_worker_database.proto
index 9502e2aefb3..767477cc8ca 100644
--- a/chromium/content/browser/service_worker/service_worker_database.proto
+++ b/chromium/content/browser/service_worker/service_worker_database.proto
@@ -23,6 +23,10 @@ message ServiceWorkerNavigationPreloadState {
}
message ServiceWorkerRegistrationData {
+ enum ServiceWorkerScriptType {
+ CLASSIC = 0;
+ MODULE = 1;
+ }
enum ServiceWorkerUpdateViaCacheType {
IMPORTS = 0;
ALL = 1;
@@ -63,6 +67,7 @@ message ServiceWorkerRegistrationData {
optional ServiceWorkerUpdateViaCacheType update_via_cache = 14
[default = IMPORTS];
+ optional ServiceWorkerScriptType script_type = 15 [default = CLASSIC];
}
message ServiceWorkerResourceRecord {
diff --git a/chromium/content/browser/service_worker/service_worker_database_unittest.cc b/chromium/content/browser/service_worker/service_worker_database_unittest.cc
index 8b0dca82d17..011e30bfbad 100644
--- a/chromium/content/browser/service_worker/service_worker_database_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_database_unittest.cc
@@ -9,7 +9,6 @@
#include <string>
-#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
@@ -17,7 +16,6 @@
#include "base/strings/string_number_conversions.h"
#include "content/browser/service_worker/service_worker_database.pb.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/common/content_switches.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
@@ -72,14 +70,15 @@ void VerifyRegistrationData(const RegistrationData& expected,
EXPECT_EQ(expected.registration_id, actual.registration_id);
EXPECT_EQ(expected.scope, actual.scope);
EXPECT_EQ(expected.script, actual.script);
+ EXPECT_EQ(expected.script_type, actual.script_type);
+ EXPECT_EQ(expected.update_via_cache, actual.update_via_cache);
EXPECT_EQ(expected.version_id, actual.version_id);
EXPECT_EQ(expected.is_active, actual.is_active);
EXPECT_EQ(expected.has_fetch_handler, actual.has_fetch_handler);
EXPECT_EQ(expected.last_update_check, actual.last_update_check);
+ EXPECT_EQ(expected.used_features, actual.used_features);
EXPECT_EQ(expected.resources_total_size_bytes,
actual.resources_total_size_bytes);
- EXPECT_EQ(expected.used_features, actual.used_features);
- EXPECT_EQ(expected.update_via_cache, actual.update_via_cache);
}
void VerifyResourceRecords(const std::vector<Resource>& expected,
@@ -126,7 +125,7 @@ TEST(ServiceWorkerDatabaseTest, OpenDatabase_InMemory) {
}
TEST(ServiceWorkerDatabaseTest, DatabaseVersion_ValidSchemaVersion) {
- GURL origin("http://example.com");
+ GURL origin("https://example.com");
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
@@ -163,7 +162,7 @@ TEST(ServiceWorkerDatabaseTest, DatabaseVersion_ObsoleteSchemaVersion) {
// First writing triggers database initialization and bumps the schema
// version.
- GURL origin("http://example.com");
+ GURL origin("https://example.com");
std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
resources.push_back(CreateResource(1, URL(origin, "/resource"), 10));
ServiceWorkerDatabase::RegistrationData deleted_version;
@@ -203,7 +202,7 @@ TEST(ServiceWorkerDatabaseTest, DatabaseVersion_CorruptedSchemaVersion) {
// First writing triggers database initialization and bumps the schema
// version.
- GURL origin("http://example.com");
+ GURL origin("https://example.com");
std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
resources.push_back(CreateResource(1, URL(origin, "/resource"), 10));
ServiceWorkerDatabase::RegistrationData deleted_version;
@@ -239,7 +238,7 @@ TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
std::unique_ptr<ServiceWorkerDatabase> database(
CreateDatabase(database_dir.GetPath()));
- GURL origin("http://example.com");
+ GURL origin("https://example.com");
// The database has never been used, so returns initial values.
AvailableIds ids;
@@ -345,7 +344,7 @@ TEST(ServiceWorkerDatabaseTest, GetOriginsWithRegistrations) {
ServiceWorkerDatabase::RegistrationData deleted_version;
std::vector<int64_t> newly_purgeable_resources;
- GURL origin1("http://example.com");
+ GURL origin1("https://example.com");
RegistrationData data1;
data1.registration_id = 123;
data1.scope = URL(origin1, "/foo");
@@ -441,7 +440,7 @@ TEST(ServiceWorkerDatabaseTest, GetOriginsWithRegistrations) {
TEST(ServiceWorkerDatabaseTest, GetRegistrationsForOrigin) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- GURL origin1("http://example.com");
+ GURL origin1("https://example.com");
GURL origin2("https://www.example.com");
GURL origin3("https://example.org");
@@ -548,11 +547,6 @@ TEST(ServiceWorkerDatabaseTest, GetRegistrationsForOrigin) {
}
TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) {
- // TODO(https://crbug.com/618076): Remove the following command line switch
- // when update_via_cache is shipped to stable.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableExperimentalWebPlatformFeatures);
-
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
std::vector<RegistrationData> registrations;
@@ -563,7 +557,7 @@ TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) {
ServiceWorkerDatabase::RegistrationData deleted_version;
std::vector<int64_t> newly_purgeable_resources;
- GURL origin1("http://www1.example.com");
+ GURL origin1("https://www1.example.com");
RegistrationData data1;
data1.registration_id = 100;
data1.scope = URL(origin1, "/foo");
@@ -576,7 +570,7 @@ TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) {
database->WriteRegistration(data1, resources1, &deleted_version,
&newly_purgeable_resources));
- GURL origin2("http://www2.example.com");
+ GURL origin2("https://www2.example.com");
RegistrationData data2;
data2.registration_id = 200;
data2.scope = URL(origin2, "/bar");
@@ -590,7 +584,7 @@ TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) {
database->WriteRegistration(data2, resources2, &deleted_version,
&newly_purgeable_resources));
- GURL origin3("http://www3.example.com");
+ GURL origin3("https://www3.example.com");
RegistrationData data3;
data3.registration_id = 300;
data3.scope = URL(origin3, "/hoge");
@@ -620,6 +614,7 @@ TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) {
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
database->GetAllRegistrations(&registrations));
EXPECT_EQ(4U, registrations.size());
+
VerifyRegistrationData(data1, registrations[0]);
VerifyRegistrationData(data2, registrations[1]);
VerifyRegistrationData(data3, registrations[2]);
@@ -629,7 +624,7 @@ TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) {
TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- GURL origin("http://example.com");
+ GURL origin("https://example.com");
RegistrationData data;
data.registration_id = 100;
data.scope = URL(origin, "/foo");
@@ -717,7 +712,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
TEST(ServiceWorkerDatabaseTest, DeleteNonExistentRegistration) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- GURL origin("http://example.com");
+ GURL origin("https://example.com");
RegistrationData data;
data.registration_id = 100;
data.scope = URL(origin, "/foo");
@@ -758,24 +753,18 @@ TEST(ServiceWorkerDatabaseTest, DeleteNonExistentRegistration) {
deleted_version.version_id = kArbitraryVersionId;
newly_purgeable_resources.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
- database->DeleteRegistration(kNonExistentRegistrationId,
- GURL("http://example.net"),
- &deleted_version,
- &newly_purgeable_resources));
+ database->DeleteRegistration(
+ kNonExistentRegistrationId, GURL("https://example.net"),
+ &deleted_version, &newly_purgeable_resources));
EXPECT_EQ(blink::mojom::kInvalidServiceWorkerVersionId,
deleted_version.version_id);
EXPECT_TRUE(newly_purgeable_resources.empty());
}
TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
- // TODO(https://crbug.com/618076): Remove the following command line switch
- // when update_via_cache is shipped to stable.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableExperimentalWebPlatformFeatures);
-
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- GURL origin("http://example.com");
+ GURL origin("https://example.com");
RegistrationData data;
data.registration_id = 100;
data.scope = URL(origin, "/foo");
@@ -814,6 +803,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
updated_data.version_id = data.version_id + 1;
updated_data.resources_total_size_bytes = 12 + 13;
updated_data.used_features = {109, 421, 9101};
+ updated_data.script_type = blink::mojom::ScriptType::kModule;
updated_data.update_via_cache =
blink::mojom::ServiceWorkerUpdateViaCache::kAll;
std::vector<Resource> resources2;
@@ -848,7 +838,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
TEST(ServiceWorkerDatabaseTest, Registration_Multiple) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- GURL origin("http://example.com");
+ GURL origin("https://example.com");
ServiceWorkerDatabase::RegistrationData deleted_version;
std::vector<int64_t> newly_purgeable_resources;
@@ -953,7 +943,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Multiple) {
TEST(ServiceWorkerDatabaseTest, Registration_UninitializedDatabase) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- const GURL origin("http://example.com");
+ const GURL origin("https://example.com");
// Should be failed because the database does not exist.
RegistrationData data_out;
@@ -1001,9 +991,90 @@ TEST(ServiceWorkerDatabaseTest, Registration_UninitializedDatabase) {
EXPECT_TRUE(newly_purgeable_resources.empty());
}
+TEST(ServiceWorkerDatabaseTest, Registration_ScriptType) {
+ std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
+
+ ServiceWorkerDatabase::RegistrationData deleted_version;
+ std::vector<int64_t> newly_purgeable_resources;
+
+ // Default script type.
+ GURL origin1("https://www1.example.com");
+ RegistrationData data1;
+ data1.registration_id = 100;
+ data1.scope = URL(origin1, "/foo");
+ data1.script = URL(origin1, "/resource1");
+ data1.version_id = 100;
+ data1.resources_total_size_bytes = 10 + 10000;
+ EXPECT_EQ(blink::mojom::ScriptType::kClassic, data1.script_type);
+ std::vector<Resource> resources1;
+ resources1.push_back(CreateResource(1, URL(origin1, "/resource1"), 10));
+ resources1.push_back(CreateResource(2, URL(origin1, "/resource2"), 10000));
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteRegistration(data1, resources1, &deleted_version,
+ &newly_purgeable_resources));
+
+ // Classic script type.
+ GURL origin2("https://www2.example.com");
+ RegistrationData data2;
+ data2.registration_id = 200;
+ data2.scope = URL(origin2, "/bar");
+ data2.script = URL(origin2, "/resource3");
+ data2.version_id = 200;
+ data2.resources_total_size_bytes = 20 + 20000;
+ data2.script_type = blink::mojom::ScriptType::kClassic;
+ std::vector<Resource> resources2;
+ resources2.push_back(CreateResource(3, URL(origin2, "/resource3"), 20));
+ resources2.push_back(CreateResource(4, URL(origin2, "/resource4"), 20000));
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteRegistration(data2, resources2, &deleted_version,
+ &newly_purgeable_resources));
+
+ // Module script type.
+ GURL origin3("https://www3.example.com");
+ RegistrationData data3;
+ data3.registration_id = 300;
+ data3.scope = URL(origin3, "/baz");
+ data3.script = URL(origin3, "/resource5");
+ data3.version_id = 300;
+ data3.resources_total_size_bytes = 30 + 30000;
+ data3.script_type = blink::mojom::ScriptType::kModule;
+ std::vector<Resource> resources3;
+ resources3.push_back(CreateResource(5, URL(origin3, "/resource5"), 30));
+ resources3.push_back(CreateResource(6, URL(origin3, "/resource6"), 30000));
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->WriteRegistration(data3, resources3, &deleted_version,
+ &newly_purgeable_resources));
+
+ RegistrationData data;
+ std::vector<Resource> resources;
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->ReadRegistration(data1.registration_id, origin1, &data,
+ &resources));
+ VerifyRegistrationData(data1, data);
+ VerifyResourceRecords(resources1, resources);
+ EXPECT_EQ(2U, resources.size());
+ resources.clear();
+
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->ReadRegistration(data2.registration_id, origin2, &data,
+ &resources));
+ VerifyRegistrationData(data2, data);
+ VerifyResourceRecords(resources2, resources);
+ EXPECT_EQ(2U, resources.size());
+ resources.clear();
+
+ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
+ database->ReadRegistration(data3.registration_id, origin3, &data,
+ &resources));
+ VerifyRegistrationData(data3, data);
+ VerifyResourceRecords(resources3, resources);
+ EXPECT_EQ(2U, resources.size());
+ resources.clear();
+}
+
TEST(ServiceWorkerDatabaseTest, UserData_Basic) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- const GURL kOrigin("http://example.com");
+ const GURL kOrigin("https://example.com");
// Add a registration.
RegistrationData data;
@@ -1119,7 +1190,7 @@ TEST(ServiceWorkerDatabaseTest, UserData_Basic) {
TEST(ServiceWorkerDatabaseTest,
UserData_ReadUserDataForAllRegistrationsByKeyPrefix) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- const GURL kOrigin("http://example.com");
+ const GURL kOrigin("https://example.com");
// Add registration 1.
RegistrationData data1;
@@ -1196,7 +1267,7 @@ TEST(ServiceWorkerDatabaseTest,
TEST(ServiceWorkerDatabaseTest, ReadUserDataByKeyPrefix) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- const GURL kOrigin("http://example.com");
+ const GURL kOrigin("https://example.com");
// Add a registration.
RegistrationData data;
@@ -1242,7 +1313,7 @@ TEST(ServiceWorkerDatabaseTest, ReadUserDataByKeyPrefix) {
TEST(ServiceWorkerDatabaseTest, ReadUserKeysAndDataByKeyPrefix) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- const GURL kOrigin("http://example.com");
+ const GURL kOrigin("https://example.com");
// Add a registration.
RegistrationData data;
@@ -1292,7 +1363,7 @@ TEST(ServiceWorkerDatabaseTest, ReadUserKeysAndDataByKeyPrefix) {
TEST(ServiceWorkerDatabaseTest, UserData_DeleteUserDataByKeyPrefixes) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- const GURL kOrigin("http://example.com");
+ const GURL kOrigin("https://example.com");
// Add registration 1.
RegistrationData data1;
@@ -1392,7 +1463,7 @@ TEST(ServiceWorkerDatabaseTest, UserData_DeleteUserDataByKeyPrefixes) {
TEST(ServiceWorkerDatabaseTest, UserData_DataIsolation) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- const GURL kOrigin("http://example.com");
+ const GURL kOrigin("https://example.com");
// Add registration 1.
RegistrationData data1;
@@ -1488,7 +1559,7 @@ TEST(ServiceWorkerDatabaseTest, UserData_DataIsolation) {
TEST(ServiceWorkerDatabaseTest, UserData_DeleteRegistration) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- const GURL kOrigin("http://example.com");
+ const GURL kOrigin("https://example.com");
// Add registration 1.
RegistrationData data1;
@@ -1569,7 +1640,7 @@ TEST(ServiceWorkerDatabaseTest, UserData_DeleteRegistration) {
TEST(ServiceWorkerDatabaseTest, UserData_UninitializedDatabase) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- const GURL kOrigin("http://example.com");
+ const GURL kOrigin("https://example.com");
// Should be failed because the database does not exist.
std::vector<std::string> user_data_out;
@@ -1601,7 +1672,7 @@ TEST(ServiceWorkerDatabaseTest, UserData_UninitializedDatabase) {
TEST(ServiceWorkerDatabaseTest, UpdateVersionToActive) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- GURL origin("http://example.com");
+ GURL origin("https://example.com");
ServiceWorkerDatabase::RegistrationData deleted_version;
std::vector<int64_t> newly_purgeable_resources;
@@ -1662,7 +1733,7 @@ TEST(ServiceWorkerDatabaseTest, UpdateVersionToActive) {
TEST(ServiceWorkerDatabaseTest, UpdateLastCheckTime) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
- GURL origin("http://example.com");
+ GURL origin("https://example.com");
ServiceWorkerDatabase::RegistrationData deleted_version;
std::vector<int64_t> newly_purgeable_resources;
@@ -1782,8 +1853,8 @@ TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
std::vector<int64_t> newly_purgeable_resources;
// Data associated with |origin1| will be removed.
- GURL origin1("http://example.com");
- GURL origin2("http://example.org");
+ GURL origin1("https://example.com");
+ GURL origin2("https://example.org");
// |origin1| has two registrations (registration1 and registration2).
RegistrationData data1;
@@ -1942,7 +2013,7 @@ TEST(ServiceWorkerDatabaseTest, Corruption_NoMainResource) {
ServiceWorkerDatabase::RegistrationData deleted_version;
std::vector<int64_t> newly_purgeable_resources;
- GURL origin("http://example.com");
+ GURL origin("https://example.com");
RegistrationData data;
data.registration_id = 10;
diff --git a/chromium/content/browser/service_worker/service_worker_disk_cache.cc b/chromium/content/browser/service_worker/service_worker_disk_cache.cc
index 27989a034f7..4ec1b562ced 100644
--- a/chromium/content/browser/service_worker/service_worker_disk_cache.cc
+++ b/chromium/content/browser/service_worker/service_worker_disk_cache.cc
@@ -9,23 +9,21 @@
namespace content {
ServiceWorkerDiskCache::ServiceWorkerDiskCache()
- : AppCacheDiskCache(true /* use_simple_cache */) {
- uma_name_ = "DiskCache.ServiceWorker";
-}
+ : AppCacheDiskCache("DiskCache.ServiceWorker", /*use_simple_cache=*/true) {}
ServiceWorkerResponseReader::ServiceWorkerResponseReader(
int64_t resource_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache)
+ base::WeakPtr<AppCacheDiskCache> disk_cache)
: AppCacheResponseReader(resource_id, std::move(disk_cache)) {}
ServiceWorkerResponseWriter::ServiceWorkerResponseWriter(
int64_t resource_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache)
+ base::WeakPtr<AppCacheDiskCache> disk_cache)
: AppCacheResponseWriter(resource_id, std::move(disk_cache)) {}
ServiceWorkerResponseMetadataWriter::ServiceWorkerResponseMetadataWriter(
int64_t resource_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache)
+ base::WeakPtr<AppCacheDiskCache> disk_cache)
: AppCacheResponseMetadataWriter(resource_id, std::move(disk_cache)) {}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_disk_cache.h b/chromium/content/browser/service_worker/service_worker_disk_cache.h
index bfadf688bf3..df46478094d 100644
--- a/chromium/content/browser/service_worker/service_worker_disk_cache.h
+++ b/chromium/content/browser/service_worker/service_worker_disk_cache.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include "content/browser/appcache/appcache_disk_cache.h"
+#include "content/browser/appcache/appcache_response.h"
#include "content/common/content_export.h"
namespace content {
@@ -29,9 +30,8 @@ class CONTENT_EXPORT ServiceWorkerResponseReader
// Should only be constructed by the storage class.
friend class ServiceWorkerStorage;
- ServiceWorkerResponseReader(
- int64_t resource_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache);
+ ServiceWorkerResponseReader(int64_t resource_id,
+ base::WeakPtr<AppCacheDiskCache> disk_cache);
};
class CONTENT_EXPORT ServiceWorkerResponseWriter
@@ -40,9 +40,8 @@ class CONTENT_EXPORT ServiceWorkerResponseWriter
// Should only be constructed by the storage class.
friend class ServiceWorkerStorage;
- ServiceWorkerResponseWriter(
- int64_t resource_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache);
+ ServiceWorkerResponseWriter(int64_t resource_id,
+ base::WeakPtr<AppCacheDiskCache> disk_cache);
};
class CONTENT_EXPORT ServiceWorkerResponseMetadataWriter
@@ -53,7 +52,7 @@ class CONTENT_EXPORT ServiceWorkerResponseMetadataWriter
ServiceWorkerResponseMetadataWriter(
int64_t resource_id,
- base::WeakPtr<AppCacheDiskCacheInterface> disk_cache);
+ base::WeakPtr<AppCacheDiskCache> disk_cache);
};
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc b/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc
index 93a89c2faac..a1511aebbb8 100644
--- a/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -6,10 +6,12 @@
#include <utility>
+#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/common/child_process_host.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
@@ -41,8 +43,8 @@ void ServiceWorkerDispatcherHost::RenderProcessExited(
// renderer is destroyed. But if we don't remove the hosts immediately here,
// collisions of <process_id, provider_id> can occur if |this| is reused for
// another new renderer process due to reuse of the RenderProcessHost.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ServiceWorkerDispatcherHost::RemoveAllProviderHostsForProcess,
base::Unretained(this)));
diff --git a/chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc b/chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
index 7bdd0811226..ed9fb83a1d7 100644
--- a/chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
@@ -11,6 +11,7 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "content/browser/service_worker/embedded_worker_instance.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
@@ -22,6 +23,7 @@
#include "content/browser/service_worker/service_worker_object_host.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/child_process_termination_info.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_switches.h"
@@ -50,8 +52,8 @@ struct RemoteProviderInfo {
std::unique_ptr<ServiceWorkerNavigationHandleCore> CreateNavigationHandleCore(
ServiceWorkerContextWrapper* context_wrapper) {
std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core;
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(
[](ServiceWorkerContextWrapper* wrapper) {
return std::make_unique<ServiceWorkerNavigationHandleCore>(nullptr,
@@ -107,7 +109,8 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
options.scope = scope;
registration_ =
new ServiceWorkerRegistration(options, 1L, context()->AsWeakPtr());
- version_ = new ServiceWorkerVersion(registration_.get(), script_url, 1L,
+ version_ = new ServiceWorkerVersion(registration_.get(), script_url,
+ blink::mojom::ScriptType::kClassic, 1L,
context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
records.push_back(
diff --git a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index 21e9f3cb7df..015e215aad1 100644
--- a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -11,6 +11,7 @@
#include "base/bind.h"
#include "base/containers/queue.h"
#include "base/feature_list.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/devtools/service_worker_devtools_agent_host.h"
@@ -26,6 +27,7 @@
#include "content/browser/url_loader_factory_getter.h"
#include "content/common/service_worker/service_worker.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_features.h"
@@ -182,8 +184,8 @@ class DelegatingURLLoaderClient final : public network::mojom::URLLoaderClient {
if (!worker_id_ || !devtools_enabled_)
return;
while (!devtools_callbacks.empty()) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(devtools_callbacks.front()), *worker_id_,
devtools_request_id_));
devtools_callbacks.pop();
@@ -323,25 +325,27 @@ class ServiceWorkerFetchDispatcher::ResponseCallback
}
// Implements blink::mojom::ServiceWorkerFetchResponseCallback.
- void OnResponse(blink::mojom::FetchAPIResponsePtr response,
- base::Time dispatch_event_time) override {
+ void OnResponse(
+ blink::mojom::FetchAPIResponsePtr response,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) override {
HandleResponse(fetch_dispatcher_, version_, fetch_event_id_,
std::move(response), nullptr /* body_as_stream */,
- FetchEventResult::kGotResponse, dispatch_event_time);
+ FetchEventResult::kGotResponse, std::move(timing));
}
void OnResponseStream(
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- base::Time dispatch_event_time) override {
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) override {
HandleResponse(fetch_dispatcher_, version_, fetch_event_id_,
std::move(response), std::move(body_as_stream),
- FetchEventResult::kGotResponse, dispatch_event_time);
+ FetchEventResult::kGotResponse, std::move(timing));
}
- void OnFallback(base::Time dispatch_event_time) override {
+ void OnFallback(
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) override {
HandleResponse(fetch_dispatcher_, version_, fetch_event_id_,
blink::mojom::FetchAPIResponse::New(),
nullptr /* body_as_stream */,
- FetchEventResult::kShouldFallback, dispatch_event_time);
+ FetchEventResult::kShouldFallback, std::move(timing));
}
private:
@@ -354,16 +358,17 @@ class ServiceWorkerFetchDispatcher::ResponseCallback
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
FetchEventResult fetch_result,
- base::Time dispatch_event_time) {
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) {
if (!version->FinishRequest(fetch_event_id.value(),
fetch_result == FetchEventResult::kGotResponse,
- dispatch_event_time))
+ timing->dispatch_event_time))
NOTREACHED() << "Should only receive one reply per event";
// |fetch_dispatcher| is null if the URLRequest was killed.
if (!fetch_dispatcher)
return;
fetch_dispatcher->DidFinish(fetch_event_id.value(), fetch_result,
- std::move(response), std::move(body_as_stream));
+ std::move(response), std::move(body_as_stream),
+ std::move(timing));
}
mojo::Binding<blink::mojom::ServiceWorkerFetchResponseCallback> binding_;
@@ -563,24 +568,27 @@ void ServiceWorkerFetchDispatcher::DidFail(
blink::ServiceWorkerStatusCode status) {
DCHECK_NE(blink::ServiceWorkerStatusCode::kOk, status);
Complete(status, FetchEventResult::kShouldFallback,
- blink::mojom::FetchAPIResponse::New(), nullptr /* body_as_stream */);
+ blink::mojom::FetchAPIResponse::New(), nullptr /* body_as_stream */,
+ nullptr /* timing */);
}
void ServiceWorkerFetchDispatcher::DidFinish(
int request_id,
FetchEventResult fetch_result,
blink::mojom::FetchAPIResponsePtr response,
- blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream) {
+ blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) {
net_log_.EndEvent(net::NetLogEventType::SERVICE_WORKER_FETCH_EVENT);
Complete(blink::ServiceWorkerStatusCode::kOk, fetch_result,
- std::move(response), std::move(body_as_stream));
+ std::move(response), std::move(body_as_stream), std::move(timing));
}
void ServiceWorkerFetchDispatcher::Complete(
blink::ServiceWorkerStatusCode status,
FetchEventResult fetch_result,
blink::mojom::FetchAPIResponsePtr response,
- blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream) {
+ blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) {
DCHECK(fetch_callback_);
did_complete_ = true;
@@ -590,7 +598,7 @@ void ServiceWorkerFetchDispatcher::Complete(
std::move(fetch_callback_)
.Run(status, fetch_result, std::move(response), std::move(body_as_stream),
- version_);
+ std::move(timing), version_);
}
// Non-S13nServiceWorker
@@ -752,7 +760,7 @@ void ServiceWorkerFetchDispatcher::OnFetchEventFinished(
int event_finish_id,
scoped_refptr<URLLoaderAssets> url_loader_assets,
blink::mojom::ServiceWorkerEventStatus status,
- base::Time dispatch_event_time) {
+ base::TimeTicks dispatch_event_time) {
version->FinishRequest(
event_finish_id,
status != blink::mojom::ServiceWorkerEventStatus::ABORTED,
diff --git a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
index c8024ab6147..319cf6e6f70 100644
--- a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
+++ b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -51,6 +51,7 @@ class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
FetchEventResult,
blink::mojom::FetchAPIResponsePtr,
blink::mojom::ServiceWorkerStreamHandlePtr,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr,
scoped_refptr<ServiceWorkerVersion>)>;
// |request_body_*| and |client_id| are used in non-S13nServiceWorker only.
@@ -98,11 +99,13 @@ class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
void DidFinish(int request_id,
FetchEventResult fetch_result,
blink::mojom::FetchAPIResponsePtr response,
- blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream);
+ blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing);
void Complete(blink::ServiceWorkerStatusCode status,
FetchEventResult fetch_result,
blink::mojom::FetchAPIResponsePtr response,
- blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream);
+ blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing);
// The fetch event stays open until all respondWith() and waitUntil() promises
// are settled. This function is called once the renderer signals that
@@ -113,7 +116,7 @@ class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
int event_finish_id,
scoped_refptr<URLLoaderAssets> url_loader_assets,
blink::mojom::ServiceWorkerEventStatus status,
- base::Time dispatch_event_time);
+ base::TimeTicks dispatch_event_time);
ServiceWorkerMetrics::EventType GetEventType() const;
diff --git a/chromium/content/browser/service_worker/service_worker_installed_script_reader.cc b/chromium/content/browser/service_worker/service_worker_installed_script_reader.cc
index 8c42abbd0ae..3b8c5c2cba2 100644
--- a/chromium/content/browser/service_worker/service_worker_installed_script_reader.cc
+++ b/chromium/content/browser/service_worker/service_worker_installed_script_reader.cc
@@ -11,6 +11,7 @@
#include "content/browser/service_worker/service_worker_metrics.h"
#include "net/http/http_response_headers.h"
#include "services/network/public/cpp/net_adapters.h"
+#include "third_party/blink/public/common/blob/blob_utils.h"
namespace content {
@@ -114,29 +115,43 @@ void ServiceWorkerInstalledScriptReader::OnReadInfoComplete(
DCHECK_GE(result, 0);
mojo::ScopedDataPipeConsumerHandle meta_data_consumer;
- mojo::ScopedDataPipeConsumerHandle body_consumer;
DCHECK_GE(http_info->response_data_size, 0);
uint64_t body_size = http_info->response_data_size;
uint64_t meta_data_size = 0;
- if (mojo::CreateDataPipe(nullptr, &body_handle_, &body_consumer) !=
- MOJO_RESULT_OK) {
+
+ MojoCreateDataPipeOptions options;
+ options.struct_size = sizeof(MojoCreateDataPipeOptions);
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
+ options.element_num_bytes = 1;
+ options.capacity_num_bytes = blink::BlobUtils::GetDataPipeCapacity(body_size);
+
+ mojo::ScopedDataPipeConsumerHandle body_consumer_handle;
+ MojoResult rv =
+ mojo::CreateDataPipe(&options, &body_handle_, &body_consumer_handle);
+ if (rv != MOJO_RESULT_OK) {
CompleteSendIfNeeded(FinishedReason::kCreateDataPipeError);
return;
}
+
// Start sending meta data (V8 code cache data).
if (http_info->http_info->metadata) {
- mojo::ScopedDataPipeProducerHandle meta_data_producer;
- if (mojo::CreateDataPipe(nullptr, &meta_data_producer,
- &meta_data_consumer) != MOJO_RESULT_OK) {
+ DCHECK_GE(http_info->http_info->metadata->size(), 0);
+ meta_data_size = http_info->http_info->metadata->size();
+
+ mojo::ScopedDataPipeProducerHandle meta_producer_handle;
+ options.capacity_num_bytes =
+ blink::BlobUtils::GetDataPipeCapacity(meta_data_size);
+ rv = mojo::CreateDataPipe(&options, &meta_producer_handle,
+ &meta_data_consumer);
+ if (rv != MOJO_RESULT_OK) {
CompleteSendIfNeeded(FinishedReason::kCreateDataPipeError);
return;
}
+
meta_data_sender_ = std::make_unique<MetaDataSender>(
- http_info->http_info->metadata, std::move(meta_data_producer));
+ http_info->http_info->metadata, std::move(meta_producer_handle));
meta_data_sender_->Start(base::BindOnce(
&ServiceWorkerInstalledScriptReader::OnMetaDataSent, AsWeakPtr()));
- DCHECK_GE(http_info->http_info->metadata->size(), 0);
- meta_data_size = http_info->http_info->metadata->size();
}
// Start sending body.
@@ -168,7 +183,7 @@ void ServiceWorkerInstalledScriptReader::OnReadInfoComplete(
}
client_->OnStarted(charset, std::move(header_strings),
- std::move(body_consumer), body_size,
+ std::move(body_consumer_handle), body_size,
std::move(meta_data_consumer), meta_data_size);
client_->OnHttpInfoRead(http_info);
}
@@ -181,6 +196,9 @@ void ServiceWorkerInstalledScriptReader::OnWritableBody(MojoResult) {
uint32_t num_bytes = 0;
MojoResult rv = network::NetToMojoPendingBuffer::BeginWrite(
&body_handle_, &body_pending_write_, &num_bytes);
+
+ num_bytes = std::min(num_bytes, blink::BlobUtils::GetDataPipeChunkSize());
+
switch (rv) {
case MOJO_RESULT_INVALID_ARGUMENT:
case MOJO_RESULT_BUSY:
diff --git a/chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc b/chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
index db4c5af12d0..9a11be1b4a5 100644
--- a/chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
@@ -7,11 +7,13 @@
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
+#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/io_buffer.h"
@@ -40,8 +42,8 @@ void ReadDataPipeInternal(mojo::DataPipeConsumerHandle handle,
std::move(quit_closure).Run();
return;
case MOJO_RESULT_SHOULD_WAIT:
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ReadDataPipeInternal, handle, result,
std::move(quit_closure)));
return;
@@ -182,6 +184,7 @@ class ServiceWorkerInstalledScriptsSenderTest : public testing::Test {
version_ = base::MakeRefCounted<ServiceWorkerVersion>(
registration_.get(),
GURL("http://www.example.com/test/service_worker.js"),
+ blink::mojom::ScriptType::kClassic,
context()->storage()->NewVersionId(), context()->AsWeakPtr());
version_->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
diff --git a/chromium/content/browser/service_worker/service_worker_internals_ui.cc b/chromium/content/browser/service_worker/service_worker_internals_ui.cc
index 3af388b83b0..926a0559406 100644
--- a/chromium/content/browser/service_worker/service_worker_internals_ui.cc
+++ b/chromium/content/browser/service_worker/service_worker_internals_ui.cc
@@ -13,6 +13,7 @@
#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
+#include "base/task/post_task.h"
#include "base/values.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/service_worker_devtools_agent_host.h"
@@ -24,6 +25,7 @@
#include "content/browser/service_worker/service_worker_version.h"
#include "content/grit/content_resources.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
@@ -52,9 +54,9 @@ void OperationCompleteCallback(WeakPtr<ServiceWorkerInternalsUI> internals,
int callback_id,
blink::ServiceWorkerStatusCode status) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(OperationCompleteCallback, internals,
- callback_id, status));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(OperationCompleteCallback,
+ internals, callback_id, status));
return;
}
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -155,10 +157,7 @@ void UpdateVersionInfo(const ServiceWorkerVersionInfo& version,
std::unique_ptr<ListValue> GetRegistrationListValue(
const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
auto result = std::make_unique<ListValue>();
- for (std::vector<ServiceWorkerRegistrationInfo>::const_iterator it =
- registrations.begin();
- it != registrations.end();
- ++it) {
+ for (auto it = registrations.begin(); it != registrations.end(); ++it) {
const ServiceWorkerRegistrationInfo& registration = *it;
auto registration_info = std::make_unique<DictionaryValue>();
registration_info->SetString("scope", registration.pattern.spec());
@@ -192,10 +191,7 @@ std::unique_ptr<ListValue> GetRegistrationListValue(
std::unique_ptr<ListValue> GetVersionListValue(
const std::vector<ServiceWorkerVersionInfo>& versions) {
auto result = std::make_unique<ListValue>();
- for (std::vector<ServiceWorkerVersionInfo>::const_iterator it =
- versions.begin();
- it != versions.end();
- ++it) {
+ for (auto it = versions.begin(); it != versions.end(); ++it) {
auto info = std::make_unique<DictionaryValue>();
UpdateVersionInfo(*it, info.get());
result->Append(std::move(info));
@@ -209,8 +205,8 @@ void DidGetStoredRegistrationsOnIOThread(
blink::ServiceWorkerStatusCode status,
const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(callback, context->GetAllLiveRegistrationInfo(),
context->GetAllLiveVersionInfo(), stored_registrations));
}
@@ -422,8 +418,8 @@ void ServiceWorkerInternalsUI::AddContextFromStoragePartition(
std::move(new_observer);
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
GetRegistrationsOnIOThread, context,
base::Bind(DidGetRegistrations, AsWeakPtr(), partition_id,
@@ -567,8 +563,8 @@ void ServiceWorkerInternalsUI::StopWorkerWithId(
int64_t version_id,
StatusCallback callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerInternalsUI::StopWorkerWithId,
base::Unretained(this), context, version_id,
std::move(callback)));
@@ -593,8 +589,8 @@ void ServiceWorkerInternalsUI::UnregisterWithScope(
const GURL& scope,
ServiceWorkerInternalsUI::StatusCallback callback) const {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerInternalsUI::UnregisterWithScope,
base::Unretained(this), context, scope,
std::move(callback)));
diff --git a/chromium/content/browser/service_worker/service_worker_job_unittest.cc b/chromium/content/browser/service_worker/service_worker_job_unittest.cc
index 9de6ec76b1f..5ff941b5a30 100644
--- a/chromium/content/browser/service_worker/service_worker_job_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_job_unittest.cc
@@ -33,6 +33,7 @@
#include "net/base/test_completion_callback.h"
#include "net/http/http_response_headers.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
@@ -550,7 +551,8 @@ TEST_F(ServiceWorkerJobTest, ParallelRegNewScript) {
job_coordinator()->Register(
script_url1,
blink::mojom::ServiceWorkerRegistrationOptions(
- pattern, blink::mojom::ServiceWorkerUpdateViaCache::kNone),
+ pattern, blink::mojom::ScriptType::kClassic,
+ blink::mojom::ServiceWorkerUpdateViaCache::kNone),
SaveRegistration(blink::ServiceWorkerStatusCode::kOk,
&registration1_called, &registration1));
@@ -560,7 +562,8 @@ TEST_F(ServiceWorkerJobTest, ParallelRegNewScript) {
job_coordinator()->Register(
script_url2,
blink::mojom::ServiceWorkerRegistrationOptions(
- pattern, blink::mojom::ServiceWorkerUpdateViaCache::kAll),
+ pattern, blink::mojom::ScriptType::kClassic,
+ blink::mojom::ServiceWorkerUpdateViaCache::kAll),
SaveRegistration(blink::ServiceWorkerStatusCode::kOk,
&registration2_called, &registration2));
@@ -764,7 +767,8 @@ TEST_F(ServiceWorkerJobTest, UnregisterWaitingSetsRedundant) {
// Manually create the waiting worker since there is no way to become a
// waiting worker until Update is implemented.
scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
- registration.get(), script_url, 1L, helper_->context()->AsWeakPtr());
+ registration.get(), script_url, blink::mojom::ScriptType::kClassic, 1L,
+ helper_->context()->AsWeakPtr());
base::Optional<blink::ServiceWorkerStatusCode> status;
version->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status));
@@ -884,7 +888,8 @@ void WriteResponse(ServiceWorkerStorage* storage,
void WriteStringResponse(ServiceWorkerStorage* storage,
int64_t id,
const std::string& body) {
- scoped_refptr<IOBuffer> body_buffer(new WrappedIOBuffer(body.data()));
+ scoped_refptr<IOBuffer> body_buffer =
+ base::MakeRefCounted<WrappedIOBuffer>(body.data());
const char kHttpHeaders[] = "HTTP/1.0 200 HONKYDORY\0\0";
std::string headers(kHttpHeaders, arraysize(kHttpHeaders));
WriteResponse(storage, id, headers, body_buffer.get(), body.length());
@@ -896,7 +901,7 @@ class UpdateJobTestHelper : public EmbeddedWorkerTestHelper,
public:
struct AttributeChangeLogEntry {
int64_t registration_id;
- ChangedVersionAttributesMask mask;
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr mask;
ServiceWorkerRegistrationInfo info;
};
@@ -905,7 +910,8 @@ class UpdateJobTestHelper : public EmbeddedWorkerTestHelper,
ServiceWorkerVersion::Status status;
};
- UpdateJobTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
+ UpdateJobTestHelper()
+ : EmbeddedWorkerTestHelper(base::FilePath()), weak_factory_(this) {}
~UpdateJobTestHelper() override {
if (observed_registration_.get())
observed_registration_->RemoveListener(this);
@@ -922,6 +928,10 @@ class UpdateJobTestHelper : public EmbeddedWorkerTestHelper,
force_start_worker_failure_ = force_start_worker_failure;
}
+ const base::Optional<bool>& will_be_terminated() const {
+ return will_be_terminated_;
+ }
+
scoped_refptr<ServiceWorkerRegistration> SetupInitialRegistration(
const GURL& test_origin) {
blink::mojom::ServiceWorkerRegistrationOptions options;
@@ -942,6 +952,17 @@ class UpdateJobTestHelper : public EmbeddedWorkerTestHelper,
return registration;
}
+ void RequestTermination(int embedded_worker_id) {
+ GetEmbeddedWorkerInstanceHost(embedded_worker_id)
+ ->RequestTermination(
+ base::BindOnce(&UpdateJobTestHelper::OnRequestedTermination,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ void OnRequestedTermination(bool will_be_terminated) {
+ will_be_terminated_ = will_be_terminated;
+ }
+
// EmbeddedWorkerTestHelper overrides
void OnStartWorker(
int embedded_worker_id,
@@ -1041,13 +1062,13 @@ class UpdateJobTestHelper : public EmbeddedWorkerTestHelper,
// ServiceWorkerRegistration::Listener overrides
void OnVersionAttributesChanged(
ServiceWorkerRegistration* registration,
- ChangedVersionAttributesMask changed_mask,
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
const ServiceWorkerRegistrationInfo& info) override {
AttributeChangeLogEntry entry;
entry.registration_id = registration->id();
- entry.mask = changed_mask;
+ entry.mask = std::move(changed_mask);
entry.info = info;
- attribute_change_log_.push_back(entry);
+ attribute_change_log_.push_back(std::move(entry));
}
void OnRegistrationFailed(ServiceWorkerRegistration* registration) override {
@@ -1063,7 +1084,7 @@ class UpdateJobTestHelper : public EmbeddedWorkerTestHelper,
StateChangeLogEntry entry;
entry.version_id = version->version_id();
entry.status = version->status();
- state_change_log_.push_back(entry);
+ state_change_log_.push_back(std::move(entry));
}
scoped_refptr<ServiceWorkerRegistration> observed_registration_;
@@ -1074,6 +1095,9 @@ class UpdateJobTestHelper : public EmbeddedWorkerTestHelper,
std::set<int /* embedded_worker_id */> started_workers_;
bool update_found_ = false;
bool force_start_worker_failure_ = false;
+ base::Optional<bool> will_be_terminated_;
+
+ base::WeakPtrFactory<UpdateJobTestHelper> weak_factory_;
};
// Helper class for update tests that evicts the active version when the update
@@ -1231,39 +1255,47 @@ TEST_F(ServiceWorkerJobTest, Update_NewVersion) {
EXPECT_FALSE(registration->waiting_version());
ASSERT_EQ(3u, update_helper->attribute_change_log_.size());
- UpdateJobTestHelper::AttributeChangeLogEntry entry;
- entry = update_helper->attribute_change_log_[0];
- EXPECT_TRUE(entry.mask.installing_changed());
- EXPECT_FALSE(entry.mask.waiting_changed());
- EXPECT_FALSE(entry.mask.active_changed());
- EXPECT_NE(entry.info.installing_version.version_id,
- blink::mojom::kInvalidServiceWorkerVersionId);
- EXPECT_EQ(entry.info.waiting_version.version_id,
- blink::mojom::kInvalidServiceWorkerVersionId);
- EXPECT_NE(entry.info.active_version.version_id,
- blink::mojom::kInvalidServiceWorkerVersionId);
-
- entry = update_helper->attribute_change_log_[1];
- EXPECT_TRUE(entry.mask.installing_changed());
- EXPECT_TRUE(entry.mask.waiting_changed());
- EXPECT_FALSE(entry.mask.active_changed());
- EXPECT_EQ(entry.info.installing_version.version_id,
- blink::mojom::kInvalidServiceWorkerVersionId);
- EXPECT_NE(entry.info.waiting_version.version_id,
- blink::mojom::kInvalidServiceWorkerVersionId);
- EXPECT_NE(entry.info.active_version.version_id,
- blink::mojom::kInvalidServiceWorkerVersionId);
-
- entry = update_helper->attribute_change_log_[2];
- EXPECT_FALSE(entry.mask.installing_changed());
- EXPECT_TRUE(entry.mask.waiting_changed());
- EXPECT_TRUE(entry.mask.active_changed());
- EXPECT_EQ(entry.info.installing_version.version_id,
- blink::mojom::kInvalidServiceWorkerVersionId);
- EXPECT_EQ(entry.info.waiting_version.version_id,
- blink::mojom::kInvalidServiceWorkerVersionId);
- EXPECT_NE(entry.info.active_version.version_id,
- blink::mojom::kInvalidServiceWorkerVersionId);
+ {
+ const UpdateJobTestHelper::AttributeChangeLogEntry& entry =
+ update_helper->attribute_change_log_[0];
+ EXPECT_TRUE(entry.mask->installing);
+ EXPECT_FALSE(entry.mask->waiting);
+ EXPECT_FALSE(entry.mask->active);
+ EXPECT_NE(entry.info.installing_version.version_id,
+ blink::mojom::kInvalidServiceWorkerVersionId);
+ EXPECT_EQ(entry.info.waiting_version.version_id,
+ blink::mojom::kInvalidServiceWorkerVersionId);
+ EXPECT_NE(entry.info.active_version.version_id,
+ blink::mojom::kInvalidServiceWorkerVersionId);
+ }
+
+ {
+ const UpdateJobTestHelper::AttributeChangeLogEntry& entry =
+ update_helper->attribute_change_log_[1];
+ EXPECT_TRUE(entry.mask->installing);
+ EXPECT_TRUE(entry.mask->waiting);
+ EXPECT_FALSE(entry.mask->active);
+ EXPECT_EQ(entry.info.installing_version.version_id,
+ blink::mojom::kInvalidServiceWorkerVersionId);
+ EXPECT_NE(entry.info.waiting_version.version_id,
+ blink::mojom::kInvalidServiceWorkerVersionId);
+ EXPECT_NE(entry.info.active_version.version_id,
+ blink::mojom::kInvalidServiceWorkerVersionId);
+ }
+
+ {
+ const UpdateJobTestHelper::AttributeChangeLogEntry& entry =
+ update_helper->attribute_change_log_[2];
+ EXPECT_FALSE(entry.mask->installing);
+ EXPECT_TRUE(entry.mask->waiting);
+ EXPECT_TRUE(entry.mask->active);
+ EXPECT_EQ(entry.info.installing_version.version_id,
+ blink::mojom::kInvalidServiceWorkerVersionId);
+ EXPECT_EQ(entry.info.waiting_version.version_id,
+ blink::mojom::kInvalidServiceWorkerVersionId);
+ EXPECT_NE(entry.info.active_version.version_id,
+ blink::mojom::kInvalidServiceWorkerVersionId);
+ }
// expected version state transitions:
// new.installing, new.installed,
@@ -1314,8 +1346,8 @@ TEST_F(ServiceWorkerJobTest, Update_ScriptUrlChanged) {
// Add a waiting version with a new script.
GURL new_script("https://www.example.com/new_worker.js");
scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
- registration.get(), new_script, 2L /* dummy version id */,
- helper_->context()->AsWeakPtr());
+ registration.get(), new_script, blink::mojom::ScriptType::kClassic,
+ 2L /* dummy version id */, helper_->context()->AsWeakPtr());
registration->SetWaitingVersion(version);
// Run the update job.
@@ -1612,18 +1644,18 @@ class EventCallbackHelper : public EmbeddedWorkerTestHelper {
void OnInstallEvent(
mojom::ServiceWorker::DispatchInstallEventCallback callback) override {
if (!install_callback_.is_null())
- install_callback_.Run();
+ std::move(install_callback_).Run();
std::move(callback).Run(install_event_result_, has_fetch_handler_,
- base::Time::Now());
+ base::TimeTicks::Now());
}
void OnActivateEvent(
mojom::ServiceWorker::DispatchActivateEventCallback callback) override {
- std::move(callback).Run(activate_event_result_, base::Time::Now());
+ std::move(callback).Run(activate_event_result_, base::TimeTicks::Now());
}
- void set_install_callback(const base::Closure& callback) {
- install_callback_ = callback;
+ void set_install_callback(base::OnceClosure callback) {
+ install_callback_ = std::move(callback);
}
void set_install_event_result(blink::mojom::ServiceWorkerEventStatus result) {
install_event_result_ = result;
@@ -1637,7 +1669,7 @@ class EventCallbackHelper : public EmbeddedWorkerTestHelper {
}
private:
- base::Closure install_callback_;
+ base::OnceClosure install_callback_;
blink::mojom::ServiceWorkerEventStatus install_event_result_;
blink::mojom::ServiceWorkerEventStatus activate_event_result_;
bool has_fetch_handler_ = true;
@@ -1664,8 +1696,8 @@ TEST_F(ServiceWorkerJobTest, RemoveControlleeDuringInstall) {
// Register another script. While installing, old_version loses controllee.
helper->set_install_callback(
- base::BindRepeating(&ServiceWorkerVersion::RemoveControllee, old_version,
- host->client_uuid()));
+ base::BindOnce(&ServiceWorkerVersion::RemoveControllee, old_version,
+ host->client_uuid()));
EXPECT_EQ(registration, RunRegisterJob(script2, options));
EXPECT_FALSE(registration->is_uninstalling());
@@ -1706,8 +1738,8 @@ TEST_F(ServiceWorkerJobTest, RemoveControlleeDuringRejectedInstall) {
// Register another script that fails to install. While installing,
// old_version loses controllee.
helper->set_install_callback(
- base::BindRepeating(&ServiceWorkerVersion::RemoveControllee, old_version,
- host->client_uuid()));
+ base::BindOnce(&ServiceWorkerVersion::RemoveControllee, old_version,
+ host->client_uuid()));
helper->set_install_event_result(
blink::mojom::ServiceWorkerEventStatus::REJECTED);
EXPECT_EQ(registration, RunRegisterJob(script2, options));
@@ -1745,8 +1777,8 @@ TEST_F(ServiceWorkerJobTest, RemoveControlleeDuringInstall_RejectActivate) {
// Register another script that fails to activate. While installing,
// old_version loses controllee.
helper->set_install_callback(
- base::BindRepeating(&ServiceWorkerVersion::RemoveControllee, old_version,
- host->client_uuid()));
+ base::BindOnce(&ServiceWorkerVersion::RemoveControllee, old_version,
+ host->client_uuid()));
helper->set_activate_event_result(
blink::mojom::ServiceWorkerEventStatus::REJECTED);
EXPECT_EQ(registration, RunRegisterJob(script2, options));
@@ -1879,6 +1911,17 @@ TEST_F(ServiceWorkerJobTest, ActivateCancelsOnShutdown) {
// until the runner runs again.
first_version->RemoveControllee(host->client_uuid());
base::RunLoop().RunUntilIdle();
+
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ // S13nServiceWorker: Activating the new version won't happen until
+ // RequestTermination() is called.
+ EXPECT_EQ(first_version.get(), registration->active_version());
+ update_helper->RequestTermination(
+ first_version->embedded_worker()->embedded_worker_id());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(update_helper->will_be_terminated().value());
+ }
+
EXPECT_EQ(new_version.get(), registration->active_version());
EXPECT_EQ(ServiceWorkerVersion::ACTIVATING, new_version->status());
diff --git a/chromium/content/browser/service_worker/service_worker_metrics.cc b/chromium/content/browser/service_worker/service_worker_metrics.cc
index 19d807e0725..ffa5b01803c 100644
--- a/chromium/content/browser/service_worker/service_worker_metrics.cc
+++ b/chromium/content/browser/service_worker/service_worker_metrics.cc
@@ -11,8 +11,10 @@
#include "base/metrics/histogram_macros.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "content/browser/service_worker/embedded_worker_status.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
@@ -382,8 +384,8 @@ void ServiceWorkerMetrics::CountControlledPageLoad(Site site,
if (ShouldExcludeSiteFromHistogram(site))
return;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&RecordURLMetricOnUI, "ServiceWorker.ControlledPageUrl",
url));
}
@@ -892,15 +894,6 @@ void ServiceWorkerMetrics::RecordRuntime(base::TimeDelta time) {
kBucketCount);
}
-void ServiceWorkerMetrics::RecordUninstalledScriptImport(const GURL& url) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&RecordURLMetricOnUI,
- "ServiceWorker.ContextRequestHandlerStatus."
- "UninstalledScriptImport",
- url));
-}
-
void ServiceWorkerMetrics::RecordStartServiceWorkerForNavigationHintResult(
StartServiceWorkerForNavigationHintResult result) {
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartForNavigationHint.Result",
diff --git a/chromium/content/browser/service_worker/service_worker_metrics.h b/chromium/content/browser/service_worker/service_worker_metrics.h
index a0898955023..4b64c16b04a 100644
--- a/chromium/content/browser/service_worker/service_worker_metrics.h
+++ b/chromium/content/browser/service_worker/service_worker_metrics.h
@@ -62,8 +62,8 @@ class ServiceWorkerMetrics {
// worker.
kAbortedWithoutDispatchingFetchEvent = 13,
- // The request was not routed because it was cancelled.
- kJobWasCancelled = 14,
+ // The request was not routed because the job was destroyed.
+ kJobWasDestroyed = 14,
kMaxValue = 14,
};
@@ -473,11 +473,6 @@ class ServiceWorkerMetrics {
static void RecordRuntime(base::TimeDelta time);
- // Records when an installed service worker imports a script that was not
- // previously installed.
- // TODO(falken): Remove after this is deprecated. https://crbug.com/737044
- static void RecordUninstalledScriptImport(const GURL& url);
-
// Records the result of starting service worker for a navigation hint.
static void RecordStartServiceWorkerForNavigationHintResult(
StartServiceWorkerForNavigationHintResult result);
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc b/chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc
index c27a6b691bd..357d82e02f4 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc
+++ b/chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc
@@ -7,12 +7,14 @@
#include <utility>
#include "base/bind.h"
+#include "base/task/post_task.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_navigation_handle.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/child_process_host.h"
@@ -54,8 +56,8 @@ void ServiceWorkerNavigationHandleCore::DidPreCreateProviderHost(
DCHECK(ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id));
provider_id_ = provider_id;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&ServiceWorkerNavigationHandle::DidCreateServiceWorkerProviderHost,
ui_handle_, provider_id_));
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader.cc b/chromium/content/browser/service_worker/service_worker_navigation_loader.cc
index 79f9270e1c1..4e0a8c2a299 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader.cc
+++ b/chromium/content/browser/service_worker/service_worker_navigation_loader.cc
@@ -7,16 +7,17 @@
#include <sstream>
#include <utility>
+#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "base/trace_event/trace_event.h"
+#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/url_loader_factory_getter.h"
#include "content/common/service_worker/service_worker_loader_helpers.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_request_info.h"
-#include "content/public/common/content_features.h"
-#include "content/public/common/content_switches.h"
+#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
namespace content {
@@ -88,10 +89,12 @@ ServiceWorkerNavigationLoader::ServiceWorkerNavigationLoader(
NavigationLoaderInterceptor::FallbackCallback fallback_callback,
Delegate* delegate,
const network::ResourceRequest& tentative_resource_request,
+ base::WeakPtr<ServiceWorkerProviderHost> provider_host,
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter)
: loader_callback_(std::move(callback)),
fallback_callback_(std::move(fallback_callback)),
delegate_(delegate),
+ provider_host_(std::move(provider_host)),
url_loader_factory_getter_(std::move(url_loader_factory_getter)),
binding_(this),
weak_factory_(this) {
@@ -124,21 +127,24 @@ void ServiceWorkerNavigationLoader::FallbackToNetwork() {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker", "ServiceWorkerNavigationLoader::FallbackToNetwork", this,
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ // The URLJobWrapper only calls this if this loader never intercepted the
+ // request. Fallback to network after interception uses |fallback_callback_|
+ // instead.
+ DCHECK_EQ(status_, Status::kNotStarted);
+ DCHECK_EQ(response_type_, ResponseType::NOT_DETERMINED);
response_type_ = ResponseType::FALLBACK_TO_NETWORK;
- status_ = Status::kCompleted;
- // This could be called multiple times in some cases because we simply
- // call this synchronously here and don't wait for a separate async
- // StartRequest cue like what URLRequestJob case does.
- // TODO(kinuko): Make sure this is ok or we need to make this async.
- if (loader_callback_)
- std::move(loader_callback_).Run({});
+ TransitionToStatus(Status::kCompleted);
+ std::move(loader_callback_).Run({});
}
void ServiceWorkerNavigationLoader::ForwardToServiceWorker() {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker", "ServiceWorkerNavigationLoader::ForwardToServiceWorker",
this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ DCHECK_EQ(status_, Status::kNotStarted);
+ DCHECK_EQ(response_type_, ResponseType::NOT_DETERMINED);
+
response_type_ = ResponseType::FORWARD_TO_SERVICE_WORKER;
std::move(loader_callback_)
@@ -154,10 +160,6 @@ bool ServiceWorkerNavigationLoader::ShouldForwardToServiceWorker() {
return response_type_ == ResponseType::FORWARD_TO_SERVICE_WORKER;
}
-bool ServiceWorkerNavigationLoader::WasCanceled() const {
- return status_ == Status::kCancelled;
-}
-
void ServiceWorkerNavigationLoader::DetachedFromRequest() {
delegate_ = nullptr;
DeleteIfNeeded();
@@ -173,6 +175,10 @@ void ServiceWorkerNavigationLoader::StartRequest(
network::mojom::URLLoaderRequest request,
network::mojom::URLLoaderClientPtr client) {
resource_request_ = resource_request;
+ if (provider_host_ && provider_host_->fetch_request_window_id()) {
+ resource_request_.fetch_window_id =
+ base::make_optional(provider_host_->fetch_request_window_id());
+ }
DCHECK(delegate_);
DCHECK(!binding_.is_bound());
@@ -184,8 +190,7 @@ void ServiceWorkerNavigationLoader::StartRequest(
url_loader_client_ = std::move(client);
DCHECK_EQ(ResponseType::FORWARD_TO_SERVICE_WORKER, response_type_);
- DCHECK_EQ(Status::kNotStarted, status_);
- status_ = Status::kStarted;
+ TransitionToStatus(Status::kStarted);
TRACE_EVENT_WITH_FLOW0("ServiceWorker",
"ServiceWorkerNavigationLoader::StartRequest", this,
@@ -237,21 +242,21 @@ void ServiceWorkerNavigationLoader::StartRequest(
fetch_dispatcher_->MaybeStartNavigationPreloadWithURLLoader(
resource_request_, url_loader_factory_getter_.get(),
base::DoNothing(/* TODO(crbug/762357): metrics? */));
+
+ // Record worker start time here as |fetch_dispatcher_| will start a service
+ // worker if there is no running service worker.
response_head_.service_worker_start_time = base::TimeTicks::Now();
- response_head_.load_timing.send_start = base::TimeTicks::Now();
- response_head_.load_timing.send_end = base::TimeTicks::Now();
fetch_dispatcher_->Run();
}
void ServiceWorkerNavigationLoader::CommitResponseHeaders() {
- DCHECK_EQ(Status::kStarted, status_);
DCHECK(url_loader_client_.is_bound());
TRACE_EVENT_WITH_FLOW2(
"ServiceWorker", "ServiceWorkerNavigationLoader::CommitResponseHeaders",
this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
"response_code", response_head_.headers->response_code(), "status_text",
response_head_.headers->GetStatusText());
- status_ = Status::kSentHeader;
+ TransitionToStatus(Status::kSentHeader);
url_loader_client_->OnReceiveResponse(response_head_);
}
@@ -261,9 +266,10 @@ void ServiceWorkerNavigationLoader::CommitCompleted(int error_code) {
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
"error_code", net::ErrorToString(error_code));
- DCHECK_LT(status_, Status::kCompleted);
DCHECK(url_loader_client_.is_bound());
- status_ = Status::kCompleted;
+ TransitionToStatus(Status::kCompleted);
+ if (error_code == net::OK)
+ RecordTimingMetrics(true);
// |stream_waiter_| calls this when done.
stream_waiter_.reset();
@@ -281,7 +287,14 @@ void ServiceWorkerNavigationLoader::DidPrepareFetchEvent(
"initial_worker_status",
EmbeddedWorkerInstance::StatusToString(initial_worker_status));
- response_head_.service_worker_ready_time = base::TimeTicks::Now();
+ // At this point a service worker is running and the fetch event is about
+ // to dispatch. Record some load timings.
+ base::TimeTicks now = base::TimeTicks::Now();
+ response_head_.service_worker_ready_time = now;
+ response_head_.load_timing.send_start = now;
+ response_head_.load_timing.send_end = now;
+
+ devtools_attached_ = version->embedded_worker()->devtools_attached();
// Note that we don't record worker preparation time in S13nServiceWorker
// path for now. If we want to measure worker preparation time we can
@@ -299,8 +312,10 @@ void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing,
scoped_refptr<ServiceWorkerVersion> version) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_EQ(status_, Status::kStarted);
TRACE_EVENT_WITH_FLOW2(
"ServiceWorker", "ServiceWorkerNavigationLoader::DidDispatchFetchEvent",
@@ -323,6 +338,8 @@ void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
return;
}
+ fetch_event_timing_ = std::move(timing);
+
if (status != blink::ServiceWorkerStatusCode::kOk) {
// Dispatching the event to the service worker failed. Do a last resort
// attempt to load the page via network as if there was no service worker.
@@ -337,6 +354,8 @@ void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
if (fetch_result ==
ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback) {
+ TransitionToStatus(Status::kCompleted);
+ RecordTimingMetrics(false);
// TODO(falken): Propagate the timing info to the renderer somehow, or else
// Navigation Timing etc APIs won't know about service worker.
std::move(fallback_callback_)
@@ -350,6 +369,7 @@ void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
// A response with status code 0 is Blink telling us to respond with
// network error.
if (response->status_code == 0) {
+ // TODO(falken): Use more specific errors. Or just add ERR_SERVICE_WORKER?
CommitCompleted(net::ERR_FAILED);
return;
}
@@ -362,6 +382,9 @@ void ServiceWorkerNavigationLoader::StartResponse(
blink::mojom::FetchAPIResponsePtr response,
scoped_refptr<ServiceWorkerVersion> version,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_EQ(status_, Status::kStarted);
+
ServiceWorkerLoaderHelpers::SaveResponseInfo(*response, &response_head_);
ServiceWorkerLoaderHelpers::SaveResponseHeaders(
response->status_code, response->status_text, response->headers,
@@ -381,9 +404,8 @@ void ServiceWorkerNavigationLoader::StartResponse(
// Handle a redirect response. ComputeRedirectInfo returns non-null redirect
// info if the given response is a redirect.
base::Optional<net::RedirectInfo> redirect_info =
- ServiceWorkerLoaderHelpers::ComputeRedirectInfo(
- resource_request_, response_head_,
- response_head_.ssl_info->token_binding_negotiated);
+ ServiceWorkerLoaderHelpers::ComputeRedirectInfo(resource_request_,
+ response_head_);
if (redirect_info) {
TRACE_EVENT_WITH_FLOW2(
"ServiceWorker", "ServiceWorkerNavigationLoader::StartResponse", this,
@@ -394,7 +416,7 @@ void ServiceWorkerNavigationLoader::StartResponse(
url_loader_client_->OnReceiveRedirect(*redirect_info, response_head_);
// Our client is the navigation loader, which will start a new URLLoader for
// the redirect rather than calling FollowRedirect(), so we're done here.
- status_ = Status::kCompleted;
+ TransitionToStatus(Status::kCompleted);
return;
}
@@ -421,7 +443,7 @@ void ServiceWorkerNavigationLoader::StartResponse(
body_as_blob_.Bind(std::move(response->blob->blob));
mojo::ScopedDataPipeConsumerHandle data_pipe;
int error = ServiceWorkerLoaderHelpers::ReadBlobResponseBody(
- &body_as_blob_, resource_request_.headers,
+ &body_as_blob_, response->blob->size,
base::BindOnce(&ServiceWorkerNavigationLoader::OnBlobReadingComplete,
weak_factory_.GetWeakPtr()),
&data_pipe);
@@ -478,19 +500,24 @@ void ServiceWorkerNavigationLoader::OnBlobReadingComplete(int net_error) {
}
void ServiceWorkerNavigationLoader::OnConnectionClosed() {
+ TRACE_EVENT_WITH_FLOW0(
+ "ServiceWorker", "ServiceWorkerNavigationLoader::OnConnectionClosed",
+ this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
+ // The fetch dispatcher or stream waiter may still be running. Don't let them
+ // do callbacks back to this loader, since it is now done with the request.
+ // TODO(falken): Try to move this to CommitCompleted(), since the same
+ // justification applies there too.
weak_factory_.InvalidateWeakPtrs();
fetch_dispatcher_.reset();
stream_waiter_.reset();
binding_.Close();
- // Cancel the request if this loader hasn't yet responded to it.
- if (status_ != Status::kCompleted && status_ != Status::kCancelled) {
- status_ = Status::kCancelled;
- url_loader_client_->OnComplete(
- network::URLLoaderCompletionStatus(net::ERR_ABORTED));
- }
- url_loader_client_.reset();
+ // Respond to the request if it's not yet responded to.
+ if (status_ != Status::kCompleted)
+ CommitCompleted(net::ERR_ABORTED);
+ url_loader_client_.reset();
DeleteIfNeeded();
}
@@ -499,4 +526,101 @@ void ServiceWorkerNavigationLoader::DeleteIfNeeded() {
delete this;
}
+void ServiceWorkerNavigationLoader::RecordTimingMetrics(bool handled) {
+ DCHECK(fetch_event_timing_);
+ DCHECK(!completion_time_.is_null());
+
+ // We only record these metrics for top-level navigation.
+ if (resource_request_.resource_type != RESOURCE_TYPE_MAIN_FRAME)
+ return;
+
+ // |fetch_event_timing_| is recorded in renderer so we can get reasonable
+ // metrics only when TimeTicks are consistent across processes.
+ if (!base::TimeTicks::IsHighResolution() ||
+ !base::TimeTicks::IsConsistentAcrossProcesses())
+ return;
+
+ // Don't record metrics when DevTools is attached to reduce noise.
+ if (devtools_attached_)
+ return;
+
+ // Time between the request is made and the request is routed to this loader.
+ UMA_HISTOGRAM_TIMES(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "StartToForwardServiceWorker",
+ response_head_.service_worker_start_time -
+ response_head_.load_timing.request_start);
+
+ // Time spent for service worker startup.
+ UMA_HISTOGRAM_TIMES(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "ForwardServiceWorkerToWorkerReady",
+ response_head_.service_worker_ready_time -
+ response_head_.service_worker_start_time);
+
+ // Browser -> Renderer IPC delay.
+ UMA_HISTOGRAM_TIMES(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "WorkerReadyToFetchHandlerStart",
+ fetch_event_timing_->dispatch_event_time -
+ response_head_.service_worker_ready_time);
+
+ // Time spent by fetch handlers.
+ UMA_HISTOGRAM_TIMES(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "FetchHandlerStartToFetchHandlerEnd",
+ fetch_event_timing_->respond_with_settled_time -
+ fetch_event_timing_->dispatch_event_time);
+
+ if (handled) {
+ // Renderer -> Browser IPC delay.
+ UMA_HISTOGRAM_TIMES(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "FetchHandlerEndToResponseReceived",
+ response_head_.load_timing.receive_headers_end -
+ fetch_event_timing_->respond_with_settled_time);
+
+ // Time spent reading response body.
+ UMA_HISTOGRAM_TIMES(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "ResponseReceivedToCompleted",
+ completion_time_ - response_head_.load_timing.receive_headers_end);
+ } else {
+ // Renderer -> Browser IPC delay (network fallback case).
+ UMA_HISTOGRAM_TIMES(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "FetchHandlerEndToFallbackNetwork",
+ completion_time_ - fetch_event_timing_->respond_with_settled_time);
+ }
+}
+
+void ServiceWorkerNavigationLoader::TransitionToStatus(Status new_status) {
+#if DCHECK_IS_ON()
+ switch (new_status) {
+ case Status::kNotStarted:
+ NOTREACHED();
+ break;
+ case Status::kStarted:
+ DCHECK_EQ(status_, Status::kNotStarted);
+ break;
+ case Status::kSentHeader:
+ DCHECK_EQ(status_, Status::kStarted);
+ break;
+ case Status::kCompleted:
+ // kNotStarted -> kCompleted happens on network fallback before
+ // interception.
+ // kStarted -> kCompleted happens on error or network fallback after
+ // interception.
+ // kSentHeader -> kCompleted happens in the success case or error
+ // while sending the body.
+ DCHECK_NE(status_, Status::kCompleted);
+ break;
+ }
+#endif // DCHECK_IS_ON()
+
+ status_ = new_status;
+ if (new_status == Status::kCompleted)
+ completion_time_ = base::TimeTicks::Now();
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader.h b/chromium/content/browser/service_worker/service_worker_navigation_loader.h
index f31dc270ae8..d2153bc10f1 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader.h
+++ b/chromium/content/browser/service_worker/service_worker_navigation_loader.h
@@ -80,6 +80,7 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
NavigationLoaderInterceptor::FallbackCallback fallback_callback,
Delegate* delegate,
const network::ResourceRequest& tentative_resource_request,
+ base::WeakPtr<ServiceWorkerProviderHost> provider_host,
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter);
~ServiceWorkerNavigationLoader() override;
@@ -89,7 +90,6 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
void ForwardToServiceWorker();
bool ShouldFallbackToNetwork();
bool ShouldForwardToServiceWorker();
- bool WasCanceled() const;
// The navigation request that was holding this job is
// going away. Calling this internally calls |DeleteIfNeeded()|
@@ -102,6 +102,18 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
private:
class StreamWaiter;
+ enum class Status {
+ kNotStarted,
+ // |binding_| is bound and the fetch event is being dispatched to the
+ // service worker.
+ kStarted,
+ // The response head has been sent to |url_loader_client_|. The response
+ // body is being streamed.
+ kSentHeader,
+ // OnComplete() was called on |url_loader_client_|, or fallback to network
+ // occurred so the request was not handled.
+ kCompleted,
+ };
// For FORWARD_TO_SERVICE_WORKER case.
void StartRequest(const network::ResourceRequest& resource_request,
@@ -114,6 +126,7 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing,
scoped_refptr<ServiceWorkerVersion> version);
void StartResponse(blink::mojom::FetchAPIResponsePtr response,
@@ -144,6 +157,13 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
void ReportDestination(
ServiceWorkerMetrics::MainResourceRequestDestination destination);
+ // Records loading milestones. Called only after ForwardToServiceWorker() is
+ // called and there was no error. |handled| is true when a fetch handler
+ // handled the request (i.e. non network fallback case).
+ void RecordTimingMetrics(bool handled);
+
+ void TransitionToStatus(Status new_status);
+
ResponseType response_type_ = ResponseType::NOT_DETERMINED;
NavigationLoaderInterceptor::LoaderCallback loader_callback_;
NavigationLoaderInterceptor::FallbackCallback fallback_callback_;
@@ -158,6 +178,7 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
Delegate* delegate_ = nullptr;
network::ResourceRequest resource_request_;
+ base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter_;
std::unique_ptr<ServiceWorkerFetchDispatcher> fetch_dispatcher_;
std::unique_ptr<StreamWaiter> stream_waiter_;
@@ -167,17 +188,14 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
bool did_navigation_preload_ = false;
network::ResourceResponseHead response_head_;
+ bool devtools_attached_ = false;
+ blink::mojom::ServiceWorkerFetchEventTimingPtr fetch_event_timing_;
+ base::TimeTicks completion_time_;
+
// Pointer to the URLLoaderClient (i.e. NavigationURLLoader).
network::mojom::URLLoaderClientPtr url_loader_client_;
mojo::Binding<network::mojom::URLLoader> binding_;
- enum class Status {
- kNotStarted,
- kStarted,
- kSentHeader,
- kCompleted,
- kCancelled
- };
Status status_ = Status::kNotStarted;
base::WeakPtrFactory<ServiceWorkerNavigationLoader> weak_factory_;
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc b/chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
index 02010ab2c3e..5a4c5957f6f 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
@@ -4,7 +4,10 @@
#include "content/browser/service_worker/service_worker_navigation_loader.h"
+#include <string>
+#include <utility>
#include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "content/browser/loader/navigation_loader_interceptor.h"
@@ -51,6 +54,10 @@ blink::mojom::FetchAPIResponsePtr OkResponse(
response->status_text = "OK";
response->response_type = network::mojom::FetchResponseType::kDefault;
response->blob = std::move(blob_body);
+ if (response->blob) {
+ response->headers.emplace("Content-Length",
+ base::NumberToString(response->blob->size));
+ }
return response;
}
@@ -137,10 +144,11 @@ class NavigationPreloadLoaderClient final
response->status_text = response_head_.headers->GetStatusText();
response->response_type = response_head_.response_type;
response_callback_->OnResponseStream(
- std::move(response), std::move(stream_handle), base::Time::Now());
+ std::move(response), std::move(stream_handle),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(finish_callback_)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
stream_callback->OnCompleted();
delete this;
}
@@ -231,10 +239,23 @@ class Helper : public EmbeddedWorkerTestHelper {
void FinishWaitUntil() {
std::move(finish_callback_)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
base::RunLoop().RunUntilIdle();
}
+ // Tells this helper to wait for FinishRespondWith() to be called before
+ // providing the response to the fetch event.
+ void DeferResponse() { response_mode_ = ResponseMode::kDeferredResponse; }
+ void FinishRespondWith() {
+ response_callback_->OnResponse(
+ OkResponse(nullptr /* blob_body */),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
+ response_callback_.FlushForTesting();
+ std::move(finish_callback_)
+ .Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
+ base::TimeTicks::Now());
+ }
+
void ReadRequestBody(std::string* out_string) {
ASSERT_TRUE(request_body_);
const std::vector<network::DataElement>* elements =
@@ -246,6 +267,14 @@ class Helper : public EmbeddedWorkerTestHelper {
*out_string = std::string(element.bytes(), element.length());
}
+ void RunUntilFetchEvent() {
+ if (has_received_fetch_event_)
+ return;
+ base::RunLoop run_loop;
+ quit_closure_for_fetch_event_ = run_loop.QuitClosure();
+ run_loop.Run();
+ }
+
protected:
void OnFetchEvent(
int embedded_worker_id,
@@ -258,6 +287,7 @@ class Helper : public EmbeddedWorkerTestHelper {
EXPECT_TRUE(ServiceWorkerUtils::IsMainResourceType(
static_cast<ResourceType>(request.resource_type)));
+ has_received_fetch_event_ = true;
request_body_ = request.request_body;
switch (response_mode_) {
@@ -265,40 +295,44 @@ class Helper : public EmbeddedWorkerTestHelper {
EmbeddedWorkerTestHelper::OnFetchEvent(
embedded_worker_id, request, std::move(preload_handle),
std::move(response_callback), std::move(finish_callback));
- return;
+ break;
case ResponseMode::kBlob:
- response_callback->OnResponse(OkResponse(std::move(blob_body_)),
- base::Time::Now());
+ response_callback->OnResponse(
+ OkResponse(std::move(blob_body_)),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
- return;
+ base::TimeTicks::Now());
+ break;
case ResponseMode::kStream:
- response_callback->OnResponseStream(OkResponse(nullptr /* blob_body */),
- std::move(stream_handle_),
- base::Time::Now());
+ response_callback->OnResponseStream(
+ OkResponse(nullptr /* blob_body */), std::move(stream_handle_),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
- return;
+ base::TimeTicks::Now());
+ break;
case ResponseMode::kFallbackResponse:
- response_callback->OnFallback(base::Time::Now());
+ response_callback->OnFallback(
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
- return;
+ base::TimeTicks::Now());
+ break;
case ResponseMode::kErrorResponse:
- response_callback->OnResponse(ErrorResponse(), base::Time::Now());
+ response_callback->OnResponse(
+ ErrorResponse(),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::REJECTED,
- base::Time::Now());
- return;
+ base::TimeTicks::Now());
+ break;
case ResponseMode::kNavigationPreloadResponse:
// Deletes itself when done.
new NavigationPreloadLoaderClient(std::move(preload_handle),
std::move(response_callback),
std::move(finish_callback));
- return;
+ break;
case ResponseMode::kFailFetchEventDispatch:
// Simulate failure by stopping the worker before the event finishes.
// This causes ServiceWorkerVersion::StartRequest() to call its error
@@ -313,23 +347,32 @@ class Helper : public EmbeddedWorkerTestHelper {
// callbacks after an unexpected stop.
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::ABORTED,
- base::Time::Now());
- return;
+ base::TimeTicks::Now());
+ break;
+ case ResponseMode::kDeferredResponse:
+ finish_callback_ = std::move(finish_callback);
+ response_callback_ = std::move(response_callback);
+ // Now the caller must call FinishRespondWith() to finish the event.
+ break;
case ResponseMode::kEarlyResponse:
finish_callback_ = std::move(finish_callback);
- response_callback->OnResponse(OkResponse(nullptr /* blob_body */),
- base::Time::Now());
+ response_callback->OnResponse(
+ OkResponse(nullptr /* blob_body */),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
// Now the caller must call FinishWaitUntil() to finish the event.
- return;
+ break;
case ResponseMode::kRedirect:
- response_callback->OnResponse(RedirectResponse(redirected_url_.spec()),
- base::Time::Now());
+ response_callback->OnResponse(
+ RedirectResponse(redirected_url_.spec()),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
- return;
+ base::TimeTicks::Now());
+ break;
}
- NOTREACHED();
+
+ if (quit_closure_for_fetch_event_)
+ std::move(quit_closure_for_fetch_event_).Run();
}
private:
@@ -341,6 +384,7 @@ class Helper : public EmbeddedWorkerTestHelper {
kErrorResponse,
kNavigationPreloadResponse,
kFailFetchEventDispatch,
+ kDeferredResponse,
kEarlyResponse,
kRedirect
};
@@ -354,12 +398,15 @@ class Helper : public EmbeddedWorkerTestHelper {
// For ResponseMode::kStream.
blink::mojom::ServiceWorkerStreamHandlePtr stream_handle_;
- // For ResponseMode::kEarlyResponse.
+ // For ResponseMode::kEarlyResponse and kDeferredResponse.
mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_;
+ blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_;
// For ResponseMode::kRedirect.
GURL redirected_url_;
+ bool has_received_fetch_event_ = false;
+ base::OnceClosure quit_closure_for_fetch_event_;
DISALLOW_COPY_AND_ASSIGN(Helper);
};
@@ -415,7 +462,8 @@ class ServiceWorkerNavigationLoaderTest
helper_->context()->AsWeakPtr());
version_ = new ServiceWorkerVersion(
registration_.get(), GURL("https://example.com/service_worker.js"),
- storage()->NewVersionId(), helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, storage()->NewVersionId(),
+ helper_->context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
records.push_back(WriteToDiskCacheSync(
storage(), version_->script_url(), storage()->NewResourceId(),
@@ -456,7 +504,7 @@ class ServiceWorkerNavigationLoaderTest
base::BindOnce(&ReceiveRequestHandler, &handler),
base::BindOnce(&ServiceWorkerNavigationLoaderTest::Fallback,
base::Unretained(this)),
- this, *request,
+ this, *request, nullptr,
base::WrapRefCounted<URLLoaderFactoryGetter>(
helper_->context()->loader_factory_getter()));
loader_->ForwardToServiceWorker();
@@ -539,6 +587,10 @@ class ServiceWorkerNavigationLoaderTest
void MainResourceLoadFailed() override {
was_main_resource_load_failed_called_ = true;
}
+
+ bool HasWorkInBrowser(ServiceWorkerVersion* version) const {
+ return version->HasWorkInBrowser();
+ }
// --------------------------------------------------------------------------
TestBrowserThreadBundle thread_bundle_;
@@ -573,6 +625,10 @@ TEST_F(ServiceWorkerNavigationLoaderTest, Basic) {
histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent,
blink::ServiceWorkerStatusCode::kOk, 1);
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "ResponseReceivedToCompleted",
+ 1);
}
TEST_F(ServiceWorkerNavigationLoaderTest, NoActiveWorker) {
@@ -590,6 +646,10 @@ TEST_F(ServiceWorkerNavigationLoaderTest, NoActiveWorker) {
// No fetch event was dispatched.
histogram_tester.ExpectTotalCount(kHistogramMainResourceFetchEvent, 0);
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "StartToForwardServiceWorker",
+ 0);
}
// Test that the request body is passed to the fetch event.
@@ -615,6 +675,8 @@ TEST_F(ServiceWorkerNavigationLoaderTest, RequestBody) {
}
TEST_F(ServiceWorkerNavigationLoaderTest, BlobResponse) {
+ base::HistogramTester histogram_tester;
+
// Construct the blob to respond with.
const std::string kResponseBody = "Here is sample text for the blob.";
auto blob_data = std::make_unique<storage::BlobDataBuilder>("blob-id:myblob");
@@ -637,6 +699,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, BlobResponse) {
const network::ResourceResponseHead& info = client_.response_head();
EXPECT_EQ(200, info.headers->response_code());
ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());
+ EXPECT_EQ(33, info.content_length);
// Test the body.
std::string body;
@@ -645,10 +708,18 @@ TEST_F(ServiceWorkerNavigationLoaderTest, BlobResponse) {
mojo::BlockingCopyToString(client_.response_body_release(), &body));
EXPECT_EQ(kResponseBody, body);
EXPECT_EQ(net::OK, client_.completion_status().error_code);
+
+ // Test histogram of reading body.
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "ResponseReceivedToCompleted",
+ 1);
}
// Tell the helper to respond with a non-existent Blob.
TEST_F(ServiceWorkerNavigationLoaderTest, BrokenBlobResponse) {
+ base::HistogramTester histogram_tester;
+
const std::string kBrokenUUID = "broken_uuid";
// Create the broken blob.
@@ -675,9 +746,21 @@ TEST_F(ServiceWorkerNavigationLoaderTest, BrokenBlobResponse) {
// the body.
client_.RunUntilComplete();
EXPECT_EQ(net::ERR_OUT_OF_MEMORY, client_.completion_status().error_code);
+
+ // Timing histograms shouldn't be recorded on broken response.
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "StartToForwardServiceWorker",
+ 0);
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "ResponseReceivedToCompleted",
+ 0);
}
TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponse) {
+ base::HistogramTester histogram_tester;
+
// Construct the Stream to respond with.
const char kResponseBody[] = "Here is sample text for the Stream.";
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
@@ -694,7 +777,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponse) {
EXPECT_EQ(200, info.headers->response_code());
ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());
- EXPECT_TRUE(version_->HasWorkInBrowser());
+ EXPECT_FALSE(version_->HasNoWork());
// Write the body stream.
uint32_t written_bytes = sizeof(kResponseBody) - 1;
@@ -714,10 +797,18 @@ TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponse) {
EXPECT_TRUE(
mojo::BlockingCopyToString(client_.response_body_release(), &response));
EXPECT_EQ(kResponseBody, response);
+
+ // Test histogram of reading body.
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "ResponseReceivedToCompleted",
+ 1);
}
// Test when a stream response body is aborted.
TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponse_Abort) {
+ base::HistogramTester histogram_tester;
+
// Construct the Stream to respond with.
const char kResponseBody[] = "Here is sample text for the Stream.";
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
@@ -752,10 +843,22 @@ TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponse_Abort) {
EXPECT_TRUE(
mojo::BlockingCopyToString(client_.response_body_release(), &response));
EXPECT_EQ(kResponseBody, response);
+
+ // Timing histograms shouldn't be recorded on abort.
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "StartToForwardServiceWorker",
+ 0);
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "ResponseReceivedToCompleted",
+ 0);
}
// Test when the loader is cancelled while a stream response is being written.
TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponseAndCancel) {
+ base::HistogramTester histogram_tester;
+
// Construct the Stream to respond with.
const char kResponseBody[] = "Here is sample text for the Stream.";
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
@@ -772,22 +875,21 @@ TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponseAndCancel) {
EXPECT_EQ(200, info.headers->response_code());
ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());
- // Start writing the body stream, then cancel the loader before finishing.
+ // Start writing the body stream, then break the Mojo connection to the loader
+ // before finishing.
uint32_t written_bytes = sizeof(kResponseBody) - 1;
MojoResult mojo_result = data_pipe.producer_handle->WriteData(
kResponseBody, &written_bytes, MOJO_WRITE_DATA_FLAG_NONE);
ASSERT_EQ(MOJO_RESULT_OK, mojo_result);
EXPECT_EQ(sizeof(kResponseBody) - 1, written_bytes);
EXPECT_TRUE(data_pipe.producer_handle.is_valid());
- EXPECT_FALSE(loader_->WasCanceled());
- EXPECT_TRUE(version_->HasWorkInBrowser());
+ EXPECT_TRUE(HasWorkInBrowser(version_.get()));
loader_ptr_.reset();
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(loader_->WasCanceled());
- EXPECT_FALSE(version_->HasWorkInBrowser());
+ EXPECT_FALSE(HasWorkInBrowser(version_.get()));
// Although ServiceWorkerNavigationLoader resets its URLLoaderClient pointer
- // in Cancel(), the URLLoaderClient still exists. In this test, it is
+ // on connection error, the URLLoaderClient still exists. In this test, it is
// |client_| which owns the data pipe, so it's still valid to write data to
// it.
mojo_result = data_pipe.producer_handle->WriteData(
@@ -798,6 +900,16 @@ TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponseAndCancel) {
client_.RunUntilComplete();
EXPECT_FALSE(data_pipe.consumer_handle.is_valid());
EXPECT_EQ(net::ERR_ABORTED, client_.completion_status().error_code);
+
+ // Timing histograms shouldn't be recorded on cancel.
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "StartToForwardServiceWorker",
+ 0);
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "ResponseReceivedToCompleted",
+ 0);
}
// Test when the service worker responds with network fallback.
@@ -820,6 +932,12 @@ TEST_F(ServiceWorkerNavigationLoaderTest, FallbackResponse) {
EXPECT_FALSE(was_main_resource_load_failed_called_);
histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent,
blink::ServiceWorkerStatusCode::kOk, 1);
+
+ // Test histogram of network fallback.
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "FetchHandlerEndToFallbackNetwork",
+ 1);
}
// Test when the service worker rejects the FetchEvent.
@@ -837,6 +955,11 @@ TEST_F(ServiceWorkerNavigationLoaderTest, ErrorResponse) {
// Event dispatch still succeeded.
histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent,
blink::ServiceWorkerStatusCode::kOk, 1);
+ // Timing UMAs shouldn't be recorded when we receive an error response.
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "StartToForwardServiceWorker",
+ 0);
}
// Test when dispatching the fetch event to the service worker failed.
@@ -856,6 +979,11 @@ TEST_F(ServiceWorkerNavigationLoaderTest, FailFetchDispatch) {
histogram_tester.ExpectUniqueSample(
kHistogramMainResourceFetchEvent,
blink::ServiceWorkerStatusCode::kErrorFailed, 1);
+ // Timing UMAs shouldn't be recorded when failed to dispatch an event.
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "StartToForwardServiceWorker",
+ 0);
}
// Test when the respondWith() promise resolves before the waitUntil() promise
@@ -874,9 +1002,9 @@ TEST_F(ServiceWorkerNavigationLoaderTest, EarlyResponse) {
// Although the response was already received, the event remains outstanding
// until waitUntil() resolves.
- EXPECT_TRUE(version_->HasWorkInBrowser());
+ EXPECT_TRUE(HasWorkInBrowser(version_.get()));
helper_->FinishWaitUntil();
- EXPECT_FALSE(version_->HasWorkInBrowser());
+ EXPECT_FALSE(HasWorkInBrowser(version_.get()));
}
// Test asking the loader to fallback to network. In production code, this
@@ -898,7 +1026,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, FallbackToNetwork) {
base::BindOnce(&ReceiveRequestHandler, &handler),
base::BindOnce(&ServiceWorkerNavigationLoaderTest::Fallback,
base::Unretained(this)),
- this, request,
+ this, request, nullptr,
base::WrapRefCounted<URLLoaderFactoryGetter>(
helper_->context()->loader_factory_getter()));
// Ask the loader to fallback to network. In production code,
@@ -909,6 +1037,10 @@ TEST_F(ServiceWorkerNavigationLoaderTest, FallbackToNetwork) {
// No fetch event was dispatched.
histogram_tester.ExpectTotalCount(kHistogramMainResourceFetchEvent, 0);
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.LoadTiming.MainFrame.MainResource."
+ "StartToForwardServiceWorker",
+ 0);
}
// Test responding to the fetch event with the navigation preload response.
@@ -998,7 +1130,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, LifetimeAfterFallbackToNetwork) {
base::BindOnce(&ReceiveRequestHandler, &handler),
base::BindOnce(&ServiceWorkerNavigationLoaderTest::Fallback,
base::Unretained(this)),
- this, request,
+ this, request, nullptr,
base::WrapRefCounted<URLLoaderFactoryGetter>(
helper_->context()->loader_factory_getter()));
base::WeakPtr<ServiceWorkerNavigationLoader> loader_weakptr =
@@ -1015,6 +1147,27 @@ TEST_F(ServiceWorkerNavigationLoaderTest, LifetimeAfterFallbackToNetwork) {
EXPECT_FALSE(loader_weakptr);
}
+TEST_F(ServiceWorkerNavigationLoaderTest, ConnectionErrorDuringFetchEvent) {
+ helper_->DeferResponse();
+ LoaderResult result = StartRequest(CreateRequest());
+ EXPECT_EQ(LoaderResult::kHandledRequest, result);
+
+ // Wait for the fetch event to be dispatched.
+ helper_->RunUntilFetchEvent();
+
+ // Break the Mojo connection. The loader should return an aborted status.
+ loader_ptr_.reset();
+ client_.RunUntilComplete();
+ EXPECT_EQ(net::ERR_ABORTED, client_.completion_status().error_code);
+
+ // The loader is still alive. Finish the fetch event. It shouldn't crash or
+ // call any callbacks on |client_|, which would throw an error.
+ helper_->FinishRespondWith();
+ // There's no event to wait for, so just pump the message loop and the test
+ // passes if there is no error or crash.
+ base::RunLoop().RunUntilIdle();
+}
+
TEST_F(ServiceWorkerNavigationLoaderTest, DetachedDuringFetchEvent) {
LoaderResult result = StartRequest(CreateRequest());
EXPECT_EQ(LoaderResult::kHandledRequest, result);
diff --git a/chromium/content/browser/service_worker/service_worker_new_script_loader.cc b/chromium/content/browser/service_worker/service_worker_new_script_loader.cc
index fc38698dff6..71e2fea8961 100644
--- a/chromium/content/browser/service_worker/service_worker_new_script_loader.cc
+++ b/chromium/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -90,6 +90,8 @@ ServiceWorkerNewScriptLoader::ServiceWorkerNewScriptLoader(
// may be used by ServiceWorkerNavigationLoader for navigations handled
// by this service worker.
options |= network::mojom::kURLLoadOptionSendSSLInfoWithResponse;
+
+ resource_request.headers.SetHeader("Service-Worker", "script");
}
// Bypass the browser cache if needed, e.g., updateViaCache demands it or 24
@@ -103,8 +105,6 @@ ServiceWorkerNewScriptLoader::ServiceWorkerNewScriptLoader(
resource_request.load_flags |= net::LOAD_BYPASS_CACHE;
}
- resource_request.headers.SetHeader("Service-Worker", "script");
-
// Create response readers only when we have to do the byte-for-byte check.
std::unique_ptr<ServiceWorkerResponseReader> compare_reader;
std::unique_ptr<ServiceWorkerResponseReader> copy_reader;
@@ -115,7 +115,8 @@ ServiceWorkerNewScriptLoader::ServiceWorkerNewScriptLoader(
}
cache_writer_ = std::make_unique<ServiceWorkerCacheWriter>(
std::move(compare_reader), std::move(copy_reader),
- storage->CreateResponseWriter(cache_resource_id));
+ storage->CreateResponseWriter(cache_resource_id),
+ false /* pause_when_not_identical */);
version_->script_cache_map()->NotifyStartedCaching(request_url_,
cache_resource_id);
@@ -247,6 +248,8 @@ void ServiceWorkerNewScriptLoader::OnReceiveResponse(
version_->SetMainScriptHttpResponseInfo(*response_info);
}
+ network_loader_state_ = NetworkLoaderState::kWaitingForBody;
+
WriteHeaders(
base::MakeRefCounted<HttpResponseInfoIOBuffer>(std::move(response_info)));
@@ -258,11 +261,9 @@ void ServiceWorkerNewScriptLoader::OnReceiveResponse(
network::ResourceResponseHead new_response_head = response_head;
new_response_head.ssl_info.reset();
client_->OnReceiveResponse(new_response_head);
- } else {
- client_->OnReceiveResponse(response_head);
+ return;
}
-
- network_loader_state_ = NetworkLoaderState::kWaitingForBody;
+ client_->OnReceiveResponse(response_head);
}
void ServiceWorkerNewScriptLoader::OnReceiveRedirect(
diff --git a/chromium/content/browser/service_worker/service_worker_new_script_loader_unittest.cc b/chromium/content/browser/service_worker/service_worker_new_script_loader_unittest.cc
index 7494702698a..1016c4f6df0 100644
--- a/chromium/content/browser/service_worker/service_worker_new_script_loader_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_new_script_loader_unittest.cc
@@ -173,7 +173,6 @@ class ServiceWorkerNewScriptLoaderTest : public testing::Test {
"this is an import script response body from the network")));
// Initialize URLLoaderFactory.
- network::mojom::URLLoaderFactoryPtr test_loader_factory;
mock_url_loader_factory_ =
std::make_unique<MockNetworkURLLoaderFactory>(mock_server_.get());
helper_->SetNetworkFactory(mock_url_loader_factory_.get());
@@ -217,8 +216,8 @@ class ServiceWorkerNewScriptLoaderTest : public testing::Test {
// possibly updating if registration has an installed worker.
void SetUpVersion(const GURL& script_url) {
version_ = base::MakeRefCounted<ServiceWorkerVersion>(
- registration_.get(), script_url, context()->storage()->NewVersionId(),
- context()->AsWeakPtr());
+ registration_.get(), script_url, blink::mojom::ScriptType::kClassic,
+ context()->storage()->NewVersionId(), context()->AsWeakPtr());
version_->SetStatus(ServiceWorkerVersion::NEW);
if (registration_->waiting_version() || registration_->active_version())
diff --git a/chromium/content/browser/service_worker/service_worker_object_host.cc b/chromium/content/browser/service_worker/service_worker_object_host.cc
index cd4f6ea5728..9989c75efcb 100644
--- a/chromium/content/browser/service_worker/service_worker_object_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_object_host.cc
@@ -88,7 +88,7 @@ bool PrepareExtendableMessageEventFromClient(
DCHECK(source_client_info && !source_client_info->client_uuid.empty());
(*event)->source_info_for_client = std::move(source_client_info);
// Hide the client url if the client has a unique origin.
- if ((*event)->source_origin.unique())
+ if ((*event)->source_origin.opaque())
(*event)->source_info_for_client->url = GURL();
// Reset |registration->self_update_delay| iff postMessage is coming from a
@@ -130,7 +130,7 @@ bool PrepareExtendableMessageEventFromServiceWorker(
(*event)->source_info_for_service_worker = std::move(source_worker_info);
// Hide the service worker url if the service worker has a unique origin.
- if ((*event)->source_origin.unique())
+ if ((*event)->source_origin.opaque())
(*event)->source_info_for_service_worker->url = GURL();
return true;
}
diff --git a/chromium/content/browser/service_worker/service_worker_object_host_unittest.cc b/chromium/content/browser/service_worker/service_worker_object_host_unittest.cc
index fd1ca22f735..fbcb6c00497 100644
--- a/chromium/content/browser/service_worker/service_worker_object_host_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_object_host_unittest.cc
@@ -56,7 +56,7 @@ class ExtendableMessageEventTestHelper : public EmbeddedWorkerTestHelper {
override {
events_.push_back(std::move(event));
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
const std::vector<mojom::ExtendableMessageEventPtr>& events() {
@@ -130,10 +130,10 @@ class ServiceWorkerObjectHostTest : public testing::Test {
registration_ = new ServiceWorkerRegistration(
options, helper_->context()->storage()->NewRegistrationId(),
helper_->context()->AsWeakPtr());
- version_ =
- new ServiceWorkerVersion(registration_.get(), script_url,
- helper_->context()->storage()->NewVersionId(),
- helper_->context()->AsWeakPtr());
+ version_ = new ServiceWorkerVersion(
+ registration_.get(), script_url, blink::mojom::ScriptType::kClassic,
+ helper_->context()->storage()->NewVersionId(),
+ helper_->context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
records.push_back(
ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100));
diff --git a/chromium/content/browser/service_worker/service_worker_provider_host.cc b/chromium/content/browser/service_worker/service_worker_provider_host.cc
index 1f25d3eb9be..1309c7a5b57 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_provider_host.cc
@@ -11,6 +11,7 @@
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "content/browser/bad_message.h"
#include "content/browser/interface_provider_filtering.h"
@@ -26,9 +27,11 @@
#include "content/browser/service_worker/service_worker_type_converters.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/url_loader_factory_getter.h"
+#include "content/browser/web_contents/web_contents_getter_registry.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
@@ -40,9 +43,10 @@
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "net/base/url_util.h"
+#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "storage/browser/blob/blob_storage_context.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
@@ -323,6 +327,8 @@ ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
context_->UnregisterProviderHostByClientID(client_uuid_);
if (controller_)
controller_->RemoveControllee(client_uuid_);
+ if (fetch_request_window_id_)
+ WebContentsGetterRegistry::GetInstance()->Remove(fetch_request_window_id_);
// Remove |this| as an observer of ServiceWorkerRegistrations.
// TODO(falken): Use ScopedObserver instead of this explicit call.
@@ -393,11 +399,11 @@ ServiceWorkerProviderHost::GetControllerMode() const {
void ServiceWorkerProviderHost::OnVersionAttributesChanged(
ServiceWorkerRegistration* registration,
- ChangedVersionAttributesMask changed_mask,
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
const ServiceWorkerRegistrationInfo& /* info */) {
if (!get_ready_callback_ || get_ready_callback_->is_null())
return;
- if (changed_mask.active_changed() && registration->active_version()) {
+ if (changed_mask->active && registration->active_version()) {
// Wait until the state change so we don't send the get for ready
// registration complete message before set version attributes message.
registration->active_version()->RegisterStatusChangeCallback(base::BindOnce(
@@ -445,7 +451,20 @@ ServiceWorkerProviderHost::GetControllerServiceWorkerPtr() {
void ServiceWorkerProviderHost::SetDocumentUrl(const GURL& url) {
DCHECK(!url.has_ref());
DCHECK(!controller());
+ if (document_url_ == url)
+ return;
document_url_ = url;
+
+ // Revoke the token on URL change since any service worker holding the token
+ // may no longer be the potential controller of this frame and shouldn't have
+ // the power to display SSL dialogs for it.
+ if (info_->type == blink::mojom::ServiceWorkerProviderType::kForWindow) {
+ auto* registry = WebContentsGetterRegistry::GetInstance();
+ registry->Remove(fetch_request_window_id_);
+ fetch_request_window_id_ = base::UnguessableToken::Create();
+ registry->Add(fetch_request_window_id_, web_contents_getter());
+ }
+
if (IsProviderForClient())
SyncMatchingRegistrations();
}
@@ -478,14 +497,30 @@ void ServiceWorkerProviderHost::UpdateController(bool notify_controllerchange) {
// SetController message should be sent only for clients.
DCHECK(IsProviderForClient());
- // If there is no connection to the renderer yet, |this| is hosting a reserved
- // client undergoing navigation. The controller will be sent on navigation
- // commit. See CommitNavigation in frame.mojom.
- if (!container_.is_bound()) {
- DCHECK_EQ(blink::mojom::ServiceWorkerClientType::kWindow, client_type());
- DCHECK(!is_execution_ready_);
- return;
+
+ // The final response hasn't been committed yet, so there's no reason to send
+ // the controller since it can be changed again before the final response.
+ if (!is_execution_ready_) {
+ if (client_type() == blink::mojom::ServiceWorkerClientType::kWindow) {
+ // |this| is hosting a reserved client undergoing navigation. The
+ // controller will be sent on navigation commit. See CommitNavigation in
+ // frame.mojom.
+ DCHECK(!container_.is_bound());
+ return;
+ }
+ DCHECK_EQ(blink::mojom::ServiceWorkerClientType::kSharedWorker,
+ client_type());
+
+ // NetworkService (PlzWorker):
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // When PlzWorker is enabled, the controller will be sent when the
+ // response is committed to the renderer at SharedWorkerHost::Start().
+ return;
+ }
+ // When NetworkService is disabled and the client is for a shared worker,
+ // the controller won't be sent on response commit, so send it here.
}
+
SendSetControllerServiceWorker(notify_controllerchange);
}
@@ -568,8 +603,7 @@ void ServiceWorkerProviderHost::RemoveMatchingRegistration(
ServiceWorkerRegistration*
ServiceWorkerProviderHost::MatchRegistration() const {
- ServiceWorkerRegistrationMap::const_reverse_iterator it =
- matching_registrations_.rbegin();
+ auto it = matching_registrations_.rbegin();
for (; it != matching_registrations_.rend(); ++it) {
if (it->second->is_uninstalled())
continue;
@@ -625,7 +659,7 @@ ServiceWorkerProviderHost::CreateRequestHandler(
const std::string& integrity,
bool keepalive,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
scoped_refptr<network::ResourceRequestBody> body,
@@ -694,13 +728,29 @@ void ServiceWorkerProviderHost::PostMessageToClient(
void ServiceWorkerProviderHost::CountFeature(blink::mojom::WebFeature feature) {
// CountFeature message should be sent only for clients.
DCHECK(IsProviderForClient());
- // If there is no connection to the renderer yet, |this| is hosting a reserved
- // client undergoing navigation. The use counter will be sent correctly in
- // CompleteNavigationInitialized() later.
- if (!container_.is_bound()) {
- DCHECK_EQ(blink::mojom::ServiceWorkerClientType::kWindow, client_type());
- DCHECK(!is_execution_ready_);
- return;
+
+ // The final response hasn't been committed yet, so there's no reason to send
+ // the use counter since it can be changed again before the final response.
+ if (!is_execution_ready_) {
+ if (client_type() == blink::mojom::ServiceWorkerClientType::kWindow) {
+ // |this| is hosting a reserved client undergoing navigation. The use
+ // counter will be sent correctly in CompleteNavigationInitialized()
+ // later.
+ DCHECK(!container_.is_bound());
+ return;
+ }
+ DCHECK_EQ(blink::mojom::ServiceWorkerClientType::kSharedWorker,
+ client_type());
+
+ // NetworkService (PlzWorker):
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // When PlzWorker is enabled, the use counter will be sent when the
+ // response is committed to the renderer at SharedWorkerHost::Start().
+ // TODO(nhiroki): Send the use counter on starting the shared worker.
+ return;
+ }
+ // When NetworkService is disabled and the client is for a shared worker,
+ // the use counter won't be sent on response commit, so send it here.
}
container_->CountFeature(feature);
@@ -866,6 +916,10 @@ void ServiceWorkerProviderHost::SendSetControllerServiceWorker(
auto controller_info = mojom::ControllerServiceWorkerInfo::New();
controller_info->client_id = client_uuid();
+ if (fetch_request_window_id_) {
+ controller_info->fetch_request_window_id =
+ base::make_optional(fetch_request_window_id_);
+ }
if (!controller_) {
container_->SetController(std::move(controller_info),
@@ -1183,11 +1237,10 @@ void ServiceWorkerProviderHost::EnsureControllerServiceWorker(
AsWeakPtr(), std::move(controller_request)));
}
-void ServiceWorkerProviderHost::CloneForWorker(
+void ServiceWorkerProviderHost::CloneContainerHost(
mojom::ServiceWorkerContainerHostRequest container_host_request) {
DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
- bindings_for_worker_threads_.AddBinding(this,
- std::move(container_host_request));
+ additional_bindings_.AddBinding(this, std::move(container_host_request));
}
void ServiceWorkerProviderHost::Ping(PingCallback callback) {
@@ -1261,8 +1314,8 @@ void ServiceWorkerProviderHost::GetInterface(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK_NE(kDocumentMainThreadId, render_thread_id_);
DCHECK(IsProviderForServiceWorker());
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&GetInterfaceImpl, interface_name, std::move(interface_pipe),
running_hosted_version_->script_origin(), render_process_id_));
diff --git a/chromium/content/browser/service_worker/service_worker_provider_host.h b/chromium/content/browser/service_worker/service_worker_provider_host.h
index 2fe3e1ef2b8..ee6c66ecce8 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host.h
+++ b/chromium/content/browser/service_worker/service_worker_provider_host.h
@@ -19,13 +19,13 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
+#include "base/unguessable_token.h"
#include "content/browser/service_worker/service_worker_object_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_container.mojom.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -34,6 +34,7 @@
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/web_feature.mojom.h"
namespace network {
@@ -178,6 +179,9 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
~ServiceWorkerProviderHost() override;
const std::string& client_uuid() const { return client_uuid_; }
+ const base::UnguessableToken& fetch_request_window_id() const {
+ return fetch_request_window_id_;
+ }
base::TimeTicks create_time() const { return create_time_; }
int process_id() const { return render_process_id_; }
int provider_id() const { return info_->provider_id; }
@@ -326,7 +330,7 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
const std::string& integrity,
bool keepalive,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
scoped_refptr<network::ResourceRequestBody> body,
@@ -494,7 +498,7 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// ServiceWorkerRegistration::Listener overrides.
void OnVersionAttributesChanged(
ServiceWorkerRegistration* registration,
- ChangedVersionAttributesMask changed_mask,
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
const ServiceWorkerRegistrationInfo& info) override;
void OnRegistrationFailed(ServiceWorkerRegistration* registration) override;
void OnRegistrationFinishedUninstalling(
@@ -541,7 +545,7 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
void EnsureControllerServiceWorker(
mojom::ControllerServiceWorkerRequest controller_request,
mojom::ControllerServiceWorkerPurpose purpose) override;
- void CloneForWorker(
+ void CloneContainerHost(
mojom::ServiceWorkerContainerHostRequest container_host_request) override;
void Ping(PingCallback callback) override;
void HintToUpdateServiceWorker() override;
@@ -594,7 +598,19 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
const char* error_prefix,
Args... args);
+ // A GUID that is web-exposed as FetchEvent.clientId.
const std::string client_uuid_;
+
+ // For window clients. A token used internally to identify this context in
+ // requests. Corresponds to the Fetch specification's concept of a request's
+ // associated window: https://fetch.spec.whatwg.org/#concept-request-window
+ // This gets reset on redirects, unlike |client_uuid_|.
+ //
+ // TODO(falken): Consider using this for |client_uuid_| as well. We can't
+ // right now because this gets reset on redirects, and potentially sites rely
+ // on the GUID format.
+ base::UnguessableToken fetch_request_window_id_;
+
const base::TimeTicks create_time_;
int render_process_id_;
@@ -673,17 +689,10 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// content::ServiceWorkerProviderHost will be destroyed.
mojo::AssociatedBinding<mojom::ServiceWorkerContainerHost> binding_;
- // Mojo bindings for provider host pointers which are used from (dedicated or
- // shared) worker threads.
- // When this is hosting a shared worker, |bindings_for_worker_threads_|
- // contains exactly one element for the shared worker thread. This binding is
- // needed because the host pointer which is bound to |binding_| can only be
- // used from the main thread.
- // When this is hosting a document, |bindings_for_worker_threads_| contains
- // all dedicated workers associated with the document. This binding is needed
- // for the host pointers which are used from the dedicated worker threads.
- mojo::BindingSet<mojom::ServiceWorkerContainerHost>
- bindings_for_worker_threads_;
+ // Container host bindings other than the original |binding_|. These include
+ // bindings for container host pointers used from (dedicated or shared) worker
+ // threads, or from ServiceWorkerSubresourceLoaderFactory.
+ mojo::BindingSet<mojom::ServiceWorkerContainerHost> additional_bindings_;
// For service worker execution contexts.
mojo::Binding<service_manager::mojom::InterfaceProvider>
diff --git a/chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc b/chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc
index 926cb6bedf1..a4c9a827e40 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc
@@ -459,7 +459,8 @@ TEST_P(ServiceWorkerProviderHostTest, Controller) {
// Create an active version and then start the navigation.
scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
registration1_.get(), GURL("https://www.example.com/sw.js"),
- 1 /* version_id */, helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, 1 /* version_id */,
+ helper_->context()->AsWeakPtr());
version->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
version->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -494,7 +495,8 @@ TEST_P(ServiceWorkerProviderHostTest, UncontrolledWithMatchingRegistration) {
// Create an installing version and then start the navigation.
scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
registration1_.get(), GURL("https://www.example.com/sw.js"),
- 1 /* version_id */, helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, 1 /* version_id */,
+ helper_->context()->AsWeakPtr());
registration1_->SetInstallingVersion(version);
// Finish the navigation.
@@ -559,7 +561,8 @@ TEST_P(ServiceWorkerProviderHostTest, AllowsServiceWorker) {
scoped_refptr<ServiceWorkerVersion> version =
base::MakeRefCounted<ServiceWorkerVersion>(
registration1_.get(), GURL("https://www.example.com/sw.js"),
- 1 /* version_id */, helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, 1 /* version_id */,
+ helper_->context()->AsWeakPtr());
registration1_->SetActiveVersion(version);
ServiceWorkerRemoteProviderEndpoint remote_endpoint;
@@ -870,90 +873,6 @@ TEST_P(ServiceWorkerProviderHostTest,
}
}
-// Regression test for https://crbug.com/860106. When a provider host
-// is destroyed, it removes itself as a controllee from its controller.
-// This can trigger the waiting version starting to activate. The
-// destructing host shouldn't try to change its controller to the new
-// active version.
-TEST_P(ServiceWorkerProviderHostTest, DontSetControllerInDestructor) {
- // This test requires the idle timeout mechanism of S13nSW to exercise the
- // desired code path.
- if (!IsServiceWorkerServicificationEnabled())
- return;
-
- // Make a window.
- ServiceWorkerProviderHost* provider_host1 =
- CreateProviderHost(GURL("https://www.example.com/example1.html"));
-
- // Make an active version.
- auto version1 = base::MakeRefCounted<ServiceWorkerVersion>(
- registration1_.get(), GURL("https://www.example.com/sw.js"),
- 1 /* version_id */, helper_->context()->AsWeakPtr());
- version1->set_fetch_handler_existence(
- ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
- version1->SetStatus(ServiceWorkerVersion::ACTIVATED);
- registration1_->SetActiveVersion(version1);
-
- // Make the registration findable via storage functions. This allows
- // the service worker to start, which will be needed later.
- base::RunLoop loop;
- helper_->context()->storage()->LazyInitializeForTest(loop.QuitClosure());
- loop.Run();
- std::vector<ServiceWorkerDatabase::ResourceRecord> records;
- records.push_back(WriteToDiskCacheSync(
- helper_->context()->storage(), version1->script_url(),
- helper_->context()->storage()->NewResourceId(), {} /* headers */,
- "I'm the body", "I'm the meta data"));
- version1->script_cache_map()->SetResources(records);
- version1->SetMainScriptHttpResponseInfo(
- EmbeddedWorkerTestHelper::CreateHttpResponseInfo());
- base::Optional<blink::ServiceWorkerStatusCode> status;
- helper_->context()->storage()->StoreRegistration(
- registration1_.get(), version1.get(),
- CreateReceiverOnCurrentThread(&status));
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
-
- // Make the active worker the controller and give it an ongoing request. This
- // way when a waiting worker calls SkipWaiting(), activation won't trigger
- // until we're ready.
- provider_host1->SetControllerRegistration(registration1_, false);
- EXPECT_EQ(version1.get(), provider_host1->controller());
- // The worker must be running to have a request.
- version1->StartWorker(ServiceWorkerMetrics::EventType::PUSH,
- base::DoNothing());
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version1->running_status());
- int request = version1->StartRequest(ServiceWorkerMetrics::EventType::PUSH,
- base::DoNothing());
-
- // Make the waiting worker and have it call SkipWaiting().
- auto version2 = base::MakeRefCounted<ServiceWorkerVersion>(
- registration1_.get(), GURL("https://www.example.com/sw.js"),
- 2 /* version_id */, helper_->context()->AsWeakPtr());
- version2->set_fetch_handler_existence(
- ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
- version2->SetStatus(ServiceWorkerVersion::INSTALLED);
- registration1_->SetWaitingVersion(version2);
- version2->SkipWaiting(base::DoNothing());
-
- // Finish the request. Activation won't yet occur until as
- // |idle_time_fired_in_renderer_| isn't true.
- version1->FinishRequest(request, true, base::Time::Now());
-
- // Destroy the provider host. This triggers activation, and since
- // SkipWaiting() was called, the provider host is in danger
- // of receiving an OnSkippedWaiting() call during destruction.
- ASSERT_TRUE(remote_endpoints_.back().host_ptr()->is_bound());
- remote_endpoints_.back().host_ptr()->reset();
- base::RunLoop().RunUntilIdle();
-
- // No crash should occur, and the new version should be the active
- // one.
- EXPECT_EQ(version2.get(), registration1_->active_version());
- EXPECT_FALSE(version2->HasControllee());
-}
-
// Tests that the service worker involved with a navigation (via
// AddServiceWorkerToUpdate) is updated when the host for the navigation is
// destroyed.
@@ -969,7 +888,8 @@ TEST_P(ServiceWorkerProviderHostTest, UpdateServiceWorkerOnDestruction) {
// Make an active version.
auto version1 = base::MakeRefCounted<ServiceWorkerVersion>(
registration1_.get(), GURL("https://www.example.com/sw.js"),
- 1 /* version_id */, helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, 1 /* version_id */,
+ helper_->context()->AsWeakPtr());
version1->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
version1->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -977,7 +897,8 @@ TEST_P(ServiceWorkerProviderHostTest, UpdateServiceWorkerOnDestruction) {
auto version2 = base::MakeRefCounted<ServiceWorkerVersion>(
registration2_.get(), GURL("https://www.example.com/sw.js"),
- 2 /* version_id */, helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, 2 /* version_id */,
+ helper_->context()->AsWeakPtr());
version2->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
version2->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1008,7 +929,8 @@ TEST_P(ServiceWorkerProviderHostTest, HintToUpdateServiceWorker) {
// Make an active version.
auto version1 = base::MakeRefCounted<ServiceWorkerVersion>(
registration1_.get(), GURL("https://www.example.com/sw.js"),
- 1 /* version_id */, helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, 1 /* version_id */,
+ helper_->context()->AsWeakPtr());
version1->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
version1->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1049,7 +971,8 @@ TEST_P(ServiceWorkerProviderHostTest,
// Make an active version.
auto version1 = base::MakeRefCounted<ServiceWorkerVersion>(
registration1_.get(), GURL("https://www.example.com/sw.js"),
- 1 /* version_id */, helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, 1 /* version_id */,
+ helper_->context()->AsWeakPtr());
version1->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
version1->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1079,7 +1002,8 @@ TEST_P(ServiceWorkerProviderHostTest, HintToUpdateServiceWorkerMultiple) {
// Make active versions.
auto version1 = base::MakeRefCounted<ServiceWorkerVersion>(
registration1_.get(), GURL("https://www.example.com/sw.js"),
- 1 /* version_id */, helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, 1 /* version_id */,
+ helper_->context()->AsWeakPtr());
version1->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
version1->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1087,7 +1011,8 @@ TEST_P(ServiceWorkerProviderHostTest, HintToUpdateServiceWorkerMultiple) {
auto version2 = base::MakeRefCounted<ServiceWorkerVersion>(
registration2_.get(), GURL("https://www.example.com/sw.js"),
- 2 /* version_id */, helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, 2 /* version_id */,
+ helper_->context()->AsWeakPtr());
version2->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
version2->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1095,7 +1020,8 @@ TEST_P(ServiceWorkerProviderHostTest, HintToUpdateServiceWorkerMultiple) {
auto version3 = base::MakeRefCounted<ServiceWorkerVersion>(
registration3_.get(), GURL("https://other.example.com/sw.js"),
- 3 /* version_id */, helper_->context()->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, 3 /* version_id */,
+ helper_->context()->AsWeakPtr());
version3->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
version3->SetStatus(ServiceWorkerVersion::ACTIVATED);
diff --git a/chromium/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc b/chromium/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc
index 150c6466381..188907a1fd2 100644
--- a/chromium/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc
@@ -40,19 +40,19 @@ const int64_t kNonExistentResourceId = 12;
const int64_t kResourceSize = 100;
void DidStoreRegistration(blink::ServiceWorkerStatusCode* status_out,
- const base::Closure& quit_closure,
+ base::OnceClosure quit_closure,
blink::ServiceWorkerStatusCode status) {
*status_out = status;
- quit_closure.Run();
+ std::move(quit_closure).Run();
}
void DidFindRegistration(
blink::ServiceWorkerStatusCode* status_out,
- const base::Closure& quit_closure,
+ base::OnceClosure quit_closure,
blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
*status_out = status;
- quit_closure.Run();
+ std::move(quit_closure).Run();
}
} // namespace
@@ -96,6 +96,7 @@ class ServiceWorkerReadFromCacheJobTest : public testing::Test {
registration_ = new ServiceWorkerRegistration(options, kRegistrationId,
context()->AsWeakPtr());
version_ = new ServiceWorkerVersion(registration_.get(), main_script_.url,
+ blink::mojom::ScriptType::kClassic,
kVersionId, context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
resources.push_back(main_script_);
@@ -113,7 +114,8 @@ class ServiceWorkerReadFromCacheJobTest : public testing::Test {
const char kHttpBody[] = "Hello";
const int length = arraysize(kHttpBody);
std::string headers(kHttpHeaders, arraysize(kHttpHeaders));
- scoped_refptr<net::IOBuffer> body(new net::WrappedIOBuffer(kHttpBody));
+ scoped_refptr<net::IOBuffer> body =
+ base::MakeRefCounted<net::WrappedIOBuffer>(kHttpBody);
std::unique_ptr<ServiceWorkerResponseWriter> writer =
context()->storage()->CreateResponseWriter(resource_id);
diff --git a/chromium/content/browser/service_worker/service_worker_register_job.cc b/chromium/content/browser/service_worker/service_worker_register_job.cc
index f832ed1c409..2c38456a810 100644
--- a/chromium/content/browser/service_worker/service_worker_register_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_register_job.cc
@@ -19,6 +19,7 @@
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/service_worker/service_worker_write_to_cache_job.h"
+#include "content/browser/url_loader_factory_getter.h"
#include "content/common/service_worker/service_worker.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.h"
@@ -26,6 +27,7 @@
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "net/base/net_errors.h"
#include "third_party/blink/public/common/service_worker/service_worker_type_converters.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
namespace content {
@@ -40,6 +42,7 @@ ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
job_type_(REGISTRATION_JOB),
pattern_(options.scope),
script_url_(script_url),
+ worker_script_type_(options.type),
update_via_cache_(options.update_via_cache),
phase_(INITIAL),
doom_installing_worker_(false),
@@ -64,9 +67,15 @@ ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
is_promise_resolved_(false),
should_uninstall_on_failure_(false),
force_bypass_cache_(force_bypass_cache),
- skip_script_comparison_(skip_script_comparison),
promise_resolved_status_(blink::ServiceWorkerStatusCode::kOk),
weak_factory_(this) {
+ // |skip_script_comparison_| should be true when
+ // ServiceWorkerImportedScriptUpdateCheck is enabled, because then script
+ // comparison happens before starting a worker and it doesn't need to happen
+ // during the worker startup.
+ skip_script_comparison_ =
+ blink::ServiceWorkerUtils::IsImportedScriptUpdateCheckEnabled() ||
+ skip_script_comparison;
internal_.registration = registration;
}
@@ -225,10 +234,16 @@ void ServiceWorkerRegisterJob::ContinueWithRegistration(
}
DCHECK(existing_registration->GetNewestVersion());
- // "If scriptURL is equal to registration.[[ScriptURL]] and
- // "update_via_cache is equal to registration.[[update_via_cache]], then:"
+ // We also compare |script_type| here to proceed with registration when the
+ // script type is changed.
+ // TODO(asamidoi): Update the spec comment once
+ // https://github.com/w3c/ServiceWorker/issues/1359 is resolved.
+ // "If scriptURL is equal to registration.[[ScriptURL]] and "update_via_cache
+ // is equal to registration.[[update_via_cache]], then:"
if (existing_registration->GetNewestVersion()->script_url() == script_url_ &&
- existing_registration->update_via_cache() == update_via_cache_) {
+ existing_registration->update_via_cache() == update_via_cache_ &&
+ existing_registration->GetNewestVersion()->script_type() ==
+ worker_script_type_) {
// "Set registration.[[Uninstalling]] to false."
existing_registration->AbortPendingClear(base::BindOnce(
&ServiceWorkerRegisterJob::ContinueWithRegistrationForSameScriptUrl,
@@ -275,11 +290,47 @@ void ServiceWorkerRegisterJob::ContinueWithUpdate(
DCHECK(script_url_.is_empty());
script_url_ = registration()->GetNewestVersion()->script_url();
+ worker_script_type_ = registration()->GetNewestVersion()->script_type();
// TODO(michaeln): If the last update check was less than 24 hours
// ago, depending on the freshness of the cached worker script we
// may be able to complete the update job right here.
+ if (blink::ServiceWorkerUtils::IsImportedScriptUpdateCheckEnabled()) {
+ ServiceWorkerVersion* version_to_update =
+ registration()->GetNewestVersion();
+ std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
+ version_to_update->script_cache_map()->GetResources(&resources);
+ update_checker_ = std::make_unique<ServiceWorkerUpdateChecker>(
+ resources, version_to_update,
+ context_->loader_factory_getter()->GetNetworkFactory());
+ update_checker_->Start(
+ base::BindOnce(&ServiceWorkerRegisterJob::OnUpdateCheckFinished,
+ weak_factory_.GetWeakPtr()));
+ return;
+ }
+
+ UpdateAndContinue();
+}
+
+void ServiceWorkerRegisterJob::OnUpdateCheckFinished(bool script_changed) {
+ DCHECK(blink::ServiceWorkerUtils::IsImportedScriptUpdateCheckEnabled());
+ if (!script_changed) {
+ // TODO(momohatt): Set phase correctly.
+ // TODO(momohatt): Update the last update check time correctly.
+ ServiceWorkerVersion* newest_version = registration()->GetNewestVersion();
+ if (newest_version->force_bypass_cache_for_scripts()) {
+ registration()->set_last_update_check(base::Time::Now());
+ }
+ context_->storage()->UpdateLastUpdateCheckTime(registration());
+ ResolvePromise(blink::ServiceWorkerStatusCode::kOk, std::string(),
+ registration());
+ // This terminates the current job (|this|).
+ Complete(blink::ServiceWorkerStatusCode::kErrorExists,
+ "The updated worker is identical to the incumbent.");
+ return;
+ }
+
UpdateAndContinue();
}
@@ -293,8 +344,8 @@ void ServiceWorkerRegisterJob::RegisterAndContinue() {
return;
}
- blink::mojom::ServiceWorkerRegistrationOptions options(pattern_,
- update_via_cache_);
+ blink::mojom::ServiceWorkerRegistrationOptions options(
+ pattern_, worker_script_type_, update_via_cache_);
set_registration(
new ServiceWorkerRegistration(options, registration_id, context_));
AddRegistrationToMatchingProviderHosts(registration());
@@ -355,8 +406,8 @@ void ServiceWorkerRegisterJob::UpdateAndContinue() {
// "Let worker be a new ServiceWorker object..." and start
// the worker.
- set_new_version(new ServiceWorkerVersion(registration(), script_url_,
- version_id, context_));
+ set_new_version(new ServiceWorkerVersion(
+ registration(), script_url_, worker_script_type_, version_id, context_));
new_version()->set_force_bypass_cache_for_scripts(force_bypass_cache_);
if (registration()->has_installed_version() && !skip_script_comparison_) {
new_version()->SetToPauseAfterDownload(
@@ -453,7 +504,7 @@ void ServiceWorkerRegisterJob::OnInstallFinished(
int request_id,
blink::mojom::ServiceWorkerEventStatus event_status,
bool has_fetch_handler,
- base::Time dispatch_event_time) {
+ base::TimeTicks dispatch_event_time) {
bool succeeded =
event_status == blink::mojom::ServiceWorkerEventStatus::COMPLETED;
new_version()->FinishRequest(request_id, succeeded, dispatch_event_time);
@@ -608,6 +659,7 @@ void ServiceWorkerRegisterJob::AddRegistrationToMatchingProviderHosts(
}
void ServiceWorkerRegisterJob::OnPausedAfterDownload() {
+ DCHECK(!blink::ServiceWorkerUtils::IsImportedScriptUpdateCheckEnabled());
net::URLRequestStatus status =
new_version()->script_cache_map()->main_script_status();
if (!status.is_success()) {
diff --git a/chromium/content/browser/service_worker/service_worker_register_job.h b/chromium/content/browser/service_worker/service_worker_register_job.h
index 53814919752..1b9cca0be50 100644
--- a/chromium/content/browser/service_worker/service_worker_register_job.h
+++ b/chromium/content/browser/service_worker/service_worker_register_job.h
@@ -13,6 +13,7 @@
#include "base/time/time.h"
#include "content/browser/service_worker/service_worker_register_job_base.h"
#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/browser/service_worker/service_worker_update_checker.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
@@ -105,6 +106,11 @@ class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase {
void ContinueWithUpdate(
blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
+
+ // This method is only called when ServiceWorkerImportedScriptUpdateCheck is
+ // enabled.
+ void OnUpdateCheckFinished(bool script_changed);
+
void RegisterAndContinue();
void ContinueWithUninstallingRegistration(
scoped_refptr<ServiceWorkerRegistration> existing_registration,
@@ -117,11 +123,10 @@ class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase {
void OnStoreRegistrationComplete(blink::ServiceWorkerStatusCode status);
void InstallAndContinue();
void DispatchInstallEvent(blink::ServiceWorkerStatusCode start_worker_status);
- void OnInstallFinished(
- int request_id,
- blink::mojom::ServiceWorkerEventStatus event_status,
- bool has_fetch_handler,
- base::Time dispatch_event_time);
+ void OnInstallFinished(int request_id,
+ blink::mojom::ServiceWorkerEventStatus event_status,
+ bool has_fetch_handler,
+ base::TimeTicks dispatch_event_time);
void OnInstallFailed(blink::ServiceWorkerStatusCode status);
void Complete(blink::ServiceWorkerStatusCode status);
void Complete(blink::ServiceWorkerStatusCode status,
@@ -142,9 +147,15 @@ class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase {
// The ServiceWorkerContextCore object should always outlive this.
base::WeakPtr<ServiceWorkerContextCore> context_;
+ std::unique_ptr<ServiceWorkerUpdateChecker> update_checker_;
+
RegistrationJobType job_type_;
const GURL pattern_;
GURL script_url_;
+ // "A job has a worker type ("classic" or "module")."
+ // https://w3c.github.io/ServiceWorker/#dfn-job-worker-type
+ blink::mojom::ScriptType worker_script_type_ =
+ blink::mojom::ScriptType::kClassic;
const blink::mojom::ServiceWorkerUpdateViaCache update_via_cache_;
std::vector<RegistrationCallback> callbacks_;
Phase phase_;
diff --git a/chromium/content/browser/service_worker/service_worker_registration.cc b/chromium/content/browser/service_worker/service_worker_registration.cc
index f215fd804ed..c7bec6f8845 100644
--- a/chromium/content/browser/service_worker/service_worker_registration.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration.cc
@@ -94,10 +94,10 @@ void ServiceWorkerRegistration::NotifyUpdateFound() {
}
void ServiceWorkerRegistration::NotifyVersionAttributesChanged(
- ChangedVersionAttributesMask mask) {
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr mask) {
for (auto& observer : listeners_)
- observer.OnVersionAttributesChanged(this, mask, GetInfo());
- if (mask.active_changed() || mask.waiting_changed())
+ observer.OnVersionAttributesChanged(this, mask.Clone(), GetInfo());
+ if (mask->active || mask->waiting)
NotifyRegistrationFinished();
}
@@ -121,9 +121,10 @@ void ServiceWorkerRegistration::SetActiveVersion(
should_activate_when_ready_ = false;
- ChangedVersionAttributesMask mask;
+ auto mask =
+ blink::mojom::ChangedServiceWorkerObjectsMask::New(false, false, false);
if (version)
- UnsetVersionInternal(version.get(), &mask);
+ UnsetVersionInternal(version.get(), mask.get());
if (active_version_)
active_version_->RemoveObserver(this);
active_version_ = version;
@@ -131,9 +132,9 @@ void ServiceWorkerRegistration::SetActiveVersion(
active_version_->AddObserver(this);
active_version_->SetNavigationPreloadState(navigation_preload_state_);
}
- mask.add(ChangedVersionAttributesMask::ACTIVE_VERSION);
+ mask->active = true;
- NotifyVersionAttributesChanged(mask);
+ NotifyVersionAttributesChanged(std::move(mask));
}
void ServiceWorkerRegistration::SetWaitingVersion(
@@ -143,53 +144,55 @@ void ServiceWorkerRegistration::SetWaitingVersion(
should_activate_when_ready_ = false;
- ChangedVersionAttributesMask mask;
+ auto mask =
+ blink::mojom::ChangedServiceWorkerObjectsMask::New(false, false, false);
if (version)
- UnsetVersionInternal(version.get(), &mask);
+ UnsetVersionInternal(version.get(), mask.get());
waiting_version_ = version;
- mask.add(ChangedVersionAttributesMask::WAITING_VERSION);
+ mask->waiting = true;
- NotifyVersionAttributesChanged(mask);
+ NotifyVersionAttributesChanged(std::move(mask));
}
void ServiceWorkerRegistration::SetInstallingVersion(
const scoped_refptr<ServiceWorkerVersion>& version) {
if (installing_version_ == version)
return;
-
- ChangedVersionAttributesMask mask;
+ auto mask =
+ blink::mojom::ChangedServiceWorkerObjectsMask::New(false, false, false);
if (version)
- UnsetVersionInternal(version.get(), &mask);
+ UnsetVersionInternal(version.get(), mask.get());
installing_version_ = version;
- mask.add(ChangedVersionAttributesMask::INSTALLING_VERSION);
-
- NotifyVersionAttributesChanged(mask);
+ mask->installing = true;
+ NotifyVersionAttributesChanged(std::move(mask));
}
void ServiceWorkerRegistration::UnsetVersion(ServiceWorkerVersion* version) {
if (!version)
return;
- ChangedVersionAttributesMask mask;
- UnsetVersionInternal(version, &mask);
- if (mask.changed())
- NotifyVersionAttributesChanged(mask);
+ auto mask =
+ blink::mojom::ChangedServiceWorkerObjectsMask::New(false, false, false);
+ UnsetVersionInternal(version, mask.get());
+ if (mask->installing || mask->waiting || mask->active)
+ NotifyVersionAttributesChanged(std::move(mask));
}
void ServiceWorkerRegistration::UnsetVersionInternal(
ServiceWorkerVersion* version,
- ChangedVersionAttributesMask* mask) {
+ blink::mojom::ChangedServiceWorkerObjectsMask* mask) {
DCHECK(version);
+
if (installing_version_.get() == version) {
installing_version_ = nullptr;
- mask->add(ChangedVersionAttributesMask::INSTALLING_VERSION);
+ mask->installing = true;
} else if (waiting_version_.get() == version) {
waiting_version_ = nullptr;
should_activate_when_ready_ = false;
- mask->add(ChangedVersionAttributesMask::WAITING_VERSION);
+ mask->waiting = true;
} else if (active_version_.get() == version) {
active_version_->RemoveObserver(this);
active_version_ = nullptr;
- mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION);
+ mask->active = true;
}
}
@@ -216,7 +219,7 @@ void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() {
// If the waiting worker is ready and the active worker needs to be
// swapped out, ask the active worker to trigger idle timer as soon as
// possible.
- active_version()->endpoint()->SetIdleTimerDelayToZero();
+ active_version()->TriggerIdleTerminationAsap();
}
StartLameDuckTimer();
}
@@ -299,7 +302,7 @@ void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) {
// If the waiting worker is ready and the active worker needs to be
// swapped out, ask the active worker to trigger idle timer as soon as
// possible.
- active_version()->endpoint()->SetIdleTimerDelayToZero();
+ active_version()->TriggerIdleTerminationAsap();
}
StartLameDuckTimer();
}
@@ -310,7 +313,7 @@ void ServiceWorkerRegistration::OnNoWork(ServiceWorkerVersion* version) {
return;
DCHECK_EQ(active_version(), version);
if (IsReadyToActivate())
- ActivateWaitingVersion(false /* delay */);
+ ActivateWaitingVersion(true /* delay */);
}
bool ServiceWorkerRegistration::IsReadyToActivate() const {
@@ -324,7 +327,7 @@ bool ServiceWorkerRegistration::IsReadyToActivate() const {
return true;
}
if (IsLameDuckActiveVersion()) {
- return !active->HasWorkInBrowser() ||
+ return active->HasNoWork() ||
waiting->TimeSinceSkipWaiting() > kMaxLameDuckTime ||
active->TimeSinceNoControllees() > kMaxLameDuckTime;
}
@@ -462,10 +465,10 @@ void ServiceWorkerRegistration::DeleteVersion(
}
void ServiceWorkerRegistration::NotifyRegistrationFinished() {
- std::vector<base::Closure> callbacks;
+ std::vector<base::OnceClosure> callbacks;
callbacks.swap(registration_finished_callbacks_);
- for (const auto& callback : callbacks)
- callback.Run();
+ for (auto& callback : callbacks)
+ std::move(callback).Run();
}
void ServiceWorkerRegistration::SetTaskRunnerForTest(
@@ -487,11 +490,11 @@ void ServiceWorkerRegistration::SetNavigationPreloadHeader(
}
void ServiceWorkerRegistration::RegisterRegistrationFinishedCallback(
- const base::Closure& callback) {
+ base::OnceClosure callback) {
// This should only be called if the registration is in progress.
DCHECK(!active_version() && !waiting_version() && !is_uninstalled() &&
!is_uninstalling());
- registration_finished_callbacks_.push_back(callback);
+ registration_finished_callbacks_.push_back(std::move(callback));
}
void ServiceWorkerRegistration::DispatchActivateEvent(
@@ -568,26 +571,27 @@ void ServiceWorkerRegistration::Clear() {
context_->storage()->NotifyDoneUninstallingRegistration(this);
std::vector<scoped_refptr<ServiceWorkerVersion>> versions_to_doom;
- ChangedVersionAttributesMask mask;
+ auto mask =
+ blink::mojom::ChangedServiceWorkerObjectsMask::New(false, false, false);
if (installing_version_.get()) {
versions_to_doom.push_back(installing_version_);
installing_version_ = nullptr;
- mask.add(ChangedVersionAttributesMask::INSTALLING_VERSION);
+ mask->installing = true;
}
if (waiting_version_.get()) {
versions_to_doom.push_back(waiting_version_);
waiting_version_ = nullptr;
- mask.add(ChangedVersionAttributesMask::WAITING_VERSION);
+ mask->waiting = true;
}
if (active_version_.get()) {
versions_to_doom.push_back(active_version_);
active_version_->RemoveObserver(this);
active_version_ = nullptr;
- mask.add(ChangedVersionAttributesMask::ACTIVE_VERSION);
+ mask->active = true;
}
- if (mask.changed()) {
- NotifyVersionAttributesChanged(mask);
+ if (mask->installing || mask->waiting || mask->active) {
+ NotifyVersionAttributesChanged(std::move(mask));
// Doom only after notifying attributes changed, because the spec requires
// the attributes to be cleared by the time the statechange event is
diff --git a/chromium/content/browser/service_worker/service_worker_registration.h b/chromium/content/browser/service_worker/service_worker_registration.h
index e41fa4a0af3..1d4a5295c5e 100644
--- a/chromium/content/browser/service_worker/service_worker_registration.h
+++ b/chromium/content/browser/service_worker/service_worker_registration.h
@@ -46,7 +46,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
public:
virtual void OnVersionAttributesChanged(
ServiceWorkerRegistration* registration,
- ChangedVersionAttributesMask changed_mask,
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
const ServiceWorkerRegistrationInfo& info) {}
virtual void OnUpdateViaCacheChanged(
ServiceWorkerRegistration* registation) {}
@@ -120,7 +120,8 @@ class CONTENT_EXPORT ServiceWorkerRegistration
virtual void RemoveListener(Listener* listener);
void NotifyRegistrationFailed();
void NotifyUpdateFound();
- void NotifyVersionAttributesChanged(ChangedVersionAttributesMask mask);
+ void NotifyVersionAttributesChanged(
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr mask);
ServiceWorkerRegistrationInfo GetInfo();
@@ -174,7 +175,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
// registration from storage if there is no longer a stored version.
void DeleteVersion(const scoped_refptr<ServiceWorkerVersion>& version);
- void RegisterRegistrationFinishedCallback(const base::Closure& callback);
+ void RegisterRegistrationFinishedCallback(base::OnceClosure callback);
void NotifyRegistrationFinished();
void SetTaskRunnerForTest(
@@ -193,7 +194,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
void UnsetVersionInternal(
ServiceWorkerVersion* version,
- ChangedVersionAttributesMask* mask);
+ blink::mojom::ChangedServiceWorkerObjectsMask* mask);
// ServiceWorkerVersion::Observer override.
void OnNoControllees(ServiceWorkerVersion* version) override;
@@ -244,7 +245,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
scoped_refptr<ServiceWorkerVersion> installing_version_;
base::ObserverList<Listener>::Unchecked listeners_;
- std::vector<base::Closure> registration_finished_callbacks_;
+ std::vector<base::OnceClosure> registration_finished_callbacks_;
base::WeakPtr<ServiceWorkerContextCore> context_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/chromium/content/browser/service_worker/service_worker_registration_object_host.cc b/chromium/content/browser/service_worker/service_worker_registration_object_host.cc
index 5466cd6ef11..cd59e49c117 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_object_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration_object_host.cc
@@ -4,12 +4,14 @@
#include "content/browser/service_worker/service_worker_registration_object_host.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "content/browser/service_worker/service_worker_consts.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_object_host.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/http/http_util.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
@@ -97,9 +99,16 @@ ServiceWorkerRegistrationObjectHost::~ServiceWorkerRegistrationObjectHost() {
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr
ServiceWorkerRegistrationObjectHost::CreateObjectInfo() {
+ // |info->options->script_type| is never accessed anywhere, so just set it to
+ // kClassic.
+ // TODO(asamidoi, nhiroki): Remove |options| from
+ // ServiceWorkerRegistrationObjectInfo, since |script_type| is a
+ // non-per-registration property.
+ blink::mojom::ScriptType script_type = blink::mojom::ScriptType::kClassic;
+
auto info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New();
info->options = blink::mojom::ServiceWorkerRegistrationOptions::New(
- registration_->pattern(), registration_->update_via_cache());
+ registration_->pattern(), script_type, registration_->update_via_cache());
info->registration_id = registration_->id();
bindings_.AddBinding(this, mojo::MakeRequest(&info->host_ptr_info));
info->request = mojo::MakeRequest(&remote_registration_);
@@ -115,12 +124,12 @@ ServiceWorkerRegistrationObjectHost::CreateObjectInfo() {
void ServiceWorkerRegistrationObjectHost::OnVersionAttributesChanged(
ServiceWorkerRegistration* registration,
- ChangedVersionAttributesMask changed_mask,
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
const ServiceWorkerRegistrationInfo& info) {
DCHECK_EQ(registration->id(), registration_->id());
- SetVersionAttributes(changed_mask, registration->installing_version(),
- registration->waiting_version(),
- registration->active_version());
+ SetServiceWorkerObjects(
+ std::move(changed_mask), registration->installing_version(),
+ registration->waiting_version(), registration->active_version());
}
void ServiceWorkerRegistrationObjectHost::OnUpdateViaCacheChanged(
@@ -131,11 +140,9 @@ void ServiceWorkerRegistrationObjectHost::OnUpdateViaCacheChanged(
void ServiceWorkerRegistrationObjectHost::OnRegistrationFailed(
ServiceWorkerRegistration* registration) {
DCHECK_EQ(registration->id(), registration_->id());
- ChangedVersionAttributesMask changed_mask(
- ChangedVersionAttributesMask::INSTALLING_VERSION |
- ChangedVersionAttributesMask::WAITING_VERSION |
- ChangedVersionAttributesMask::ACTIVE_VERSION);
- SetVersionAttributes(changed_mask, nullptr, nullptr, nullptr);
+ auto changed_mask =
+ blink::mojom::ChangedServiceWorkerObjectsMask::New(true, true, true);
+ SetServiceWorkerObjects(std::move(changed_mask), nullptr, nullptr, nullptr);
}
void ServiceWorkerRegistrationObjectHost::OnUpdateFound(
@@ -205,8 +212,8 @@ void ServiceWorkerRegistrationObjectHost::DelayUpdate(
return;
}
- BrowserThread::PostDelayedTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(update_function),
blink::ServiceWorkerStatusCode::kOk),
delay);
@@ -371,29 +378,30 @@ void ServiceWorkerRegistrationObjectHost::DidUpdateNavigationPreloadHeader(
base::nullopt);
}
-void ServiceWorkerRegistrationObjectHost::SetVersionAttributes(
- ChangedVersionAttributesMask changed_mask,
+void ServiceWorkerRegistrationObjectHost::SetServiceWorkerObjects(
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
ServiceWorkerVersion* installing_version,
ServiceWorkerVersion* waiting_version,
ServiceWorkerVersion* active_version) {
- if (!changed_mask.changed())
+ if (!(changed_mask->installing || changed_mask->waiting ||
+ changed_mask->active))
return;
blink::mojom::ServiceWorkerObjectInfoPtr installing;
blink::mojom::ServiceWorkerObjectInfoPtr waiting;
blink::mojom::ServiceWorkerObjectInfoPtr active;
- if (changed_mask.installing_changed()) {
+ if (changed_mask->installing) {
installing =
CreateCompleteObjectInfoToSend(provider_host_, installing_version);
}
- if (changed_mask.waiting_changed())
+ if (changed_mask->waiting)
waiting = CreateCompleteObjectInfoToSend(provider_host_, waiting_version);
- if (changed_mask.active_changed())
+ if (changed_mask->active)
active = CreateCompleteObjectInfoToSend(provider_host_, active_version);
DCHECK(remote_registration_);
- remote_registration_->SetVersionAttributes(
- changed_mask.changed(), std::move(installing), std::move(waiting),
+ remote_registration_->SetServiceWorkerObjects(
+ std::move(changed_mask), std::move(installing), std::move(waiting),
std::move(active));
}
diff --git a/chromium/content/browser/service_worker/service_worker_registration_object_host.h b/chromium/content/browser/service_worker/service_worker_registration_object_host.h
index cfca9b43e02..db6c5f85ec3 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_object_host.h
+++ b/chromium/content/browser/service_worker/service_worker_registration_object_host.h
@@ -58,7 +58,7 @@ class CONTENT_EXPORT ServiceWorkerRegistrationObjectHost
// ServiceWorkerRegistration::Listener overrides.
void OnVersionAttributesChanged(
ServiceWorkerRegistration* registration,
- ChangedVersionAttributesMask changed_mask,
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
const ServiceWorkerRegistrationInfo& info) override;
void OnUpdateViaCacheChanged(
ServiceWorkerRegistration* registration) override;
@@ -115,10 +115,11 @@ class CONTENT_EXPORT ServiceWorkerRegistrationObjectHost
// Sets the corresponding version field to the given version or if the given
// version is nullptr, clears the field.
- void SetVersionAttributes(ChangedVersionAttributesMask changed_mask,
- ServiceWorkerVersion* installing_version,
- ServiceWorkerVersion* waiting_version,
- ServiceWorkerVersion* active_version);
+ void SetServiceWorkerObjects(
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
+ ServiceWorkerVersion* installing_version,
+ ServiceWorkerVersion* waiting_version,
+ ServiceWorkerVersion* active_version);
void OnConnectionError();
diff --git a/chromium/content/browser/service_worker/service_worker_registration_unittest.cc b/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
index 62bf488958e..4c9120a1791 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -11,6 +11,7 @@
#include "base/compiler_specific.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -27,6 +28,7 @@
#include "content/test/test_content_browser_client.h"
#include "mojo/core/embedder/embedder.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
#include "url/gurl.h"
@@ -80,7 +82,9 @@ class MockServiceWorkerRegistrationObject
int set_update_via_cache_called_count() const {
return set_update_via_cache_called_count_;
}
- int changed_mask() const { return changed_mask_; }
+ const blink::mojom::ChangedServiceWorkerObjectsMask& changed_mask() const {
+ return *changed_mask_;
+ }
const blink::mojom::ServiceWorkerObjectInfoPtr& installing() const {
return installing_;
}
@@ -96,13 +100,13 @@ class MockServiceWorkerRegistrationObject
private:
// Implements blink::mojom::ServiceWorkerRegistrationObject.
- void SetVersionAttributes(
- int changed_mask,
+ void SetServiceWorkerObjects(
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
blink::mojom::ServiceWorkerObjectInfoPtr installing,
blink::mojom::ServiceWorkerObjectInfoPtr waiting,
blink::mojom::ServiceWorkerObjectInfoPtr active) override {
set_version_attributes_called_count_++;
- changed_mask_ = changed_mask;
+ changed_mask_ = std::move(changed_mask);
installing_ = std::move(installing);
waiting_ = std::move(waiting);
active_ = std::move(active);
@@ -117,7 +121,7 @@ class MockServiceWorkerRegistrationObject
int update_found_called_count_ = 0;
int set_version_attributes_called_count_ = 0;
int set_update_via_cache_called_count_ = 0;
- int changed_mask_ = 0;
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask_;
blink::mojom::ServiceWorkerObjectInfoPtr installing_;
blink::mojom::ServiceWorkerObjectInfoPtr waiting_;
blink::mojom::ServiceWorkerObjectInfoPtr active_;
@@ -132,14 +136,36 @@ class MockServiceWorkerRegistrationObject
// will be terminated when SetIdleTimerDelayToZero() is called.
class RegistrationTestHelper : public EmbeddedWorkerTestHelper {
public:
- RegistrationTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
+ RegistrationTestHelper()
+ : EmbeddedWorkerTestHelper(base::FilePath()), weak_factory_(this) {}
~RegistrationTestHelper() override = default;
+ void RequestTermination(int embedded_worker_id) {
+ GetEmbeddedWorkerInstanceHost(embedded_worker_id)
+ ->RequestTermination(
+ base::BindOnce(&RegistrationTestHelper::OnRequestedTermination,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ const base::Optional<bool>& will_be_terminated() const {
+ return will_be_terminated_;
+ }
+
+ bool is_zero_idle_timer_delay() const { return is_zero_idle_timer_delay_; }
+
protected:
void OnSetIdleTimerDelayToZero(int embedded_worker_id) override {
- GetEmbeddedWorkerInstanceHost(embedded_worker_id)
- ->RequestTermination(base::DoNothing());
+ is_zero_idle_timer_delay_ = true;
+ }
+
+ void OnRequestedTermination(bool will_be_terminated) {
+ will_be_terminated_ = will_be_terminated;
}
+
+ private:
+ bool is_zero_idle_timer_delay_ = false;
+ base::Optional<bool> will_be_terminated_;
+ base::WeakPtrFactory<RegistrationTestHelper> weak_factory_;
};
class ServiceWorkerRegistrationTest : public testing::Test {
@@ -172,10 +198,10 @@ class ServiceWorkerRegistrationTest : public testing::Test {
void OnVersionAttributesChanged(
ServiceWorkerRegistration* registration,
- ChangedVersionAttributesMask changed_mask,
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
const ServiceWorkerRegistrationInfo& info) override {
observed_registration_ = registration;
- observed_changed_mask_ = changed_mask;
+ observed_changed_mask_ = std::move(changed_mask);
observed_info_ = info;
}
@@ -190,17 +216,17 @@ class ServiceWorkerRegistrationTest : public testing::Test {
void Reset() {
observed_registration_ = nullptr;
- observed_changed_mask_ = ChangedVersionAttributesMask();
+ observed_changed_mask_ = nullptr;
observed_info_ = ServiceWorkerRegistrationInfo();
}
scoped_refptr<ServiceWorkerRegistration> observed_registration_;
- ChangedVersionAttributesMask observed_changed_mask_;
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr observed_changed_mask_;
ServiceWorkerRegistrationInfo observed_info_;
};
protected:
- std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
+ std::unique_ptr<RegistrationTestHelper> helper_;
TestBrowserThreadBundle thread_bundle_;
};
@@ -219,10 +245,12 @@ TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
const int64_t version_2_id = 2L;
scoped_refptr<ServiceWorkerVersion> version_1 =
base::MakeRefCounted<ServiceWorkerVersion>(
- registration.get(), kScript, version_1_id, context()->AsWeakPtr());
+ registration.get(), kScript, blink::mojom::ScriptType::kClassic,
+ version_1_id, context()->AsWeakPtr());
scoped_refptr<ServiceWorkerVersion> version_2 =
base::MakeRefCounted<ServiceWorkerVersion>(
- registration.get(), kScript, version_2_id, context()->AsWeakPtr());
+ registration.get(), kScript, blink::mojom::ScriptType::kClassic,
+ version_2_id, context()->AsWeakPtr());
RegistrationListener listener;
registration->AddListener(&listener);
@@ -230,8 +258,7 @@ TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
EXPECT_EQ(version_1.get(), registration->active_version());
EXPECT_EQ(registration, listener.observed_registration_);
- EXPECT_EQ(ChangedVersionAttributesMask::ACTIVE_VERSION,
- listener.observed_changed_mask_.changed());
+ EXPECT_TRUE(listener.observed_changed_mask_->active);
EXPECT_EQ(kScope, listener.observed_info_.pattern);
EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
EXPECT_EQ(kScript, listener.observed_info_.active_version.script_url);
@@ -244,8 +271,7 @@ TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
registration->SetInstallingVersion(version_2);
EXPECT_EQ(version_2.get(), registration->installing_version());
- EXPECT_EQ(ChangedVersionAttributesMask::INSTALLING_VERSION,
- listener.observed_changed_mask_.changed());
+ EXPECT_TRUE(listener.observed_changed_mask_->installing);
EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
EXPECT_EQ(version_2_id,
listener.observed_info_.installing_version.version_id);
@@ -257,8 +283,8 @@ TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
EXPECT_EQ(version_2.get(), registration->waiting_version());
EXPECT_FALSE(registration->installing_version());
- EXPECT_TRUE(listener.observed_changed_mask_.waiting_changed());
- EXPECT_TRUE(listener.observed_changed_mask_.installing_changed());
+ EXPECT_TRUE(listener.observed_changed_mask_->waiting);
+ EXPECT_TRUE(listener.observed_changed_mask_->installing);
EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
EXPECT_EQ(version_2_id, listener.observed_info_.waiting_version.version_id);
EXPECT_EQ(listener.observed_info_.installing_version.version_id,
@@ -268,8 +294,7 @@ TEST_F(ServiceWorkerRegistrationTest, SetAndUnsetVersions) {
registration->UnsetVersion(version_2.get());
EXPECT_FALSE(registration->waiting_version());
- EXPECT_EQ(ChangedVersionAttributesMask::WAITING_VERSION,
- listener.observed_changed_mask_.changed());
+ EXPECT_TRUE(listener.observed_changed_mask_->waiting);
EXPECT_EQ(version_1_id, listener.observed_info_.active_version.version_id);
EXPECT_EQ(listener.observed_info_.waiting_version.version_id,
blink::mojom::kInvalidServiceWorkerVersionId);
@@ -316,17 +341,17 @@ TEST_F(ServiceWorkerRegistrationTest, NavigationPreload) {
base::MakeRefCounted<ServiceWorkerRegistration>(
options, storage()->NewRegistrationId(), context()->AsWeakPtr());
scoped_refptr<ServiceWorkerVersion> version_1 =
- base::MakeRefCounted<ServiceWorkerVersion>(registration.get(), kScript,
- storage()->NewVersionId(),
- context()->AsWeakPtr());
+ base::MakeRefCounted<ServiceWorkerVersion>(
+ registration.get(), kScript, blink::mojom::ScriptType::kClassic,
+ storage()->NewVersionId(), context()->AsWeakPtr());
version_1->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
registration->SetActiveVersion(version_1);
version_1->SetStatus(ServiceWorkerVersion::ACTIVATED);
scoped_refptr<ServiceWorkerVersion> version_2 =
- base::MakeRefCounted<ServiceWorkerVersion>(registration.get(), kScript,
- storage()->NewVersionId(),
- context()->AsWeakPtr());
+ base::MakeRefCounted<ServiceWorkerVersion>(
+ registration.get(), kScript, blink::mojom::ScriptType::kClassic,
+ storage()->NewVersionId(), context()->AsWeakPtr());
version_2->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
registration->SetWaitingVersion(version_2);
@@ -348,7 +373,8 @@ TEST_F(ServiceWorkerRegistrationTest, NavigationPreload) {
// Sets up a registration with a waiting worker, and an active worker
// with a controllee and an inflight request.
-class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest {
+class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest,
+ public testing::WithParamInterface<bool> {
public:
ServiceWorkerActivationTest() : ServiceWorkerRegistrationTest() {}
@@ -365,9 +391,9 @@ class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest {
// Create an active version.
scoped_refptr<ServiceWorkerVersion> version_1 =
- base::MakeRefCounted<ServiceWorkerVersion>(registration_.get(), kScript,
- storage()->NewVersionId(),
- context()->AsWeakPtr());
+ base::MakeRefCounted<ServiceWorkerVersion>(
+ registration_.get(), kScript, blink::mojom::ScriptType::kClassic,
+ storage()->NewVersionId(), context()->AsWeakPtr());
version_1->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
registration_->SetActiveVersion(version_1);
@@ -403,9 +429,9 @@ class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest {
// Create a waiting version.
scoped_refptr<ServiceWorkerVersion> version_2 =
- base::MakeRefCounted<ServiceWorkerVersion>(registration_.get(), kScript,
- storage()->NewVersionId(),
- context()->AsWeakPtr());
+ base::MakeRefCounted<ServiceWorkerVersion>(
+ registration_.get(), kScript, blink::mojom::ScriptType::kClassic,
+ storage()->NewVersionId(), context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records_2;
records_2.push_back(WriteToDiskCacheSync(
helper_->context()->storage(), version_2->script_url(),
@@ -426,6 +452,12 @@ class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest {
registration_->ActivateWaitingVersionWhenReady();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(version_1.get(), registration_->active_version());
+
+ if (devtools_should_be_attached()) {
+ // Attach DevTools to the active worker. This shouldn't prevent from
+ // promoting the waiting worker to active.
+ version_1->SetDevToolsAttached(true);
+ }
}
void TearDown() override {
@@ -433,6 +465,8 @@ class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest {
ServiceWorkerRegistrationTest::TearDown();
}
+ bool devtools_should_be_attached() const { return GetParam(); }
+
ServiceWorkerRegistration* registration() { return registration_.get(); }
ServiceWorkerProviderHost* controllee() { return host_.get(); }
int inflight_request_id() const { return inflight_request_id_; }
@@ -450,10 +484,19 @@ class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest {
// error like ServiceWorkerContext shutdown.
void SimulateSkipWaiting(ServiceWorkerVersion* version,
base::Optional<bool>* out_result) {
- version->SkipWaiting(
- base::BindOnce([](base::Optional<bool>* out_result,
- bool success) { *out_result = success; },
- out_result));
+ SimulateSkipWaitingWithCallback(version, out_result, base::DoNothing());
+ }
+
+ void SimulateSkipWaitingWithCallback(ServiceWorkerVersion* version,
+ base::Optional<bool>* out_result,
+ base::OnceClosure done_callback) {
+ version->SkipWaiting(base::BindOnce(
+ [](base::OnceClosure done_callback, base::Optional<bool>* out_result,
+ bool success) {
+ *out_result = success;
+ std::move(done_callback).Run();
+ },
+ std::move(done_callback), out_result));
base::RunLoop().RunUntilIdle();
}
@@ -465,26 +508,43 @@ class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest {
};
// Test activation triggered by finishing all requests.
-TEST_F(ServiceWorkerActivationTest, NoInflightRequest) {
+TEST_P(ServiceWorkerActivationTest, NoInflightRequest) {
scoped_refptr<ServiceWorkerRegistration> reg = registration();
scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
// Remove the controllee. Since there is an in-flight request,
// activation should not yet happen.
+ // When S13nServiceWorker is on, the idle timer living in the renderer is
+ // requested to notify the browser the idle state ASAP.
version_1->RemoveControllee(controllee()->client_uuid());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(version_1.get(), reg->active_version());
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
+ EXPECT_TRUE(helper_->is_zero_idle_timer_delay());
// Finish the request. Activation should happen.
version_1->FinishRequest(inflight_request_id(), true /* was_handled */,
- base::Time::Now());
+ base::TimeTicks::Now());
base::RunLoop().RunUntilIdle();
+
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ EXPECT_EQ(version_1.get(), reg->active_version());
+ helper_->RequestTermination(
+ version_1->embedded_worker()->embedded_worker_id());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(helper_->will_be_terminated().value());
+ }
+
EXPECT_EQ(version_2.get(), reg->active_version());
}
// Test activation triggered by loss of controllee.
-TEST_F(ServiceWorkerActivationTest, NoControllee) {
+TEST_P(ServiceWorkerActivationTest, NoControllee) {
+ // S13nServiceWorker: activation only happens when the service worker reports
+ // it's idle, so this test doesn't make sense.
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
+ return;
scoped_refptr<ServiceWorkerRegistration> reg = registration();
scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
@@ -492,7 +552,7 @@ TEST_F(ServiceWorkerActivationTest, NoControllee) {
// Finish the request. Since there is a controllee, activation should not yet
// happen.
version_1->FinishRequest(inflight_request_id(), true /* was_handled */,
- base::Time::Now());
+ base::TimeTicks::Now());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(version_1.get(), reg->active_version());
@@ -502,50 +562,88 @@ TEST_F(ServiceWorkerActivationTest, NoControllee) {
EXPECT_EQ(version_2.get(), reg->active_version());
}
-// Test activation triggered by skipWaiting.
-TEST_F(ServiceWorkerActivationTest, SkipWaiting) {
+// Test activation triggered by skipWaiting and finishing requests.
+TEST_P(ServiceWorkerActivationTest, SkipWaitingWithInflightRequest) {
scoped_refptr<ServiceWorkerRegistration> reg = registration();
scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
- // Finish the in-flight request. Since there is a controllee,
+ base::Optional<bool> result;
+ base::RunLoop skip_waiting_loop;
+ // Set skip waiting flag. Since there is still an in-flight request,
// activation should not happen.
- version_1->FinishRequest(inflight_request_id(), true /* was_handled */,
- base::Time::Now());
- base::RunLoop().RunUntilIdle();
+ SimulateSkipWaitingWithCallback(version_2.get(), &result,
+ skip_waiting_loop.QuitClosure());
+ EXPECT_FALSE(result.has_value());
EXPECT_EQ(version_1.get(), reg->active_version());
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
+ EXPECT_TRUE(helper_->is_zero_idle_timer_delay());
+
+ // Finish the request.
+ // non-S13nServiceWorker: The service worker becomes idle.
+ // S13nServiceWorker: FinishRequest() doesn't immediately make the worker
+ // "no work" state. It needs to be notfied the idle state by
+ // RequestTermination().
+ version_1->FinishRequest(inflight_request_id(), true /* was_handled */,
+ base::TimeTicks::Now());
+
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ EXPECT_EQ(version_1.get(), reg->active_version());
+ helper_->RequestTermination(
+ version_1->embedded_worker()->embedded_worker_id());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(helper_->will_be_terminated().value());
+ }
+
+ // Wait until SkipWaiting resolves.
+ skip_waiting_loop.Run();
- // Call skipWaiting. Activation should happen.
- base::Optional<bool> result;
- SimulateSkipWaiting(version_2.get(), &result);
EXPECT_TRUE(result.has_value());
EXPECT_TRUE(*result);
EXPECT_EQ(version_2.get(), reg->active_version());
}
-// Test activation triggered by skipWaiting and finishing requests.
-TEST_F(ServiceWorkerActivationTest, SkipWaitingWithInflightRequest) {
+// Test activation triggered by skipWaiting.
+TEST_P(ServiceWorkerActivationTest, SkipWaiting) {
scoped_refptr<ServiceWorkerRegistration> reg = registration();
scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
- base::Optional<bool> result;
- // Set skip waiting flag. Since there is still an in-flight request,
+ // Finish the in-flight request. Since there is a controllee,
// activation should not happen.
- SimulateSkipWaiting(version_2.get(), &result);
- EXPECT_FALSE(result.has_value());
- EXPECT_EQ(version_1.get(), reg->active_version());
-
- // Finish the request. Activation should happen.
version_1->FinishRequest(inflight_request_id(), true /* was_handled */,
- base::Time::Now());
+ base::TimeTicks::Now());
base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(version_1.get(), reg->active_version());
+
+ // Call skipWaiting.
+ // non-S13nServiceWorker: Activation should happen.
+ // S13nServiceWorker: Activation should happen after RequestTermination is
+ // triggered.
+ base::Optional<bool> result;
+ base::RunLoop skip_waiting_loop;
+ SimulateSkipWaitingWithCallback(version_2.get(), &result,
+ skip_waiting_loop.QuitClosure());
+
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ EXPECT_TRUE(helper_->is_zero_idle_timer_delay());
+ EXPECT_FALSE(result.has_value());
+ EXPECT_EQ(version_1.get(), reg->active_version());
+ helper_->RequestTermination(
+ version_1->embedded_worker()->embedded_worker_id());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(helper_->will_be_terminated().value());
+ }
+
+ // Wait until SkipWaiting resolves.
+ skip_waiting_loop.Run();
+
EXPECT_TRUE(result.has_value());
EXPECT_TRUE(*result);
EXPECT_EQ(version_2.get(), reg->active_version());
}
-TEST_F(ServiceWorkerActivationTest, TimeSinceSkipWaiting_Installing) {
+TEST_P(ServiceWorkerActivationTest, TimeSinceSkipWaiting_Installing) {
scoped_refptr<ServiceWorkerRegistration> reg = registration();
scoped_refptr<ServiceWorkerVersion> version = reg->waiting_version();
base::SimpleTestTickClock clock;
@@ -580,7 +678,7 @@ TEST_F(ServiceWorkerActivationTest, TimeSinceSkipWaiting_Installing) {
}
// Test lame duck timer triggered by skip waiting.
-TEST_F(ServiceWorkerActivationTest, LameDuckTime_SkipWaiting) {
+TEST_P(ServiceWorkerActivationTest, LameDuckTime_SkipWaiting) {
scoped_refptr<ServiceWorkerRegistration> reg = registration();
scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
@@ -613,7 +711,7 @@ TEST_F(ServiceWorkerActivationTest, LameDuckTime_SkipWaiting) {
}
// Test lame duck timer triggered by loss of controllee.
-TEST_F(ServiceWorkerActivationTest, LameDuckTime_NoControllee) {
+TEST_P(ServiceWorkerActivationTest, LameDuckTime_NoControllee) {
scoped_refptr<ServiceWorkerRegistration> reg = registration();
scoped_refptr<ServiceWorkerVersion> version_1 = reg->active_version();
scoped_refptr<ServiceWorkerVersion> version_2 = reg->waiting_version();
@@ -667,6 +765,10 @@ TEST_F(ServiceWorkerActivationTest, LameDuckTime_NoControllee) {
EXPECT_FALSE(IsLameDuckTimerRunning());
}
+INSTANTIATE_TEST_CASE_P(ServiceWorkerActivationTestWithDevTools,
+ ServiceWorkerActivationTest,
+ testing::Bool());
+
// Sets up a registration with a ServiceWorkerRegistrationObjectHost to hold it.
class ServiceWorkerRegistrationObjectHostTest
: public ServiceWorkerRegistrationTest {
@@ -764,9 +866,9 @@ class ServiceWorkerRegistrationObjectHostTest
ServiceWorkerRegistration* registration,
const GURL& script_url) {
scoped_refptr<ServiceWorkerVersion> version =
- base::MakeRefCounted<ServiceWorkerVersion>(registration, script_url,
- storage()->NewVersionId(),
- context()->AsWeakPtr());
+ base::MakeRefCounted<ServiceWorkerVersion>(
+ registration, script_url, blink::mojom::ScriptType::kClassic,
+ storage()->NewVersionId(), context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
records.push_back(WriteToDiskCacheSync(
storage(), version->script_url(), storage()->NewResourceId(),
@@ -1119,81 +1221,67 @@ TEST_F(ServiceWorkerRegistrationObjectHostTest, SetVersionAttributes) {
const int64_t version_2_id = 2L;
scoped_refptr<ServiceWorkerVersion> version_1 =
base::MakeRefCounted<ServiceWorkerVersion>(
- registration, kScriptUrl, version_1_id, context()->AsWeakPtr());
+ registration, kScriptUrl, blink::mojom::ScriptType::kClassic,
+ version_1_id, context()->AsWeakPtr());
scoped_refptr<ServiceWorkerVersion> version_2 =
base::MakeRefCounted<ServiceWorkerVersion>(
- registration, kScriptUrl, version_2_id, context()->AsWeakPtr());
+ registration, kScriptUrl, blink::mojom::ScriptType::kClassic,
+ version_2_id, context()->AsWeakPtr());
// Set an active worker.
- {
- registration->SetActiveVersion(version_1);
- EXPECT_EQ(version_1.get(), registration->active_version());
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(1,
- mock_registration_object->set_version_attributes_called_count());
- ChangedVersionAttributesMask mask(mock_registration_object->changed_mask());
- EXPECT_FALSE(mask.installing_changed());
- EXPECT_FALSE(mock_registration_object->installing());
- EXPECT_FALSE(mask.waiting_changed());
- EXPECT_FALSE(mock_registration_object->waiting());
- EXPECT_TRUE(mask.active_changed());
- EXPECT_TRUE(mock_registration_object->active());
- EXPECT_EQ(version_1_id, mock_registration_object->active()->version_id);
- EXPECT_EQ(kScriptUrl, mock_registration_object->active()->url);
- }
+ registration->SetActiveVersion(version_1);
+ EXPECT_EQ(version_1.get(), registration->active_version());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, mock_registration_object->set_version_attributes_called_count());
+ EXPECT_FALSE(mock_registration_object->changed_mask().installing);
+ EXPECT_FALSE(mock_registration_object->installing());
+ EXPECT_FALSE(mock_registration_object->changed_mask().waiting);
+ EXPECT_FALSE(mock_registration_object->waiting());
+ EXPECT_TRUE(mock_registration_object->changed_mask().active);
+ EXPECT_TRUE(mock_registration_object->active());
+ EXPECT_EQ(version_1_id, mock_registration_object->active()->version_id);
+ EXPECT_EQ(kScriptUrl, mock_registration_object->active()->url);
// Set an installing worker.
- {
- registration->SetInstallingVersion(version_2);
- EXPECT_EQ(version_2.get(), registration->installing_version());
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(2,
- mock_registration_object->set_version_attributes_called_count());
- ChangedVersionAttributesMask mask(mock_registration_object->changed_mask());
- EXPECT_TRUE(mask.installing_changed());
- EXPECT_TRUE(mock_registration_object->installing());
- EXPECT_FALSE(mask.waiting_changed());
- EXPECT_FALSE(mock_registration_object->waiting());
- EXPECT_FALSE(mask.active_changed());
- EXPECT_FALSE(mock_registration_object->active());
- EXPECT_EQ(version_2_id, mock_registration_object->installing()->version_id);
- EXPECT_EQ(kScriptUrl, mock_registration_object->installing()->url);
- }
+ registration->SetInstallingVersion(version_2);
+ EXPECT_EQ(version_2.get(), registration->installing_version());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(2, mock_registration_object->set_version_attributes_called_count());
+ EXPECT_TRUE(mock_registration_object->changed_mask().installing);
+ EXPECT_TRUE(mock_registration_object->installing());
+ EXPECT_FALSE(mock_registration_object->changed_mask().waiting);
+ EXPECT_FALSE(mock_registration_object->waiting());
+ EXPECT_FALSE(mock_registration_object->changed_mask().active);
+ EXPECT_FALSE(mock_registration_object->active());
+ EXPECT_EQ(version_2_id, mock_registration_object->installing()->version_id);
+ EXPECT_EQ(kScriptUrl, mock_registration_object->installing()->url);
// Promote the installing worker to waiting.
- {
- registration->SetWaitingVersion(version_2);
- EXPECT_EQ(version_2.get(), registration->waiting_version());
- EXPECT_FALSE(registration->installing_version());
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(3,
- mock_registration_object->set_version_attributes_called_count());
- ChangedVersionAttributesMask mask(mock_registration_object->changed_mask());
- EXPECT_TRUE(mask.installing_changed());
- EXPECT_FALSE(mock_registration_object->installing());
- EXPECT_TRUE(mask.waiting_changed());
- EXPECT_TRUE(mock_registration_object->waiting());
- EXPECT_FALSE(mask.active_changed());
- EXPECT_FALSE(mock_registration_object->active());
- EXPECT_EQ(version_2_id, mock_registration_object->waiting()->version_id);
- EXPECT_EQ(kScriptUrl, mock_registration_object->waiting()->url);
- }
+ registration->SetWaitingVersion(version_2);
+ EXPECT_EQ(version_2.get(), registration->waiting_version());
+ EXPECT_FALSE(registration->installing_version());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(3, mock_registration_object->set_version_attributes_called_count());
+ EXPECT_TRUE(mock_registration_object->changed_mask().installing);
+ EXPECT_FALSE(mock_registration_object->installing());
+ EXPECT_TRUE(mock_registration_object->changed_mask().waiting);
+ EXPECT_TRUE(mock_registration_object->waiting());
+ EXPECT_FALSE(mock_registration_object->changed_mask().active);
+ EXPECT_FALSE(mock_registration_object->active());
+ EXPECT_EQ(version_2_id, mock_registration_object->waiting()->version_id);
+ EXPECT_EQ(kScriptUrl, mock_registration_object->waiting()->url);
// Remove the waiting worker.
- {
- registration->UnsetVersion(version_2.get());
- EXPECT_FALSE(registration->waiting_version());
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(4,
- mock_registration_object->set_version_attributes_called_count());
- ChangedVersionAttributesMask mask(mock_registration_object->changed_mask());
- EXPECT_FALSE(mask.installing_changed());
- EXPECT_FALSE(mock_registration_object->installing());
- EXPECT_TRUE(mask.waiting_changed());
- EXPECT_FALSE(mock_registration_object->waiting());
- EXPECT_FALSE(mask.active_changed());
- EXPECT_FALSE(mock_registration_object->active());
- }
+ registration->UnsetVersion(version_2.get());
+ EXPECT_FALSE(registration->waiting_version());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(4, mock_registration_object->set_version_attributes_called_count());
+ EXPECT_FALSE(mock_registration_object->changed_mask().installing);
+ EXPECT_FALSE(mock_registration_object->installing());
+ EXPECT_TRUE(mock_registration_object->changed_mask().waiting);
+ EXPECT_FALSE(mock_registration_object->waiting());
+ EXPECT_FALSE(mock_registration_object->changed_mask().active);
+ EXPECT_FALSE(mock_registration_object->active());
}
TEST_F(ServiceWorkerRegistrationObjectHostTest, SetUpdateViaCache) {
diff --git a/chromium/content/browser/service_worker/service_worker_request_handler.cc b/chromium/content/browser/service_worker/service_worker_request_handler.cc
index e72645e490f..e768de507e1 100644
--- a/chromium/content/browser/service_worker/service_worker_request_handler.cc
+++ b/chromium/content/browser/service_worker/service_worker_request_handler.cc
@@ -78,7 +78,7 @@ void ServiceWorkerRequestHandler::InitializeForNavigation(
storage::BlobStorageContext* blob_storage_context,
bool skip_service_worker,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
bool is_parent_frame_secure,
scoped_refptr<network::ResourceRequestBody> body,
@@ -142,17 +142,19 @@ ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
storage::BlobStorageContext* blob_storage_context,
bool skip_service_worker,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
bool is_parent_frame_secure,
scoped_refptr<network::ResourceRequestBody> body,
- const base::Callback<WebContents*(void)>& web_contents_getter) {
+ const base::Callback<WebContents*(void)>& web_contents_getter,
+ base::WeakPtr<ServiceWorkerProviderHost>* out_provider_host) {
DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
DCHECK(navigation_handle_core);
// Create the handler even for insecure HTTP since it's used in the
// case of redirect to HTTPS.
- if (!url.SchemeIsHTTPOrHTTPS() && !OriginCanAccessServiceWorkers(url)) {
+ if (!url.SchemeIsHTTPOrHTTPS() && !OriginCanAccessServiceWorkers(url) &&
+ !SchemeMaySupportRedirectingToHTTPS(url)) {
return nullptr;
}
@@ -164,21 +166,22 @@ ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
return nullptr;
// Initialize the SWProviderHost.
- base::WeakPtr<ServiceWorkerProviderHost> provider_host =
+ *out_provider_host =
ServiceWorkerProviderHost::PreCreateNavigationHost(
context->AsWeakPtr(), is_parent_frame_secure, web_contents_getter);
std::unique_ptr<ServiceWorkerRequestHandler> handler(
- provider_host->CreateRequestHandler(
- network::mojom::FetchRequestMode::kNavigate,
- network::mojom::FetchCredentialsMode::kInclude,
- network::mojom::FetchRedirectMode::kManual,
- std::string() /* integrity */, false /* keepalive */, resource_type,
- request_context_type, frame_type, blob_storage_context->AsWeakPtr(),
- body, skip_service_worker));
+ (*out_provider_host)
+ ->CreateRequestHandler(
+ network::mojom::FetchRequestMode::kNavigate,
+ network::mojom::FetchCredentialsMode::kInclude,
+ network::mojom::FetchRedirectMode::kManual,
+ std::string() /* integrity */, false /* keepalive */,
+ resource_type, request_context_type, frame_type,
+ blob_storage_context->AsWeakPtr(), body, skip_service_worker));
navigation_handle_core->DidPreCreateProviderHost(
- provider_host->provider_id());
+ (*out_provider_host)->provider_id());
return base::WrapUnique<NavigationLoaderInterceptor>(handler.release());
}
@@ -203,7 +206,8 @@ ServiceWorkerRequestHandler::InitializeForSharedWorker(
resource_request.fetch_credentials_mode,
resource_request.fetch_redirect_mode,
resource_request.fetch_integrity, resource_request.keepalive,
- RESOURCE_TYPE_SHARED_WORKER, REQUEST_CONTEXT_TYPE_SHARED_WORKER,
+ RESOURCE_TYPE_SHARED_WORKER,
+ blink::mojom::RequestContextType::SHARED_WORKER,
resource_request.fetch_frame_type,
nullptr /* blob_storage_context: unused in S13n */,
resource_request.request_body, resource_request.skip_service_worker));
@@ -225,7 +229,7 @@ void ServiceWorkerRequestHandler::InitializeHandler(
const std::string& integrity,
bool keepalive,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
scoped_refptr<network::ResourceRequestBody> body) {
// S13nServiceWorker enabled, NetworkService disabled:
diff --git a/chromium/content/browser/service_worker/service_worker_request_handler.h b/chromium/content/browser/service_worker/service_worker_request_handler.h
index 41132905487..370fc7f36be 100644
--- a/chromium/content/browser/service_worker/service_worker_request_handler.h
+++ b/chromium/content/browser/service_worker/service_worker_request_handler.h
@@ -15,12 +15,12 @@
#include "content/browser/loader/navigation_loader_interceptor.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "net/url_request/url_request_job_factory.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
namespace net {
class NetworkDelegate;
@@ -60,7 +60,7 @@ class CONTENT_EXPORT ServiceWorkerRequestHandler
storage::BlobStorageContext* blob_storage_context,
bool skip_service_worker,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
bool is_parent_frame_secure,
scoped_refptr<network::ResourceRequestBody> body,
@@ -77,11 +77,12 @@ class CONTENT_EXPORT ServiceWorkerRequestHandler
storage::BlobStorageContext* blob_storage_context,
bool skip_service_worker,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
bool is_parent_frame_secure,
scoped_refptr<network::ResourceRequestBody> body,
- const base::Callback<WebContents*(void)>& web_contents_getter);
+ const base::Callback<WebContents*(void)>& web_contents_getter,
+ base::WeakPtr<ServiceWorkerProviderHost>* out_provider_host);
static std::unique_ptr<NavigationLoaderInterceptor> InitializeForSharedWorker(
const network::ResourceRequest& resource_request,
@@ -106,7 +107,7 @@ class CONTENT_EXPORT ServiceWorkerRequestHandler
const std::string& integrity,
bool keepalive,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
scoped_refptr<network::ResourceRequestBody> body);
diff --git a/chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc b/chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc
index 2aaa2c7e9ee..7c5d2c574de 100644
--- a/chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
@@ -14,7 +15,7 @@
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/common/service_worker/service_worker_utils.h"
-#include "content/public/common/request_context_type.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/common/resource_type.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
@@ -26,6 +27,7 @@
#include "storage/browser/blob/blob_storage_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
namespace content {
namespace service_worker_request_handler_unittest {
@@ -63,8 +65,8 @@ class ServiceWorkerRequestHandlerTest : public testing::Test {
static std::unique_ptr<ServiceWorkerNavigationHandleCore>
CreateNavigationHandleCore(ServiceWorkerContextWrapper* context_wrapper) {
std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core;
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
[](ServiceWorkerContextWrapper* wrapper) {
return std::make_unique<ServiceWorkerNavigationHandleCore>(
@@ -101,7 +103,7 @@ class ServiceWorkerRequestHandlerTest : public testing::Test {
network::mojom::FetchCredentialsMode::kOmit,
network::mojom::FetchRedirectMode::kFollow,
std::string() /* integrity */, false /* keepalive */, resource_type,
- REQUEST_CONTEXT_TYPE_HYPERLINK,
+ blink::mojom::RequestContextType::HYPERLINK,
network::mojom::RequestContextFrameType::kTopLevel, nullptr);
}
@@ -155,7 +157,7 @@ class ServiceWorkerRequestHandlerTest : public testing::Test {
ServiceWorkerRequestHandler::InitializeForNavigation(
request.get(), navigation_handle_core.get(), &blob_storage_context_,
false /* skip_service_worker */, RESOURCE_TYPE_MAIN_FRAME,
- REQUEST_CONTEXT_TYPE_HYPERLINK,
+ blink::mojom::RequestContextType::HYPERLINK,
network::mojom::RequestContextFrameType::kTopLevel,
true /* is_parent_frame_secure */, nullptr /* body */,
base::RepeatingCallback<WebContents*(void)>());
@@ -167,15 +169,17 @@ class ServiceWorkerRequestHandlerTest : public testing::Test {
bool expected_handler_created) {
std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core =
CreateNavigationHandleCore(helper_->context_wrapper());
+ base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host;
std::unique_ptr<NavigationLoaderInterceptor> interceptor =
ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
GURL(url), nullptr /* resource_context */,
navigation_handle_core.get(), &blob_storage_context_,
false /* skip_service_worker */, RESOURCE_TYPE_MAIN_FRAME,
- REQUEST_CONTEXT_TYPE_HYPERLINK,
+ blink::mojom::RequestContextType::HYPERLINK,
network::mojom::RequestContextFrameType::kTopLevel,
true /* is_parent_frame_secure */, nullptr /* body */,
- base::RepeatingCallback<WebContents*(void)>());
+ base::RepeatingCallback<WebContents*(void)>(),
+ &service_worker_provider_host);
return !!interceptor.get();
}
diff --git a/chromium/content/browser/service_worker/service_worker_script_cache_map.cc b/chromium/content/browser/service_worker/service_worker_script_cache_map.cc
index 09f44ad00a1..6ac7fb16b2e 100644
--- a/chromium/content/browser/service_worker/service_worker_script_cache_map.cc
+++ b/chromium/content/browser/service_worker/service_worker_script_cache_map.cc
@@ -81,9 +81,7 @@ void ServiceWorkerScriptCacheMap::GetResources(
void ServiceWorkerScriptCacheMap::SetResources(
const std::vector<ServiceWorkerDatabase::ResourceRecord>& resources) {
DCHECK(resource_map_.empty());
- typedef std::vector<ServiceWorkerDatabase::ResourceRecord> RecordVector;
- for (RecordVector::const_iterator it = resources.begin();
- it != resources.end(); ++it) {
+ for (auto it = resources.begin(); it != resources.end(); ++it) {
resource_map_[it->url] = *it;
}
}
@@ -97,14 +95,15 @@ void ServiceWorkerScriptCacheMap::WriteMetadata(
return;
}
- ResourceMap::iterator found = resource_map_.find(url);
+ auto found = resource_map_.find(url);
if (found == resource_map_.end() ||
found->second.resource_id == kInvalidServiceWorkerResourceId) {
callback.Run(net::ERR_FILE_NOT_FOUND);
return;
}
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(data.size()));
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(data.size());
if (data.size())
memmove(buffer->data(), &data[0], data.size());
std::unique_ptr<ServiceWorkerResponseMetadataWriter> writer;
diff --git a/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc b/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc
index e90b006c0fd..86b6e12b26d 100644
--- a/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc
+++ b/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc
@@ -51,10 +51,9 @@ void ServiceWorkerScriptLoaderFactory::CreateLoaderAndStart(
// (use ServceWorkerInstalledScriptLoader). Typically this case is handled
// by ServiceWorkerInstalledScriptsSender, but we can still get here when a
// new service worker starts up and becomes installed while it is running.
- // B) service worker is installed, script is not installed: serve from direct
- // network. This happens when the script is newly imported after
- // installation.
- // TODO(crbug.com/719052): deprecate this.
+ // B) service worker is installed, script is not installed: return a network
+ // error. This happens when the script is newly imported after
+ // installation, which is disallowed by the spec.
// C) service worker is not installed, script is installed: serve from
// storage (use ServceWorkerInstalledScriptLoader)
// D) service worker is not installed, script is not installed: serve from
@@ -78,11 +77,7 @@ void ServiceWorkerScriptLoaderFactory::CreateLoaderAndStart(
// Case B:
if (ServiceWorkerVersion::IsInstalled(version->status())) {
- // TODO(kinuko): Record the reason like what we do with netlog in
- // ServiceWorkerContextRequestHandler.
- loader_factory_->CreateLoaderAndStart(
- std::move(request), routing_id, request_id, options, resource_request,
- std::move(client), traffic_annotation);
+ client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_FAILED));
return;
}
diff --git a/chromium/content/browser/service_worker/service_worker_script_loader_factory.h b/chromium/content/browser/service_worker/service_worker_script_loader_factory.h
index 2eb05ea0815..38b60b9f6d2 100644
--- a/chromium/content/browser/service_worker/service_worker_script_loader_factory.h
+++ b/chromium/content/browser/service_worker/service_worker_script_loader_factory.h
@@ -27,7 +27,8 @@ class ServiceWorkerProviderHost;
// service worker. For installed workers, service worker script streaming
// (ServiceWorkerInstalledScriptsSender) is typically used instead. However,
// this factory can still be used when an installed worker imports a
-// non-installed script (https://crbug.com/719052).
+// non-installed script. In this case, this factory just returns a network
+// error as the spec disallows it.
//
// This factory creates either a ServiceWorkerNewScriptLoader or a
// ServiceWorkerInstalledScriptLoader to load a script.
diff --git a/chromium/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc b/chromium/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc
index c53cae17369..09a0579f561 100644
--- a/chromium/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc
@@ -96,7 +96,8 @@ class ServiceWorkerScriptLoaderFactoryTest : public testing::Test {
options, 1L /* registration_id */, context->AsWeakPtr());
version_ = base::MakeRefCounted<ServiceWorkerVersion>(
registration_.get(), GURL("https://host/script.js"),
- context->storage()->NewVersionId(), context->AsWeakPtr());
+ blink::mojom::ScriptType::kClassic, context->storage()->NewVersionId(),
+ context->AsWeakPtr());
provider_host_ = CreateProviderHostForServiceWorkerContext(
helper_->mock_render_process_id(), true /* is_parent_frame_secure */,
diff --git a/chromium/content/browser/service_worker/service_worker_single_script_update_checker.cc b/chromium/content/browser/service_worker/service_worker_single_script_update_checker.cc
new file mode 100644
index 00000000000..a08ad96b927
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_single_script_update_checker.cc
@@ -0,0 +1,385 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_single_script_update_checker.h"
+
+#include "content/browser/appcache/appcache_response.h"
+#include "content/browser/service_worker/service_worker_cache_writer.h"
+#include "content/public/common/resource_type.h"
+#include "mojo/public/cpp/system/simple_watcher.h"
+#include "services/network/public/cpp/net_adapters.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/blink/public/common/mime_util/mime_util.h"
+
+// TODO(momohatt): Use ServiceWorkerMetrics for UMA.
+
+namespace {
+
+constexpr net::NetworkTrafficAnnotationTag kUpdateCheckTrafficAnnotation =
+ net::DefineNetworkTrafficAnnotation("service_worker_update_checker",
+ R"(
+ semantics {
+ sender: "ServiceWorker System"
+ description:
+ "This request is issued by an update check to fetch the content of "
+ "the new scripts."
+ trigger:
+ "ServiceWorker's update logic, which is triggered by a navigation to a "
+ "site controlled by a service worker."
+ data:
+ "No body. 'Service-Worker: script' header is attached when it's the "
+ "main worker script. Requests may include cookies and credentials."
+ destination: WEBSITE
+ }
+ policy {
+ cookies_allowed: YES
+ cookies_store: "user"
+ setting:
+ "Users can control this feature via the 'Cookies' setting under "
+ "'Privacy, Content settings'. If cookies are disabled for a single "
+ "site, serviceworkers are disabled for the site only. If they are "
+ "totally disabled, all serviceworker requests will be stopped."
+ chrome_policy {
+ URLBlacklist {
+ URLBlacklist: { entries: '*' }
+ }
+ }
+ chrome_policy {
+ URLWhitelist {
+ URLWhitelist { }
+ }
+ }
+ }
+ comments:
+ "Chrome would be unable to update service workers without this type of "
+ "request. Using either URLBlacklist or URLWhitelist policies (or a "
+ "combination of both) limits the scope of these requests."
+ )");
+
+} // namespace
+
+namespace content {
+
+ServiceWorkerSingleScriptUpdateChecker::ServiceWorkerSingleScriptUpdateChecker(
+ const GURL& url,
+ bool is_main_script,
+ scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
+ std::unique_ptr<ServiceWorkerResponseReader> compare_reader,
+ std::unique_ptr<ServiceWorkerResponseReader> copy_reader,
+ std::unique_ptr<ServiceWorkerResponseWriter> writer,
+ ResultCallback callback)
+ : network_client_binding_(this),
+ network_watcher_(FROM_HERE,
+ mojo::SimpleWatcher::ArmingPolicy::MANUAL,
+ base::SequencedTaskRunnerHandle::Get()),
+ callback_(std::move(callback)),
+ weak_factory_(this) {
+ network::ResourceRequest resource_request;
+ resource_request.url = url;
+ resource_request.resource_type =
+ is_main_script ? RESOURCE_TYPE_SERVICE_WORKER : RESOURCE_TYPE_SCRIPT;
+ resource_request.do_not_prompt_for_login = true;
+ if (is_main_script)
+ resource_request.headers.SetHeader("Service-Worker", "script");
+
+ // TODO(momohatt): Handle cases where force_bypass_cache is enabled.
+
+ // |compare_reader| shouldn't be a nullptr, which forces
+ // ServiceWorkerCacheWriter to do the comparison.
+ DCHECK(compare_reader);
+ cache_writer_ = std::make_unique<ServiceWorkerCacheWriter>(
+ std::move(compare_reader), std::move(copy_reader), std::move(writer),
+ true /* pause_when_not_identical */);
+
+ network::mojom::URLLoaderClientPtr network_client;
+ network_client_binding_.Bind(mojo::MakeRequest(&network_client));
+
+ loader_factory->CreateLoaderAndStart(
+ mojo::MakeRequest(&network_loader_), -1 /* routing_id */,
+ -1 /* request_id */, network::mojom::kURLLoadOptionNone, resource_request,
+ std::move(network_client),
+ net::MutableNetworkTrafficAnnotationTag(kUpdateCheckTrafficAnnotation));
+ DCHECK_EQ(NetworkLoaderState::kNotStarted, network_loader_state_);
+ network_loader_state_ = NetworkLoaderState::kLoadingHeader;
+}
+
+ServiceWorkerSingleScriptUpdateChecker::
+ ~ServiceWorkerSingleScriptUpdateChecker() = default;
+
+// URLLoaderClient override ----------------------------------------------------
+
+void ServiceWorkerSingleScriptUpdateChecker::OnReceiveResponse(
+ const network::ResourceResponseHead& response_head) {
+ DCHECK_EQ(NetworkLoaderState::kLoadingHeader, network_loader_state_);
+
+ // We don't have complete info here, but fill in what we have now.
+ // At least we need headers and SSL info.
+ auto response_info = std::make_unique<net::HttpResponseInfo>();
+ response_info->headers = response_head.headers;
+ if (response_head.ssl_info.has_value())
+ response_info->ssl_info = *response_head.ssl_info;
+ response_info->was_fetched_via_spdy = response_head.was_fetched_via_spdy;
+ response_info->was_alpn_negotiated = response_head.was_alpn_negotiated;
+ response_info->alpn_negotiated_protocol =
+ response_head.alpn_negotiated_protocol;
+ response_info->connection_info = response_head.connection_info;
+ response_info->socket_address = response_head.socket_address;
+
+ // TODO(momohatt): Check for header errors.
+
+ network_loader_state_ = NetworkLoaderState::kWaitingForBody;
+
+ WriteHeaders(
+ base::MakeRefCounted<HttpResponseInfoIOBuffer>(std::move(response_info)));
+}
+
+void ServiceWorkerSingleScriptUpdateChecker::OnReceiveRedirect(
+ const net::RedirectInfo& redirect_info,
+ const network::ResourceResponseHead& response_head) {
+ // TODO(momohatt): Raise error and terminate the update check here, like
+ // ServiceWorkerNewScriptLoader does.
+ NOTIMPLEMENTED();
+}
+
+void ServiceWorkerSingleScriptUpdateChecker::OnUploadProgress(
+ int64_t current_position,
+ int64_t total_size,
+ OnUploadProgressCallback ack_callback) {
+ // The network request for update checking shouldn't have upload data.
+ NOTREACHED();
+}
+
+void ServiceWorkerSingleScriptUpdateChecker::OnReceiveCachedMetadata(
+ const std::vector<uint8_t>& data) {}
+
+void ServiceWorkerSingleScriptUpdateChecker::OnTransferSizeUpdated(
+ int32_t transfer_size_diff) {
+ NOTIMPLEMENTED();
+}
+
+void ServiceWorkerSingleScriptUpdateChecker::OnStartLoadingResponseBody(
+ mojo::ScopedDataPipeConsumerHandle consumer) {
+ DCHECK_EQ(NetworkLoaderState::kWaitingForBody, network_loader_state_);
+
+ network_consumer_ = std::move(consumer);
+ network_loader_state_ = NetworkLoaderState::kLoadingBody;
+ MaybeStartNetworkConsumerHandleWatcher();
+}
+
+void ServiceWorkerSingleScriptUpdateChecker::OnComplete(
+ const network::URLLoaderCompletionStatus& status) {
+ NetworkLoaderState previous_loader_state = network_loader_state_;
+ network_loader_state_ = NetworkLoaderState::kCompleted;
+ if (status.error_code != net::OK) {
+ Finish(false /* is_script_changed */);
+ return;
+ }
+
+ DCHECK(previous_loader_state == NetworkLoaderState::kWaitingForBody ||
+ previous_loader_state == NetworkLoaderState::kLoadingBody);
+
+ // Response body is empty.
+ if (previous_loader_state == NetworkLoaderState::kWaitingForBody) {
+ DCHECK_EQ(CacheWriterState::kNotStarted, body_writer_state_);
+ body_writer_state_ = CacheWriterState::kCompleted;
+ switch (header_writer_state_) {
+ case CacheWriterState::kNotStarted:
+ NOTREACHED()
+ << "Response header should be received before OnComplete()";
+ break;
+ case CacheWriterState::kWriting:
+ // Wait until it's written. OnWriteHeadersComplete() will call
+ // Finish().
+ return;
+ case CacheWriterState::kCompleted:
+ DCHECK(!network_consumer_.is_valid());
+ // Compare the cached data with an empty data to notify |cache_writer_|
+ // of the end of the comparison.
+ CompareData(nullptr /* pending_buffer */, 0 /* bytes_available */);
+ break;
+ }
+ }
+
+ // Response body exists.
+ if (previous_loader_state == NetworkLoaderState::kLoadingBody) {
+ switch (body_writer_state_) {
+ case CacheWriterState::kNotStarted:
+ DCHECK_EQ(CacheWriterState::kWriting, header_writer_state_);
+ return;
+ case CacheWriterState::kWriting:
+ DCHECK_EQ(CacheWriterState::kCompleted, header_writer_state_);
+ return;
+ case CacheWriterState::kCompleted:
+ DCHECK_EQ(CacheWriterState::kCompleted, header_writer_state_);
+ Finish(false /* is_script_changed */);
+ return;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void ServiceWorkerSingleScriptUpdateChecker::WriteHeaders(
+ scoped_refptr<HttpResponseInfoIOBuffer> info_buffer) {
+ DCHECK_EQ(CacheWriterState::kNotStarted, header_writer_state_);
+ header_writer_state_ = CacheWriterState::kWriting;
+
+ // Pass the header to the cache_writer_. This is written to the storage when
+ // the body had changes.
+ net::Error error = cache_writer_->MaybeWriteHeaders(
+ info_buffer.get(),
+ base::BindOnce(
+ &ServiceWorkerSingleScriptUpdateChecker::OnWriteHeadersComplete,
+ weak_factory_.GetWeakPtr()));
+ if (error == net::ERR_IO_PENDING) {
+ // OnWriteHeadersComplete() will be called asynchronously.
+ return;
+ }
+ // MaybeWriteHeaders() doesn't run the callback if it finishes synchronously,
+ // so explicitly call it here.
+ OnWriteHeadersComplete(error);
+}
+
+void ServiceWorkerSingleScriptUpdateChecker::OnWriteHeadersComplete(
+ net::Error error) {
+ DCHECK_EQ(CacheWriterState::kWriting, header_writer_state_);
+ DCHECK_NE(net::ERR_IO_PENDING, error);
+ header_writer_state_ = CacheWriterState::kCompleted;
+
+ if (error != net::OK) {
+ Finish(false /* is_script_changed */);
+ return;
+ }
+
+ // Response body is empty.
+ if (network_loader_state_ == NetworkLoaderState::kCompleted &&
+ body_writer_state_ == CacheWriterState::kCompleted) {
+ // Compare the cached data with an empty data to notify |cache_writer_|
+ // the end of the comparison.
+ CompareData(nullptr /* pending_buffer */, 0 /* bytes_available */);
+ return;
+ }
+
+ MaybeStartNetworkConsumerHandleWatcher();
+}
+
+void ServiceWorkerSingleScriptUpdateChecker::
+ MaybeStartNetworkConsumerHandleWatcher() {
+ if (network_loader_state_ == NetworkLoaderState::kWaitingForBody) {
+ // OnStartLoadingResponseBody() or OnComplete() will continue the sequence.
+ return;
+ }
+ if (header_writer_state_ != CacheWriterState::kCompleted) {
+ DCHECK_EQ(CacheWriterState::kWriting, header_writer_state_);
+ // OnWriteHeadersComplete() will continue the sequence.
+ return;
+ }
+
+ DCHECK_EQ(CacheWriterState::kNotStarted, body_writer_state_);
+ body_writer_state_ = CacheWriterState::kWriting;
+
+ network_watcher_.Watch(
+ network_consumer_.get(),
+ MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
+ base::BindRepeating(
+ &ServiceWorkerSingleScriptUpdateChecker::OnNetworkDataAvailable,
+ weak_factory_.GetWeakPtr()));
+ network_watcher_.ArmOrNotify();
+}
+
+void ServiceWorkerSingleScriptUpdateChecker::OnNetworkDataAvailable(
+ MojoResult,
+ const mojo::HandleSignalsState& state) {
+ DCHECK_EQ(CacheWriterState::kCompleted, header_writer_state_);
+ DCHECK(network_consumer_.is_valid());
+ scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer;
+ uint32_t bytes_available = 0;
+ MojoResult result = network::MojoToNetPendingBuffer::BeginRead(
+ &network_consumer_, &pending_buffer, &bytes_available);
+ switch (result) {
+ case MOJO_RESULT_OK:
+ CompareData(std::move(pending_buffer), bytes_available);
+ return;
+ case MOJO_RESULT_FAILED_PRECONDITION:
+ // Closed by peer. This indicates all the data from the network service
+ // are read or there is an error. In the error case, the reason is
+ // notified via OnComplete().
+ if (network_loader_state_ == NetworkLoaderState::kCompleted) {
+ // Compare the cached data with an empty data to notify |cache_writer_|
+ // the end of the comparison.
+ CompareData(nullptr /* pending_buffer */, 0 /* bytes_available */);
+ }
+ return;
+ case MOJO_RESULT_SHOULD_WAIT:
+ network_watcher_.ArmOrNotify();
+ return;
+ }
+ NOTREACHED() << static_cast<int>(result);
+}
+
+void ServiceWorkerSingleScriptUpdateChecker::CompareData(
+ scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer,
+ uint32_t bytes_to_compare) {
+ auto buffer = base::MakeRefCounted<net::WrappedIOBuffer>(
+ pending_buffer ? pending_buffer->buffer() : nullptr);
+
+ // Compare the network data and the stored data.
+ net::Error error = cache_writer_->MaybeWriteData(
+ buffer.get(), bytes_to_compare,
+ base::BindOnce(
+ &ServiceWorkerSingleScriptUpdateChecker::OnCompareDataComplete,
+ weak_factory_.GetWeakPtr(),
+ base::WrapRefCounted(pending_buffer.get()), bytes_to_compare));
+
+ if (pending_buffer) {
+ pending_buffer->CompleteRead(bytes_to_compare);
+ network_consumer_ = pending_buffer->ReleaseHandle();
+ }
+
+ if (error == net::ERR_IO_PENDING && !cache_writer_->is_pausing()) {
+ // OnCompareDataComplete() will be called asynchronously.
+ return;
+ }
+ // MaybeWriteData() doesn't run the callback if it finishes synchronously, so
+ // explicitly call it here.
+ OnCompareDataComplete(std::move(pending_buffer), bytes_to_compare, error);
+}
+
+void ServiceWorkerSingleScriptUpdateChecker::OnCompareDataComplete(
+ scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer,
+ uint32_t bytes_written,
+ net::Error error) {
+ if (cache_writer_->is_pausing()) {
+ // |cache_writer_| can be pausing only when it finds difference between
+ // stored body and network body.
+ DCHECK_EQ(net::ERR_IO_PENDING, error);
+ Finish(true /* is_script_changed */);
+ return;
+ }
+ if (!pending_buffer || error != net::OK) {
+ Finish(false /* is_script_changed */);
+ return;
+ }
+ DCHECK(pending_buffer);
+ network_watcher_.ArmOrNotify();
+}
+
+void ServiceWorkerSingleScriptUpdateChecker::Finish(bool is_script_changed) {
+ if (is_script_changed) {
+ // TODO(momohatt): pass the necessary information to the version to update.
+ } else {
+ network_loader_.reset();
+ network_client_binding_.Close();
+ network_consumer_.reset();
+ }
+ network_watcher_.Cancel();
+ network_loader_state_ = NetworkLoaderState::kCompleted;
+ header_writer_state_ = CacheWriterState::kCompleted;
+ body_writer_state_ = CacheWriterState::kCompleted;
+
+ std::move(callback_).Run(is_script_changed);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_single_script_update_checker.h b/chromium/content/browser/service_worker/service_worker_single_script_update_checker.h
new file mode 100644
index 00000000000..d006ae26cc1
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_single_script_update_checker.h
@@ -0,0 +1,141 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SINGLE_SCRIPT_UPDATE_CHECKER_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SINGLE_SCRIPT_UPDATE_CHECKER_H_
+
+#include "content/browser/service_worker/service_worker_disk_cache.h"
+#include "content/common/content_export.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
+
+namespace network {
+class MojoToNetPendingBuffer;
+class SharedURLLoaderFactory;
+} // namespace network
+
+namespace content {
+
+struct HttpResponseInfoIOBuffer;
+class ServiceWorkerCacheWriter;
+
+// Executes byte-for-byte update check of one script. This loads the script from
+// the network and compares it with the stored counterpart read from
+// |compare_reader|. The result will be passed as an argument of |callback|:
+// true when they are identical and false otherwise. When |callback| is
+// triggered, |cache_writer_| owned by |this| should be paused if the scripts
+// were not identical.
+class CONTENT_EXPORT ServiceWorkerSingleScriptUpdateChecker
+ : public network::mojom::URLLoaderClient {
+ public:
+ using ResultCallback = base::OnceCallback<void(bool)>;
+
+ // Both |compare_reader| and |copy_reader| should be created from the same
+ // resource ID, and this ID should locate where the script specified with
+ // |url| is stored. |writer| should be created with a new resource ID.
+ ServiceWorkerSingleScriptUpdateChecker(
+ const GURL& url,
+ bool is_main_script,
+ scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
+ std::unique_ptr<ServiceWorkerResponseReader> compare_reader,
+ std::unique_ptr<ServiceWorkerResponseReader> copy_reader,
+ std::unique_ptr<ServiceWorkerResponseWriter> writer,
+ ResultCallback callback);
+
+ ~ServiceWorkerSingleScriptUpdateChecker() override;
+
+ // network::mojom::URLLoaderClient override:
+ void OnReceiveResponse(
+ const network::ResourceResponseHead& response_head) override;
+ void OnReceiveRedirect(
+ const net::RedirectInfo& redirect_info,
+ const network::ResourceResponseHead& response_head) override;
+ void OnUploadProgress(int64_t current_position,
+ int64_t total_size,
+ OnUploadProgressCallback ack_callback) override;
+ void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override;
+ void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
+ void OnStartLoadingResponseBody(
+ mojo::ScopedDataPipeConsumerHandle consumer) override;
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override;
+
+ private:
+ enum class NetworkLoaderState {
+ kNotStarted,
+ kLoadingHeader,
+ kWaitingForBody,
+ kLoadingBody,
+ kCompleted
+ };
+
+ enum class CacheWriterState { kNotStarted, kWriting, kCompleted };
+
+ void WriteHeaders(scoped_refptr<HttpResponseInfoIOBuffer> info_buffer);
+ void OnWriteHeadersComplete(net::Error error);
+
+ void MaybeStartNetworkConsumerHandleWatcher();
+ void OnNetworkDataAvailable(MojoResult,
+ const mojo::HandleSignalsState& state);
+ void CompareData(
+ scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer,
+ uint32_t bytes_available);
+ void OnCompareDataComplete(
+ scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer,
+ uint32_t bytes_written,
+ net::Error error);
+ void Finish(bool is_script_changed);
+
+ network::mojom::URLLoaderPtr network_loader_;
+ mojo::Binding<network::mojom::URLLoaderClient> network_client_binding_;
+ mojo::ScopedDataPipeConsumerHandle network_consumer_;
+ mojo::SimpleWatcher network_watcher_;
+
+ std::unique_ptr<ServiceWorkerCacheWriter> cache_writer_;
+ ResultCallback callback_;
+
+ // Represents the state of |network_loader_|.
+ // Corresponds to the steps described in the class comments.
+ //
+ // When response body exists:
+ // CreateLoaderAndStart(): kNotStarted -> kLoadingHeader
+ // OnReceiveResponse(): kLoadingHeader -> kWaitingForBody
+ // OnStartLoadingResponseBody(): kWaitingForBody -> kLoadingBody
+ // OnComplete(): kLoadingBody -> kCompleted
+ //
+ // When response body is empty:
+ // CreateLoaderAndStart(): kNotStarted -> kLoadingHeader
+ // OnReceiveResponse(): kLoadingHeader -> kWaitingForBody
+ // OnComplete(): kWaitingForBody -> kCompleted
+ NetworkLoaderState network_loader_state_ = NetworkLoaderState::kNotStarted;
+
+ // Represents the state of |cache_writer_|.
+ // Set to kWriting when it starts to send the header to |cache_writer_|, and
+ // set to kCompleted when the header has been sent.
+ //
+ // OnReceiveResponse(): kNotStarted -> kWriting (in WriteHeaders())
+ // OnWriteHeadersComplete(): kWriting -> kCompleted
+ CacheWriterState header_writer_state_ = CacheWriterState::kNotStarted;
+
+ // Represents the state of |cache_writer_| and |network_consumer_|.
+ // Set to kWriting when |this| starts watching |network_consumer_|, and set to
+ // kCompleted when |cache_writer_| reports any difference between the stored
+ // body and the network body, or the entire body is compared without any
+ // difference.
+ //
+ // When response body exists:
+ // OnStartLoadingResponseBody() && OnWriteHeadersComplete():
+ // kNotStarted -> kWriting
+ // OnNetworkDataAvailable() && MOJO_RESULT_FAILED_PRECONDITION:
+ // kWriting -> kCompleted
+ //
+ // When response body is empty:
+ // OnComplete(): kNotStarted -> kCompleted
+ CacheWriterState body_writer_state_ = CacheWriterState::kNotStarted;
+
+ base::WeakPtrFactory<ServiceWorkerSingleScriptUpdateChecker> weak_factory_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SINGLE_SCRIPT_UPDATE_CHECKER_H_
diff --git a/chromium/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc b/chromium/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc
new file mode 100644
index 00000000000..cc2188cdab5
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc
@@ -0,0 +1,288 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_single_script_update_checker.h"
+
+#include <vector>
+#include "base/containers/queue.h"
+#include "base/run_loop.h"
+#include "content/browser/service_worker/embedded_worker_test_helper.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_storage.h"
+#include "content/browser/service_worker/service_worker_test_utils.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/http/http_util.h"
+#include "services/network/test/test_url_loader_factory.h"
+
+namespace content {
+namespace {
+
+constexpr char kScriptURL[] = "https://example.com/script.js";
+constexpr char kSuccessHeader[] =
+ "HTTP/1.1 200 OK\n"
+ "Content-Type: text/javascript\n\n";
+
+class ServiceWorkerSingleScriptUpdateCheckerTest : public testing::Test {
+ public:
+ ServiceWorkerSingleScriptUpdateCheckerTest()
+ : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
+ ~ServiceWorkerSingleScriptUpdateCheckerTest() override = default;
+
+ ServiceWorkerStorage* storage() { return helper_->context()->storage(); }
+
+ void SetUp() override {
+ helper_ = std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath());
+ base::RunLoop run_loop;
+ storage()->LazyInitializeForTest(run_loop.QuitClosure());
+ run_loop.Run();
+ }
+
+ size_t TotalBytes(const std::vector<std::string>& data_chunks) {
+ size_t bytes = 0;
+ for (const auto& data : data_chunks)
+ bytes += data.size();
+ return bytes;
+ }
+
+ std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker>
+ CreateSingleScriptUpdateChecker(
+ const char* url,
+ std::unique_ptr<ServiceWorkerResponseReader> compare_reader,
+ std::unique_ptr<ServiceWorkerResponseReader> copy_reader,
+ std::unique_ptr<ServiceWorkerResponseWriter> writer,
+ network::TestURLLoaderFactory* loader_factory,
+ base::Optional<bool>* out_script_changed) {
+ helper_->SetNetworkFactory(loader_factory);
+ return std::make_unique<ServiceWorkerSingleScriptUpdateChecker>(
+ GURL(url), true /* is_main_script */,
+ helper_->url_loader_factory_getter()->GetNetworkFactory(),
+ std::move(compare_reader), std::move(copy_reader), std::move(writer),
+ base::BindOnce(
+ [](base::Optional<bool>* out_script_changed, bool script_changed) {
+ *out_script_changed = script_changed;
+ },
+ out_script_changed));
+ }
+
+ std::unique_ptr<network::TestURLLoaderFactory> CreateLoaderFactoryWithRespone(
+ const GURL& url,
+ std::string header,
+ std::string body,
+ net::Error error) {
+ auto loader_factory = std::make_unique<network::TestURLLoaderFactory>();
+ network::ResourceResponseHead head;
+ head.headers = base::MakeRefCounted<net::HttpResponseHeaders>(
+ net::HttpUtil::AssembleRawHeaders(header.c_str(), header.size()));
+ network::URLLoaderCompletionStatus status(error);
+ status.decoded_body_length = body.size();
+ loader_factory->AddResponse(url, head, body, status);
+ return loader_factory;
+ }
+
+ protected:
+ TestBrowserThreadBundle thread_bundle_;
+ std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSingleScriptUpdateCheckerTest);
+};
+
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, Identical_SingleSyncRead) {
+ // Response body from the network.
+ const std::string body_from_net("abcdef");
+
+ // Stored data for |kScriptURL|.
+ const std::vector<std::string> body_from_storage{body_from_net};
+
+ std::unique_ptr<network::TestURLLoaderFactory> loader_factory =
+ CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader,
+ body_from_net, net::OK);
+
+ auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
+ MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
+ compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
+ false /* async */);
+
+ base::Optional<bool> script_changed;
+ std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
+ CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader),
+ std::move(copy_reader), std::move(writer),
+ loader_factory.get(), &script_changed);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(script_changed.has_value());
+ EXPECT_FALSE(script_changed.value());
+ EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone());
+}
+
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, Different_SingleSyncRead) {
+ // Response body from the network.
+ const std::string body_from_net("abcdef");
+
+ // Stored data for |kScriptURL|.
+ const std::vector<std::string> body_from_storage{"abxx"};
+
+ std::unique_ptr<network::TestURLLoaderFactory> loader_factory =
+ CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader,
+ body_from_net, net::OK);
+
+ auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
+ MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
+ compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
+ false /* async */);
+
+ base::Optional<bool> script_changed;
+ std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
+ CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader),
+ std::move(copy_reader), std::move(writer),
+ loader_factory.get(), &script_changed);
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(script_changed.has_value());
+ EXPECT_TRUE(script_changed.value());
+ EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone());
+}
+
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, Different_MultipleSyncRead) {
+ // Response body from the network.
+ const std::string body_from_net("abcdef");
+
+ // Stored data for |kScriptURL| (the data for compare reader).
+ // The comparison should stop in the second block of data.
+ const std::vector<std::string> body_from_storage{"ab", "cx"};
+
+ std::unique_ptr<network::TestURLLoaderFactory> loader_factory =
+ CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader,
+ body_from_net, net::OK);
+
+ auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
+ MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
+ compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
+ false /* async */);
+
+ base::Optional<bool> script_changed;
+ std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
+ CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader),
+ std::move(copy_reader), std::move(writer),
+ loader_factory.get(), &script_changed);
+
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(script_changed.has_value());
+ EXPECT_TRUE(script_changed.value());
+ EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone());
+}
+
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, NetworkDataLong_SyncRead) {
+ // Response body from the network.
+ const std::string body_from_net("abcdef");
+
+ // Stored data for |kScriptURL| (the data for compare reader).
+ const std::vector<std::string> body_from_storage{"ab", "cd", ""};
+
+ std::unique_ptr<network::TestURLLoaderFactory> loader_factory =
+ CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader,
+ body_from_net, net::OK);
+
+ auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
+ MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
+ compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
+ false /* async */);
+
+ base::Optional<bool> script_changed;
+ std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
+ CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader),
+ std::move(copy_reader), std::move(writer),
+ loader_factory.get(), &script_changed);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(script_changed.has_value());
+ EXPECT_TRUE(script_changed.value());
+ EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone());
+}
+
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, NetworkDataShort_SyncRead) {
+ // Response body from the network.
+ const std::string body_from_net("abcdef");
+
+ // Stored data for |kScriptURL| (the data for compare reader).
+ const std::vector<std::string> body_in_storage{"ab", "cd", "ef", "gh"};
+
+ // Stored data that will actually be read from the compare reader.
+ // The last 2 bytes of |body_in_storage| won't be read.
+ const std::vector<std::string> body_read_from_storage{"ab", "cd", "ef"};
+
+ std::unique_ptr<network::TestURLLoaderFactory> loader_factory =
+ CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader,
+ body_from_net, net::OK);
+
+ auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
+ MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
+ compare_reader->ExpectReadOk(body_read_from_storage,
+ TotalBytes(body_in_storage), false /* async */);
+
+ base::Optional<bool> script_changed;
+ std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
+ CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader),
+ std::move(copy_reader), std::move(writer),
+ loader_factory.get(), &script_changed);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(script_changed.has_value());
+ EXPECT_TRUE(script_changed.value());
+ EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone());
+}
+
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, Identical_SingleAsyncRead) {
+ // Response body from the network.
+ const std::string body_from_net("abcdef");
+
+ // Stored data for |kScriptURL| (the data for compare reader).
+ const std::vector<std::string> body_from_storage{body_from_net};
+
+ std::unique_ptr<network::TestURLLoaderFactory> loader_factory =
+ CreateLoaderFactoryWithRespone(GURL(kScriptURL), kSuccessHeader,
+ body_from_net, net::OK);
+
+ auto compare_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
+ auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
+ MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
+ compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
+ true /* async */);
+
+ base::Optional<bool> script_changed;
+ std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
+ CreateSingleScriptUpdateChecker(kScriptURL, std::move(compare_reader),
+ std::move(copy_reader), std::move(writer),
+ loader_factory.get(), &script_changed);
+
+ // Update check stops in WriteHeader() due to the asynchronous read of the
+ // |compare_reader|.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(script_changed.has_value());
+
+ // Continue the update check and trigger OnWriteHeadersComplete(). The resumed
+ // update check stops again at CompareData().
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(script_changed.has_value());
+
+ // Continue the update check and trigger OnCompareDataComplete(). This will
+ // finish the entire update check.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(script_changed.has_value());
+ EXPECT_FALSE(script_changed.value());
+ EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone());
+}
+
+} // namespace
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_storage.cc b/chromium/content/browser/service_worker/service_worker_storage.cc
index 92b13a6c60e..ca3e8917c36 100644
--- a/chromium/content/browser/service_worker/service_worker_storage.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage.cc
@@ -431,8 +431,9 @@ void ServiceWorkerStorage::StoreRegistration(
ServiceWorkerDatabase::RegistrationData data;
data.registration_id = registration->id();
data.scope = registration->pattern();
- data.update_via_cache = registration->update_via_cache();
data.script = version->script_url();
+ data.script_type = version->script_type();
+ data.update_via_cache = registration->update_via_cache();
data.has_fetch_handler = version->fetch_handler_existence() ==
ServiceWorkerVersion::FetchHandlerExistence::EXISTS;
data.version_id = version->version_id();
@@ -1537,8 +1538,8 @@ ServiceWorkerStorage::GetOrCreateRegistration(
if (registration)
return registration;
- blink::mojom::ServiceWorkerRegistrationOptions options(data.scope,
- data.update_via_cache);
+ blink::mojom::ServiceWorkerRegistrationOptions options(
+ data.scope, data.script_type, data.update_via_cache);
registration =
new ServiceWorkerRegistration(options, data.registration_id, context_);
registration->set_resources_total_size_bytes(data.resources_total_size_bytes);
@@ -1550,8 +1551,9 @@ ServiceWorkerStorage::GetOrCreateRegistration(
scoped_refptr<ServiceWorkerVersion> version =
context_->GetLiveVersion(data.version_id);
if (!version) {
- version = new ServiceWorkerVersion(
- registration.get(), data.script, data.version_id, context_);
+ version = base::MakeRefCounted<ServiceWorkerVersion>(
+ registration.get(), data.script, data.script_type, data.version_id,
+ context_);
version->set_fetch_handler_existence(
data.has_fetch_handler
? ServiceWorkerVersion::FetchHandlerExistence::EXISTS
diff --git a/chromium/content/browser/service_worker/service_worker_storage_unittest.cc b/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
index 9d1aab24ec6..818540eb154 100644
--- a/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -69,10 +69,10 @@ const uint8_t kTestPublicKey[] = {
};
void StatusAndQuitCallback(blink::ServiceWorkerStatusCode* result,
- const base::Closure& quit_closure,
+ base::OnceClosure quit_closure,
blink::ServiceWorkerStatusCode status) {
*result = status;
- quit_closure.Run();
+ std::move(quit_closure).Run();
}
void StatusCallback(bool* was_called,
@@ -200,7 +200,8 @@ int WriteStringResponse(ServiceWorkerStorage* storage,
int64_t id,
const std::string& headers,
const std::string& body) {
- scoped_refptr<IOBuffer> body_buffer(new WrappedIOBuffer(body.data()));
+ scoped_refptr<IOBuffer> body_buffer =
+ base::MakeRefCounted<WrappedIOBuffer>(body.data());
return WriteResponse(storage, id, headers, body_buffer.get(), body.length());
}
@@ -237,7 +238,8 @@ bool VerifyBasicResponse(ServiceWorkerStorage* storage,
std::string received_body;
const int kBigEnough = 512;
- scoped_refptr<net::IOBuffer> buffer = new IOBuffer(kBigEnough);
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<IOBuffer>(kBigEnough);
TestCompletionCallback cb;
reader->ReadData(buffer.get(), kBigEnough, cb.callback());
rv = cb.WaitForResult();
@@ -259,7 +261,8 @@ bool VerifyBasicResponse(ServiceWorkerStorage* storage,
int WriteResponseMetadata(ServiceWorkerStorage* storage,
int64_t id,
const std::string& metadata) {
- scoped_refptr<IOBuffer> body_buffer(new WrappedIOBuffer(metadata.data()));
+ scoped_refptr<IOBuffer> body_buffer =
+ base::MakeRefCounted<WrappedIOBuffer>(metadata.data());
std::unique_ptr<ServiceWorkerResponseMetadataWriter> metadata_writer =
storage->CreateResponseMetadataWriter(id);
TestCompletionCallback cb;
@@ -368,8 +371,8 @@ class ServiceWorkerStorageTest : public testing::Test {
auto registration = base::MakeRefCounted<ServiceWorkerRegistration>(
options, storage()->NewRegistrationId(), context()->AsWeakPtr());
auto version = base::MakeRefCounted<ServiceWorkerVersion>(
- registration.get(), script, storage()->NewVersionId(),
- context()->AsWeakPtr());
+ registration.get(), script, blink::mojom::ScriptType::kClassic,
+ storage()->NewVersionId(), context()->AsWeakPtr());
std::vector<ResourceRecord> records = {
ResourceRecord(storage()->NewResourceId(), script, 100)};
version->script_cache_map()->SetResources(records);
@@ -646,7 +649,8 @@ TEST_F(ServiceWorkerStorageTest, DisabledStorage) {
new ServiceWorkerRegistration(options, kRegistrationId,
context()->AsWeakPtr());
scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
- live_registration.get(), kScript, kVersionId, context()->AsWeakPtr());
+ live_registration.get(), kScript, blink::mojom::ScriptType::kClassic,
+ kVersionId, context()->AsWeakPtr());
EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
StoreRegistration(live_registration, live_version));
@@ -734,7 +738,8 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
new ServiceWorkerRegistration(options, kRegistrationId,
context()->AsWeakPtr());
scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
- live_registration.get(), kResource1, kVersionId, context()->AsWeakPtr());
+ live_registration.get(), kResource1, blink::mojom::ScriptType::kClassic,
+ kVersionId, context()->AsWeakPtr());
live_version->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
live_version->SetStatus(ServiceWorkerVersion::INSTALLED);
@@ -904,7 +909,8 @@ TEST_F(ServiceWorkerStorageTest, InstallingRegistrationsAreFindable) {
new ServiceWorkerRegistration(options, kRegistrationId,
context()->AsWeakPtr());
scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
- live_registration.get(), kScript, kVersionId, context()->AsWeakPtr());
+ live_registration.get(), kScript, blink::mojom::ScriptType::kClassic,
+ kVersionId, context()->AsWeakPtr());
live_version->SetStatus(ServiceWorkerVersion::INSTALLING);
live_registration->SetWaitingVersion(live_version);
@@ -1657,8 +1663,8 @@ TEST_F(ServiceWorkerResourceStorageTest, UpdateRegistration) {
// Make an updated registration.
scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
- registration_.get(), script_, storage()->NewVersionId(),
- context()->AsWeakPtr());
+ registration_.get(), script_, blink::mojom::ScriptType::kClassic,
+ storage()->NewVersionId(), context()->AsWeakPtr());
live_version->SetStatus(ServiceWorkerVersion::NEW);
registration_->SetWaitingVersion(live_version);
std::vector<ResourceRecord> records;
@@ -1859,7 +1865,8 @@ TEST_F(ServiceWorkerStorageOriginTrialsDiskTest, FromMainScript) {
new ServiceWorkerRegistration(options, kRegistrationId,
context()->AsWeakPtr());
scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
- registration.get(), kScript, kVersionId, context()->AsWeakPtr());
+ registration.get(), kScript, blink::mojom::ScriptType::kClassic,
+ kVersionId, context()->AsWeakPtr());
net::HttpResponseInfo http_info;
http_info.ssl_info.cert =
diff --git a/chromium/content/browser/service_worker/service_worker_test_utils.cc b/chromium/content/browser/service_worker/service_worker_test_utils.cc
index 05e9cb72dea..ec53a3c6872 100644
--- a/chromium/content/browser/service_worker/service_worker_test_utils.cc
+++ b/chromium/content/browser/service_worker/service_worker_test_utils.cc
@@ -281,4 +281,175 @@ WriteToDiskCacheWithCustomResponseInfoAsync(
body.size());
}
+MockServiceWorkerResponseReader::MockServiceWorkerResponseReader()
+ : ServiceWorkerResponseReader(/* resource_id=*/0, /*disk_cache=*/nullptr) {}
+
+MockServiceWorkerResponseReader::~MockServiceWorkerResponseReader() {}
+
+void MockServiceWorkerResponseReader::ReadInfo(
+ HttpResponseInfoIOBuffer* info_buf,
+ OnceCompletionCallback callback) {
+ DCHECK(!expected_reads_.empty());
+ ExpectedRead expected = expected_reads_.front();
+ EXPECT_TRUE(expected.info);
+ if (expected.async) {
+ pending_info_ = info_buf;
+ pending_callback_ = std::move(callback);
+ } else {
+ expected_reads_.pop();
+ info_buf->response_data_size = expected.len;
+ std::move(callback).Run(expected.result);
+ }
+}
+
+void MockServiceWorkerResponseReader::ReadData(
+ net::IOBuffer* buf,
+ int buf_len,
+ OnceCompletionCallback callback) {
+ DCHECK(!expected_reads_.empty());
+ ExpectedRead expected = expected_reads_.front();
+ EXPECT_FALSE(expected.info);
+ if (expected.async) {
+ pending_callback_ = std::move(callback);
+ pending_buffer_ = buf;
+ pending_buffer_len_ = static_cast<size_t>(buf_len);
+ } else {
+ expected_reads_.pop();
+ if (expected.len > 0) {
+ size_t to_read = std::min(static_cast<size_t>(buf_len), expected.len);
+ memcpy(buf->data(), expected.data, to_read);
+ }
+ std::move(callback).Run(expected.result);
+ }
+}
+
+void MockServiceWorkerResponseReader::ExpectReadInfo(size_t len,
+ bool async,
+ int result) {
+ expected_reads_.push(ExpectedRead(len, async, result));
+}
+
+void MockServiceWorkerResponseReader::ExpectReadInfoOk(size_t len, bool async) {
+ expected_reads_.push(ExpectedRead(len, async, len));
+}
+
+void MockServiceWorkerResponseReader::ExpectReadData(const char* data,
+ size_t len,
+ bool async,
+ int result) {
+ expected_reads_.push(ExpectedRead(data, len, async, result));
+}
+
+void MockServiceWorkerResponseReader::ExpectReadDataOk(const std::string& data,
+ bool async) {
+ expected_reads_.push(
+ ExpectedRead(data.data(), data.size(), async, data.size()));
+}
+
+void MockServiceWorkerResponseReader::ExpectReadOk(
+ const std::vector<std::string>& stored_data,
+ const size_t bytes_stored,
+ const bool async) {
+ ExpectReadInfoOk(bytes_stored, async);
+ for (const auto& data : stored_data)
+ ExpectReadDataOk(data, async);
+}
+
+void MockServiceWorkerResponseReader::CompletePendingRead() {
+ DCHECK(!expected_reads_.empty());
+ ExpectedRead expected = expected_reads_.front();
+ expected_reads_.pop();
+ EXPECT_TRUE(expected.async);
+ if (expected.info) {
+ pending_info_->response_data_size = expected.len;
+ } else {
+ size_t to_read = std::min(pending_buffer_len_, expected.len);
+ if (to_read > 0)
+ memcpy(pending_buffer_->data(), expected.data, to_read);
+ }
+ pending_info_ = nullptr;
+ pending_buffer_ = nullptr;
+ OnceCompletionCallback callback = std::move(pending_callback_);
+ pending_callback_.Reset();
+ std::move(callback).Run(expected.result);
+}
+
+MockServiceWorkerResponseWriter::MockServiceWorkerResponseWriter()
+ : ServiceWorkerResponseWriter(/*resource_id=*/0, /*disk_cache=*/nullptr),
+ info_written_(0),
+ data_written_(0) {}
+
+MockServiceWorkerResponseWriter::~MockServiceWorkerResponseWriter() = default;
+
+void MockServiceWorkerResponseWriter::WriteInfo(
+ HttpResponseInfoIOBuffer* info_buf,
+ OnceCompletionCallback callback) {
+ DCHECK(!expected_writes_.empty());
+ ExpectedWrite write = expected_writes_.front();
+ EXPECT_TRUE(write.is_info);
+ if (write.result > 0) {
+ EXPECT_EQ(write.length, static_cast<size_t>(info_buf->response_data_size));
+ info_written_ += info_buf->response_data_size;
+ }
+ if (!write.async) {
+ expected_writes_.pop();
+ std::move(callback).Run(write.result);
+ } else {
+ pending_callback_ = std::move(callback);
+ }
+}
+
+void MockServiceWorkerResponseWriter::WriteData(
+ net::IOBuffer* buf,
+ int buf_len,
+ OnceCompletionCallback callback) {
+ DCHECK(!expected_writes_.empty());
+ ExpectedWrite write = expected_writes_.front();
+ EXPECT_FALSE(write.is_info);
+ if (write.result > 0) {
+ EXPECT_EQ(write.length, static_cast<size_t>(buf_len));
+ data_written_ += buf_len;
+ }
+ if (!write.async) {
+ expected_writes_.pop();
+ std::move(callback).Run(write.result);
+ } else {
+ pending_callback_ = std::move(callback);
+ }
+}
+
+void MockServiceWorkerResponseWriter::ExpectWriteInfoOk(size_t length,
+ bool async) {
+ ExpectWriteInfo(length, async, length);
+}
+
+void MockServiceWorkerResponseWriter::ExpectWriteDataOk(size_t length,
+ bool async) {
+ ExpectWriteData(length, async, length);
+}
+
+void MockServiceWorkerResponseWriter::ExpectWriteInfo(size_t length,
+ bool async,
+ int result) {
+ DCHECK_NE(net::ERR_IO_PENDING, result);
+ ExpectedWrite expected(true, length, async, result);
+ expected_writes_.push(expected);
+}
+
+void MockServiceWorkerResponseWriter::ExpectWriteData(size_t length,
+ bool async,
+ int result) {
+ DCHECK_NE(net::ERR_IO_PENDING, result);
+ ExpectedWrite expected(false, length, async, result);
+ expected_writes_.push(expected);
+}
+
+void MockServiceWorkerResponseWriter::CompletePendingWrite() {
+ DCHECK(!expected_writes_.empty());
+ ExpectedWrite write = expected_writes_.front();
+ DCHECK(write.async);
+ expected_writes_.pop();
+ std::move(pending_callback_).Run(write.result);
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_test_utils.h b/chromium/content/browser/service_worker/service_worker_test_utils.h
index 7b550c6efd0..aa81bbfca95 100644
--- a/chromium/content/browser/service_worker/service_worker_test_utils.h
+++ b/chromium/content/browser/service_worker/service_worker_test_utils.h
@@ -11,8 +11,11 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/memory/weak_ptr.h"
+#include "base/task/post_task.h"
#include "content/browser/service_worker/service_worker_database.h"
+#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -33,29 +36,30 @@ class ServiceWorkerVersion;
template <typename Arg>
void ReceiveResult(BrowserThread::ID run_quit_thread,
- const base::Closure& quit,
+ base::OnceClosure quit,
base::Optional<Arg>* out,
Arg actual) {
*out = actual;
if (!quit.is_null())
- BrowserThread::PostTask(run_quit_thread, FROM_HERE, quit);
+ base::PostTaskWithTraits(FROM_HERE, {run_quit_thread}, std::move(quit));
}
template <typename Arg>
base::OnceCallback<void(Arg)> CreateReceiver(BrowserThread::ID run_quit_thread,
- const base::RepeatingClosure& quit,
+ base::OnceClosure quit,
base::Optional<Arg>* out) {
- return base::BindOnce(&ReceiveResult<Arg>, run_quit_thread, quit, out);
+ return base::BindOnce(&ReceiveResult<Arg>, run_quit_thread, std::move(quit),
+ out);
}
template <typename Arg>
base::OnceCallback<void(Arg)> CreateReceiverOnCurrentThread(
base::Optional<Arg>* out,
- const base::Closure& quit = base::Closure()) {
+ base::OnceClosure quit = base::OnceClosure()) {
BrowserThread::ID id;
bool ret = BrowserThread::GetCurrentThreadIdentifier(&id);
DCHECK(ret);
- return CreateReceiver(id, quit, out);
+ return CreateReceiver(id, std::move(quit), out);
}
// Container for keeping the Mojo connection to the service worker provider on
@@ -162,6 +166,154 @@ WriteToDiskCacheWithCustomResponseInfoAsync(
const std::string& meta_data,
base::OnceClosure callback);
+// A test implementation of ServiceWorkerResponseReader.
+//
+// This class exposes the ability to expect reads (see ExpectRead*() below).
+// Each call to ReadInfo() or ReadData() consumes another expected read, in the
+// order those reads were expected, so:
+// reader->ExpectReadInfoOk(5, false);
+// reader->ExpectReadDataOk("abcdef", false);
+// reader->ExpectReadDataOk("ghijkl", false);
+// Expects these calls, in this order:
+// reader->ReadInfo(...); // reader writes 5 into
+// // |info_buf->response_data_size|
+// reader->ReadData(...); // reader writes "abcdef" into |buf|
+// reader->ReadData(...); // reader writes "ghijkl" into |buf|
+// If an unexpected call happens, this class DCHECKs.
+// If an expected read is marked "async", it will not complete immediately, but
+// must be completed by the test using CompletePendingRead().
+// These is a convenience method AllExpectedReadsDone() which returns whether
+// there are any expected reads that have not yet happened.
+class MockServiceWorkerResponseReader : public ServiceWorkerResponseReader {
+ public:
+ MockServiceWorkerResponseReader();
+ ~MockServiceWorkerResponseReader() override;
+
+ // ServiceWorkerResponseReader overrides
+ void ReadInfo(HttpResponseInfoIOBuffer* info_buf,
+ OnceCompletionCallback callback) override;
+ void ReadData(net::IOBuffer* buf,
+ int buf_len,
+ OnceCompletionCallback callback) override;
+
+ // Test helpers. ExpectReadInfo() and ExpectReadData() give precise control
+ // over both the data to be written and the result to return.
+ // ExpectReadInfoOk() and ExpectReadDataOk() are convenience functions for
+ // expecting successful reads, which always have their length as their result.
+
+ // Expect a call to ReadInfo() on this reader. For these functions, |len| will
+ // be used as |response_data_size|, not as the length of this particular read.
+ void ExpectReadInfo(size_t len, bool async, int result);
+ void ExpectReadInfoOk(size_t len, bool async);
+
+ // Expect a call to ReadData() on this reader. For these functions, |len| is
+ // the length of the data to be written back; in ExpectReadDataOk(), |len| is
+ // implicitly the length of |data|.
+ void ExpectReadData(const char* data, size_t len, bool async, int result);
+ void ExpectReadDataOk(const std::string& data, bool async);
+
+ // Convenient method for calling ExpectReadInfoOk() with the length being
+ // |bytes_stored|, and ExpectReadDataOk() for each element of |stored_data|.
+ void ExpectReadOk(const std::vector<std::string>& stored_data,
+ const size_t bytes_stored,
+ const bool async);
+
+ // Complete a pending async read. It is an error to call this function without
+ // a pending async read (ie, a previous call to ReadInfo() or ReadData()
+ // having not run its callback yet).
+ void CompletePendingRead();
+
+ // Returns whether all expected reads have occurred.
+ bool AllExpectedReadsDone() { return expected_reads_.size() == 0; }
+
+ private:
+ struct ExpectedRead {
+ ExpectedRead(size_t len, bool async, int result)
+ : data(nullptr), len(len), info(true), async(async), result(result) {}
+ ExpectedRead(const char* data, size_t len, bool async, int result)
+ : data(data), len(len), info(false), async(async), result(result) {}
+ const char* data;
+ size_t len;
+ bool info;
+ bool async;
+ int result;
+ };
+
+ base::queue<ExpectedRead> expected_reads_;
+ scoped_refptr<net::IOBuffer> pending_buffer_;
+ size_t pending_buffer_len_;
+ scoped_refptr<HttpResponseInfoIOBuffer> pending_info_;
+ OnceCompletionCallback pending_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerResponseReader);
+};
+
+// A test implementation of ServiceWorkerResponseWriter.
+//
+// This class exposes the ability to expect writes (see ExpectWrite*Ok() below).
+// Each write to this class via WriteInfo() or WriteData() consumes another
+// expected write, in the order they were added, so:
+// writer->ExpectWriteInfoOk(5, false);
+// writer->ExpectWriteDataOk(6, false);
+// writer->ExpectWriteDataOk(6, false);
+// Expects these calls, in this order:
+// writer->WriteInfo(...); // checks that |buf->response_data_size| == 5
+// writer->WriteData(...); // checks that 6 bytes are being written
+// writer->WriteData(...); // checks that another 6 bytes are being written
+// If this class receives an unexpected call to WriteInfo() or WriteData(), it
+// DCHECKs.
+// Expected writes marked async do not complete synchronously, but rather return
+// without running their callback and need to be completed with
+// CompletePendingWrite().
+// A convenience method AllExpectedWritesDone() is exposed so tests can ensure
+// that all expected writes have been consumed by matching calls to WriteInfo()
+// or WriteData().
+class MockServiceWorkerResponseWriter : public ServiceWorkerResponseWriter {
+ public:
+ MockServiceWorkerResponseWriter();
+ ~MockServiceWorkerResponseWriter() override;
+
+ // ServiceWorkerResponseWriter overrides
+ void WriteInfo(HttpResponseInfoIOBuffer* info_buf,
+ OnceCompletionCallback callback) override;
+ void WriteData(net::IOBuffer* buf,
+ int buf_len,
+ OnceCompletionCallback callback) override;
+
+ // Enqueue expected writes.
+ void ExpectWriteInfoOk(size_t len, bool async);
+ void ExpectWriteInfo(size_t len, bool async, int result);
+ void ExpectWriteDataOk(size_t len, bool async);
+ void ExpectWriteData(size_t len, bool async, int result);
+
+ // Complete a pending asynchronous write. This method DCHECKs unless there is
+ // a pending write (a write for which WriteInfo() or WriteData() has been
+ // called but the callback has not yet been run).
+ void CompletePendingWrite();
+
+ // Returns whether all expected reads have been consumed.
+ bool AllExpectedWritesDone() { return expected_writes_.size() == 0; }
+
+ private:
+ struct ExpectedWrite {
+ ExpectedWrite(bool is_info, size_t length, bool async, int result)
+ : is_info(is_info), length(length), async(async), result(result) {}
+ bool is_info;
+ size_t length;
+ bool async;
+ int result;
+ };
+
+ base::queue<ExpectedWrite> expected_writes_;
+
+ size_t info_written_;
+ size_t data_written_;
+
+ OnceCompletionCallback pending_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerResponseWriter);
+};
+
} // namespace content
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_TEST_UTILS_H_
diff --git a/chromium/content/browser/service_worker/service_worker_tls_browsertest.cc b/chromium/content/browser/service_worker/service_worker_tls_browsertest.cc
new file mode 100644
index 00000000000..42e9efdadd0
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_tls_browsertest.cc
@@ -0,0 +1,146 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/test/scoped_feature_list.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/shell/browser/shell_content_browser_client.h"
+#include "net/ssl/ssl_server_config.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "services/network/public/cpp/features.h"
+#include "third_party/blink/public/common/features.h"
+#include "url/gurl.h"
+
+namespace content {
+
+namespace {
+enum class ServicifiedFeatures { kNone, kServiceWorker, kNetwork };
+}
+
+// Tests TLS + service workers. Inspired by
+// content/browser/shared_worker/worker_browsertest.cc.
+class ServiceWorkerTlsTest
+ : public ContentBrowserTest,
+ public ::testing::WithParamInterface<ServicifiedFeatures> {
+ public:
+ ServiceWorkerTlsTest() = default;
+
+ void SetUp() override {
+ ServicifiedFeatures param = GetParam();
+ switch (param) {
+ case ServicifiedFeatures::kNone:
+ scoped_feature_list_.InitWithFeatures(
+ {}, {blink::features::kServiceWorkerServicification,
+ network::features::kNetworkService});
+ break;
+ case ServicifiedFeatures::kServiceWorker:
+ scoped_feature_list_.InitWithFeatures(
+ {blink::features::kServiceWorkerServicification},
+ {network::features::kNetworkService});
+ break;
+ case ServicifiedFeatures::kNetwork:
+ scoped_feature_list_.InitAndEnableFeature(
+ network::features::kNetworkService);
+ break;
+ }
+ ContentBrowserTest::SetUp();
+ }
+
+ void SetUpOnMainThread() override {
+ ShellContentBrowserClient::Get()->set_select_client_certificate_callback(
+ base::BindRepeating(&ServiceWorkerTlsTest::OnSelectClientCertificate,
+ base::Unretained(this)));
+ ASSERT_TRUE(embedded_test_server()->Start());
+ }
+
+ void TearDownOnMainThread() override {
+ ShellContentBrowserClient::Get()->set_select_client_certificate_callback(
+ base::RepeatingClosure());
+ }
+
+ int select_certificate_count() const { return select_certificate_count_; }
+
+ GURL GetTestURL(const std::string& test_case, const std::string& query) {
+ std::string url_string = "/workers/" + test_case + "?" + query;
+ return embedded_test_server()->GetURL(url_string);
+ }
+
+ private:
+ void OnSelectClientCertificate() { select_certificate_count_++; }
+
+ int select_certificate_count_ = 0;
+ base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+// Tests that TLS client auth prompts for a page controlled by a service
+// worker, when the service worker calls fetch() for the main resource.
+IN_PROC_BROWSER_TEST_P(ServiceWorkerTlsTest, ClientAuthFetchMainResource) {
+ // Start an HTTPS server which doesn't need client certs.
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
+ net::SSLServerConfig ssl_config;
+ ssl_config.client_cert_type =
+ net::SSLServerConfig::ClientCertType::NO_CLIENT_CERT;
+ https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
+ ASSERT_TRUE(https_server.Start());
+
+ // Load a page that installs the service worker.
+ EXPECT_TRUE(NavigateToURL(
+ shell(), https_server.GetURL("/workers/service_worker_setup.html")));
+ EXPECT_EQ("ok", EvalJs(shell(), "setup();"));
+
+ // Set the HTTPS server to require client certs.
+ ssl_config.client_cert_type =
+ net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
+ https_server.ResetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
+
+ // Load a page that the SW intercepts with respondWith(fetch()). It should
+ // prompt client certificate selection. (The navigation fails because
+ // this test doesn't select a client certificate.)
+ EXPECT_FALSE(NavigateToURL(
+ shell(), https_server.GetURL("/workers/simple.html?intercept")));
+ EXPECT_EQ(1, select_certificate_count());
+}
+
+// Tests that TLS client auth prompts for a page controlled by a service
+// worker, when the service worker calls fetch() for a subresource.
+IN_PROC_BROWSER_TEST_P(ServiceWorkerTlsTest, ClientAuthFetchSubResource) {
+ // Load a page that installs the service worker.
+ EXPECT_TRUE(NavigateToURL(
+ shell(), GetTestURL("service_worker_setup.html", std::string())));
+ EXPECT_EQ("ok", EvalJs(shell(), "setup();"));
+
+ // Load a page controlled by the service worker.
+ EXPECT_TRUE(NavigateToURL(shell(),
+ GetTestURL("simple.html?fallback", std::string())));
+
+ // Start HTTPS server.
+ net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server.ServeFilesFromSourceDirectory("content/test/data");
+ net::SSLServerConfig ssl_config;
+ ASSERT_TRUE(https_server.Start());
+ ssl_config.client_cert_type =
+ net::SSLServerConfig::ClientCertType::REQUIRE_CLIENT_CERT;
+ https_server.ResetSSLConfig(net::EmbeddedTestServer::CERT_OK, ssl_config);
+
+ // Perform a fetch from the controlled page to the https server. It should
+ // prompt client certificate selection. (The fetch fails because this test
+ // doesn't select a client certificate.)
+ std::string url = https_server.GetURL("/?intercept").spec();
+ EXPECT_EQ("TypeError", EvalJs(shell(), "try_fetch('" + url + "');"));
+ EXPECT_EQ(1, select_certificate_count());
+}
+
+INSTANTIATE_TEST_CASE_P(/* no prefix */,
+ ServiceWorkerTlsTest,
+ ::testing::Values(ServicifiedFeatures::kNone,
+ ServicifiedFeatures::kServiceWorker,
+ ServicifiedFeatures::kNetwork));
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_update_checker.cc b/chromium/content/browser/service_worker/service_worker_update_checker.cc
new file mode 100644
index 00000000000..1156b0e4159
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_update_checker.cc
@@ -0,0 +1,74 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_update_checker.h"
+
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_storage.h"
+#include "content/browser/service_worker/service_worker_version.h"
+
+namespace content {
+
+ServiceWorkerUpdateChecker::ServiceWorkerUpdateChecker(
+ std::vector<ServiceWorkerDatabase::ResourceRecord> scripts_to_compare,
+ scoped_refptr<ServiceWorkerVersion> version_to_update,
+ scoped_refptr<network::SharedURLLoaderFactory> loader_factory)
+ : scripts_to_compare_(std::move(scripts_to_compare)),
+ version_to_update_(std::move(version_to_update)),
+ loader_factory_(std::move(loader_factory)),
+ weak_factory_(this) {}
+
+ServiceWorkerUpdateChecker::~ServiceWorkerUpdateChecker() = default;
+
+void ServiceWorkerUpdateChecker::Start(UpdateStatusCallback callback) {
+ DCHECK(!scripts_to_compare_.empty());
+ callback_ = std::move(callback);
+ CheckOneScript();
+}
+
+void ServiceWorkerUpdateChecker::OnOneUpdateCheckFinished(
+ bool is_script_changed) {
+ running_checker_.reset();
+ if (is_script_changed) {
+ // Found an updated script. Stop the comparison of scripts here and
+ // return to ServiceWorkerRegisterJob to continue the update.
+ // Note that running |callback_| will delete |this|.
+ std::move(callback_).Run(true);
+ return;
+ }
+ CheckOneScript();
+}
+
+void ServiceWorkerUpdateChecker::CheckOneScript() {
+ DCHECK_LE(scripts_compared_, scripts_to_compare_.size());
+ if (scripts_compared_ == scripts_to_compare_.size()) {
+ // None of the scripts that went through the comparison had any updates.
+ // Note that running |callback_| will delete |this|.
+ std::move(callback_).Run(false);
+ return;
+ }
+
+ ServiceWorkerDatabase::ResourceRecord script =
+ scripts_to_compare_[scripts_compared_++];
+ DCHECK_NE(kInvalidServiceWorkerResourceId, script.resource_id)
+ << "All the target scripts should be stored in the storage.";
+
+ bool is_main_script = script.url == version_to_update_->script_url();
+ ServiceWorkerStorage* storage = version_to_update_->context()->storage();
+
+ // We need two identical readers for comparing and reading the resource for
+ // |script.resource_id| from the storage.
+ auto compare_reader = storage->CreateResponseReader(script.resource_id);
+ auto copy_reader = storage->CreateResponseReader(script.resource_id);
+
+ auto writer = storage->CreateResponseWriter(storage->NewResourceId());
+
+ running_checker_ = std::make_unique<ServiceWorkerSingleScriptUpdateChecker>(
+ script.url, is_main_script, loader_factory_, std::move(compare_reader),
+ std::move(copy_reader), std::move(writer),
+ base::BindOnce(&ServiceWorkerUpdateChecker::OnOneUpdateCheckFinished,
+ weak_factory_.GetWeakPtr()));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_update_checker.h b/chromium/content/browser/service_worker/service_worker_update_checker.h
new file mode 100644
index 00000000000..2bd0b086b92
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_update_checker.h
@@ -0,0 +1,56 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_UPDATE_CHECKER_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_UPDATE_CHECKER_H_
+
+#include "base/callback.h"
+#include "content/browser/service_worker/service_worker_database.h"
+#include "content/browser/service_worker/service_worker_single_script_update_checker.h"
+
+namespace network {
+class SharedURLLoaderFactory;
+}
+
+namespace content {
+
+class ServiceWorkerVersion;
+
+class ServiceWorkerUpdateChecker {
+ public:
+ using UpdateStatusCallback = base::OnceCallback<void(bool)>;
+
+ ServiceWorkerUpdateChecker(
+ std::vector<ServiceWorkerDatabase::ResourceRecord> scripts_to_compare,
+ scoped_refptr<ServiceWorkerVersion> version_to_update,
+ scoped_refptr<network::SharedURLLoaderFactory> loader_factory);
+ ~ServiceWorkerUpdateChecker();
+
+ // |callback| is always triggered when Start() finishes. If the scripts are
+ // found to have any changes, the argument of |callback| is true and otherwise
+ // false.
+ void Start(UpdateStatusCallback callback);
+
+ void OnOneUpdateCheckFinished(bool is_script_changed);
+
+ private:
+ void CheckOneScript();
+
+ std::vector<ServiceWorkerDatabase::ResourceRecord> scripts_to_compare_;
+ size_t scripts_compared_ = 0;
+
+ // The version which triggered this update.
+ scoped_refptr<ServiceWorkerVersion> version_to_update_;
+
+ std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> running_checker_;
+
+ UpdateStatusCallback callback_;
+
+ scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
+ base::WeakPtrFactory<ServiceWorkerUpdateChecker> weak_factory_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_UPDATE_CHECKER_H_
diff --git a/chromium/content/browser/service_worker/service_worker_url_job_wrapper.cc b/chromium/content/browser/service_worker/service_worker_url_job_wrapper.cc
index eaf770dc02d..9df6d060839 100644
--- a/chromium/content/browser/service_worker/service_worker_url_job_wrapper.cc
+++ b/chromium/content/browser/service_worker/service_worker_url_job_wrapper.cc
@@ -79,12 +79,8 @@ void ServiceWorkerURLJobWrapper::FailDueToLostController() {
url_request_job_->FailDueToLostController();
}
-bool ServiceWorkerURLJobWrapper::WasCanceled() const {
- if (url_loader_job_) {
- return url_loader_job_->WasCanceled();
- } else {
- return !url_request_job_;
- }
+bool ServiceWorkerURLJobWrapper::IsAlive() const {
+ return url_loader_job_ || url_request_job_;
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_url_job_wrapper.h b/chromium/content/browser/service_worker/service_worker_url_job_wrapper.h
index c2cc39872ce..e6e84117b44 100644
--- a/chromium/content/browser/service_worker/service_worker_url_job_wrapper.h
+++ b/chromium/content/browser/service_worker/service_worker_url_job_wrapper.h
@@ -85,8 +85,10 @@ class CONTENT_EXPORT ServiceWorkerURLJobWrapper {
// if needed later.
void FailDueToLostController();
- // Returns true if the underlying job has been canceled or destroyed.
- bool WasCanceled() const;
+ // Returns true if the underlying job has not been destroyed. This only useful
+ // in the non-S13nServiceWorker case, since this wrapper owns the job in the
+ // S13nServiceWorker case.
+ bool IsAlive() const;
private:
enum class JobType { kURLRequest, kURLLoader };
diff --git a/chromium/content/browser/service_worker/service_worker_url_request_job.cc b/chromium/content/browser/service_worker/service_worker_url_request_job.cc
index 033f55cb8cd..1bb65c47c41 100644
--- a/chromium/content/browser/service_worker/service_worker_url_request_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_url_request_job.cc
@@ -312,7 +312,7 @@ bool ServiceWorkerURLRequestJob::Delegate::RequestStillValid(
ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
- const std::string& client_id,
+ base::WeakPtr<ServiceWorkerProviderHost> provider_host,
base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
const ResourceContext* resource_context,
network::mojom::FetchRequestMode request_mode,
@@ -321,7 +321,7 @@ ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
const std::string& integrity,
bool keepalive,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
scoped_refptr<network::ResourceRequestBody> body,
Delegate* delegate)
@@ -330,7 +330,9 @@ ServiceWorkerURLRequestJob::ServiceWorkerURLRequestJob(
response_type_(ResponseType::NOT_DETERMINED),
is_started_(false),
fetch_response_type_(network::mojom::FetchResponseType::kDefault),
- client_id_(client_id),
+ provider_host_(std::move(provider_host)),
+ client_id_(provider_host_ ? provider_host_->client_uuid()
+ : std::string()),
blob_storage_context_(blob_storage_context),
resource_context_(resource_context),
request_mode_(request_mode),
@@ -569,13 +571,20 @@ ServiceWorkerURLRequestJob::CreateResourceRequest() {
request->fetch_credentials_mode = credentials_mode_;
request->load_flags = request_->load_flags();
request->fetch_redirect_mode = redirect_mode_;
- request->fetch_request_context_type = request_context_type_;
+ request->fetch_request_context_type = static_cast<int>(request_context_type_);
request->fetch_frame_type = frame_type_;
const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request_);
if (info)
request->transition_type = info->GetPageTransition();
request->fetch_integrity = integrity_;
request->keepalive = keepalive_;
+ // Set the request window id if we have one. If we don't, or the provider
+ // host is gone, it just means client certification authentication may fail
+ // so continue on without it anyway.
+ if (provider_host_ && provider_host_->fetch_request_window_id()) {
+ request->fetch_window_id =
+ base::make_optional(provider_host_->fetch_request_window_id());
+ }
return request;
}
@@ -586,7 +595,7 @@ blink::mojom::BlobPtr ServiceWorkerURLRequestJob::CreateRequestBodyBlob(
auto blob_builder =
std::make_unique<storage::BlobDataBuilder>(base::GenerateGUID());
for (const network::DataElement& element : (*body_->elements())) {
- blob_builder->AppendIPCDataElement(element, nullptr,
+ blob_builder->AppendIPCDataElement(element,
blob_storage_context_->registry());
}
@@ -660,6 +669,7 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing,
scoped_refptr<ServiceWorkerVersion> version) {
// Do not clear |fetch_dispatcher_| if it has dispatched a navigation preload
// request to keep the network::mojom::URLLoader related objects in it,
diff --git a/chromium/content/browser/service_worker/service_worker_url_request_job.h b/chromium/content/browser/service_worker/service_worker_url_request_job.h
index ea2182bae3d..de3e85b0ca7 100644
--- a/chromium/content/browser/service_worker/service_worker_url_request_job.h
+++ b/chromium/content/browser/service_worker/service_worker_url_request_job.h
@@ -24,7 +24,6 @@
#include "content/browser/service_worker/service_worker_url_job_wrapper.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker.mojom.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/http/http_byte_range.h"
@@ -37,6 +36,7 @@
#include "storage/common/blob_storage/blob_storage_constants.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "url/gurl.h"
namespace net {
@@ -77,7 +77,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
ServiceWorkerURLRequestJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
- const std::string& client_id,
+ base::WeakPtr<ServiceWorkerProviderHost> provider_host,
base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
const ResourceContext* resource_context,
network::mojom::FetchRequestMode request_mode,
@@ -86,7 +86,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
const std::string& integrity,
bool keepalive,
ResourceType resource_type,
- RequestContextType request_context_type,
+ blink::mojom::RequestContextType request_context_type,
network::mojom::RequestContextFrameType frame_type,
scoped_refptr<network::ResourceRequestBody> body,
Delegate* delegate);
@@ -194,6 +194,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing,
scoped_refptr<ServiceWorkerVersion> version);
void SetResponse(blink::mojom::FetchAPIResponsePtr response);
@@ -309,6 +310,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
// Used when response type is FORWARD_TO_SERVICE_WORKER.
std::unique_ptr<ServiceWorkerFetchDispatcher> fetch_dispatcher_;
+ base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
std::string client_id_;
base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
const ResourceContext* resource_context_;
@@ -322,7 +324,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
std::string integrity_;
const bool keepalive_;
const ResourceType resource_type_;
- RequestContextType request_context_type_;
+ blink::mojom::RequestContextType request_context_type_;
network::mojom::RequestContextFrameType frame_type_;
bool fall_back_required_;
// ResourceRequestBody has a collection of BlobDataHandles attached to it
diff --git a/chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc
index fef3544e4ba..5e3136dabb0 100644
--- a/chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -35,7 +35,6 @@
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/blob_handle.h"
#include "content/public/common/browser_side_navigation_policy.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "content/public/test/mock_resource_context.h"
#include "content/public/test/test_browser_context.h"
@@ -66,6 +65,7 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
namespace content {
namespace service_worker_url_request_job_unittest {
@@ -115,13 +115,12 @@ class MockProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
}
job_ = new ServiceWorkerURLRequestJob(
- request, network_delegate, provider_host_->client_uuid(),
- blob_storage_context_, resource_context_,
- network::mojom::FetchRequestMode::kNoCORS,
+ request, network_delegate, provider_host_, blob_storage_context_,
+ resource_context_, network::mojom::FetchRequestMode::kNoCORS,
network::mojom::FetchCredentialsMode::kOmit,
network::mojom::FetchRedirectMode::kFollow,
std::string() /* integrity */, false /* keepalive */, resource_type_,
- REQUEST_CONTEXT_TYPE_HYPERLINK,
+ blink::mojom::RequestContextType::HYPERLINK,
network::mojom::RequestContextFrameType::kTopLevel,
scoped_refptr<network::ResourceRequestBody>(), delegate_);
if (simulate_navigation_preload_) {
@@ -233,7 +232,8 @@ class ServiceWorkerURLRequestJobTest
registration_ = new ServiceWorkerRegistration(
options, 1L, helper_->context()->AsWeakPtr());
version_ = new ServiceWorkerVersion(
- registration_.get(), GURL("https://example.com/service_worker.js"), 1L,
+ registration_.get(), GURL("https://example.com/service_worker.js"),
+ blink::mojom::ScriptType::kClassic, 1L,
helper_->context()->AsWeakPtr());
std::vector<ServiceWorkerDatabase::ResourceRecord> records;
records.push_back(WriteToDiskCacheWithCustomResponseInfoSync(
@@ -342,7 +342,7 @@ class ServiceWorkerURLRequestJobTest
expected_response, expect_valid_ssl);
}
- bool HasWork() { return version_->HasWorkInBrowser(); }
+ bool HasWork() { return !version_->HasNoWork(); }
// Runs a request where the active worker starts a request in ACTIVATING state
// and fails to reach ACTIVATED.
@@ -490,10 +490,11 @@ class DelayHelper : public EmbeddedWorkerTestHelper {
}
void Respond() {
- response_callback_->OnResponse(MakeOkResponse(), base::Time::Now());
+ response_callback_->OnResponse(
+ MakeOkResponse(), blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(finish_callback_)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
protected:
@@ -707,10 +708,11 @@ class ProviderDeleteHelper : public EmbeddedWorkerTestHelper {
mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
override {
context()->RemoveProviderHost(mock_render_process_id(), kProviderID);
- response_callback->OnResponse(MakeOkResponse(), base::Time::Now());
+ response_callback->OnResponse(
+ MakeOkResponse(), blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
private:
@@ -794,10 +796,12 @@ class BlobResponder : public EmbeddedWorkerTestHelper {
// Mojo, we give it a dummy value.
auto dummy_request = mojo::MakeRequest(&response->blob->blob);
- response_callback->OnResponse(std::move(response), base::Time::Now());
+ response_callback->OnResponse(
+ std::move(response),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
std::string blob_uuid_;
@@ -889,10 +893,11 @@ class StreamResponder : public EmbeddedWorkerTestHelper {
blink::mojom::FetchAPIResponsePtr response = MakeOkResponse();
response->headers = MakeHeaders();
response_callback->OnResponseStream(
- std::move(response), std::move(stream_handle_), base::Time::Now());
+ std::move(response), std::move(stream_handle_),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
blink::mojom::ServiceWorkerStreamHandlePtr stream_handle_;
@@ -1272,7 +1277,7 @@ class FailFetchHelper : public EmbeddedWorkerTestHelper {
SimulateWorkerStopped(embedded_worker_id);
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::ABORTED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
private:
@@ -1351,7 +1356,7 @@ class EarlyResponseHelper : public EmbeddedWorkerTestHelper {
void FinishWaitUntil() {
std::move(finish_callback_)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
}
protected:
@@ -1363,7 +1368,8 @@ class EarlyResponseHelper : public EmbeddedWorkerTestHelper {
mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
override {
finish_callback_ = std::move(finish_callback);
- response_callback->OnResponse(MakeOkResponse(), base::Time::Now());
+ response_callback->OnResponse(
+ MakeOkResponse(), blink::mojom::ServiceWorkerFetchEventTiming::New());
}
private:
@@ -1395,10 +1401,10 @@ TEST_F(ServiceWorkerURLRequestJobTest, EarlyResponse) {
EXPECT_FALSE(info->response_is_in_cache_storage());
EXPECT_EQ(std::string(), info->response_cache_storage_cache_name());
- EXPECT_TRUE(version_->HasWorkInBrowser());
+ EXPECT_FALSE(version_->HasNoWork());
helper->FinishWaitUntil();
base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(version_->HasWorkInBrowser());
+ EXPECT_TRUE(version_->HasNoWork());
}
// Test cancelling the URLRequest while the fetch event is in flight.
@@ -1423,12 +1429,12 @@ TEST_F(ServiceWorkerURLRequestJobTest, CancelRequest) {
base::RunLoop().RunUntilIdle();
// Respond to the fetch event.
- EXPECT_TRUE(version_->HasWorkInBrowser());
+ EXPECT_FALSE(version_->HasNoWork());
helper->Respond();
base::RunLoop().RunUntilIdle();
// The fetch event request should no longer be in-flight.
- EXPECT_FALSE(version_->HasWorkInBrowser());
+ EXPECT_TRUE(version_->HasNoWork());
}
// TODO(kinuko): Add more tests with different response data and also for
diff --git a/chromium/content/browser/service_worker/service_worker_version.cc b/chromium/content/browser/service_worker/service_worker_version.cc
index 5d8213494b9..248382497e3 100644
--- a/chromium/content/browser/service_worker/service_worker_version.cc
+++ b/chromium/content/browser/service_worker/service_worker_version.cc
@@ -226,6 +226,7 @@ base::TimeDelta ServiceWorkerVersion::GetTickDuration(
ServiceWorkerVersion::ServiceWorkerVersion(
ServiceWorkerRegistration* registration,
const GURL& script_url,
+ blink::mojom::ScriptType script_type,
int64_t version_id,
base::WeakPtr<ServiceWorkerContextCore> context)
: version_id_(version_id),
@@ -233,6 +234,7 @@ ServiceWorkerVersion::ServiceWorkerVersion(
script_url_(script_url),
script_origin_(url::Origin::Create(script_url_)),
scope_(registration->pattern()),
+ script_type_(script_type),
fetch_handler_existence_(FetchHandlerExistence::UNKNOWN),
site_for_uma_(ServiceWorkerMetrics::SiteFromURL(scope_)),
binding_(this),
@@ -464,6 +466,39 @@ void ServiceWorkerVersion::StopWorker(base::OnceClosure callback) {
NOTREACHED();
}
+void ServiceWorkerVersion::TriggerIdleTerminationAsap() {
+ needs_to_be_terminated_asap_ = true;
+ endpoint()->SetIdleTimerDelayToZero();
+}
+
+bool ServiceWorkerVersion::OnRequestTermination() {
+ if (running_status() == EmbeddedWorkerStatus::STOPPING)
+ return true;
+ DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, running_status());
+
+ worker_is_idle_on_renderer_ = true;
+
+ // Determine if the worker can be terminated.
+ bool will_be_terminated = HasNoWork();
+ if (embedded_worker_->devtools_attached()) {
+ // Basically the service worker won't be terminated if DevTools is attached.
+ // But when activation is happening and this worker needs to be terminated
+ // asap, it'll be terminated.
+ will_be_terminated = needs_to_be_terminated_asap_;
+ }
+
+ if (will_be_terminated) {
+ embedded_worker_->Stop();
+ } else {
+ // The worker needs to run more. The worker should start handling queued
+ // events dispatched to the worker directly (e.g. FetchEvent for
+ // subresources).
+ worker_is_idle_on_renderer_ = false;
+ }
+
+ return will_be_terminated;
+}
+
void ServiceWorkerVersion::ScheduleUpdate() {
if (!context_)
return;
@@ -570,7 +605,7 @@ int ServiceWorkerVersion::StartRequestWithCustomTimeout(
// be dispatched will reset the idle status. That means the worker can receive
// events directly from any clients, so we cannot trigger OnNoWork after this
// point.
- idle_timer_fired_in_renderer_ = false;
+ worker_is_idle_on_renderer_ = false;
return request_id;
}
@@ -597,7 +632,7 @@ bool ServiceWorkerVersion::StartExternalRequest(
bool ServiceWorkerVersion::FinishRequest(int request_id,
bool was_handled,
- base::Time dispatch_event_time) {
+ base::TimeTicks dispatch_event_time) {
InflightRequest* request = inflight_requests_.Lookup(request_id);
if (!request)
return false;
@@ -607,7 +642,7 @@ bool ServiceWorkerVersion::FinishRequest(int request_id,
request->event_type, tick_clock_->NowTicks() - request->start_time_ticks,
was_handled);
ServiceWorkerMetrics::RecordEventDispatchingDelay(
- request->event_type, dispatch_event_time - request->start_time);
+ request->event_type, dispatch_event_time - request->start_time_ticks);
RestartTick(&idle_time_);
TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request",
@@ -630,12 +665,11 @@ bool ServiceWorkerVersion::FinishExternalRequest(
if (running_status() != EmbeddedWorkerStatus::RUNNING)
return false;
- RequestUUIDToRequestIDMap::iterator iter =
- external_request_uuid_to_request_id_.find(request_uuid);
+ auto iter = external_request_uuid_to_request_id_.find(request_uuid);
if (iter != external_request_uuid_to_request_id_.end()) {
int request_id = iter->second;
external_request_uuid_to_request_id_.erase(iter);
- return FinishRequest(request_id, true, clock_->Now());
+ return FinishRequest(request_id, true, tick_clock_->NowTicks());
}
// It is possible that the request was cancelled or timed out before and we
@@ -713,8 +747,10 @@ void ServiceWorkerVersion::OnStreamResponseStarted() {
void ServiceWorkerVersion::OnStreamResponseFinished() {
DCHECK_GT(inflight_stream_response_count_, 0);
inflight_stream_response_count_--;
- if (!HasWorkInBrowser())
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled() &&
+ !HasWorkInBrowser()) {
OnNoWorkInBrowser();
+ }
}
void ServiceWorkerVersion::AddObserver(Observer* observer) {
@@ -868,6 +904,12 @@ void ServiceWorkerVersion::SetClockForTesting(base::Clock* clock) {
clock_ = clock;
}
+bool ServiceWorkerVersion::HasNoWork() const {
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled())
+ return !HasWorkInBrowser();
+ return !HasWorkInBrowser() && worker_is_idle_on_renderer_;
+}
+
const net::HttpResponseInfo*
ServiceWorkerVersion::GetMainScriptHttpResponseInfo() {
return main_script_http_info_.get();
@@ -1335,10 +1377,15 @@ void ServiceWorkerVersion::OpenWindow(
base::BindOnce(&OnOpenWindowFinished, std::move(callback)));
}
+bool ServiceWorkerVersion::HasWorkInBrowser() const {
+ return !inflight_requests_.IsEmpty() || inflight_stream_response_count_ > 0 ||
+ !start_callbacks_.empty();
+}
+
void ServiceWorkerVersion::OnSimpleEventFinished(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- base::Time dispatch_event_time) {
+ base::TimeTicks dispatch_event_time) {
InflightRequest* request = inflight_requests_.Lookup(request_id);
// |request| will be null when the request has been timed out.
if (!request)
@@ -1512,7 +1559,8 @@ void ServiceWorkerVersion::StartWorkerInternal() {
// again from OnStoppedInternal if StopWorker is called before OnStarted.
StartTimeoutTimer();
- idle_timer_fired_in_renderer_ = false;
+ worker_is_idle_on_renderer_ = false;
+ needs_to_be_terminated_asap_ = false;
auto provider_info = mojom::ServiceWorkerProviderInfoForStartWorker::New();
provider_host_ = ServiceWorkerProviderHost::PreCreateForController(
@@ -1522,6 +1570,7 @@ void ServiceWorkerVersion::StartWorkerInternal() {
params->service_worker_version_id = version_id_;
params->scope = scope_;
params->script_url = script_url_;
+ params->script_type = script_type_;
params->is_installed = IsInstalled(status_);
params->pause_after_download = pause_after_download();
@@ -1699,7 +1748,8 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
// skip this check.
if (!blink::ServiceWorkerUtils::IsServicificationEnabled() &&
GetTickDuration(idle_time_) > kIdleWorkerTimeout) {
- StopWorkerIfIdle(false /* requested_from_renderer */);
+ if (HasNoWork())
+ embedded_worker_->StopIfNotAttachedToDevTools();
return;
}
@@ -1724,53 +1774,7 @@ void ServiceWorkerVersion::OnPingTimeout() {
// blink::ServiceWorkerStatusCode::kErrorTimeout.
embedded_worker_->AddMessageToConsole(blink::WebConsoleMessage::kLevelVerbose,
kNotRespondingErrorMesage);
- StopWorkerIfIdle(false /* requested_from_renderer */);
-}
-
-void ServiceWorkerVersion::StopWorkerIfIdle(bool requested_from_renderer) {
- if (running_status() == EmbeddedWorkerStatus::STOPPED ||
- running_status() == EmbeddedWorkerStatus::STOPPING ||
- !stop_callbacks_.empty()) {
- return;
- }
-
- if (!blink::ServiceWorkerUtils::IsServicificationEnabled()) {
- // StopWorkerIfIdle() may be called for two reasons: "idle-timeout" or
- // "ping-timeout". For idle-timeout (i.e. ping hasn't timed out), check if
- // the worker really is idle.
- if (!ping_controller_.IsTimedOut() && HasWorkInBrowser())
- return;
- embedded_worker_->StopIfNotAttachedToDevTools();
- return;
- }
-
- DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
- // Ping timeout
- if (ping_controller_.IsTimedOut()) {
- DCHECK(!requested_from_renderer);
- embedded_worker_->StopIfNotAttachedToDevTools();
- return;
- }
-
- // Idle timeout
- DCHECK(requested_from_renderer);
- DCHECK(start_callbacks_.empty());
- idle_timer_fired_in_renderer_ = true;
-
- // We may still have some work in the browser-side that are not
- // observable by the renderer, i.e. response streaming. In such case
- // we return here with setting |idle_timer_fired_in_renderer_| to true.
- // It will be checked later (i.e. when streaming finishes) to see if we
- // we should fire OnNoWork().
- if (HasWorkInBrowser())
- return;
embedded_worker_->StopIfNotAttachedToDevTools();
- OnNoWorkInBrowser();
-}
-
-bool ServiceWorkerVersion::HasWorkInBrowser() const {
- return !inflight_requests_.IsEmpty() || inflight_stream_response_count_ > 0 ||
- !start_callbacks_.empty();
}
void ServiceWorkerVersion::RecordStartWorkerResult(
@@ -1951,7 +1955,6 @@ void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) {
should_restart);
ClearTick(&stop_time_);
}
- idle_timer_fired_in_renderer_ = false;
StopTimeoutTimer();
// Fire all stop callbacks.
@@ -1987,6 +1990,7 @@ void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) {
installed_scripts_sender_.reset();
binding_.Close();
pending_external_requests_.clear();
+ worker_is_idle_on_renderer_ = true;
for (auto& observer : observers_)
observer.OnRunningStateChanged(this);
@@ -2020,14 +2024,10 @@ void ServiceWorkerVersion::OnNoWorkInBrowser() {
}
DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
- if (!idle_timer_fired_in_renderer_ &&
- running_status() != EmbeddedWorkerStatus::STOPPED) {
- return;
+ if (worker_is_idle_on_renderer_) {
+ for (auto& observer : observers_)
+ observer.OnNoWork(this);
}
-
- for (auto& observer : observers_)
- observer.OnNoWork(this);
- idle_timer_fired_in_renderer_ = false;
}
bool ServiceWorkerVersion::IsStartWorkerAllowed() const {
diff --git a/chromium/content/browser/service_worker/service_worker_version.h b/chromium/content/browser/service_worker/service_worker_version.h
index 166f9093530..014c8eaad5b 100644
--- a/chromium/content/browser/service_worker/service_worker_version.h
+++ b/chromium/content/browser/service_worker/service_worker_version.h
@@ -101,6 +101,10 @@ namespace service_worker_registration_unittest {
class ServiceWorkerActivationTest;
} // namespace service_worker_registration_unittest
+namespace service_worker_navigation_loader_unittest {
+class ServiceWorkerNavigationLoaderTest;
+} // namespace service_worker_navigation_loader_unittest
+
// This class corresponds to a specific version of a ServiceWorker
// script for a given pattern. When a script is upgraded, there may be
// more than one ServiceWorkerVersion "running" at a time, but only
@@ -117,7 +121,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
base::OnceCallback<void(blink::ServiceWorkerStatusCode)>;
using SimpleEventCallback =
base::OnceCallback<void(blink::mojom::ServiceWorkerEventStatus,
- base::Time)>;
+ base::TimeTicks)>;
// Current version status; some of the status (e.g. INSTALLED and ACTIVATED)
// should be persisted unlike running status.
@@ -183,6 +187,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
ServiceWorkerVersion(ServiceWorkerRegistration* registration,
const GURL& script_url,
+ blink::mojom::ScriptType script_type,
int64_t version_id,
base::WeakPtr<ServiceWorkerContextCore> context);
@@ -191,6 +196,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
const GURL& script_url() const { return script_url_; }
const url::Origin& script_origin() const { return script_origin_; }
const GURL& scope() const { return scope_; }
+ blink::mojom::ScriptType script_type() const { return script_type_; }
EmbeddedWorkerStatus running_status() const {
return embedded_worker_->status();
}
@@ -246,13 +252,18 @@ class CONTENT_EXPORT ServiceWorkerVersion
// Stops an embedded worker for this version.
void StopWorker(base::OnceClosure callback);
- // Stops the worker if it is idle (has no in-flight requests) or timed out
- // ping.
- //
+ // Asks the renderer to notify the browser that it becomes idle as soon as
+ // possible, and it results in letting idle termination occur earlier. This is
+ // typically used for activation. An active worker needs to be swapped out
+ // soon after the service worker becomes idle if a waiting worker exists.
+ void TriggerIdleTerminationAsap();
+
// S13nServiceWorker:
- // |requested_from_renderer| should be true if StopWorkerIfIdle() is called by
- // mojom::EmbeddedWorkerInstanceHost::RequestTermination().
- void StopWorkerIfIdle(bool requested_from_renderer);
+ // Called when the renderer notifies the browser that the worker is now idle.
+ // Returns true if the worker will be terminated and the worker should not
+ // handle any events dispatched directly from clients (e.g. FetchEvents for
+ // subresources).
+ bool OnRequestTermination();
// Skips waiting and forces this version to become activated.
void SkipWaitingFromDevTools();
@@ -317,7 +328,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
// TODO(mek): Use something other than a bool for event status.
bool FinishRequest(int request_id,
bool was_handled,
- base::Time dispatch_event_time);
+ base::TimeTicks dispatch_event_time);
// Finishes an external request that was started by StartExternalRequest().
// Returns false if there was an error finishing the request: e.g. the request
@@ -375,8 +386,12 @@ class CONTENT_EXPORT ServiceWorkerVersion
base::WeakPtr<ServiceWorkerContextCore> context() const { return context_; }
// Called when the browser process starts/finishes reading a fetch event
- // response via Mojo data pipe from the service worker. We try to not stop the
- // service worker while there is an ongoing response.
+ // response via Mojo data pipe from the service worker.
+ // Non-S13nServiceWorker: We try to not stop the service worker while there is
+ // an ongoing response.
+ // S13nServiceWorker: Renderer's idle timer recognizes stream responses, so we
+ // rely on it instead of keeping track of stream responses in the browser
+ // process.
void OnStreamResponseStarted();
void OnStreamResponseFinished();
@@ -459,17 +474,9 @@ class CONTENT_EXPORT ServiceWorkerVersion
// Used to allow tests to change wall clock for testing.
void SetClockForTesting(base::Clock* clock);
- // Non-S13nServiceWorker: returns true if the service worker has work to do:
- // it has inflight requests, in-progress streaming URLRequestJobs, or pending
- // start callbacks.
- //
- // S13nServiceWorker: returns true if the worker has work on the browser.
- // Note that this method may return false even when the service worker still
- // has work to do; clients may dispatch events to the service worker directly.
- // You can ensure no inflight requests exist when HasWorkInBrowser() returns
- // false and |idle_timer_fired_in_renderer_| is true, or when the worker is
- // stopped.
- bool HasWorkInBrowser() const;
+ // Returns true when the service worker isn't handling any events or stream
+ // responses, initiated from either the browser or the renderer.
+ bool HasNoWork() const;
// Returns the number of pending external request count of this worker.
size_t GetExternalRequestCountForTest() const {
@@ -521,6 +528,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
friend class service_worker_registration_unittest::
ServiceWorkerActivationTest;
friend class service_worker_version_unittest::ServiceWorkerVersionTest;
+ friend class service_worker_navigation_loader_unittest::
+ ServiceWorkerNavigationLoaderTest;
FRIEND_TEST_ALL_PREFIXES(service_worker_controllee_request_handler_unittest::
ServiceWorkerControlleeRequestHandlerTest,
@@ -704,12 +713,30 @@ class CONTENT_EXPORT ServiceWorkerVersion
scoped_refptr<ServiceWorkerRegistration> registration);
void StartWorkerInternal();
+ // Stops the worker if it is idle (has no in-flight requests) or timed out
+ // ping.
+ void StopWorkerIfIdle();
+
+ // Non-S13nServiceWorker: returns true if the service worker has work to do:
+ // it has inflight requests, in-progress streaming URLRequestJobs, or pending
+ // start callbacks.
+ //
+ // S13nServiceWorker: returns true if the service worker has work to do:
+ // because the browser process initiated a request to the service worker which
+ // isn't done yet.
+ // Note that this method may return false even when the service worker still
+ // has work to do; clients may dispatch events to the service worker directly.
+ // You can ensure no inflight requests exist when HasWorkInBrowser() returns
+ // false and |worker_is_idle_on_renderer_| is true, or when the worker is
+ // stopped.
+ bool HasWorkInBrowser() const;
+
// Callback function for simple events dispatched through mojo interface
// mojom::ServiceWorker. Use CreateSimpleEventCallback() to
// create a callback for a given |request_id|.
void OnSimpleEventFinished(int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- base::Time dispatch_event_time);
+ base::TimeTicks dispatch_event_time);
// The timeout timer periodically calls OnTimeoutTimer, which stops the worker
// if it is excessively idle or unresponsive to ping.
@@ -774,6 +801,10 @@ class CONTENT_EXPORT ServiceWorkerVersion
const GURL script_url_;
const url::Origin script_origin_;
const GURL scope_;
+ // A service worker has an associated type which is either
+ // "classic" or "module". Unless stated otherwise, it is "classic".
+ // https://w3c.github.io/ServiceWorker/#dfn-type
+ const blink::mojom::ScriptType script_type_;
FetchHandlerExistence fetch_handler_existence_;
// The source of truth for navigation preload state is the
// ServiceWorkerRegistration. |navigation_preload_state_| is essentially a
@@ -835,7 +866,11 @@ class CONTENT_EXPORT ServiceWorkerVersion
// Set to true if the worker has no inflight events and the idle timer has
// been triggered. Set back to false if another event starts since the worker
// is no longer idle.
- bool idle_timer_fired_in_renderer_ = false;
+ bool worker_is_idle_on_renderer_ = true;
+
+ // S13nServiceWorker: Set to true when the worker needs to be terminated as
+ // soon as possible (e.g. activation).
+ bool needs_to_be_terminated_asap_ = false;
// Keeps track of the provider hosting this running service worker for this
// version. |provider_host_| is always valid as long as this version is
diff --git a/chromium/content/browser/service_worker/service_worker_version_unittest.cc b/chromium/content/browser/service_worker/service_worker_version_unittest.cc
index fddd9d4ccef..5fbc9c59c10 100644
--- a/chromium/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_version_unittest.cc
@@ -30,6 +30,7 @@
#include "content/public/test/test_utils.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom.h"
@@ -155,6 +156,7 @@ class ServiceWorkerVersionTest : public testing::Test {
version_ = new ServiceWorkerVersion(
registration_.get(),
GURL("https://www.example.com/test/service_worker.js"),
+ blink::mojom::ScriptType::kClassic,
helper_->context()->storage()->NewVersionId(),
helper_->context()->AsWeakPtr());
EXPECT_EQ(url::Origin::Create(pattern_), version_->script_origin());
@@ -213,7 +215,7 @@ class ServiceWorkerVersionTest : public testing::Test {
// And finish request, as if a response to the event was received.
EXPECT_TRUE(version_->FinishRequest(request_id, true /* was_handled */,
- base::Time::Now()));
+ base::TimeTicks::Now()));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
}
@@ -445,17 +447,45 @@ TEST_F(ServiceWorkerVersionTest, DispatchEventToStoppedWorker) {
// Dispatch an event without starting the worker.
version_->SetStatus(ServiceWorkerVersion::INSTALLING);
+ EXPECT_TRUE(version_->HasNoWork());
SimulateDispatchEvent(ServiceWorkerMetrics::EventType::INSTALL);
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ // The worker may still be handling events dispatched directly from
+ // controllees. We cannot say the version doesn't handle any tasks until the
+ // worker reports "No Work" (= ServiceWorkerVersion::OnRequestTermination()
+ // is called).
+ EXPECT_FALSE(version_->HasNoWork());
+ } else {
+ // In non-S13nServiceWorker case, ServiceWorkerVersion manages all of events
+ // dispatched to the service worker. Once all events have finished in the
+ // browser, the version should have no work.
+ EXPECT_TRUE(version_->HasNoWork());
+ }
+
// The worker should be now started.
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
// Stop the worker, and then dispatch an event immediately after that.
bool has_stopped = false;
version_->StopWorker(base::BindOnce(&VerifyCalled, &has_stopped));
+ EXPECT_TRUE(version_->HasNoWork());
SimulateDispatchEvent(ServiceWorkerMetrics::EventType::INSTALL);
EXPECT_TRUE(has_stopped);
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ // The worker may still be handling events dispatched directly from
+ // controllees. We cannot say the version doesn't handle any tasks until the
+ // worker reports "No Work" (= ServiceWorkerVersion::OnRequestTermination()
+ // is called).
+ EXPECT_FALSE(version_->HasNoWork());
+ } else {
+ // In non-S13nServiceWorker case, ServiceWorkerVersion manages all of events
+ // dispatched to the service worker. Once all events have finished in the
+ // browser, the version should have no work.
+ EXPECT_TRUE(version_->HasNoWork());
+ }
+
// The worker should be now started again.
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
}
@@ -624,7 +654,7 @@ TEST_F(ServiceWorkerVersionTest, IdleTimeout) {
version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC,
CreateReceiverOnCurrentThread(&status));
EXPECT_TRUE(version_->FinishRequest(request_id, true /* was_handled */,
- base::Time::Now()));
+ base::TimeTicks::Now()));
EXPECT_LT(idle_time, version_->idle_time_);
}
@@ -981,12 +1011,12 @@ TEST_F(ServiceWorkerRequestTimeoutTest, RequestTimeout) {
error_status.value());
// Calling FinishRequest should be no-op, since the request timed out.
EXPECT_FALSE(version_->FinishRequest(request_id, true /* was_handled */,
- base::Time::Now()));
+ base::TimeTicks::Now()));
// Simulate the renderer aborting the inflight event.
// This should not crash: https://crbug.com/676984.
TakeExtendableMessageEventCallback().Run(
- blink::mojom::ServiceWorkerEventStatus::ABORTED, base::Time::Now());
+ blink::mojom::ServiceWorkerEventStatus::ABORTED, base::TimeTicks::Now());
base::RunLoop().RunUntilIdle();
// Simulate the renderer stopping the worker.
@@ -1013,7 +1043,7 @@ TEST_F(ServiceWorkerVersionTest, RequestNowTimeout) {
EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout, status.value());
EXPECT_FALSE(version_->FinishRequest(request_id, true /* was_handled */,
- base::Time::Now()));
+ base::TimeTicks::Now()));
// CONTINUE_ON_TIMEOUT timeouts don't stop the service worker.
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
@@ -1037,7 +1067,7 @@ TEST_F(ServiceWorkerVersionTest, RequestNowTimeoutKill) {
EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout, status.value());
EXPECT_FALSE(version_->FinishRequest(request_id, true /* was_handled */,
- base::Time::Now()));
+ base::TimeTicks::Now()));
// KILL_ON_TIMEOUT timeouts should stop the service worker.
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
@@ -1095,10 +1125,10 @@ TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeout) {
second_status.value());
EXPECT_FALSE(version_->FinishRequest(first_request_id, true /* was_handled */,
- base::Time::Now()));
+ base::TimeTicks::Now()));
EXPECT_FALSE(version_->FinishRequest(
- second_request_id, true /* was_handled */, base::Time::Now()));
+ second_request_id, true /* was_handled */, base::TimeTicks::Now()));
// KILL_ON_TIMEOUT timeouts should stop the service worker.
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
@@ -1135,7 +1165,7 @@ TEST_F(ServiceWorkerVersionTest, MixedRequestTimeouts) {
// Gracefully handle the sync event finishing after the timeout.
EXPECT_FALSE(version_->FinishRequest(sync_request_id, true /* was_handled */,
- base::Time::Now()));
+ base::TimeTicks::Now()));
// Verify that the fetch times out later.
version_->SetAllRequestExpirations(base::TimeTicks::Now());
@@ -1146,7 +1176,7 @@ TEST_F(ServiceWorkerVersionTest, MixedRequestTimeouts) {
// Fetch request should no longer exist.
EXPECT_FALSE(version_->FinishRequest(fetch_request_id, true /* was_handled */,
- base::Time::Now()));
+ base::TimeTicks::Now()));
// Other timeouts do stop the service worker.
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
@@ -1282,7 +1312,7 @@ TEST_F(ServiceWorkerVersionTest, RendererCrashDuringEvent) {
// Request already failed, calling finsh should return false.
EXPECT_FALSE(version_->FinishRequest(request_id, true /* was_handled */,
- base::Time::Now()));
+ base::TimeTicks::Now()));
}
TEST_F(ServiceWorkerVersionTest, PingController) {
@@ -1312,6 +1342,7 @@ TEST_F(ServiceWorkerVersionTest, BadOrigin) {
auto version = base::MakeRefCounted<ServiceWorkerVersion>(
registration_.get(),
GURL("bad-origin://www.example.com/test/service_worker.js"),
+ blink::mojom::ScriptType::kClassic,
helper_->context()->storage()->NewVersionId(),
helper_->context()->AsWeakPtr());
base::Optional<blink::ServiceWorkerStatusCode> status;
diff --git a/chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc b/chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc
index 33975df1026..42494f91b5b 100644
--- a/chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc
@@ -72,9 +72,26 @@ ServiceWorkerWriteToCacheJob::ServiceWorkerWriteToCacheJob(
version_(version),
weak_factory_(this) {
DCHECK(version_);
- DCHECK(resource_type_ == RESOURCE_TYPE_SCRIPT ||
- (resource_type_ == RESOURCE_TYPE_SERVICE_WORKER &&
- version_->script_url() == url_));
+
+#if DCHECK_IS_ON()
+ switch (version_->script_type()) {
+ case blink::mojom::ScriptType::kClassic:
+ // For classic scripts, the main service worker script should have the
+ // "service worker" resource type and imported scripts should have the
+ // "script" resource type.
+ DCHECK(resource_type_ == RESOURCE_TYPE_SCRIPT ||
+ (resource_type_ == RESOURCE_TYPE_SERVICE_WORKER &&
+ version_->script_url() == url_));
+ break;
+ case blink::mojom::ScriptType::kModule:
+ // For module scripts, both the main service worker script and
+ // static-imported scripts should have the "service worker" resource type
+ // because static import inherits the resource type of the top-level
+ // module script.
+ DCHECK_EQ(RESOURCE_TYPE_SERVICE_WORKER, resource_type_);
+ break;
+ }
+#endif // DCHECK_IS_ON()
InitNetRequest(extra_load_flags);
}
@@ -112,7 +129,8 @@ void ServiceWorkerWriteToCacheJob::StartAsync() {
}
cache_writer_ = std::make_unique<ServiceWorkerCacheWriter>(
std::move(compare_reader), std::move(copy_reader),
- context_->storage()->CreateResponseWriter(resource_id_));
+ context_->storage()->CreateResponseWriter(resource_id_),
+ false /* pause_when_not_identical */);
version_->script_cache_map()->NotifyStartedCaching(url_, resource_id_);
did_notify_started_ = true;
@@ -231,7 +249,9 @@ void ServiceWorkerWriteToCacheJob::InitNetRequest(
if (extra_load_flags)
net_request_->SetLoadFlags(net_request_->load_flags() | extra_load_flags);
- if (resource_type_ == RESOURCE_TYPE_SERVICE_WORKER) {
+ // Add the 'Service-Worker' header for the main script request.
+ // https://w3c.github.io/ServiceWorker/#service-worker-script-request
+ if (IsMainScript()) {
// This will get copied into net_request_ when URLRequest::StartJob calls
// ServiceWorkerWriteToCacheJob::SetExtraRequestHeaders.
request()->SetExtraRequestHeaderByName("Service-Worker", "script", true);
@@ -330,7 +350,7 @@ void ServiceWorkerWriteToCacheJob::OnResponseStarted(net::URLRequest* request,
return;
}
- if (resource_type_ == RESOURCE_TYPE_SERVICE_WORKER) {
+ if (IsMainScript()) {
std::string mime_type;
request->GetMimeType(&mime_type);
if (!blink::IsSupportedJavascriptMimeType(mime_type)) {
@@ -496,4 +516,9 @@ bool ServiceWorkerWriteToCacheJob::ShouldByteForByteCheck() const {
version_->pause_after_download();
}
+bool ServiceWorkerWriteToCacheJob::IsMainScript() const {
+ return url_ == version_->script_url() &&
+ resource_type_ == RESOURCE_TYPE_SERVICE_WORKER;
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h b/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h
index 46572db78e5..5c18785aeee 100644
--- a/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h
+++ b/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h
@@ -132,6 +132,10 @@ class CONTENT_EXPORT ServiceWorkerWriteToCacheJob
// do the byte-for-byte check.
bool ShouldByteForByteCheck() const;
+ // Returns true if this writer is writing the main script for the service
+ // worker.
+ bool IsMainScript() const;
+
const ResourceType resource_type_; // Differentiate main script and imports
scoped_refptr<net::IOBuffer> io_buffer_;
int io_buffer_bytes_;
diff --git a/chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc b/chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
index bf253b43748..db5b37740ba 100644
--- a/chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc
@@ -221,7 +221,7 @@ class ResponseVerifier : public base::RefCounted<ResponseVerifier> {
void Start() {
info_buffer_ = new HttpResponseInfoIOBuffer();
- io_buffer_ = new net::IOBuffer(kBlockSize);
+ io_buffer_ = base::MakeRefCounted<net::IOBuffer>(kBlockSize);
reader_->ReadInfo(
info_buffer_.get(),
base::BindOnce(&ResponseVerifier::OnReadInfoComplete, this));
@@ -323,7 +323,8 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
network::mojom::FetchCredentialsMode::kOmit,
network::mojom::FetchRedirectMode::kFollow,
std::string() /* integrity */, false /* keepalive */,
- RESOURCE_TYPE_SERVICE_WORKER, REQUEST_CONTEXT_TYPE_SERVICE_WORKER,
+ RESOURCE_TYPE_SERVICE_WORKER,
+ blink::mojom::RequestContextType::SERVICE_WORKER,
network::mojom::RequestContextFrameType::kNone,
scoped_refptr<network::ResourceRequestBody>());
}
@@ -338,9 +339,9 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
options.scope = scope_;
registration_ =
new ServiceWorkerRegistration(options, 1L, context()->AsWeakPtr());
- version_ =
- new ServiceWorkerVersion(registration_.get(), script_url_,
- NextVersionId(), context()->AsWeakPtr());
+ version_ = new ServiceWorkerVersion(
+ registration_.get(), script_url_, blink::mojom::ScriptType::kClassic,
+ NextVersionId(), context()->AsWeakPtr());
base::WeakPtr<ServiceWorkerProviderHost> host =
CreateHostForVersion(helper_->mock_render_process_id(), version_);
ASSERT_TRUE(host);
@@ -392,9 +393,9 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
// to the script |response|. Returns the new version.
scoped_refptr<ServiceWorkerVersion> UpdateScript(
const std::string& response) {
- scoped_refptr<ServiceWorkerVersion> new_version =
- new ServiceWorkerVersion(registration_.get(), script_url_,
- NextVersionId(), context()->AsWeakPtr());
+ scoped_refptr<ServiceWorkerVersion> new_version = new ServiceWorkerVersion(
+ registration_.get(), script_url_, blink::mojom::ScriptType::kClassic,
+ NextVersionId(), context()->AsWeakPtr());
new_version->SetToPauseAfterDownload(base::DoNothing());
base::WeakPtr<ServiceWorkerProviderHost> host =
CreateHostForVersion(helper_->mock_render_process_id(), new_version);
diff --git a/chromium/content/browser/shareable_file_reference_unittest.cc b/chromium/content/browser/shareable_file_reference_unittest.cc
index 5003f6c6e68..d2ec24e388f 100644
--- a/chromium/content/browser/shareable_file_reference_unittest.cc
+++ b/chromium/content/browser/shareable_file_reference_unittest.cc
@@ -6,9 +6,9 @@
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -17,7 +17,7 @@ using storage::ShareableFileReference;
namespace content {
TEST(ShareableFileReferenceTest, TestReferences) {
- base::MessageLoop message_loop;
+ base::test::ScopedTaskEnvironment task_environment;
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
base::ThreadTaskRunnerHandle::Get();
base::ScopedTempDir temp_dir;
diff --git a/chromium/content/browser/shared_worker/mock_shared_worker.cc b/chromium/content/browser/shared_worker/mock_shared_worker.cc
index b23879ffa4d..d6b17d1afcb 100644
--- a/chromium/content/browser/shared_worker/mock_shared_worker.cc
+++ b/chromium/content/browser/shared_worker/mock_shared_worker.cc
@@ -61,6 +61,7 @@ void MockSharedWorker::Terminate() {
}
void MockSharedWorker::BindDevToolsAgent(
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host_ptr_info,
blink::mojom::DevToolsAgentAssociatedRequest request) {
NOTREACHED();
}
@@ -105,8 +106,10 @@ void MockSharedWorkerFactory::CreateSharedWorker(
service_worker_provider_info,
int appcache_host_id,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
- script_loader_factory_ptr_info,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
+ main_script_loader_factory,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_sciript_load_params,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ mojom::ControllerServiceWorkerInfoPtr controller_info,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider) {
diff --git a/chromium/content/browser/shared_worker/mock_shared_worker.h b/chromium/content/browser/shared_worker/mock_shared_worker.h
index 954fbad4b54..7297a82f82a 100644
--- a/chromium/content/browser/shared_worker/mock_shared_worker.h
+++ b/chromium/content/browser/shared_worker/mock_shared_worker.h
@@ -17,7 +17,7 @@
#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/common/shared_worker/shared_worker_factory.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
class GURL;
@@ -40,6 +40,7 @@ class MockSharedWorker : public mojom::SharedWorker {
mojo::ScopedMessagePipeHandle port) override;
void Terminate() override;
void BindDevToolsAgent(
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host_ptr_info,
blink::mojom::DevToolsAgentAssociatedRequest request) override;
mojo::Binding<mojom::SharedWorker> binding_;
@@ -74,8 +75,10 @@ class MockSharedWorkerFactory : public mojom::SharedWorkerFactory {
service_worker_provider_info,
int appcache_host_id,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
- script_loader_factory_ptr_info,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
+ main_script_loader_factory,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ mojom::ControllerServiceWorkerInfoPtr controller_info,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider) override;
diff --git a/chromium/content/browser/shared_worker/shared_worker_connector_impl.cc b/chromium/content/browser/shared_worker/shared_worker_connector_impl.cc
index 2fe70f50171..454febaba66 100644
--- a/chromium/content/browser/shared_worker/shared_worker_connector_impl.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_connector_impl.cc
@@ -11,7 +11,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
namespace content {
diff --git a/chromium/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.cc b/chromium/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.cc
index ba7feb60615..3626969ae8c 100644
--- a/chromium/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_content_settings_proxy_impl.cc
@@ -26,7 +26,7 @@ SharedWorkerContentSettingsProxyImpl::~SharedWorkerContentSettingsProxyImpl() =
void SharedWorkerContentSettingsProxyImpl::AllowIndexedDB(
const base::string16& name,
AllowIndexedDBCallback callback) {
- if (!origin_.unique()) {
+ if (!origin_.opaque()) {
owner_->AllowIndexedDB(origin_.GetURL(), name, std::move(callback));
} else {
std::move(callback).Run(false);
@@ -35,7 +35,7 @@ void SharedWorkerContentSettingsProxyImpl::AllowIndexedDB(
void SharedWorkerContentSettingsProxyImpl::RequestFileSystemAccessSync(
RequestFileSystemAccessSyncCallback callback) {
- if (!origin_.unique()) {
+ if (!origin_.opaque()) {
owner_->AllowFileSystem(origin_.GetURL(), std::move(callback));
} else {
std::move(callback).Run(false);
diff --git a/chromium/content/browser/shared_worker/shared_worker_host.cc b/chromium/content/browser/shared_worker/shared_worker_host.cc
index a2f6eea00a8..03f17983ff2 100644
--- a/chromium/content/browser/shared_worker/shared_worker_host.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_host.cc
@@ -8,6 +8,7 @@
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
+#include "base/task/post_task.h"
#include "base/unguessable_token.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
#include "content/browser/devtools/shared_worker_devtools_manager.h"
@@ -17,15 +18,18 @@
#include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/browser/shared_worker/shared_worker_service_impl.h"
#include "content/browser/storage_partition_impl.h"
+#include "content/common/navigation_subresource_loader_params.h"
#include "content/common/url_loader_factory_bundle.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_client.h"
#include "content/public/common/renderer_preference_watcher.mojom.h"
#include "services/network/public/cpp/features.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/platform/web_feature.mojom.h"
#include "third_party/blink/public/web/worker_content_settings_proxy.mojom.h"
@@ -36,8 +40,8 @@ namespace {
void AllowFileSystemOnIOThreadResponse(base::OnceCallback<void(bool)> callback,
bool result) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), result));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback), result));
}
void AllowFileSystemOnIOThread(const GURL& url,
@@ -103,6 +107,12 @@ SharedWorkerHost::SharedWorkerHost(
// AddClient() or Start(). AddClient() can sometimes be called before Start()
// when two clients call new SharedWorker() at around the same time.
worker_request_ = mojo::MakeRequest(&worker_);
+
+ // Keep the renderer process alive that will be hosting the shared worker.
+ RenderProcessHost* process_host = RenderProcessHost::FromID(process_id);
+ DCHECK(!IsShuttingDown(process_host));
+ process_host->IncrementKeepAliveRefCount(
+ RenderProcessHost::KeepAliveClientType::kSharedWorker);
}
SharedWorkerHost::~SharedWorkerHost() {
@@ -122,6 +132,12 @@ SharedWorkerHost::~SharedWorkerHost() {
case Phase::kTerminationSentAndClosed:
break;
}
+
+ RenderProcessHost* process_host = RenderProcessHost::FromID(process_id_);
+ if (!IsShuttingDown(process_host)) {
+ process_host->DecrementKeepAliveRefCount(
+ RenderProcessHost::KeepAliveClientType::kSharedWorker);
+ }
}
void SharedWorkerHost::Start(
@@ -130,10 +146,41 @@ void SharedWorkerHost::Start(
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
main_script_loader_factory,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories) {
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ base::Optional<SubresourceLoaderParams> subresource_loader_params) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
AdvanceTo(Phase::kStarted);
+#if DCHECK_IS_ON()
+ // Verify the combination of the given args based on the flags. See the
+ // function comment for details.
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // NetworkService (PlzWorker):
+ DCHECK(service_worker_provider_info);
+ DCHECK(!main_script_loader_factory);
+ DCHECK(main_script_load_params);
+ DCHECK(subresource_loader_factories);
+ DCHECK(!subresource_loader_factories->default_factory_info());
+ } else if (base::FeatureList::IsEnabled(
+ blink::features::kServiceWorkerServicification)) {
+ // S13nServiceWorker (non-NetworkService):
+ DCHECK(service_worker_provider_info);
+ DCHECK(main_script_loader_factory);
+ DCHECK(subresource_loader_factories);
+ DCHECK(subresource_loader_factories->default_factory_info());
+ DCHECK(!subresource_loader_params);
+ DCHECK(!main_script_load_params);
+ } else {
+ // Legacy case (to be deprecated):
+ DCHECK(!service_worker_provider_info);
+ DCHECK(!main_script_loader_factory);
+ DCHECK(!subresource_loader_factories);
+ DCHECK(!subresource_loader_params);
+ DCHECK(!main_script_load_params);
+ }
+#endif // DCHECK_IS_ON()
+
mojom::SharedWorkerInfoPtr info(mojom::SharedWorkerInfo::New(
instance_->url(), instance_->name(), instance_->content_security_policy(),
instance_->content_security_policy_type(),
@@ -173,29 +220,42 @@ void SharedWorkerHost::Start(
mojom::kNavigation_SharedWorkerSpec, process_id_,
mojo::MakeRequest(&interface_provider)));
- // Add the default factory to the bundle for subresource loading to pass to
- // the renderer. The bundle is only provided if
- // NetworkService/S13nServiceWorker is enabled.
- // TODO(nhiroki): We might need to set the default factory to AppCache
- // instead, as we do for frames, if requests from this shared worker are
- // supposed to go through AppCache. Currently, we set the default factory to a
- // direct network.
- if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
- DCHECK(subresource_loader_factories);
- DCHECK(!subresource_loader_factories->default_factory_info());
- if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- network::mojom::URLLoaderFactoryPtrInfo network_factory_info;
- CreateNetworkFactory(mojo::MakeRequest(&network_factory_info));
- subresource_loader_factories->default_factory_info() =
- std::move(network_factory_info);
+ // Set the default factory to the bundle for subresource loading to pass to
+ // the renderer when NetworkService is on. When S13nServiceWorker is on, the
+ // default factory is already provided by SharedWorkerServiceImpl.
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // If the caller has supplied a default URLLoaderFactory override (for,
+ // e.g., AppCache), use that.
+ network::mojom::URLLoaderFactoryPtrInfo default_factory_info;
+ if (subresource_loader_params &&
+ subresource_loader_params->loader_factory_info.is_valid()) {
+ default_factory_info =
+ std::move(subresource_loader_params->loader_factory_info);
} else {
- // Use the non-NetworkService network factory for the process when
- // NetworkService is off.
- network::mojom::URLLoaderFactoryPtr default_factory;
- RenderProcessHost::FromID(process_id_)
- ->CreateURLLoaderFactory(mojo::MakeRequest(&default_factory));
- subresource_loader_factories->default_factory_info() =
- default_factory.PassInterface();
+ CreateNetworkFactory(mojo::MakeRequest(&default_factory_info));
+ }
+ subresource_loader_factories->default_factory_info() =
+ std::move(default_factory_info);
+ }
+
+ // NetworkService (PlzWorker):
+ // Prepare the controller service worker info to pass to the renderer. This is
+ // only provided if NetworkService is enabled. In the non-NetworkService case,
+ // the controller is sent in SetController IPCs during the request for the
+ // shared worker script.
+ mojom::ControllerServiceWorkerInfoPtr controller;
+ blink::mojom::ServiceWorkerObjectAssociatedPtrInfo remote_object;
+ blink::mojom::ServiceWorkerState sent_state;
+ if (subresource_loader_params &&
+ subresource_loader_params->controller_service_worker_info) {
+ DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
+ controller =
+ std::move(subresource_loader_params->controller_service_worker_info);
+ // |object_info| can be nullptr when the service worker context or the
+ // service worker version is gone during shared worker startup.
+ if (controller->object_info) {
+ controller->object_info->request = mojo::MakeRequest(&remote_object);
+ sent_state = controller->object_info->state;
}
}
@@ -207,9 +267,24 @@ void SharedWorkerHost::Start(
std::move(content_settings), std::move(service_worker_provider_info),
appcache_handle_ ? appcache_handle_->appcache_host_id()
: kAppCacheNoHostId,
- std::move(main_script_loader_factory),
- std::move(subresource_loader_factories), std::move(host),
- std::move(worker_request_), std::move(interface_provider));
+ std::move(main_script_loader_factory), std::move(main_script_load_params),
+ std::move(subresource_loader_factories), std::move(controller),
+ std::move(host), std::move(worker_request_),
+ std::move(interface_provider));
+
+ // NetworkService (PlzWorker):
+ // |remote_object| is an associated interface ptr, so calls can't be made on
+ // it until its request endpoint is sent. Now that the request endpoint was
+ // sent, it can be used, so add it to ServiceWorkerObjectHost.
+ if (remote_object.is_valid()) {
+ DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(
+ &ServiceWorkerObjectHost::AddRemoteObjectPtrAndUpdateState,
+ subresource_loader_params->controller_service_worker_object_host,
+ std::move(remote_object), sent_state));
+ }
// Monitor the lifetime of the worker.
worker_.set_connection_error_handler(base::BindOnce(
@@ -217,7 +292,9 @@ void SharedWorkerHost::Start(
}
// This is similar to
-// RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryAndObserve.
+// RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryAndObserve, but this
+// host doesn't observe network service crashes. Instead, the renderer detects
+// the connection error and terminates the worker.
void SharedWorkerHost::CreateNetworkFactory(
network::mojom::URLLoaderFactoryRequest request) {
network::mojom::URLLoaderFactoryParamsPtr params =
@@ -228,16 +305,13 @@ void SharedWorkerHost::CreateNetworkFactory(
service_->storage_partition()->GetNetworkContext()->CreateURLLoaderFactory(
std::move(request), std::move(params));
-
- // TODO(crbug.com/848256): Detect connection error and send a IPC with a new
- // network factory like UpdateSubresourceLoaderFactories does for frames.
}
void SharedWorkerHost::AllowFileSystem(
const GURL& url,
base::OnceCallback<void(bool)> callback) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AllowFileSystemOnIOThread, url,
RenderProcessHost::FromID(process_id_)
->GetBrowserContext()
@@ -248,8 +322,8 @@ void SharedWorkerHost::AllowFileSystem(
void SharedWorkerHost::AllowIndexedDB(const GURL& url,
const base::string16& name,
base::OnceCallback<void(bool)> callback) {
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AllowIndexedDBOnIOThread, url, name,
RenderProcessHost::FromID(process_id_)
->GetBrowserContext()
@@ -431,8 +505,9 @@ void SharedWorkerHost::AddClient(mojom::SharedWorkerClientPtr client,
}
void SharedWorkerHost::BindDevToolsAgent(
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host,
blink::mojom::DevToolsAgentAssociatedRequest request) {
- worker_->BindDevToolsAgent(std::move(request));
+ worker_->BindDevToolsAgent(std::move(host), std::move(request));
}
void SharedWorkerHost::SetAppCacheHandle(
diff --git a/chromium/content/browser/shared_worker/shared_worker_host.h b/chromium/content/browser/shared_worker/shared_worker_host.h
index c75d9920a90..0bf7bbac4aa 100644
--- a/chromium/content/browser/shared_worker/shared_worker_host.h
+++ b/chromium/content/browser/shared_worker/shared_worker_host.h
@@ -25,6 +25,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/service_manager/public/mojom/interface_provider.mojom.h"
+#include "third_party/blink/public/mojom/shared_worker/shared_worker_main_script_load_params.mojom.h"
#include "third_party/blink/public/web/devtools_agent.mojom.h"
class GURL;
@@ -40,6 +41,7 @@ class SharedWorkerContentSettingsProxyImpl;
class SharedWorkerInstance;
class SharedWorkerServiceImpl;
class URLLoaderFactoryBundleInfo;
+struct SubresourceLoaderParams;
// The SharedWorkerHost is the interface that represents the browser side of
// the browser <-> worker communication channel. This is owned by
@@ -61,25 +63,41 @@ class CONTENT_EXPORT SharedWorkerHost
// information about its ServiceWorkerProviderHost, the browser-side host for
// supporting the shared worker as a service worker client.
//
- // S13nServiceWorker:
+ // S13nServiceWorker (non-NetworkService):
// |main_script_loader_factory| is sent to the renderer process and is to be
// used to request the shared worker's main script. Currently it's only
- // non-null when S13nServiceWorker is enabled, to allow service worker
- // machinery to observe the request, but other web platform features may also
- // use it someday.
+ // non-null when S13nServiceWorker is enabled but NetworkService is disabled,
+ // to allow service worker machinery to observe the request.
+ //
+ // NetworkService (PlzWorker):
+ // |main_script_load_params| is sent to the renderer process and to be used to
+ // load the shared worker main script pre-requested by the browser process.
+ // This is only non-null when NetworkService is enabled.
//
// NetworkService:
// |subresource_loader_factories| is sent to the renderer process and is to be
// used to request subresources where applicable. For example, this allows the
// shared worker to load chrome-extension:// URLs which the renderer's default
// loader factory can't load.
+ //
+ // NetworkService (PlzWorker):
+ // |subresource_loader_params| contains information about the default loader
+ // factory for |subresource_loader_factories_| and the service worker
+ // controller. The default loader factory can be associated with some request
+ // interceptor like AppCacheRequestHandler. This is only non-null when
+ // NetworkService is enabled.
+ // When S13nServiceWorker is enabled but NetworkService is disabled, the
+ // default network loader factory is created by the RenderFrameHost, and
+ // service worker controller is sent via ServiceWorkerContainer#SetController.
void Start(
mojom::SharedWorkerFactoryPtr factory,
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
main_script_loader_factory,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories);
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ base::Optional<SubresourceLoaderParams> subresource_loader_params);
void AllowFileSystem(const GURL& url,
base::OnceCallback<void(bool)> callback);
@@ -95,7 +113,8 @@ class CONTENT_EXPORT SharedWorkerHost
int frame_id,
const blink::MessagePortChannel& port);
- void BindDevToolsAgent(blink::mojom::DevToolsAgentAssociatedRequest request);
+ void BindDevToolsAgent(blink::mojom::DevToolsAgentHostAssociatedPtrInfo host,
+ blink::mojom::DevToolsAgentAssociatedRequest request);
void SetAppCacheHandle(
std::unique_ptr<AppCacheNavigationHandle> appcache_handle);
diff --git a/chromium/content/browser/shared_worker/shared_worker_host_unittest.cc b/chromium/content/browser/shared_worker/shared_worker_host_unittest.cc
index c5043d87b0f..402e6ef8d9b 100644
--- a/chromium/content/browser/shared_worker/shared_worker_host_unittest.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_host_unittest.cc
@@ -11,35 +11,80 @@
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "content/browser/appcache/chrome_appcache_service.h"
+#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/shared_worker/mock_shared_worker.h"
#include "content/browser/shared_worker/shared_worker_connector_impl.h"
#include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/browser/shared_worker/shared_worker_service_impl.h"
+#include "content/common/navigation_subresource_loader_params.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
-#include "content/public/test/test_storage_partition.h"
#include "content/public/test/test_utils.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/strong_associated_binding.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/test_support/test_utils.h"
-#include "services/network/test/test_network_context.h"
+#include "services/network/public/cpp/features.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "url/origin.h"
using blink::MessagePortChannel;
namespace content {
+namespace {
+
+// A mock URLLoaderFactory which just fails to create a loader. This is
+// sufficient because the tests don't exercise script loading.
+class NotImplementedNetworkURLLoaderFactory final
+ : public network::mojom::URLLoaderFactory {
+ public:
+ NotImplementedNetworkURLLoaderFactory() = default;
+
+ // network::mojom::URLLoaderFactory implementation.
+ void CreateLoaderAndStart(network::mojom::URLLoaderRequest request,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const network::ResourceRequest& url_request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag&
+ traffic_annotation) override {
+ network::URLLoaderCompletionStatus status;
+ status.error_code = net::ERR_NOT_IMPLEMENTED;
+ client->OnComplete(status);
+ }
+
+ void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+ bindings_.AddBinding(this, std::move(request));
+ }
+
+ private:
+ mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+
+ DISALLOW_COPY_AND_ASSIGN(NotImplementedNetworkURLLoaderFactory);
+};
+
+} // namespace
+
class SharedWorkerHostTest : public testing::Test {
public:
+ void SetUp() override {
+ helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
+ mock_url_loader_factory_ =
+ std::make_unique<NotImplementedNetworkURLLoaderFactory>();
+ mock_render_process_host_.OverrideURLLoaderFactory(
+ mock_url_loader_factory_.get());
+ }
+
SharedWorkerHostTest()
: mock_render_process_host_(&browser_context_),
- service_(&storage_partition_,
+ service_(nullptr /* storage_partition */,
nullptr /* service_worker_context */,
- nullptr /* appcache_service */) {
- storage_partition_.set_network_context(&network_context_);
- }
+ nullptr /* appcache_service */) {}
base::WeakPtr<SharedWorkerHost> CreateHost() {
GURL url("http://www.example.com/w.js");
@@ -66,9 +111,59 @@ class SharedWorkerHostTest : public testing::Test {
void StartWorker(SharedWorkerHost* host,
mojom::SharedWorkerFactoryPtr factory) {
- host->Start(std::move(factory), nullptr /* service_worker_provider_info */,
- {} /* main_script_loader_factory */,
- nullptr /* subresource_loader_factories */);
+ mojom::ServiceWorkerProviderInfoForSharedWorkerPtr provider_info = nullptr;
+ network::mojom::URLLoaderFactoryAssociatedPtrInfo
+ main_script_loader_factory;
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params;
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories;
+ base::Optional<SubresourceLoaderParams> subresource_loader_params;
+
+ // Set up various mocks based on NetworkService/S13nServiceWorker
+ // configuration. See the comment on SharedWorkerHost::Start() for details.
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ provider_info = mojom::ServiceWorkerProviderInfoForSharedWorker::New();
+ ServiceWorkerProviderHost::PreCreateForSharedWorker(
+ helper_->context()->AsWeakPtr(), mock_render_process_host_.GetID(),
+ &provider_info);
+
+ main_script_load_params =
+ blink::mojom::SharedWorkerMainScriptLoadParams::New();
+ subresource_loader_factories.reset(new URLLoaderFactoryBundleInfo());
+ subresource_loader_params = SubresourceLoaderParams();
+
+ network::mojom::URLLoaderFactoryPtr loader_factory_ptr;
+ mojo::MakeStrongBinding(
+ std::make_unique<NotImplementedNetworkURLLoaderFactory>(),
+ mojo::MakeRequest(&loader_factory_ptr));
+
+ subresource_loader_params->loader_factory_info =
+ loader_factory_ptr.PassInterface();
+ } else if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ provider_info = mojom::ServiceWorkerProviderInfoForSharedWorker::New();
+ ServiceWorkerProviderHost::PreCreateForSharedWorker(
+ helper_->context()->AsWeakPtr(), mock_render_process_host_.GetID(),
+ &provider_info);
+
+ mojo::MakeStrongAssociatedBinding(
+ std::make_unique<NotImplementedNetworkURLLoaderFactory>(),
+ mojo::MakeRequest(&main_script_loader_factory));
+
+ network::mojom::URLLoaderFactoryPtr default_factory_ptr;
+ mojo::MakeStrongBinding(
+ std::make_unique<NotImplementedNetworkURLLoaderFactory>(),
+ mojo::MakeRequest(&default_factory_ptr));
+ subresource_loader_factories.reset(new URLLoaderFactoryBundleInfo(
+ default_factory_ptr.PassInterface(),
+ URLLoaderFactoryBundleInfo::SchemeMap(),
+ URLLoaderFactoryBundleInfo::OriginMap(),
+ true /* bypass_redirect_checks */));
+ }
+
+ host->Start(std::move(factory), std::move(provider_info),
+ std::move(main_script_loader_factory),
+ std::move(main_script_load_params),
+ std::move(subresource_loader_factories),
+ std::move(subresource_loader_params));
}
MessagePortChannel AddClient(SharedWorkerHost* host,
@@ -83,10 +178,12 @@ class SharedWorkerHostTest : public testing::Test {
protected:
TestBrowserThreadBundle test_browser_thread_bundle_;
- TestStoragePartition storage_partition_;
- network::TestNetworkContext network_context_;
TestBrowserContext browser_context_;
+ // This URLLoaderFactory is used in MockRenderProcessHost.
+ std::unique_ptr<NotImplementedNetworkURLLoaderFactory>
+ mock_url_loader_factory_;
MockRenderProcessHost mock_render_process_host_;
+ std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
SharedWorkerServiceImpl service_;
@@ -195,11 +292,8 @@ TEST_F(SharedWorkerHostTest, TerminateAfterStarting) {
// Create the factory.
mojom::SharedWorkerFactoryPtr factory;
MockSharedWorkerFactory factory_impl(mojo::MakeRequest(&factory));
-
// Start the worker.
- host->Start(std::move(factory), nullptr /* service_worker_provider_info */,
- {} /* main_script_loader_factory */,
- nullptr /* subresource_loader_factories */);
+ StartWorker(host.get(), std::move(factory));
// Add a client.
MockSharedWorkerClient client;
diff --git a/chromium/content/browser/shared_worker/shared_worker_script_fetcher.cc b/chromium/content/browser/shared_worker/shared_worker_script_fetcher.cc
new file mode 100644
index 00000000000..6c50fba1143
--- /dev/null
+++ b/chromium/content/browser/shared_worker/shared_worker_script_fetcher.cc
@@ -0,0 +1,205 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/shared_worker/shared_worker_script_fetcher.h"
+
+#include "base/feature_list.h"
+#include "content/browser/shared_worker/shared_worker_script_loader.h"
+#include "content/browser/shared_worker/shared_worker_script_loader_factory.h"
+#include "content/common/throttling_url_loader.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/url_loader_throttle.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/resource_response.h"
+
+namespace content {
+
+namespace {
+
+const net::NetworkTrafficAnnotationTag
+ kSharedWorkerScriptLoadTrafficAnnotation =
+ net::DefineNetworkTrafficAnnotation("shared_worker_script_load",
+ R"(
+ semantics {
+ sender: "Shared Worker Script Load"
+ description:
+ "This request is issued by SharedWorker to fetch its main script."
+ trigger:
+ "Calling new SharedWorker()."
+ data: "Anything the initiator wants to send."
+ destination: OTHER
+ }
+ policy {
+ cookies_allowed: YES
+ cookies_store: "user"
+ setting: "This request can be prevented by disabling JavaScript."
+ chrome_policy {
+ URLBlacklist {
+ URLBlacklist: { entries: '*' }
+ }
+ }
+ chrome_policy {
+ URLWhitelist {
+ URLWhitelist { }
+ }
+ }
+ }
+)");
+
+} // namespace
+
+void SharedWorkerScriptFetcher::CreateAndStart(
+ std::unique_ptr<SharedWorkerScriptLoaderFactory> script_loader_factory,
+ std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
+ std::unique_ptr<network::ResourceRequest> resource_request,
+ CreateAndStartCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
+ // This fetcher will delete itself. See the class level comment.
+ (new SharedWorkerScriptFetcher(std::move(script_loader_factory),
+ std::move(resource_request),
+ std::move(callback)))
+ ->Start(std::move(throttles));
+}
+
+SharedWorkerScriptFetcher::SharedWorkerScriptFetcher(
+ std::unique_ptr<SharedWorkerScriptLoaderFactory> script_loader_factory,
+ std::unique_ptr<network::ResourceRequest> resource_request,
+ CreateAndStartCallback callback)
+ : script_loader_factory_(std::move(script_loader_factory)),
+ resource_request_(std::move(resource_request)),
+ callback_(std::move(callback)),
+ response_url_loader_binding_(this) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+}
+
+SharedWorkerScriptFetcher::~SharedWorkerScriptFetcher() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+}
+
+void SharedWorkerScriptFetcher::Start(
+ std::vector<std::unique_ptr<URLLoaderThrottle>> throttles) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ auto shared_url_loader_factory =
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+ script_loader_factory_.get());
+
+ // SharedWorker doesn't have a frame.
+ int32_t routing_id = MSG_ROUTING_NONE;
+
+ // NetworkService is not interested in the request ID.
+ int request_id = -1;
+
+ url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
+ std::move(shared_url_loader_factory), std::move(throttles), routing_id,
+ request_id, network::mojom::kURLLoadOptionNone, resource_request_.get(),
+ this, kSharedWorkerScriptLoadTrafficAnnotation,
+ base::ThreadTaskRunnerHandle::Get());
+}
+
+void SharedWorkerScriptFetcher::OnReceiveResponse(
+ const network::ResourceResponseHead& head) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ base::WeakPtr<SharedWorkerScriptLoader> script_loader =
+ script_loader_factory_->GetScriptLoader();
+ if (script_loader && script_loader->default_loader_used_) {
+ // If the default network loader was used to handle the URL load request we
+ // need to see if the request interceptors want to potentially create a new
+ // loader for the response, e.g. AppCache's fallback.
+ DCHECK(!response_url_loader_);
+ network::mojom::URLLoaderClientRequest response_client_request;
+ if (script_loader->MaybeCreateLoaderForResponse(head, &response_url_loader_,
+ &response_client_request,
+ url_loader_.get())) {
+ DCHECK(response_url_loader_);
+ response_url_loader_binding_.Bind(std::move(response_client_request));
+ subresource_loader_params_ = script_loader->TakeSubresourceLoaderParams();
+ url_loader_.reset();
+ // OnReceiveResponse() will be called again.
+ return;
+ }
+ }
+
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params =
+ blink::mojom::SharedWorkerMainScriptLoadParams::New();
+
+ // Fill in params for loading shared worker's main script and subresources.
+ main_script_load_params->response_head = head;
+ if (url_loader_) {
+ // The main script was served by a request interceptor or the default
+ // network loader.
+ DCHECK(!response_url_loader_);
+ main_script_load_params->url_loader_client_endpoints =
+ url_loader_->Unbind();
+ subresource_loader_params_ = script_loader->TakeSubresourceLoaderParams();
+ } else {
+ // The main script was served by the default network loader first, and then
+ // a request interceptor created another loader |response_url_loader_| for
+ // serving an alternative response.
+ DCHECK(response_url_loader_);
+ DCHECK(response_url_loader_binding_.is_bound());
+ main_script_load_params->url_loader_client_endpoints =
+ network::mojom::URLLoaderClientEndpoints::New(
+ response_url_loader_.PassInterface(),
+ response_url_loader_binding_.Unbind());
+ }
+
+ for (size_t i = 0; i < redirect_infos_.size(); ++i) {
+ main_script_load_params->redirect_infos.emplace_back(redirect_infos_[i]);
+ main_script_load_params->redirect_response_heads.emplace_back(
+ redirect_response_heads_[i]);
+ }
+
+ std::move(callback_).Run(std::move(main_script_load_params),
+ std::move(subresource_loader_params_),
+ true /* success */);
+ delete this;
+}
+
+void SharedWorkerScriptFetcher::OnReceiveRedirect(
+ const net::RedirectInfo& redirect_info,
+ const network::ResourceResponseHead& head) {
+ redirect_infos_.push_back(redirect_info);
+ redirect_response_heads_.push_back(head);
+ url_loader_->FollowRedirect(base::nullopt);
+}
+
+void SharedWorkerScriptFetcher::OnUploadProgress(
+ int64_t current_position,
+ int64_t total_size,
+ OnUploadProgressCallback callback) {
+ NOTREACHED();
+}
+
+void SharedWorkerScriptFetcher::OnReceiveCachedMetadata(
+ const std::vector<uint8_t>& data) {
+ NOTREACHED();
+}
+
+void SharedWorkerScriptFetcher::OnTransferSizeUpdated(
+ int32_t transfer_size_diff) {
+ NOTREACHED();
+}
+
+void SharedWorkerScriptFetcher::OnStartLoadingResponseBody(
+ mojo::ScopedDataPipeConsumerHandle body) {
+ // Not reached. At this point, the loader and client endpoints must have
+ // been unbound and forwarded to the renderer.
+ NOTREACHED();
+}
+
+void SharedWorkerScriptFetcher::OnComplete(
+ const network::URLLoaderCompletionStatus& status) {
+ // We can reach here only when loading fails before receiving a response head.
+ DCHECK_NE(net::OK, status.error_code);
+ std::move(callback_).Run(nullptr /* main_script_load_params */,
+ base::nullopt /* subresource_loader_params */,
+ false /* success */);
+ delete this;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/shared_worker/shared_worker_script_fetcher.h b/chromium/content/browser/shared_worker/shared_worker_script_fetcher.h
new file mode 100644
index 00000000000..4117d0d73c2
--- /dev/null
+++ b/chromium/content/browser/shared_worker/shared_worker_script_fetcher.h
@@ -0,0 +1,97 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_SCRIPT_FETCHER_H_
+#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_SCRIPT_FETCHER_H_
+
+#include "base/callback.h"
+#include "base/optional.h"
+#include "content/common/navigation_subresource_loader_params.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "net/url_request/redirect_info.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/public/mojom/url_loader.mojom.h"
+#include "third_party/blink/public/mojom/shared_worker/shared_worker_main_script_load_params.mojom.h"
+
+namespace network {
+struct ResourceResponseHead;
+struct ResourceRequest;
+} // namespace network
+
+namespace content {
+
+class SharedWorkerScriptLoaderFactory;
+class ThrottlingURLLoader;
+class URLLoaderThrottle;
+
+// NetworkService (PlzWorker):
+// This is an implementation of the URLLoaderClient for shared worker's main
+// script fetch. The loader and client bounded with this class are to be unbound
+// and forwarded to the renderer process on OnReceiveResponse, and the resource
+// loader in the renderer process will take them over.
+//
+// SharedWorkerScriptFetcher deletes itself when the ownership of the loader and
+// client is passed to the renderer, or on failure. It lives on the IO thread.
+class SharedWorkerScriptFetcher : public network::mojom::URLLoaderClient {
+ public:
+ using CreateAndStartCallback =
+ base::OnceCallback<void(blink::mojom::SharedWorkerMainScriptLoadParamsPtr,
+ base::Optional<SubresourceLoaderParams>,
+ bool /* success */)>;
+
+ // Called on the IO thread, and calls |callback| on the IO thread when
+ // OnReceiveResponse is called on |this|.
+ static void CreateAndStart(
+ std::unique_ptr<SharedWorkerScriptLoaderFactory> script_loader_factory,
+ std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
+ std::unique_ptr<network::ResourceRequest> resource_request,
+ CreateAndStartCallback callback);
+
+ private:
+ SharedWorkerScriptFetcher(
+ std::unique_ptr<SharedWorkerScriptLoaderFactory> script_loader_factory,
+ std::unique_ptr<network::ResourceRequest> resource_request,
+ CreateAndStartCallback callback);
+
+ ~SharedWorkerScriptFetcher() override;
+
+ void Start(std::vector<std::unique_ptr<URLLoaderThrottle>> throttles);
+
+ // network::mojom::URLLoaderClient
+ void OnReceiveResponse(const network::ResourceResponseHead& head) override;
+ void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
+ const network::ResourceResponseHead& head) override;
+ void OnUploadProgress(int64_t current_position,
+ int64_t total_size,
+ OnUploadProgressCallback callback) override;
+ void OnReceiveCachedMetadata(const std::vector<uint8_t>& data) override;
+ void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
+ void OnStartLoadingResponseBody(
+ mojo::ScopedDataPipeConsumerHandle body) override;
+ void OnComplete(const network::URLLoaderCompletionStatus& status) override;
+
+ std::unique_ptr<SharedWorkerScriptLoaderFactory> script_loader_factory_;
+
+ std::unique_ptr<network::ResourceRequest> resource_request_;
+ CreateAndStartCallback callback_;
+
+ // URLLoader instance backed by a request interceptor (e.g.,
+ // AppCacheRequestHandler) or the network service.
+ std::unique_ptr<ThrottlingURLLoader> url_loader_;
+
+ // URLLoader instance for handling a response received from the default
+ // network loader. This can be provided by an interceptor. For example,
+ // AppCache's interceptor creates this for AppCache's fallback case.
+ network::mojom::URLLoaderPtr response_url_loader_;
+ mojo::Binding<network::mojom::URLLoaderClient> response_url_loader_binding_;
+
+ base::Optional<SubresourceLoaderParams> subresource_loader_params_;
+
+ std::vector<net::RedirectInfo> redirect_infos_;
+ std::vector<network::ResourceResponseHead> redirect_response_heads_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_SCRIPT_FETCHER_H_
diff --git a/chromium/content/browser/shared_worker/shared_worker_script_loader.cc b/chromium/content/browser/shared_worker/shared_worker_script_loader.cc
index 0ded2f6fabd..f8299e8ab95 100644
--- a/chromium/content/browser/shared_worker/shared_worker_script_loader.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_script_loader.cc
@@ -62,6 +62,10 @@ SharedWorkerScriptLoader::SharedWorkerScriptLoader(
SharedWorkerScriptLoader::~SharedWorkerScriptLoader() = default;
+base::WeakPtr<SharedWorkerScriptLoader> SharedWorkerScriptLoader::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
void SharedWorkerScriptLoader::Start() {
if (interceptor_index_ < interceptors_.size()) {
auto* interceptor = interceptors_[interceptor_index_++].get();
@@ -82,13 +86,11 @@ void SharedWorkerScriptLoader::MaybeStartLoader(
SingleRequestURLLoaderFactory::RequestHandler single_request_handler) {
DCHECK(interceptor);
- // TODO(nhiroki): Create SubresourceLoaderParams for intercepting subresource
- // requests and populating the "controller" field in ServiceWorkerContainer,
- // and send the params to the renderer when we create the SharedWorker.
- // Note that we shouldn't try the next interceptor if this interceptor
- // provides SubresourceLoaderParams. See comments on
- // NavigationLoaderInterceptor::MaybeCreateSubresourceLoaderParams() for
- // details.
+ // Create SubresourceLoaderParams for intercepting subresource requests and
+ // populating the "controller" field in ServiceWorkerContainer. This can be
+ // null if the interceptor is not interested in this request.
+ subresource_loader_params_ =
+ interceptor->MaybeCreateSubresourceLoaderParams();
if (single_request_handler) {
// The interceptor elected to handle the request. Use it.
@@ -103,12 +105,19 @@ void SharedWorkerScriptLoader::MaybeStartLoader(
return;
}
+ // We shouldn't try the remaining interceptors if this interceptor provides
+ // SubresourceLoaderParams. For details, see comments on
+ // NavigationLoaderInterceptor::MaybeCreateSubresourceLoaderParams().
+ if (subresource_loader_params_)
+ interceptor_index_ = interceptors_.size();
+
// Continue until all the interceptors are tried.
Start();
}
void SharedWorkerScriptLoader::LoadFromNetwork(
bool reset_subresource_loader_params) {
+ default_loader_used_ = true;
network::mojom::URLLoaderClientPtr client;
if (url_loader_client_binding_)
url_loader_client_binding_.Unbind();
@@ -237,4 +246,26 @@ void SharedWorkerScriptLoader::OnComplete(
client_->OnComplete(status);
}
+bool SharedWorkerScriptLoader::MaybeCreateLoaderForResponse(
+ const network::ResourceResponseHead& response,
+ network::mojom::URLLoaderPtr* response_url_loader,
+ network::mojom::URLLoaderClientRequest* response_client_request,
+ ThrottlingURLLoader* url_loader) {
+ DCHECK(default_loader_used_);
+ for (auto& interceptor : interceptors_) {
+ bool skip_other_interceptors = false;
+ if (interceptor->MaybeCreateLoaderForResponse(
+ response, response_url_loader, response_client_request, url_loader,
+ &skip_other_interceptors)) {
+ // Both ServiceWorkerRequestHandler and AppCacheRequestHandler don't set
+ // skip_other_interceptors.
+ DCHECK(!skip_other_interceptors);
+ subresource_loader_params_ =
+ interceptor->MaybeCreateSubresourceLoaderParams();
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace content
diff --git a/chromium/content/browser/shared_worker/shared_worker_script_loader.h b/chromium/content/browser/shared_worker/shared_worker_script_loader.h
index e8a876e5ca7..017ca7f6a4c 100644
--- a/chromium/content/browser/shared_worker/shared_worker_script_loader.h
+++ b/chromium/content/browser/shared_worker/shared_worker_script_loader.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_SCRIPT_LOADER_H_
#include "base/macros.h"
+#include "content/common/navigation_subresource_loader_params.h"
#include "content/common/single_request_url_loader_factory.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
@@ -19,6 +20,7 @@ class SharedURLLoaderFactory;
namespace content {
class AppCacheHost;
+class ThrottlingURLLoader;
class NavigationLoaderInterceptor;
class ResourceContext;
class ServiceWorkerProviderHost;
@@ -82,6 +84,25 @@ class SharedWorkerScriptLoader : public network::mojom::URLLoader,
mojo::ScopedDataPipeConsumerHandle body) override;
void OnComplete(const network::URLLoaderCompletionStatus& status) override;
+ // Returns a URLLoader client endpoint if an interceptor wants to handle the
+ // response, i.e. return a different response. For e.g. AppCache may have
+ // fallback content.
+ bool MaybeCreateLoaderForResponse(
+ const network::ResourceResponseHead& response,
+ network::mojom::URLLoaderPtr* response_url_loader,
+ network::mojom::URLLoaderClientRequest* response_client_request,
+ ThrottlingURLLoader* url_loader);
+
+ base::Optional<SubresourceLoaderParams> TakeSubresourceLoaderParams() {
+ return std::move(subresource_loader_params_);
+ }
+
+ base::WeakPtr<SharedWorkerScriptLoader> GetWeakPtr();
+
+ // Set to true if the default URLLoader (network service) was used for the
+ // current request.
+ bool default_loader_used_ = false;
+
private:
void Start();
void MaybeStartLoader(
@@ -94,6 +115,8 @@ class SharedWorkerScriptLoader : public network::mojom::URLLoader,
std::vector<std::unique_ptr<NavigationLoaderInterceptor>> interceptors_;
size_t interceptor_index_ = 0;
+ base::Optional<SubresourceLoaderParams> subresource_loader_params_;
+
const int process_id_;
const int32_t routing_id_;
const int32_t request_id_;
diff --git a/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.cc b/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.cc
index 74eaef69a4b..bdbec0c41e5 100644
--- a/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.cc
@@ -5,6 +5,7 @@
#include "content/browser/shared_worker/shared_worker_script_loader_factory.h"
#include <memory>
+#include "base/feature_list.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
@@ -12,6 +13,7 @@
#include "content/browser/shared_worker/shared_worker_script_loader.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
@@ -51,29 +53,40 @@ void SharedWorkerScriptLoaderFactory::CreateLoaderAndStart(
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // Handle only the main script (RESOURCE_TYPE_SHARED_WORKER). Import scripts
- // should go to the network loader or controller.
- if (resource_request.resource_type != RESOURCE_TYPE_SHARED_WORKER) {
- mojo::ReportBadMessage(
- "SharedWorkerScriptLoaderFactory should only get requests for shared "
- "worker scripts");
- return;
+ // When NetworkService is not enabled, this function is called from the
+ // renderer process, so use ReportBadMessage() instead of DCHECK().
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // Handle only the main script (RESOURCE_TYPE_SHARED_WORKER). Import scripts
+ // should go to the network loader or controller.
+ if (resource_request.resource_type != RESOURCE_TYPE_SHARED_WORKER) {
+ mojo::ReportBadMessage(
+ "SharedWorkerScriptLoaderFactory should only get requests for shared "
+ "worker scripts");
+ return;
+ }
+ if (script_loader_) {
+ mojo::ReportBadMessage(
+ "SharedWorkerScriptLoaderFactory should be used only one time");
+ return;
+ }
}
+ DCHECK_EQ(RESOURCE_TYPE_SHARED_WORKER, resource_request.resource_type);
+ DCHECK(!script_loader_);
// Create a SharedWorkerScriptLoader to load the script.
- mojo::MakeStrongBinding(
- std::make_unique<SharedWorkerScriptLoader>(
- process_id_, routing_id, request_id, options, resource_request,
- std::move(client), service_worker_provider_host_, appcache_host_,
- resource_context_, loader_factory_, traffic_annotation),
- std::move(request));
+ auto script_loader = std::make_unique<SharedWorkerScriptLoader>(
+ process_id_, routing_id, request_id, options, resource_request,
+ std::move(client), service_worker_provider_host_, appcache_host_,
+ resource_context_, loader_factory_, traffic_annotation);
+ script_loader_ = script_loader->GetWeakPtr();
+ mojo::MakeStrongBinding(std::move(script_loader), std::move(request));
}
void SharedWorkerScriptLoaderFactory::Clone(
network::mojom::URLLoaderFactoryRequest request) {
// This method is required to support synchronous requests, which shared
// worker script requests are not.
- NOTIMPLEMENTED();
+ NOTREACHED();
}
} // namespace content
diff --git a/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.h b/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.h
index f54949bad5b..58072e3a966 100644
--- a/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.h
+++ b/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_SHARED_WORKER_SHARED_WORKER_SCRIPT_LOADER_FACTORY_H_
#include "base/macros.h"
+#include "content/common/navigation_subresource_loader_params.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace network {
@@ -17,6 +18,7 @@ namespace content {
class AppCacheHost;
class ServiceWorkerContextWrapper;
class ServiceWorkerProviderHost;
+class SharedWorkerScriptLoader;
class ResourceContext;
// S13nServiceWorker:
@@ -28,7 +30,8 @@ class ResourceContext;
//
// This creates a SharedWorkerScriptLoader to load the script, which follows
// redirects and sets the controller service worker on the shared worker if
-// needed.
+// needed. It's an error to call CreateLoaderAndStart() more than a total of one
+// time across this object or any of its clones.
class SharedWorkerScriptLoaderFactory
: public network::mojom::URLLoaderFactory {
public:
@@ -56,6 +59,10 @@ class SharedWorkerScriptLoaderFactory
traffic_annotation) override;
void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+ base::WeakPtr<SharedWorkerScriptLoader> GetScriptLoader() {
+ return script_loader_;
+ }
+
private:
const int process_id_;
base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host_;
@@ -63,6 +70,10 @@ class SharedWorkerScriptLoaderFactory
ResourceContext* resource_context_ = nullptr;
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
+ // This is owned by StrongBinding associated with the given URLLoaderRequest,
+ // and invalidated after request completion or failure.
+ base::WeakPtr<SharedWorkerScriptLoader> script_loader_;
+
DISALLOW_COPY_AND_ASSIGN(SharedWorkerScriptLoaderFactory);
};
diff --git a/chromium/content/browser/shared_worker/shared_worker_service_impl.cc b/chromium/content/browser/shared_worker/shared_worker_service_impl.cc
index 51f91bdd7e2..04d1913121e 100644
--- a/chromium/content/browser/shared_worker/shared_worker_service_impl.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -8,58 +8,75 @@
#include <algorithm>
#include <iterator>
+#include <string>
+#include "base/bind.h"
#include "base/callback.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/metrics/field_trial_params.h"
#include "base/task/post_task.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
#include "content/browser/appcache/appcache_navigation_handle_core.h"
#include "content/browser/file_url_loader_factory.h"
#include "content/browser/shared_worker/shared_worker_host.h"
#include "content/browser/shared_worker/shared_worker_instance.h"
+#include "content/browser/shared_worker/shared_worker_script_fetcher.h"
+#include "content/browser/shared_worker/shared_worker_script_loader.h"
#include "content/browser/shared_worker/shared_worker_script_loader_factory.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/url_loader_factory_getter.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/content_constants_internal.h"
+#include "content/common/navigation_subresource_loader_params.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/common/shared_worker/shared_worker_client.mojom.h"
+#include "content/common/throttling_url_loader.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/common/bind_interface_helpers.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/renderer_preferences.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/network/loader_util.h"
#include "services/network/public/cpp/features.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "url/origin.h"
namespace content {
namespace {
-bool IsShuttingDown(RenderProcessHost* host) {
- return !host || host->FastShutdownStarted() ||
- host->IsKeepAliveRefCountDisabled();
-}
+using StartLoaderCallback =
+ base::OnceCallback<void(mojom::ServiceWorkerProviderInfoForSharedWorkerPtr,
+ network::mojom::URLLoaderFactoryAssociatedPtrInfo,
+ std::unique_ptr<URLLoaderFactoryBundleInfo>,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr,
+ base::Optional<SubresourceLoaderParams>,
+ bool)>;
std::unique_ptr<URLLoaderFactoryBundleInfo> CreateFactoryBundle(
int process_id,
StoragePartitionImpl* storage_partition,
bool file_support) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
- ContentBrowserClient::NonNetworkURLLoaderFactoryMap factories;
+ ContentBrowserClient::NonNetworkURLLoaderFactoryMap non_network_factories;
GetContentClient()
->browser()
->RegisterNonNetworkSubresourceURLLoaderFactories(
- process_id, MSG_ROUTING_NONE, &factories);
+ process_id, MSG_ROUTING_NONE, &non_network_factories);
auto factory_bundle = std::make_unique<URLLoaderFactoryBundleInfo>();
- for (auto& pair : factories) {
+ for (auto& pair : non_network_factories) {
const std::string& scheme = pair.first;
std::unique_ptr<network::mojom::URLLoaderFactory> factory =
std::move(pair.second);
@@ -67,8 +84,8 @@ std::unique_ptr<URLLoaderFactoryBundleInfo> CreateFactoryBundle(
network::mojom::URLLoaderFactoryPtr factory_ptr;
mojo::MakeStrongBinding(std::move(factory),
mojo::MakeRequest(&factory_ptr));
- factory_bundle->factories_info().emplace(scheme,
- factory_ptr.PassInterface());
+ factory_bundle->scheme_specific_factory_infos().emplace(
+ scheme, factory_ptr.PassInterface());
}
if (file_support) {
@@ -80,13 +97,51 @@ std::unique_ptr<URLLoaderFactoryBundleInfo> CreateFactoryBundle(
network::mojom::URLLoaderFactoryPtr file_factory_ptr;
mojo::MakeStrongBinding(std::move(file_factory),
mojo::MakeRequest(&file_factory_ptr));
- factory_bundle->factories_info().emplace(url::kFileScheme,
- file_factory_ptr.PassInterface());
+ factory_bundle->scheme_specific_factory_infos().emplace(
+ url::kFileScheme, file_factory_ptr.PassInterface());
+ }
+
+ // Use RenderProcessHost's network factory as the default factory if
+ // NetworkService is off. If NetworkService is on the default factory is
+ // set in CreateScriptLoaderOnIO().
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // Using an opaque origin here should be safe - the URLLoaderFactory created
+ // for such origin shouldn't have any special privileges. Additionally, the
+ // origin should not be inspected at all in the legacy, non-NetworkService
+ // path.
+ const url::Origin kSafeOrigin = url::Origin();
+
+ network::mojom::URLLoaderFactoryPtr default_factory;
+ RenderProcessHost::FromID(process_id)
+ ->CreateURLLoaderFactory(kSafeOrigin,
+ mojo::MakeRequest(&default_factory));
+ factory_bundle->default_factory_info() = default_factory.PassInterface();
}
return factory_bundle;
}
+void DidCreateScriptLoaderOnIO(
+ StartLoaderCallback callback,
+ mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
+ service_worker_provider_info,
+ network::mojom::URLLoaderFactoryAssociatedPtrInfo
+ main_script_loader_factory,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ base::Optional<SubresourceLoaderParams> subresource_loader_params,
+ bool success) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(callback),
+ std::move(service_worker_provider_info),
+ std::move(main_script_loader_factory),
+ std::move(subresource_loader_factories),
+ std::move(main_script_load_params),
+ std::move(subresource_loader_params), success));
+}
+
void CreateScriptLoaderOnIO(
scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter,
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_for_browser_info,
@@ -95,12 +150,11 @@ void CreateScriptLoaderOnIO(
AppCacheNavigationHandleCore* appcache_handle_core,
std::unique_ptr<network::SharedURLLoaderFactoryInfo>
blob_url_loader_factory_info,
+ std::unique_ptr<network::ResourceRequest> resource_request,
int process_id,
- base::OnceCallback<void(mojom::ServiceWorkerProviderInfoForSharedWorkerPtr,
- network::mojom::URLLoaderFactoryAssociatedPtrInfo,
- std::unique_ptr<URLLoaderFactoryBundleInfo>)>
- callback) {
+ StartLoaderCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
// Set up for service worker.
auto provider_info = mojom::ServiceWorkerProviderInfoForSharedWorker::New();
@@ -116,22 +170,24 @@ void CreateScriptLoaderOnIO(
url_loader_factory = network::SharedURLLoaderFactory::Create(
std::move(blob_url_loader_factory_info));
} else {
- // Add the default factory to the bundle for browser.
- DCHECK(!factory_bundle_for_browser_info->default_factory_info());
-
// Create a factory bundle to use.
scoped_refptr<URLLoaderFactoryBundle> factory_bundle =
base::MakeRefCounted<URLLoaderFactoryBundle>(
std::move(factory_bundle_for_browser_info));
- // Get the direct network factory from |loader_factory_getter|. When
- // NetworkService is enabled, it returns a factory that doesn't support
- // reconnection to the network service after a crash, but it's OK since it's
- // used for a single shared worker startup.
- network::mojom::URLLoaderFactoryPtr network_factory_ptr;
- loader_factory_getter->CloneNetworkFactory(
- mojo::MakeRequest(&network_factory_ptr));
- factory_bundle->SetDefaultFactory(std::move(network_factory_ptr));
+ // Add the default factory to the bundle for browser if NetworkService
+ // is on. When NetworkService is off, we already created the default factory
+ // in CreateFactoryBundle().
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // Get the direct network factory from |loader_factory_getter|. When
+ // NetworkService is enabled, it returns a factory that doesn't support
+ // reconnection to the network service after a crash, but it's OK since
+ // it's used for a single shared worker startup.
+ network::mojom::URLLoaderFactoryPtr network_factory_ptr;
+ loader_factory_getter->CloneNetworkFactory(
+ mojo::MakeRequest(&network_factory_ptr));
+ factory_bundle->SetDefaultFactory(std::move(network_factory_ptr));
+ }
url_loader_factory = factory_bundle;
}
@@ -144,6 +200,31 @@ void CreateScriptLoaderOnIO(
appcache_handle_core ? appcache_handle_core->host()->GetWeakPtr()
: nullptr;
+ // NetworkService (PlzWorker):
+ // Start loading a shared worker main script.
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // TODO(nhiroki): Figure out what we should do in |wc_getter| for loading
+ // shared worker's main script.
+ base::RepeatingCallback<WebContents*()> wc_getter =
+ base::BindRepeating([]() -> WebContents* { return nullptr; });
+ std::vector<std::unique_ptr<URLLoaderThrottle>> throttles =
+ GetContentClient()->browser()->CreateURLLoaderThrottles(
+ *resource_request, context->resource_context(), wc_getter,
+ nullptr /* navigation_ui_data */, -1 /* frame_tree_node_id */);
+
+ SharedWorkerScriptFetcher::CreateAndStart(
+ std::make_unique<SharedWorkerScriptLoaderFactory>(
+ process_id, context.get(), host,
+ std::move(appcache_host), context->resource_context(),
+ std::move(url_loader_factory)),
+ std::move(throttles), std::move(resource_request),
+ base::BindOnce(DidCreateScriptLoaderOnIO, std::move(callback),
+ std::move(provider_info),
+ nullptr /* main_script_loader_factory */,
+ std::move(subresource_loader_factories)));
+ return;
+ }
+
// Create the SharedWorkerScriptLoaderFactory.
network::mojom::URLLoaderFactoryAssociatedPtrInfo main_script_loader_factory;
mojo::MakeStrongAssociatedBinding(
@@ -153,18 +234,23 @@ void CreateScriptLoaderOnIO(
std::move(url_loader_factory)),
mojo::MakeRequest(&main_script_loader_factory));
- // We continue in StartWorker.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), std::move(provider_info),
- std::move(main_script_loader_factory),
- std::move(subresource_loader_factories)));
+ DidCreateScriptLoaderOnIO(std::move(callback), std::move(provider_info),
+ std::move(main_script_loader_factory),
+ std::move(subresource_loader_factories),
+ nullptr /* main_script_load_params */,
+ base::nullopt /* subresource_loader_params */,
+ true /* success */);
}
} // namespace
+bool IsShuttingDown(RenderProcessHost* host) {
+ return !host || host->FastShutdownStarted() ||
+ host->IsKeepAliveRefCountDisabled();
+}
+
SharedWorkerServiceImpl::SharedWorkerServiceImpl(
- StoragePartition* storage_partition,
+ StoragePartitionImpl* storage_partition,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
scoped_refptr<ChromeAppCacheService> appcache_service)
: storage_partition_(storage_partition),
@@ -203,12 +289,20 @@ void SharedWorkerServiceImpl::TerminateAllWorkersForTesting(
std::move(callback));
} else {
terminate_all_workers_callback_ = std::move(callback);
- for (auto& host : worker_hosts_)
- host->TerminateWorker();
- // Monitor for actual termination in DestroyHost.
+ // Use an explicit iterator and be careful because TerminateWorker() can
+ // call DestroyHost(), which removes the host from |worker_hosts_| and could
+ // invalidate the iterator.
+ for (auto it = worker_hosts_.begin(); it != worker_hosts_.end();)
+ (*it++)->TerminateWorker();
}
}
+void SharedWorkerServiceImpl::SetWorkerTerminationCallbackForTesting(
+ base::OnceClosure callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ terminate_all_workers_callback_ = std::move(callback);
+}
+
void SharedWorkerServiceImpl::ConnectToWorker(
int process_id,
int frame_id,
@@ -273,17 +367,60 @@ void SharedWorkerServiceImpl::ConnectToWorker(
void SharedWorkerServiceImpl::DestroyHost(SharedWorkerHost* host) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- RenderProcessHost* process_host =
- RenderProcessHost::FromID(host->process_id());
worker_hosts_.erase(worker_hosts_.find(host));
- // Complete the call to TerminateAllWorkersForTesting if no more workers.
+ // Run the termination callback if no more workers.
if (worker_hosts_.empty() && terminate_all_workers_callback_)
std::move(terminate_all_workers_callback_).Run();
+}
+
+// TODO(nhiroki): Align this function with AddAdditionalRequestHeaders() in
+// navigation_request.cc, FrameFetchContext, and WorkerFetchContext.
+void SharedWorkerServiceImpl::AddAdditionalRequestHeaders(
+ network::ResourceRequest* resource_request,
+ BrowserContext* browser_context) {
+ DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
+
+ // TODO(nhiroki): Return early when the request is neither HTTP nor HTTPS
+ // (i.e., Blob URL or Data URL). This should be checked by
+ // SchemeIsHTTPOrHTTPS(), but currently cross-origin workers on extensions
+ // are allowed and the check doesn't work well. See https://crbug.com/867302.
+
+ // Set the "Accept" header.
+ resource_request->headers.SetHeaderIfMissing(network::kAcceptHeader,
+ network::kDefaultAcceptHeader);
+
+ // Set the "DNT" header if necessary.
+ RendererPreferences renderer_preferences;
+ GetContentClient()->browser()->UpdateRendererPreferencesForWorker(
+ browser_context, &renderer_preferences);
+ if (renderer_preferences.enable_do_not_track)
+ resource_request->headers.SetHeaderIfMissing(kDoNotTrackHeader, "1");
+
+ // Set the "Save-Data" header if necessary.
+ if (GetContentClient()->browser()->IsDataSaverEnabled(browser_context) &&
+ !base::GetFieldTrialParamByFeatureAsBool(features::kDataSaverHoldback,
+ "holdback_web", false)) {
+ resource_request->headers.SetHeaderIfMissing("Save-Data", "on");
+ }
- if (!IsShuttingDown(process_host))
- process_host->DecrementKeepAliveRefCount(
- RenderProcessHost::KeepAliveClientType::kSharedWorker);
+ // Set the "Sec-Metadata" header if necessary.
+ if (base::FeatureList::IsEnabled(features::kSecMetadata) ||
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableExperimentalWebPlatformFeatures)) {
+ // The worker's origin can be different from the constructor's origin, for
+ // example, when the worker created from the extension.
+ // TODO(hiroshige): Add DCHECK to make sure the same-originness once the
+ // cross-origin workers are deprecated (https://crbug.com/867302).
+ std::string site_value = "cross-site";
+ if (resource_request->request_initiator->IsSameOriginWith(
+ url::Origin::Create(resource_request->url))) {
+ site_value = "same-origin";
+ }
+ std::string value = base::StringPrintf(
+ "destination=\"sharedworker\", site=\"%s\"", site_value.c_str());
+ resource_request->headers.SetHeaderIfMissing("Sec-Metadata", value);
+ }
}
void SharedWorkerServiceImpl::CreateWorker(
@@ -294,7 +431,6 @@ void SharedWorkerServiceImpl::CreateWorker(
const blink::MessagePortChannel& message_port,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
DCHECK(!blob_url_loader_factory || instance->url().SchemeIsBlob());
bool constructor_uses_file_url =
@@ -312,24 +448,37 @@ void SharedWorkerServiceImpl::CreateWorker(
// Bounce to the IO thread to setup service worker and appcache support in
// case the request for the worker script will need to be intercepted by them.
if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
- StoragePartitionImpl* storage_partition =
- service_worker_context_->storage_partition();
- if (!storage_partition) {
- // The context is shutting down. Just drop the request.
- return;
- }
-
// Set up the factory bundle for non-NetworkService URLs, e.g.,
// chrome-extension:// URLs. One factory bundle is consumed by the browser
// for SharedWorkerScriptLoaderFactory, and one is sent to the renderer for
// subresource loading.
std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_for_browser =
- CreateFactoryBundle(process_id, storage_partition,
+ CreateFactoryBundle(process_id, storage_partition_,
constructor_uses_file_url);
std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories =
- CreateFactoryBundle(process_id, storage_partition,
+ CreateFactoryBundle(process_id, storage_partition_,
constructor_uses_file_url);
+ // NetworkService (PlzWorker):
+ // Create a resource request for initiating shared worker script fetch from
+ // the browser process.
+ std::unique_ptr<network::ResourceRequest> resource_request;
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // TODO(nhiroki): Populate more fields like referrer.
+ // (https://crbug.com/715632)
+ resource_request = std::make_unique<network::ResourceRequest>();
+ resource_request->url = weak_host->instance()->url();
+ resource_request->request_initiator =
+ weak_host->instance()->constructor_origin();
+ resource_request->resource_type = RESOURCE_TYPE_SHARED_WORKER;
+
+ auto* render_process_host = RenderProcessHost::FromID(process_id);
+ DCHECK(!IsShuttingDown(render_process_host));
+ AddAdditionalRequestHeaders(resource_request.get(),
+ render_process_host->GetBrowserContext());
+ }
+
+ // NetworkService (PlzWorker):
// An appcache interceptor is available only when the network service is
// enabled.
AppCacheNavigationHandleCore* appcache_handle_core = nullptr;
@@ -340,27 +489,67 @@ void SharedWorkerServiceImpl::CreateWorker(
weak_host->SetAppCacheHandle(std::move(appcache_handle));
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&CreateScriptLoaderOnIO,
- service_worker_context_->storage_partition()
- ->url_loader_factory_getter(),
+ storage_partition_->url_loader_factory_getter(),
std::move(factory_bundle_for_browser),
std::move(subresource_loader_factories), service_worker_context_,
appcache_handle_core,
blob_url_loader_factory ? blob_url_loader_factory->Clone()
: nullptr,
- process_id,
- base::BindOnce(&SharedWorkerServiceImpl::StartWorker,
+ std::move(resource_request), process_id,
+ base::BindOnce(&SharedWorkerServiceImpl::DidCreateScriptLoader,
weak_factory_.GetWeakPtr(), std::move(instance),
weak_host, std::move(client), process_id, frame_id,
message_port)));
return;
}
+ // Legacy case (to be deprecated):
StartWorker(std::move(instance), weak_host, std::move(client), process_id,
- frame_id, message_port, nullptr, {}, nullptr);
+ frame_id, message_port,
+ nullptr /* service_worker_provider_info */,
+ {} /* main_script_loader_factory */,
+ nullptr /* subresource_loader_factories */,
+ nullptr /* main_script_load_params */,
+ base::nullopt /* subresource_loader_params */);
+}
+
+void SharedWorkerServiceImpl::DidCreateScriptLoader(
+ std::unique_ptr<SharedWorkerInstance> instance,
+ base::WeakPtr<SharedWorkerHost> host,
+ mojom::SharedWorkerClientPtr client,
+ int process_id,
+ int frame_id,
+ const blink::MessagePortChannel& message_port,
+ mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
+ service_worker_provider_info,
+ network::mojom::URLLoaderFactoryAssociatedPtrInfo
+ main_script_loader_factory,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ base::Optional<SubresourceLoaderParams> subresource_loader_params,
+ bool success) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
+
+ // NetworkService (PlzWorker):
+ // If the script fetcher fails to load shared worker's main script, notify the
+ // client of the failure and abort shared worker startup.
+ if (!success) {
+ DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
+ client->OnScriptLoadFailed();
+ return;
+ }
+
+ StartWorker(
+ std::move(instance), std::move(host), std::move(client), process_id,
+ frame_id, message_port, std::move(service_worker_provider_info),
+ std::move(main_script_loader_factory),
+ std::move(subresource_loader_factories),
+ std::move(main_script_load_params), std::move(subresource_loader_params));
}
void SharedWorkerServiceImpl::StartWorker(
@@ -374,7 +563,9 @@ void SharedWorkerServiceImpl::StartWorker(
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
main_script_loader_factory,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories) {
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ base::Optional<SubresourceLoaderParams> subresource_loader_params) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// The host may already be gone if something forcibly terminated the worker
@@ -391,10 +582,6 @@ void SharedWorkerServiceImpl::StartWorker(
return;
}
- // Keep the renderer process alive that will be hosting the shared worker.
- process_host->IncrementKeepAliveRefCount(
- RenderProcessHost::KeepAliveClientType::kSharedWorker);
-
// Get the factory used to instantiate the new shared worker instance in
// the target process.
mojom::SharedWorkerFactoryPtr factory;
@@ -402,7 +589,9 @@ void SharedWorkerServiceImpl::StartWorker(
host->Start(std::move(factory), std::move(service_worker_provider_info),
std::move(main_script_loader_factory),
- std::move(subresource_loader_factories));
+ std::move(main_script_load_params),
+ std::move(subresource_loader_factories),
+ std::move(subresource_loader_params));
host->AddClient(std::move(client), process_id, frame_id, message_port);
}
diff --git a/chromium/content/browser/shared_worker/shared_worker_service_impl.h b/chromium/content/browser/shared_worker/shared_worker_service_impl.h
index 219003f234e..1433f18361b 100644
--- a/chromium/content/browser/shared_worker/shared_worker_service_impl.h
+++ b/chromium/content/browser/shared_worker/shared_worker_service_impl.h
@@ -20,7 +20,9 @@
#include "content/common/shared_worker/shared_worker_connector.mojom.h"
#include "content/common/shared_worker/shared_worker_factory.mojom.h"
#include "content/public/browser/shared_worker_service.h"
+#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "third_party/blink/public/mojom/shared_worker/shared_worker_main_script_load_params.mojom.h"
namespace blink {
class MessagePortChannel;
@@ -31,13 +33,17 @@ namespace content {
class ChromeAppCacheService;
class SharedWorkerInstance;
class SharedWorkerHost;
-class StoragePartition;
+class StoragePartitionImpl;
+struct SubresourceLoaderParams;
+
+// Shared helper function
+bool IsShuttingDown(RenderProcessHost* host);
// Created per StoragePartition.
class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
public:
SharedWorkerServiceImpl(
- StoragePartition* storage_partition,
+ StoragePartitionImpl* storage_partition,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
scoped_refptr<ChromeAppCacheService> appcache_service);
~SharedWorkerServiceImpl() override;
@@ -48,6 +54,7 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
const url::Origin& constructor_origin) override;
void TerminateAllWorkersForTesting(base::OnceClosure callback);
+ void SetWorkerTerminationCallbackForTesting(base::OnceClosure callback);
// Creates the worker if necessary or connects to an already existing worker.
void ConnectToWorker(
@@ -61,11 +68,16 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
void DestroyHost(SharedWorkerHost* host);
- StoragePartition* storage_partition() { return storage_partition_; }
+ StoragePartitionImpl* storage_partition() { return storage_partition_; }
private:
friend class SharedWorkerServiceImplTest;
friend class SharedWorkerHostTest;
+ FRIEND_TEST_ALL_PREFIXES(NetworkServiceRestartBrowserTest, SharedWorker);
+
+ static void AddAdditionalRequestHeaders(
+ network::ResourceRequest* resource_request,
+ BrowserContext* browser_context);
void CreateWorker(
std::unique_ptr<SharedWorkerInstance> instance,
@@ -74,6 +86,21 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
int frame_id,
const blink::MessagePortChannel& message_port,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory);
+ void DidCreateScriptLoader(
+ std::unique_ptr<SharedWorkerInstance> instance,
+ base::WeakPtr<SharedWorkerHost> host,
+ mojom::SharedWorkerClientPtr client,
+ int process_id,
+ int frame_id,
+ const blink::MessagePortChannel& message_port,
+ mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
+ service_worker_provider_info,
+ network::mojom::URLLoaderFactoryAssociatedPtrInfo
+ main_script_loader_factory,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ base::Optional<SubresourceLoaderParams> subresource_loader_params,
+ bool success);
void StartWorker(
std::unique_ptr<SharedWorkerInstance> instance,
base::WeakPtr<SharedWorkerHost> host,
@@ -85,7 +112,9 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
main_script_loader_factory,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories);
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ base::Optional<SubresourceLoaderParams> subresource_loader_params);
// Returns nullptr if there is no such host.
SharedWorkerHost* FindSharedWorkerHost(int process_id, int route_id);
@@ -97,7 +126,7 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
base::OnceClosure terminate_all_workers_callback_;
// |storage_partition_| owns |this|.
- StoragePartition* const storage_partition_;
+ StoragePartitionImpl* const storage_partition_;
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
scoped_refptr<ChromeAppCacheService> appcache_service_;
diff --git a/chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc b/chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
index e5d67bd381d..5f04ca09b0a 100644
--- a/chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
@@ -24,7 +24,7 @@
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
using blink::MessagePortChannel;
diff --git a/chromium/content/browser/shared_worker/worker_browsertest.cc b/chromium/content/browser/shared_worker/worker_browsertest.cc
index 9c7ffc1364b..b0f78e91ec4 100644
--- a/chromium/content/browser/shared_worker/worker_browsertest.cc
+++ b/chromium/content/browser/shared_worker/worker_browsertest.cc
@@ -9,10 +9,12 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_info.h"
+#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/common/content_features.h"
@@ -95,7 +97,8 @@ class WorkerTest : public ContentBrowserTest {
}
static void QuitUIMessageLoop(base::Callback<void()> callback) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(callback));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ std::move(callback));
}
void NavigateAndWaitForAuth(const GURL& url) {
diff --git a/chromium/content/browser/site_instance_impl.cc b/chromium/content/browser/site_instance_impl.cc
index 073dc2d4f99..c3b4522f4ee 100644
--- a/chromium/content/browser/site_instance_impl.cc
+++ b/chromium/content/browser/site_instance_impl.cc
@@ -273,11 +273,6 @@ bool SiteInstanceImpl::HasWrongProcessForURL(const GURL& url) {
origin_lock);
}
-scoped_refptr<SiteInstanceImpl>
-SiteInstanceImpl::GetDefaultSubframeSiteInstance() {
- return browsing_instance_->GetDefaultSubframeSiteInstance();
-}
-
bool SiteInstanceImpl::RequiresDedicatedProcess() {
if (!has_site_)
return false;
@@ -285,11 +280,6 @@ bool SiteInstanceImpl::RequiresDedicatedProcess() {
return DoesSiteRequireDedicatedProcess(GetBrowserContext(), site_);
}
-bool SiteInstanceImpl::IsDefaultSubframeSiteInstance() const {
- return process_reuse_policy_ ==
- ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS;
-}
-
void SiteInstanceImpl::IncrementActiveFrameCount() {
active_frame_count_++;
}
@@ -401,7 +391,11 @@ bool SiteInstanceImpl::IsSameWebSite(BrowserContext* browser_context,
}
// If the sites are the same, check isolated origins. If either URL matches
- // an isolated origin, compare origins rather than sites.
+ // an isolated origin, compare origins rather than sites. As an optimization
+ // to avoid unneeded isolated origin lookups, shortcut this check if the two
+ // origins are the same.
+ if (src_origin == dest_origin)
+ return true;
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
url::Origin src_isolated_origin;
url::Origin dest_isolated_origin;
@@ -449,27 +443,21 @@ GURL SiteInstanceImpl::GetSiteForURL(BrowserContext* browser_context,
: real_url;
url::Origin origin = url::Origin::Create(url);
- // Isolated origins should use the full origin as their site URL. A subdomain
- // of an isolated origin should also use that isolated origin's site URL. It
- // is important to check |url| rather than |real_url| here, since some
- // effective URLs (such as for NTP) need to be resolved prior to the isolated
- // origin lookup.
- auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
- url::Origin isolated_origin;
- if (policy->GetMatchingIsolatedOrigin(origin, &isolated_origin))
- return isolated_origin.GetURL();
-
// If the url has a host, then determine the site. Skip file URLs to avoid a
// situation where site URL of file://localhost/ would mismatch Blink's origin
// (which ignores the hostname in this case - see https://crbug.com/776160).
if (!origin.host().empty() && origin.scheme() != url::kFileScheme) {
- // Only keep the scheme and registered domain of |origin|.
- std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
- origin.host(),
- net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
- std::string site = origin.scheme();
- site += url::kStandardSchemeSeparator;
- site += domain.empty() ? origin.host() : domain;
+ GURL site_url(GetSiteForOrigin(origin));
+
+ // Isolated origins should use the full origin as their site URL. A
+ // subdomain of an isolated origin should also use that isolated origin's
+ // site URL. It is important to check |origin| (based on |url|) rather than
+ // |real_url| here, since some effective URLs (such as for NTP) need to be
+ // resolved prior to the isolated origin lookup.
+ auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
+ url::Origin isolated_origin;
+ if (policy->GetMatchingIsolatedOrigin(origin, site_url, &isolated_origin))
+ return isolated_origin.GetURL();
// If an effective URL was used, augment the effective site URL with the
// underlying web site in the hash. This is needed to keep
@@ -479,17 +467,21 @@ GURL SiteInstanceImpl::GetSiteForURL(BrowserContext* browser_context,
// TODO(https://crbug.com/734722): Consider replacing this hack with
// a proper security principal.
if (should_use_effective_urls && url != real_url) {
- site += "#" + GetSiteForURL(browser_context, real_url,
- false /* should_use_effective_urls */)
- .spec();
+ std::string non_translated_site_url(
+ GetSiteForURL(browser_context, real_url,
+ false /* should_use_effective_urls */)
+ .spec());
+ GURL::Replacements replacements;
+ replacements.SetRefStr(non_translated_site_url.c_str());
+ site_url = site_url.ReplaceComponents(replacements);
}
- return GURL(site);
+ return site_url;
}
// If there is no host but there is a scheme, return the scheme.
// This is useful for cases like file URLs.
- if (!origin.unique()) {
+ if (!origin.opaque()) {
// Prefer to use the scheme of |origin| rather than |url|, to correctly
// cover blob:file: and filesystem:file: URIs (see also
// https://crbug.com/697111).
@@ -536,6 +528,18 @@ GURL SiteInstanceImpl::GetSiteForURL(BrowserContext* browser_context,
}
// static
+GURL SiteInstanceImpl::GetSiteForOrigin(const url::Origin& origin) {
+ // Only keep the scheme and registered domain of |origin|.
+ std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
+ origin.host(),
+ net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+ std::string site = origin.scheme();
+ site += url::kStandardSchemeSeparator;
+ site += domain.empty() ? origin.host() : domain;
+ return GURL(site);
+}
+
+// static
GURL SiteInstanceImpl::GetEffectiveURL(BrowserContext* browser_context,
const GURL& url) {
return GetContentClient()->browser()->GetEffectiveURL(browser_context, url);
@@ -555,16 +559,21 @@ bool SiteInstanceImpl::DoesSiteRequireDedicatedProcess(
if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites())
return true;
+ // Always require a dedicated process for isolated origins.
+ GURL site_url = SiteInstance::GetSiteForURL(browser_context, url);
+ auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
+ if (policy->IsIsolatedOrigin(url::Origin::Create(site_url)))
+ return true;
+
// Error pages in main frames do require isolation, however since this is
// missing the context whether this is for a main frame or not, that part
// is enforced in RenderFrameHostManager.
- if (url.SchemeIs(kChromeErrorScheme))
+ if (site_url.SchemeIs(kChromeErrorScheme))
return true;
- // Always require a dedicated process for isolated origins.
- GURL site_url = SiteInstance::GetSiteForURL(browser_context, url);
- auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
- if (policy->IsIsolatedOrigin(url::Origin::Create(site_url)))
+ // Isolate kChromeUIScheme pages from one another and from other kinds of
+ // schemes.
+ if (site_url.SchemeIs(content::kChromeUIScheme))
return true;
// Let the content embedder enable site isolation for specific URLs. Use the
@@ -597,12 +606,6 @@ bool SiteInstanceImpl::ShouldLockToOrigin(BrowserContext* browser_context,
if (site_url.SchemeIs(content::kGuestScheme))
return false;
- // TODO(creis, nick) https://crbug.com/510588 Chrome UI pages use the same
- // site (chrome://chrome), so they can't be locked because the site being
- // loaded doesn't match the SiteInstance.
- if (site_url.SchemeIs(content::kChromeUIScheme))
- return false;
-
// TODO(creis, nick): Until we can handle sites with effective URLs at the
// call sites of ChildProcessSecurityPolicy::CanAccessDataForOrigin, we
// must give the embedder a chance to exempt some sites to avoid process
diff --git a/chromium/content/browser/site_instance_impl.h b/chromium/content/browser/site_instance_impl.h
index b53db35063a..d72334b0b57 100644
--- a/chromium/content/browser/site_instance_impl.h
+++ b/chromium/content/browser/site_instance_impl.h
@@ -64,7 +64,6 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
bool IsRelatedSiteInstance(const SiteInstance* instance) override;
size_t GetRelatedActiveContentsCount() override;
bool RequiresDedicatedProcess() override;
- bool IsDefaultSubframeSiteInstance() const override;
// The policy to apply when selecting a RenderProcessHost for the
// SiteInstance. If no suitable RenderProcessHost for the SiteInstance exists
@@ -79,9 +78,6 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
// RenderProcessHost.
PROCESS_PER_SITE,
- // In this mode, subframes will be hosted in a designated RenderProcessHost.
- USE_DEFAULT_SUBFRAME_PROCESS,
-
// In this mode, the site will be rendered in a RenderProcessHost that is
// already in use for the site, either for a pending navigation or a
// committed navigation. If multiple such processes exist, ones that have
@@ -127,24 +123,25 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
// Returns the site for the given URL, which includes only the scheme and
// registered domain. Returns an empty GURL if the URL has no host.
- // |use_effective_urls| specifies whether to resolve |url| to an effective
- // URL (via ContentBrowserClient::GetEffectiveURL()) before determining the
- // site.
+ // |should_use_effective_urls| specifies whether to resolve |url| to an
+ // effective URL (via ContentBrowserClient::GetEffectiveURL()) before
+ // determining the site.
static GURL GetSiteForURL(BrowserContext* context,
const GURL& url,
- bool use_effective_urls);
+ bool should_use_effective_urls);
+
+ // Returns the site of a given |origin|. Unlike GetSiteForURL(), this does
+ // not utilize effective URLs, isolated origins, or other special logic. It
+ // only translates an origin into a site (i.e., scheme and eTLD+1) and is
+ // used internally by GetSiteForURL(). For making process model decisions,
+ // GetSiteForURL() should be used instead.
+ static GURL GetSiteForOrigin(const url::Origin& origin);
// Returns the URL to which a process should be locked for the given URL.
// This is computed similarly to the site URL (see GetSiteForURL), but
// without resolving effective URLs.
static GURL DetermineProcessLockURL(BrowserContext* context, const GURL& url);
- // Returns the SiteInstance, related to this one, that should be used
- // for subframes when an oopif is required, but a dedicated process is not.
- // This SiteInstance will be created if it doesn't already exist. There is
- // at most one of these per BrowsingInstance.
- scoped_refptr<SiteInstanceImpl> GetDefaultSubframeSiteInstance();
-
// Set the web site that this SiteInstance is rendering pages for.
// This includes the scheme and registered domain, but not the port. If the
// URL does not have a valid registered domain, then the full hostname is
@@ -225,12 +222,12 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
// true here also implies that |site_url| requires a dedicated process.
// However, the converse does not hold: this might still return false for
// certain special cases where an origin lock can't be applied even when
- // |site_url| requires a dedicated process (e.g., with
- // --site-per-process). Examples of those cases include <webview> guests,
- // WebUI, single-process mode, or extensions where a process is currently
- // allowed to be reused for different extensions. Most of these special
- // cases should eventually be removed, and this function should become
- // equivalent to DoesSiteRequireDedicatedProcess().
+ // |site_url| requires a dedicated process (e.g., with --site-per-process).
+ // Examples of those cases include <webview> guests, single-process mode, or
+ // extensions where a process is currently allowed to be reused for different
+ // extensions. Most of these special cases should eventually be removed, and
+ // this function should become equivalent to
+ // DoesSiteRequireDedicatedProcess().
static bool ShouldLockToOrigin(BrowserContext* browser_context,
GURL site_url);
@@ -252,11 +249,6 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
// Used to restrict a process' origin access rights.
void LockToOriginIfNeeded();
- // This gets the render process to use for default subframe site instances.
- RenderProcessHost* GetDefaultSubframeProcessHost(
- BrowserContext* browser_context,
- bool is_for_guests_only);
-
// An object used to construct RenderProcessHosts.
static const RenderProcessHostFactory* g_render_process_host_factory_;
diff --git a/chromium/content/browser/site_instance_impl_unittest.cc b/chromium/content/browser/site_instance_impl_unittest.cc
index ec3fa59c538..901f65023eb 100644
--- a/chromium/content/browser/site_instance_impl_unittest.cc
+++ b/chromium/content/browser/site_instance_impl_unittest.cc
@@ -676,79 +676,6 @@ TEST_F(SiteInstanceTest, OneSiteInstancePerSiteInBrowserContext) {
DrainMessageLoop();
}
-static scoped_refptr<SiteInstanceImpl> CreateSiteInstance(
- BrowserContext* browser_context,
- const GURL& url) {
- return SiteInstanceImpl::CreateForURL(browser_context, url);
-}
-
-// Test to ensure that pages that require certain privileges are grouped
-// in processes with similar pages.
-// TODO(nasko): Remove. See https://crbug.com/847127.
-TEST_F(SiteInstanceTest, ProcessSharingByType) {
- // This test shouldn't run with --site-per-process mode, which prohibits
- // the renderer process reuse this test explicitly exercises.
- if (AreAllSitesIsolatedForTesting())
- return;
-
- ChildProcessSecurityPolicyImpl* policy =
- ChildProcessSecurityPolicyImpl::GetInstance();
-
- // Make a bunch of mock renderers so that we hit the limit.
- std::unique_ptr<TestBrowserContext> browser_context(new TestBrowserContext());
- std::vector<std::unique_ptr<MockRenderProcessHost>> hosts;
- for (size_t i = 0; i < kMaxRendererProcessCount; ++i) {
- hosts.push_back(
- std::make_unique<MockRenderProcessHost>(browser_context.get()));
- hosts[i]->SetIsUsed();
- }
-
- // On Android by default the number of renderer hosts is unlimited and process
- // sharing doesn't happen. We set the override so that the test can run
- // everywhere.
- RenderProcessHost::SetMaxRendererProcessCount(kMaxRendererProcessCount);
-
- // Create some extension instances and make sure they share a process.
- scoped_refptr<SiteInstanceImpl> extension1_instance(
- CreateSiteInstance(browser_context.get(),
- GURL(kPrivilegedScheme + std::string("://foo/bar"))));
- set_privileged_process_id(extension1_instance->GetProcess()->GetID());
-
- scoped_refptr<SiteInstanceImpl> extension2_instance(
- CreateSiteInstance(browser_context.get(),
- GURL(kPrivilegedScheme + std::string("://baz/bar"))));
-
- std::unique_ptr<RenderProcessHost> extension_host(
- extension1_instance->GetProcess());
- EXPECT_EQ(extension1_instance->GetProcess(),
- extension2_instance->GetProcess());
-
- // Create some WebUI instances and make sure they share a process.
- scoped_refptr<SiteInstanceImpl> webui1_instance(
- CreateSiteInstance(browser_context.get(), GetWebUIURL(kChromeUIGpuHost)));
- policy->GrantWebUIBindings(webui1_instance->GetProcess()->GetID(),
- BINDINGS_POLICY_WEB_UI);
-
- scoped_refptr<SiteInstanceImpl> webui2_instance(CreateSiteInstance(
- browser_context.get(), GetWebUIURL(kChromeUIMediaInternalsHost)));
-
- std::unique_ptr<RenderProcessHost> dom_host(webui1_instance->GetProcess());
- EXPECT_EQ(webui1_instance->GetProcess(), webui2_instance->GetProcess());
-
- // Make sure none of differing privilege processes are mixed.
- EXPECT_NE(extension1_instance->GetProcess(), webui1_instance->GetProcess());
-
- for (size_t i = 0; i < kMaxRendererProcessCount; ++i) {
- EXPECT_NE(extension1_instance->GetProcess(), hosts[i].get());
- EXPECT_NE(webui1_instance->GetProcess(), hosts[i].get());
- }
-
- DrainMessageLoop();
-
- // Disable the process limit override.
- RenderProcessHost::SetMaxRendererProcessCount(0u);
-}
-
// Test to ensure that HasWrongProcessForURL behaves properly for different
// types of URLs.
TEST_F(SiteInstanceTest, HasWrongProcessForURL) {
@@ -945,55 +872,6 @@ TEST_F(SiteInstanceTest, IsSameWebsiteForNestedURLs) {
EXPECT_FALSE(SiteInstance::IsSameWebSite(nullptr, https_bar_url, fs_bar_url));
}
-TEST_F(SiteInstanceTest, DefaultSubframeSiteInstance) {
- if (AreAllSitesIsolatedForTesting())
- return; // --top-document-isolation is not possible.
-
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kTopDocumentIsolation);
-
- std::unique_ptr<TestBrowserContext> browser_context(new TestBrowserContext());
- scoped_refptr<SiteInstanceImpl> main_instance =
- SiteInstanceImpl::Create(browser_context.get());
- scoped_refptr<SiteInstanceImpl> subframe_instance =
- main_instance->GetDefaultSubframeSiteInstance();
- int subframe_instance_id = subframe_instance->GetId();
-
- EXPECT_NE(main_instance, subframe_instance);
- EXPECT_EQ(subframe_instance, main_instance->GetDefaultSubframeSiteInstance());
- EXPECT_FALSE(main_instance->IsDefaultSubframeSiteInstance());
- EXPECT_TRUE(subframe_instance->IsDefaultSubframeSiteInstance());
-
- EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
-
- // Free the subframe instance.
- subframe_instance = nullptr;
- EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
-
- // Calling GetDefaultSubframeSiteInstance again should return a new
- // SiteInstance with a different ID from the original.
- subframe_instance = main_instance->GetDefaultSubframeSiteInstance();
- EXPECT_NE(subframe_instance->GetId(), subframe_instance_id);
- EXPECT_FALSE(main_instance->IsDefaultSubframeSiteInstance());
- EXPECT_TRUE(subframe_instance->IsDefaultSubframeSiteInstance());
- EXPECT_EQ(subframe_instance->GetDefaultSubframeSiteInstance(),
- subframe_instance);
- EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
-
- // Free the main instance.
- main_instance = nullptr;
- EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
-
- // Free the subframe instance, which should free the browsing instance.
- subframe_instance = nullptr;
- EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(1, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
-}
-
TEST_F(SiteInstanceTest, IsolatedOrigins) {
GURL foo_url("http://www.foo.com");
GURL isolated_foo_url("http://isolated.foo.com");
diff --git a/chromium/content/browser/site_per_process_browsertest.cc b/chromium/content/browser/site_per_process_browsertest.cc
index 396d50ce3cf..5068b4b8091 100644
--- a/chromium/content/browser/site_per_process_browsertest.cc
+++ b/chromium/content/browser/site_per_process_browsertest.cc
@@ -32,6 +32,7 @@
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/test/bind_test_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/test_timeouts.h"
@@ -65,6 +66,7 @@
#include "content/common/renderer.mojom.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/interstitial_page_delegate.h"
#include "content/public/browser/navigation_handle.h"
@@ -72,7 +74,6 @@
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_observer.h"
-#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
@@ -206,9 +207,9 @@ void SimulateMouseClick(RenderWidgetHost* rwh, int x, int y) {
rwh->ForwardMouseEvent(mouse_event);
}
-// Retrieve document.origin for the frame |ftn|.
-EvalJsResult GetDocumentOrigin(FrameTreeNode* ftn) {
- return EvalJs(ftn, "document.origin;");
+// Retrieve self.origin for the frame |ftn|.
+EvalJsResult GetOriginFromRenderer(FrameTreeNode* ftn) {
+ return EvalJs(ftn, "self.origin;");
}
double GetFrameDeviceScaleFactor(const ToRenderFrameHost& adapter) {
@@ -577,8 +578,8 @@ class UpdateViewportIntersectionMessageFilter
// OnUpdateViewportIntersection returns. This additional post on the IO
// thread guarantees that by the time OnUpdateViewportIntersectionOnUI runs,
// the message has been handled on the UI thread.
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&UpdateViewportIntersectionMessageFilter::
OnUpdateViewportIntersectionPostOnIO,
this, viewport_intersection, compositing_rect,
@@ -588,8 +589,8 @@ class UpdateViewportIntersectionMessageFilter
const gfx::Rect& viewport_intersection,
const gfx::Rect& compositing_rect,
bool occluded_or_obscured) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&UpdateViewportIntersectionMessageFilter::
OnUpdateViewportIntersectionOnUI,
this, viewport_intersection, compositing_rect,
@@ -1141,7 +1142,12 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Verify that applying a CSS scale transform does not impact the size of the
// content of the nested iframe.
- EXPECT_EQ(gfx::Size(50, 50), connector->screen_space_rect_in_dip().size());
+ // The screen_space_rect_in_dip may be off by 1 due to rounding. There is no
+ // good way to avoid this due to various device-scale-factor. (e.g. when
+ // dsf=3.375, ceil(round(50 * 3.375) / 3.375) = 51. Thus, we allow the screen
+ // size in dip to be off by 1 here.
+ EXPECT_NEAR(50, connector->screen_space_rect_in_dip().size().width(), 1);
+ EXPECT_NEAR(50, connector->screen_space_rect_in_dip().size().height(), 1);
EXPECT_EQ(gfx::Size(100, 100), rwhv_nested->GetViewBounds().size());
EXPECT_EQ(gfx::Size(100, 100), connector->local_frame_size_in_dip());
EXPECT_EQ(connector->local_frame_size_in_pixels(),
@@ -1837,19 +1843,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
scroll_observer->Wait();
}
-#if defined(OS_CHROMEOS) || defined(OS_MACOSX)
-// Flaky: https://crbug.com/836200.
-// Flaky timeouts on Mac: https://crbug.com/863971.
-#define MAYBE_ScrollBubblingFromOOPIFWithBodyOverflowHidden \
- DISABLED_ScrollBubblingFromOOPIFWithBodyOverflowHidden
-#else
-#define MAYBE_ScrollBubblingFromOOPIFWithBodyOverflowHidden \
- ScrollBubblingFromOOPIFWithBodyOverflowHidden
-#endif
// Tests that scrolling bubbles from an oopif if its source body has
// "overflow:hidden" style.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
- MAYBE_ScrollBubblingFromOOPIFWithBodyOverflowHidden) {
+ ScrollBubblingFromOOPIFWithBodyOverflowHidden) {
GURL url_domain_a(embedded_test_server()->GetURL(
"a.com", "/scrollable_page_with_iframe.html"));
EXPECT_TRUE(NavigateToURL(shell(), url_domain_a));
@@ -5036,26 +5033,28 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, NavigatePopupToIllegalURL) {
EXPECT_NE(popup->web_contents()->GetSiteInstance(),
shell()->web_contents()->GetSiteInstance());
- // From the opener, navigate the popup to a file:/// URL. This should be
- // disallowed and result in an about:blank navigation.
+ ConsoleObserverDelegate console_delegate(
+ web_contents(), "Not allowed to load local resource:*");
+ web_contents()->SetDelegate(&console_delegate);
+
+ // From the opener, navigate the popup to a file:/// URL. This should result
+ // in a console error and stay on the old page.
GURL file_url("file:///");
NavigateNamedFrame(shell(), file_url, "foo");
EXPECT_TRUE(WaitForLoadStop(popup->web_contents()));
- EXPECT_EQ(GURL(url::kAboutBlankURL),
- popup->web_contents()->GetLastCommittedURL());
-
- // Navigate popup back to a cross-site URL.
- EXPECT_TRUE(NavigateToURLFromRenderer(popup, popup_url));
- EXPECT_NE(popup->web_contents()->GetSiteInstance(),
- shell()->web_contents()->GetSiteInstance());
+ EXPECT_EQ(popup_url, popup->web_contents()->GetLastCommittedURL());
+ EXPECT_TRUE(base::MatchPattern(console_delegate.message(),
+ "Not allowed to load local resource: file:*"));
// Now try the same test with a chrome:// URL.
GURL chrome_url(std::string(kChromeUIScheme) + "://" +
std::string(kChromeUIGpuHost));
NavigateNamedFrame(shell(), chrome_url, "foo");
EXPECT_TRUE(WaitForLoadStop(popup->web_contents()));
- EXPECT_EQ(GURL(url::kAboutBlankURL),
- popup->web_contents()->GetLastCommittedURL());
+ EXPECT_EQ(popup_url, popup->web_contents()->GetLastCommittedURL());
+ EXPECT_TRUE(
+ base::MatchPattern(console_delegate.message(),
+ "Not allowed to load local resource: chrome:*"));
}
// Verify that named frames are discoverable from their opener's ancestors.
@@ -5938,13 +5937,13 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Navigate to the site of the parent, but to a page that will not commit.
GURL same_site_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
- NavigationStallDelegate stall_delegate(same_site_url);
- ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
+ TestNavigationManager stalled_navigation(web_contents(), same_site_url);
{
NavigationController::LoadURLParams params(same_site_url);
params.transition_type = ui::PAGE_TRANSITION_LINK;
params.frame_tree_node_id = node->frame_tree_node_id();
node->navigator()->GetController()->LoadURLWithParams(params);
+ EXPECT_TRUE(stalled_navigation.WaitForResponse());
}
// Grab the routing id of the pending RenderFrameHost and set up a process
@@ -5990,8 +5989,6 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
shell(), embedded_test_server()->GetURL("d.com", "/title3.html")));
watcher.Wait();
EXPECT_TRUE(watcher.did_exit_normally());
-
- ResourceDispatcherHost::Get()->SetDelegate(nullptr);
}
// This test ensures that the RenderFrame isn't leaked in the renderer process
@@ -6419,9 +6416,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, SandboxFlagsInheritance) {
// Check whether each frame is sandboxed on the renderer side, by seeing if
// each frame's origin is unique ("null").
- EXPECT_EQ("null", GetDocumentOrigin(b_child));
- EXPECT_EQ("null", GetDocumentOrigin(c_child));
- EXPECT_EQ("null", GetDocumentOrigin(d_child));
+ EXPECT_EQ("null", GetOriginFromRenderer(b_child));
+ EXPECT_EQ("null", GetOriginFromRenderer(c_child));
+ EXPECT_EQ("null", GetOriginFromRenderer(d_child));
}
// Check that sandbox flags are not inherited before they take effect. Create
@@ -6473,7 +6470,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Check that the grandchild frame isn't sandboxed on the renderer side. If
// sandboxed, its origin would be unique ("null").
std::string expected_origin = url::Origin::Create(frame_url).Serialize();
- EXPECT_EQ(expected_origin, GetDocumentOrigin(grandchild));
+ EXPECT_EQ(expected_origin, GetOriginFromRenderer(grandchild));
}
// Verify that popups opened from sandboxed frames inherit sandbox flags from
@@ -6513,7 +6510,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Verify that they've also taken effect on the renderer side. The sandboxed
// frame's origin should be unique.
- EXPECT_EQ("null", GetDocumentOrigin(root->child_at(0)));
+ EXPECT_EQ("null", GetOriginFromRenderer(root->child_at(0)));
// Open a popup named "foo" from the sandboxed child frame.
Shell* foo_shell =
@@ -6530,7 +6527,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
EXPECT_EQ(expected_flags, foo_root->effective_frame_policy().sandbox_flags);
// The popup's origin should be unique, since it's sandboxed.
- EXPECT_EQ("null", GetDocumentOrigin(foo_root));
+ EXPECT_EQ("null", GetOriginFromRenderer(foo_root));
// Navigate the popup cross-site. This should keep the unique origin and the
// inherited sandbox flags.
@@ -6546,7 +6543,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Confirm that the popup is still sandboxed, both on browser and renderer
// sides.
EXPECT_EQ(expected_flags, foo_root->effective_frame_policy().sandbox_flags);
- EXPECT_EQ("null", GetDocumentOrigin(foo_root));
+ EXPECT_EQ("null", GetOriginFromRenderer(foo_root));
// Navigate the popup back to b.com. The popup should perform a
// remote-to-local navigation in the b.com process, and keep the unique
@@ -6562,7 +6559,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Confirm that the popup is still sandboxed, both on browser and renderer
// sides.
EXPECT_EQ(expected_flags, foo_root->effective_frame_policy().sandbox_flags);
- EXPECT_EQ("null", GetDocumentOrigin(foo_root));
+ EXPECT_EQ("null", GetOriginFromRenderer(foo_root));
}
// Verify that popups opened from frames sandboxed with the
@@ -6620,7 +6617,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// The popup's origin should match |b_url|, since it's not sandboxed.
EXPECT_EQ(url::Origin::Create(b_url).Serialize(),
- EvalJs(foo_root, "document.origin;"));
+ EvalJs(foo_root, "self.origin;"));
}
// Tests that the WebContents is notified when passive mixed content is
@@ -7191,7 +7188,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Test for https://crbug.com/568836. From an A-embed-B page, navigate the
// subframe from B to A. This cleans up the process for B, but the test delays
// the browser side from killing the B process right away. This allows the
-// B process to process two ViewMsg_Close messages sent to the subframe's
+// B process to process two WidgetMsg_Close messages sent to the subframe's
// RenderWidget and to the RenderView, in that order. In the bug, the latter
// crashed while detaching the subframe's LocalFrame (triggered as part of
// closing the RenderView), because this tried to access the subframe's
@@ -7720,15 +7717,15 @@ class PendingWidgetMessageFilter : public BrowserMessageFilter {
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&PendingWidgetMessageFilter::OnReceivedRoutingIDOnUI,
this, pending_widget_routing_id));
}
void OnShowWidget(int routing_id, const gfx::Rect& initial_rect) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&PendingWidgetMessageFilter::OnReceivedRoutingIDOnUI,
this, routing_id));
}
@@ -8704,9 +8701,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyJavaScriptBrowserTest,
EXPECT_TRUE(root->child_at(0)
->current_frame_host()
->GetLastCommittedOrigin()
- .unique());
+ .opaque());
// And verify that the origin in the replication state is also opaque.
- EXPECT_TRUE(root->child_at(0)->current_origin().unique());
+ EXPECT_TRUE(root->child_at(0)->current_origin().opaque());
// Ask the sandboxed iframe to report the enabled state of the geolocation
// feature. If the declared policy was correctly flagged as referring to the
@@ -8731,9 +8728,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyJavaScriptBrowserTest,
EXPECT_TRUE(root->child_at(0)
->current_frame_host()
->GetLastCommittedOrigin()
- .unique());
+ .opaque());
// And verify that the origin in the replication state is also opaque.
- EXPECT_TRUE(root->child_at(0)->current_origin().unique());
+ EXPECT_TRUE(root->child_at(0)->current_origin().opaque());
EXPECT_TRUE(ExecuteScriptAndExtractBool(
root->child_at(0),
@@ -8765,9 +8762,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyJavaScriptBrowserTest,
EXPECT_TRUE(root->child_at(0)
->current_frame_host()
->GetLastCommittedOrigin()
- .unique());
+ .opaque());
// And verify that the origin in the replication state is also opaque.
- EXPECT_TRUE(root->child_at(0)->current_origin().unique());
+ EXPECT_TRUE(root->child_at(0)->current_origin().opaque());
// Verify that geolocation is enabled in the document.
bool success = false;
@@ -8787,9 +8784,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessFeaturePolicyJavaScriptBrowserTest,
EXPECT_FALSE(root->child_at(0)
->current_frame_host()
->GetLastCommittedOrigin()
- .unique());
+ .opaque());
// Verify that the origin in the replication state is also no longer opaque.
- EXPECT_FALSE(root->child_at(0)->current_origin().unique());
+ EXPECT_FALSE(root->child_at(0)->current_origin().opaque());
// Verify that the new document does not have geolocation enabled.
EXPECT_TRUE(ExecuteScriptAndExtractBool(
@@ -9014,7 +9011,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
const blink::ParsedFeaturePolicy initial_effective_policy =
root->child_at(2)->effective_frame_policy().container_policy;
EXPECT_EQ(1UL, initial_effective_policy[0].origins.size());
- EXPECT_FALSE(initial_effective_policy[0].origins[0].unique());
+ EXPECT_FALSE(initial_effective_policy[0].origins[0].opaque());
// Set the "sandbox" attribute; pending policy should update, and should now
// be flagged as matching the opaque origin of the frame (without containing
@@ -9027,7 +9024,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
const blink::ParsedFeaturePolicy updated_pending_policy =
root->child_at(2)->pending_frame_policy().container_policy;
EXPECT_EQ(1UL, updated_effective_policy[0].origins.size());
- EXPECT_FALSE(updated_effective_policy[0].origins[0].unique());
+ EXPECT_FALSE(updated_effective_policy[0].origins[0].opaque());
EXPECT_TRUE(updated_pending_policy[0].matches_opaque_src);
EXPECT_EQ(0UL, updated_pending_policy[0].origins.size());
@@ -9625,8 +9622,8 @@ class SetIsInertMessageFilter : public content::BrowserMessageFilter {
~SetIsInertMessageFilter() override {}
void OnSetIsInert(bool is_inert) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&SetIsInertMessageFilter::OnSetIsInertOnUI, this,
is_inert));
}
@@ -10488,6 +10485,27 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAndroidSiteIsolationTest,
EXPECT_EQ(ui::TouchSelectionController::SELECTION_ACTIVE,
parent_view->touch_selection_controller()->active_status());
+ // Check that selection handles are close to the selection range.
+ ui::TouchSelectionController* touch_selection_controller =
+ parent_view->touch_selection_controller();
+
+ gfx::PointF selection_start = touch_selection_controller->GetStartPosition();
+ gfx::PointF selection_end = touch_selection_controller->GetEndPosition();
+ gfx::RectF handle_start = touch_selection_controller->GetStartHandleRect();
+ gfx::RectF handle_end = touch_selection_controller->GetEndHandleRect();
+
+ // Not all Android bots seem to actually show the handle, so check first.
+ if (!handle_start.IsEmpty()) {
+ EXPECT_FALSE(touch_selection_controller->GetEndHandleRect().IsEmpty());
+ // handle_start.y() defined the top of the handle's rect, and x() is left.
+ EXPECT_NEAR(selection_start.y(), handle_start.y(), 3.f);
+ EXPECT_GE(selection_start.x(), handle_start.x());
+ EXPECT_LE(selection_start.x(), handle_start.right());
+ EXPECT_NEAR(selection_end.y(), handle_end.y(), 3.f);
+ EXPECT_GE(selection_end.x(), handle_end.x());
+ EXPECT_LE(selection_end.x(), handle_end.right());
+ }
+
// Tap inside/outside the iframe and make sure the selection handles go away.
selection_controller_client->InitWaitForSelectionEvent(
ui::SELECTION_HANDLES_CLEARED);
@@ -12113,8 +12131,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Test to verify that viewport intersection is propagated to nested OOPIFs
// even when a parent OOPIF has been throttled.
-// TODO(crbug.com/869758) The test is flaky on android
-#if defined(OS_ANDROID)
+// TODO(crbug.com/869758) The test is flaky on android and Linux.
+#if defined(OS_ANDROID) || defined(OS_LINUX)
#define MAYBE_NestedFrameViewportIntersectionUpdated \
DISABLED_NestedFrameViewportIntersectionUpdated
#else
@@ -12253,7 +12271,8 @@ class SitePerProcessBrowserTouchActionTest : public SitePerProcessBrowserTest {
RenderWidgetHostInputEventRouter* router,
RenderWidgetHostViewBase* rwhv_root,
RenderWidgetHostViewBase* rwhv_child,
- const gfx::Point& event_position) {
+ const gfx::Point& event_position,
+ base::Optional<cc::TouchAction>& whitelisted_touch_action) {
InputEventAckWaiter ack_observer(
rwhv_child->GetRenderWidgetHost(),
base::BindRepeating([](content::InputEventAckSource source,
@@ -12276,6 +12295,14 @@ class SitePerProcessBrowserTouchActionTest : public SitePerProcessBrowserTest {
static_cast<RenderWidgetHostImpl*>(rwhv_child->GetRenderWidgetHost())
->input_router()
->AllowedTouchAction();
+ // Whitelisted touch action is sent from a separate IPC channel, so it is
+ // not guaranteed to have value when the ACK for the touch start arrived
+ // because the ACK is from the main thread.
+ whitelisted_touch_action =
+ static_cast<InputRouterImpl*>(static_cast<RenderWidgetHostImpl*>(
+ rwhv_child->GetRenderWidgetHost())
+ ->input_router())
+ ->touch_action_filter_.white_listed_touch_action_;
// Send a touch move and touch end to complete the sequence, this also
// avoids triggering DCHECKs when sending followup events.
@@ -12354,22 +12381,31 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
WaitForTouchActionUpdated(root_thread_observer.get(),
child_thread_observer.get());
+ base::Optional<cc::TouchAction> whitelisted_touch_action;
+ cc::TouchAction expected_touch_action = cc::kTouchActionPan;
// Gestures are filtered by the intersection of touch-action values of the
// touched element and all its ancestors up to the one that implements the
// gesture. Since iframe allows scrolling, touch action pan restrictions will
// not affect iframe's descendants, so we expect kTouchActionPan instead of
// kTouchActionAuto in iframe's child.
- EXPECT_EQ(cc::TouchAction::kTouchActionPan,
+ EXPECT_EQ(expected_touch_action,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
- point_inside_child));
+ point_inside_child,
+ whitelisted_touch_action));
+ if (whitelisted_touch_action.has_value())
+ EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());
EXPECT_TRUE(
ExecuteScript(shell(), "document.body.style.touchAction = 'auto'"));
WaitForTouchActionUpdated(root_thread_observer.get(),
child_thread_observer.get());
- EXPECT_EQ(cc::TouchAction::kTouchActionAuto,
+ expected_touch_action = cc::kTouchActionAuto;
+ EXPECT_EQ(expected_touch_action,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
- point_inside_child));
+ point_inside_child,
+ whitelisted_touch_action));
+ if (whitelisted_touch_action.has_value())
+ EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());
}
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
@@ -12424,9 +12460,14 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
// Child should inherit effective touch action none from root.
WaitForTouchActionUpdated(root_thread_observer.get(),
child_thread_observer.get());
- EXPECT_EQ(cc::TouchAction::kTouchActionPan,
+ base::Optional<cc::TouchAction> whitelisted_touch_action;
+ cc::TouchAction expected_touch_action = cc::kTouchActionPan;
+ EXPECT_EQ(expected_touch_action,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
- point_inside_child));
+ point_inside_child,
+ whitelisted_touch_action));
+ if (whitelisted_touch_action.has_value())
+ EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());
// Child should inherit effective touch action none from parent.
EXPECT_TRUE(
@@ -12436,9 +12477,12 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
"document.getElementById('parent-div').style.touchAction = 'none';"));
WaitForTouchActionUpdated(root_thread_observer.get(),
child_thread_observer.get());
- EXPECT_EQ(cc::TouchAction::kTouchActionPan,
+ EXPECT_EQ(expected_touch_action,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
- point_inside_child));
+ point_inside_child,
+ whitelisted_touch_action));
+ if (whitelisted_touch_action.has_value())
+ EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());
// Child should inherit effective touch action auto from root and parent.
EXPECT_TRUE(ExecuteScript(
@@ -12446,9 +12490,13 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
"document.getElementById('parent-div').style.touchAction = 'auto'"));
WaitForTouchActionUpdated(root_thread_observer.get(),
child_thread_observer.get());
- EXPECT_EQ(cc::TouchAction::kTouchActionAuto,
+ expected_touch_action = cc::kTouchActionAuto;
+ EXPECT_EQ(expected_touch_action,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
- point_inside_child));
+ point_inside_child,
+ whitelisted_touch_action));
+ if (whitelisted_touch_action.has_value())
+ EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());
}
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
@@ -12497,9 +12545,14 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
// Child should inherit effective touch action none from root.
WaitForTouchActionUpdated(root_thread_observer.get(),
child_thread_observer.get());
- EXPECT_EQ(cc::TouchAction::kTouchActionPan,
+ base::Optional<cc::TouchAction> whitelisted_touch_action;
+ cc::TouchAction expected_touch_action = cc::kTouchActionPan;
+ EXPECT_EQ(expected_touch_action,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
- point_inside_child));
+ point_inside_child,
+ whitelisted_touch_action));
+ if (whitelisted_touch_action.has_value())
+ EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());
// After navigation, child should still inherit effective touch action none
// from parent.
@@ -12519,9 +12572,12 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
WaitForTouchActionUpdated(root_thread_observer.get(),
child_thread_observer.get());
- EXPECT_EQ(cc::TouchAction::kTouchActionPan,
+ EXPECT_EQ(expected_touch_action,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
- point_inside_child));
+ point_inside_child,
+ whitelisted_touch_action));
+ if (whitelisted_touch_action.has_value())
+ EXPECT_EQ(expected_touch_action, whitelisted_touch_action.value());
}
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
@@ -12606,13 +12662,17 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Verify that no child frame metrics got logged (yet - while WebContents are
// hidden).
histograms.ExpectTotalCount("Stability.ChildFrameCrash.Visibility", 0);
+ histograms.ExpectTotalCount(
+ "Stability.ChildFrameCrash.ShownAfterCrashingReason", 0);
- // Show the web contents.
- // and verify that the expected metrics got logged.
+ // Show the web contents and verify that the expected metrics got logged.
web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
histograms.ExpectUniqueSample(
"Stability.ChildFrameCrash.Visibility",
CrossProcessFrameConnector::CrashVisibility::kShownAfterCrashing, 10);
+ histograms.ExpectUniqueSample(
+ "Stability.ChildFrameCrash.ShownAfterCrashingReason",
+ CrossProcessFrameConnector::ShownAfterCrashingReason::kTabWasShown, 10);
// Hide and show the web contents again and verify that no more metrics got
// logged.
@@ -12621,6 +12681,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
histograms.ExpectUniqueSample(
"Stability.ChildFrameCrash.Visibility",
CrossProcessFrameConnector::CrashVisibility::kShownAfterCrashing, 10);
+ histograms.ExpectUniqueSample(
+ "Stability.ChildFrameCrash.ShownAfterCrashingReason",
+ CrossProcessFrameConnector::ShownAfterCrashingReason::kTabWasShown, 10);
}
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
@@ -12690,6 +12753,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Verify that no child frame metrics got logged (yet - while the subframe is
// below the fold / is not scrolled into view).
histograms.ExpectTotalCount("Stability.ChildFrameCrash.Visibility", 0);
+ histograms.ExpectTotalCount(
+ "Stability.ChildFrameCrash.ShownAfterCrashingReason", 0);
// Scroll the subframe into view and wait until the scrolled frame draws
// itself.
@@ -12704,6 +12769,83 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
histograms.ExpectUniqueSample(
"Stability.ChildFrameCrash.Visibility",
CrossProcessFrameConnector::CrashVisibility::kShownAfterCrashing, 1);
+ histograms.ExpectUniqueSample(
+ "Stability.ChildFrameCrash.ShownAfterCrashingReason",
+ CrossProcessFrameConnector::ShownAfterCrashingReason::
+ kViewportIntersection,
+ 1);
+}
+
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ ChildFrameCrashMetrics_ScrolledIntoViewAfterTabIsShown) {
+ // Start on a page that has a single iframe, which is positioned out of
+ // view, and navigate that iframe cross-site.
+ GURL main_url(
+ embedded_test_server()->GetURL("a.com", "/iframe_out_of_view.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+ NavigateFrameToURL(root->child_at(0),
+ embedded_test_server()->GetURL("b.com", "/title1.html"));
+
+ // Hide the web contents (UpdateWebContentsVisibility is called twice to avoid
+ // hitting the |!did_first_set_visible_| case).
+ web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
+ web_contents()->UpdateWebContentsVisibility(Visibility::HIDDEN);
+
+ // Kill the child frame.
+ base::HistogramTester histograms;
+ RenderProcessHost* child_process =
+ root->child_at(0)->current_frame_host()->GetProcess();
+ RenderProcessHostWatcher crash_observer(
+ child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ child_process->Shutdown(0);
+ crash_observer.Wait();
+
+ // Verify that no child frame crash metrics got logged yet.
+ histograms.ExpectTotalCount("Stability.ChildFrameCrash.Visibility", 0);
+ histograms.ExpectTotalCount(
+ "Stability.ChildFrameCrash.ShownAfterCrashingReason", 0);
+
+ // Show the web contents. The crash metrics still shouldn't be logged, since
+ // the crashed frame is out of view.
+ web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
+ histograms.ExpectTotalCount("Stability.ChildFrameCrash.Visibility", 0);
+ histograms.ExpectTotalCount(
+ "Stability.ChildFrameCrash.ShownAfterCrashingReason", 0);
+
+ // Scroll the subframe into view and wait until the scrolled frame draws
+ // itself.
+ MainThreadFrameObserver main_widget_observer(
+ root->current_frame_host()->GetRenderWidgetHost());
+ std::string scrolling_script = R"(
+ var frame = document.body.querySelector("iframe");
+ frame.scrollIntoView();
+ )";
+ EXPECT_TRUE(ExecuteScript(root, scrolling_script));
+ main_widget_observer.Wait();
+
+ // Verify that the expected metrics got logged.
+ histograms.ExpectUniqueSample(
+ "Stability.ChildFrameCrash.Visibility",
+ CrossProcessFrameConnector::CrashVisibility::kShownAfterCrashing, 1);
+ histograms.ExpectUniqueSample(
+ "Stability.ChildFrameCrash.ShownAfterCrashingReason",
+ CrossProcessFrameConnector::ShownAfterCrashingReason::
+ kViewportIntersectionAfterTabWasShown,
+ 1);
+
+ // Hide and show the web contents again and verify that no more metrics got
+ // logged.
+ web_contents()->UpdateWebContentsVisibility(Visibility::HIDDEN);
+ web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
+ histograms.ExpectUniqueSample(
+ "Stability.ChildFrameCrash.Visibility",
+ CrossProcessFrameConnector::CrashVisibility::kShownAfterCrashing, 1);
+ histograms.ExpectUniqueSample(
+ "Stability.ChildFrameCrash.ShownAfterCrashingReason",
+ CrossProcessFrameConnector::ShownAfterCrashingReason::
+ kViewportIntersectionAfterTabWasShown,
+ 1);
}
// Check that when a frame changes a subframe's size twice and then sends a
@@ -13225,4 +13367,32 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ProcessSwapOnInnerContents) {
EXPECT_NE(a_view, b_view);
}
+// Check that a web frame can't navigate a remote subframe to a file: URL. The
+// frame should stay at the old URL, and the navigation attempt should produce
+// a console error message. See https://crbug.com/894399.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ FileURLBlockedWithConsoleErrorInRemoteFrameNavigation) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ FrameTreeNode* child = web_contents()->GetFrameTree()->root()->child_at(0);
+ GURL original_frame_url(child->current_frame_host()->GetLastCommittedURL());
+ EXPECT_EQ("b.com", original_frame_url.host());
+
+ ConsoleObserverDelegate console_delegate(
+ web_contents(), "Not allowed to load local resource: file:*");
+ web_contents()->SetDelegate(&console_delegate);
+
+ GURL file_url("file:///");
+ EXPECT_TRUE(
+ ExecJs(web_contents(),
+ JsReplace("document.querySelector('iframe').src = $1", file_url)));
+ console_delegate.Wait();
+
+ // The iframe should've stayed at the original URL.
+ EXPECT_EQ(original_frame_url,
+ child->current_frame_host()->GetLastCommittedURL());
+}
+
} // namespace content
diff --git a/chromium/content/browser/site_per_process_hit_test_browsertest.cc b/chromium/content/browser/site_per_process_hit_test_browsertest.cc
index dc73deb2e4c..8cf8f90eede 100644
--- a/chromium/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/chromium/content/browser/site_per_process_hit_test_browsertest.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/json/json_reader.h"
+#include "base/task/post_task.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h"
@@ -23,6 +24,8 @@
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
@@ -58,10 +61,6 @@
#include "content/test/mock_overscroll_refresh_handler_android.h"
#endif
-#if defined(OS_WIN)
-#include "base/debug/stack_trace.h"
-#endif
-
namespace content {
namespace {
@@ -664,20 +663,18 @@ class SetMouseCaptureInterceptor
};
#if defined(USE_AURA)
-// A class to allow intercepting and discarding of system-level mouse events
+// A class to allow intercepting and discarding of all system-level events
// that might otherwise cause unpredictable behaviour in tests.
-class MouseEventRewriter : public ui::EventRewriter {
+class SystemEventRewriter : public ui::EventRewriter {
public:
- MouseEventRewriter() = default;
- ~MouseEventRewriter() override {}
+ SystemEventRewriter() = default;
+ ~SystemEventRewriter() override {}
private:
ui::EventRewriteStatus RewriteEvent(
const ui::Event& event,
std::unique_ptr<ui::Event>* new_event) override {
- if (event.IsMouseEvent())
- return ui::EVENT_REWRITE_DISCARD;
- return ui::EVENT_REWRITE_CONTINUE;
+ return ui::EVENT_REWRITE_DISCARD;
}
ui::EventRewriteStatus NextDispatchEvent(
@@ -687,7 +684,7 @@ class MouseEventRewriter : public ui::EventRewriter {
return ui::EVENT_REWRITE_CONTINUE;
}
- DISALLOW_COPY_AND_ASSIGN(MouseEventRewriter);
+ DISALLOW_COPY_AND_ASSIGN(SystemEventRewriter);
};
#endif
@@ -728,7 +725,7 @@ class SitePerProcessHitTestBrowserTest
base::test::ScopedFeatureList feature_list_;
#if defined(USE_AURA)
- MouseEventRewriter event_rewriter;
+ SystemEventRewriter event_rewriter;
#endif
};
@@ -1093,20 +1090,11 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessInternalsHitTestBrowserTest,
}
#endif // defined(USE_AURA)
-#if defined(OS_CHROMEOS)
-// Times out flakily on Chrome OS. crbug.com/833380
-#define MAYBE_CancelWheelScrollBubblingOnWheelTargetDeletion \
- DISABLED_CancelWheelScrollBubblingOnWheelTargetDeletion
-#else
-#define MAYBE_CancelWheelScrollBubblingOnWheelTargetDeletion \
- CancelWheelScrollBubblingOnWheelTargetDeletion
-#endif
-
// Tests that wheel scroll bubbling gets cancelled when the wheel target view
// gets destroyed in the middle of a wheel scroll seqeunce. This happens in
// cases like overscroll navigation from inside an oopif.
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- MAYBE_CancelWheelScrollBubblingOnWheelTargetDeletion) {
+ CancelWheelScrollBubblingOnWheelTargetDeletion) {
ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
0);
GURL main_url(embedded_test_server()->GetURL(
@@ -1180,6 +1168,194 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
scroll_end_observer.Wait();
}
+IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
+ CSSTransformedIframeTouchEventCoordinates) {
+ // This test only makes sense if viz hit testing is enabled.
+ if (std::get<0>(GetParam()) == 0)
+ return;
+
+ GURL url(embedded_test_server()->GetURL(
+ "/frame_tree/page_with_positioned_scaled_frame.html"));
+ ASSERT_TRUE(NavigateToURL(shell(), url));
+
+ RenderFrameSubmissionObserver render_frame_submission_observer(
+ shell()->web_contents());
+
+ FrameTreeNode* root_frame_tree_node = web_contents()->GetFrameTree()->root();
+ ASSERT_EQ(1U, root_frame_tree_node->child_count());
+ FrameTreeNode* child_frame_tree_node = root_frame_tree_node->child_at(0);
+ GURL child_url(embedded_test_server()->GetURL("baz.com", "/title1.html"));
+ EXPECT_EQ(child_url, child_frame_tree_node->current_url());
+
+ auto* root_rwhv = static_cast<RenderWidgetHostViewBase*>(
+ root_frame_tree_node->current_frame_host()
+ ->GetRenderWidgetHost()
+ ->GetView());
+ auto* child_rwhv = static_cast<RenderWidgetHostViewBase*>(
+ child_frame_tree_node->current_frame_host()
+ ->GetRenderWidgetHost()
+ ->GetView());
+
+ WaitForHitTestDataOrChildSurfaceReady(
+ child_frame_tree_node->current_frame_host());
+
+ const float scale_factor =
+ render_frame_submission_observer.LastRenderFrameMetadata()
+ .page_scale_factor;
+
+ // Some basic tests on the transforms between child and root. These assume
+ // a CSS scale of 0.5 on the child, though should be robust to placement of
+ // the iframe.
+ float kScaleTolerance = 0.0001f;
+ gfx::Transform transform_to_child;
+ ASSERT_TRUE(
+ root_rwhv->GetTransformToViewCoordSpace(child_rwhv, &transform_to_child));
+ EXPECT_TRUE(transform_to_child.IsScaleOrTranslation());
+ EXPECT_NEAR(2.f / scale_factor, transform_to_child.matrix().getFloat(0, 0),
+ kScaleTolerance);
+ EXPECT_NEAR(2.f / scale_factor, transform_to_child.matrix().getFloat(1, 1),
+ kScaleTolerance);
+
+ gfx::PointF child_origin =
+ child_rwhv->TransformPointToRootCoordSpaceF(gfx::PointF());
+
+ gfx::Transform transform_from_child;
+ ASSERT_TRUE(child_rwhv->GetTransformToViewCoordSpace(root_rwhv,
+ &transform_from_child));
+ EXPECT_TRUE(transform_from_child.IsScaleOrTranslation());
+ EXPECT_NEAR(0.5f * scale_factor, transform_from_child.matrix().getFloat(0, 0),
+ kScaleTolerance);
+ EXPECT_NEAR(0.5f * scale_factor, transform_from_child.matrix().getFloat(1, 1),
+ kScaleTolerance);
+ EXPECT_EQ(child_origin.x(), transform_from_child.matrix().getFloat(0, 3));
+ EXPECT_EQ(child_origin.y(), transform_from_child.matrix().getFloat(1, 3));
+
+ gfx::Transform transform_child_to_child =
+ transform_from_child * transform_to_child;
+ // If the scale factor is 1.f, then this multiplication of the transform with
+ // its inverse will be exact, and IsIdentity will indicate that. However, if
+ // the scale is an arbitrary float (as on Android), then we instead compare
+ // element by element using EXPECT_NEAR.
+ if (scale_factor == 1.f) {
+ EXPECT_TRUE(transform_child_to_child.IsIdentity());
+ } else {
+ const float kTolerance = 0.001f;
+ const int kDim = 4;
+ for (int row = 0; row < kDim; ++row) {
+ for (int col = 0; col < kDim; ++col) {
+ EXPECT_NEAR(row == col ? 1.f : 0.f,
+ transform_child_to_child.matrix().getFloat(row, col),
+ kTolerance);
+ }
+ }
+ }
+
+ gfx::Transform transform_root_to_root;
+ ASSERT_TRUE(root_rwhv->GetTransformToViewCoordSpace(root_rwhv,
+ &transform_root_to_root));
+ EXPECT_TRUE(transform_root_to_root.IsIdentity());
+
+ // Select two points inside child, one for the touch start and a different
+ // one for a touch move.
+ gfx::PointF touch_start_point_in_child(6, 6);
+ gfx::PointF touch_move_point_in_child(10, 10);
+
+ gfx::PointF touch_start_point =
+ child_rwhv->TransformPointToRootCoordSpaceF(touch_start_point_in_child);
+ gfx::PointF touch_move_point =
+ child_rwhv->TransformPointToRootCoordSpaceF(touch_move_point_in_child);
+
+ // Install InputEventObserver on child, and collect the three events.
+ TestInputEventObserver child_event_observer(
+ child_rwhv->GetRenderWidgetHost());
+ InputEventAckWaiter child_touch_start_waiter(
+ child_rwhv->GetRenderWidgetHost(), blink::WebInputEvent::kTouchStart);
+ InputEventAckWaiter child_touch_move_waiter(child_rwhv->GetRenderWidgetHost(),
+ blink::WebInputEvent::kTouchMove);
+ InputEventAckWaiter child_touch_end_waiter(child_rwhv->GetRenderWidgetHost(),
+ blink::WebInputEvent::kTouchEnd);
+
+ // Send events and verify each one was sent to the child with correctly
+ // transformed event coordinates.
+ auto* router = web_contents()->GetInputEventRouter();
+ const float kCoordinateTolerance = 0.1f;
+
+ // TouchStart.
+ blink::WebTouchEvent touch_start_event(
+ blink::WebInputEvent::kTouchStart, blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
+ touch_start_event.touches_length = 1;
+ touch_start_event.touches[0].state = blink::WebTouchPoint::kStatePressed;
+ SetWebEventPositions(&touch_start_event.touches[0], touch_start_point,
+ root_rwhv);
+ touch_start_event.unique_touch_event_id = 1;
+ router->RouteTouchEvent(root_rwhv, &touch_start_event,
+ ui::LatencyInfo(ui::SourceEventType::TOUCH));
+ child_touch_start_waiter.Wait();
+
+ ASSERT_EQ(1U, child_event_observer.events_received().size());
+ ASSERT_EQ(blink::WebInputEvent::kTouchStart,
+ child_event_observer.event().GetType());
+ const blink::WebTouchEvent& touch_start_event_received =
+ static_cast<const blink::WebTouchEvent&>(child_event_observer.event());
+ EXPECT_NEAR(touch_start_point_in_child.x(),
+ touch_start_event_received.touches[0].PositionInWidget().x,
+ kCoordinateTolerance);
+ EXPECT_NEAR(touch_start_point_in_child.y(),
+ touch_start_event_received.touches[0].PositionInWidget().y,
+ kCoordinateTolerance);
+
+ // TouchMove.
+ blink::WebTouchEvent touch_move_event(
+ blink::WebInputEvent::kTouchMove, blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
+ touch_move_event.touches_length = 1;
+ touch_move_event.touches[0].state = blink::WebTouchPoint::kStateMoved;
+ SetWebEventPositions(&touch_move_event.touches[0], touch_move_point,
+ root_rwhv);
+ touch_move_event.unique_touch_event_id = 2;
+ router->RouteTouchEvent(root_rwhv, &touch_move_event,
+ ui::LatencyInfo(ui::SourceEventType::TOUCH));
+ child_touch_move_waiter.Wait();
+
+ ASSERT_EQ(2U, child_event_observer.events_received().size());
+ ASSERT_EQ(blink::WebInputEvent::kTouchMove,
+ child_event_observer.event().GetType());
+ const blink::WebTouchEvent& touch_move_event_received =
+ static_cast<const blink::WebTouchEvent&>(child_event_observer.event());
+ EXPECT_NEAR(touch_move_point_in_child.x(),
+ touch_move_event_received.touches[0].PositionInWidget().x,
+ kCoordinateTolerance);
+ EXPECT_NEAR(touch_move_point_in_child.y(),
+ touch_move_event_received.touches[0].PositionInWidget().y,
+ kCoordinateTolerance);
+
+ // TouchEnd.
+ blink::WebTouchEvent touch_end_event(
+ blink::WebInputEvent::kTouchEnd, blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
+ touch_end_event.touches_length = 1;
+ touch_end_event.touches[0].state = blink::WebTouchPoint::kStateReleased;
+ SetWebEventPositions(&touch_end_event.touches[0], touch_move_point,
+ root_rwhv);
+ touch_end_event.unique_touch_event_id = 3;
+ router->RouteTouchEvent(root_rwhv, &touch_end_event,
+ ui::LatencyInfo(ui::SourceEventType::TOUCH));
+ child_touch_end_waiter.Wait();
+
+ ASSERT_EQ(3U, child_event_observer.events_received().size());
+ ASSERT_EQ(blink::WebInputEvent::kTouchEnd,
+ child_event_observer.event().GetType());
+ const blink::WebTouchEvent& touch_end_event_received =
+ static_cast<const blink::WebTouchEvent&>(child_event_observer.event());
+ EXPECT_NEAR(touch_move_point_in_child.x(),
+ touch_end_event_received.touches[0].PositionInWidget().x,
+ kCoordinateTolerance);
+ EXPECT_NEAR(touch_move_point_in_child.y(),
+ touch_end_event_received.touches[0].PositionInWidget().y,
+ kCoordinateTolerance);
+}
+
// When a scroll event is bubbled, ensure that the bubbled event's coordinates
// are correctly updated to the ancestor's coordinate space. In particular,
// ensure that the transformation considers CSS scaling of the child where
@@ -1255,48 +1431,6 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
root_scroll_begin_observer.Wait();
}
-#if defined(OS_WIN)
-// Add temporary TouchMove event observer to detect spurious TouchMove events
-// leading to test flake.
-// https://crbug.com/833380.
-class EmulatedTouchTouchMoveInputObserver
- : public RenderWidgetHost::InputEventObserver {
- public:
- explicit EmulatedTouchTouchMoveInputObserver(RenderWidgetHost* host)
- : host_(host), first_touch_move_seen_(false) {
- host_->AddInputEventObserver(this);
- }
- ~EmulatedTouchTouchMoveInputObserver() override {
- host_->RemoveInputEventObserver(this);
- }
-
- void OnInputEvent(const blink::WebInputEvent& event) override {
- if (event.GetType() != blink::WebInputEvent::kTouchMove)
- return;
-
- const blink::WebTouchEvent& touch_event =
- static_cast<const blink::WebTouchEvent&>(event);
- blink::WebFloatPoint pos_in_widget =
- touch_event.touches[0].PositionInWidget();
- blink::WebFloatPoint pos_in_screen =
- touch_event.touches[0].PositionInScreen();
- LOG(ERROR) << "TouchMove seen: widget @ (" << pos_in_widget.x << ","
- << pos_in_widget.y << "), screen @ (" << pos_in_screen.x << ","
- << pos_in_screen.y << ")";
-
- if (first_touch_move_seen_)
- return;
-
- first_touch_move_seen_ = true;
- base::debug::StackTrace().Print();
- }
-
- private:
- RenderWidgetHost* host_;
- bool first_touch_move_seen_;
-};
-#endif
-
class SitePerProcessEmulatedTouchBrowserTest
: public SitePerProcessHitTestBrowserTest {
public:
@@ -1344,17 +1478,6 @@ class SitePerProcessEmulatedTouchBrowserTest
[](blink::WebInputEvent::Type expected_type,
const gfx::Point& expected_position, content::InputEventAckSource,
content::InputEventAckState, const blink::WebInputEvent& event) {
-#if defined(OS_WIN)
- // Add some logging to diagnose a potential source of flake:
- // the hypothesis is that something is causing the gesture
- // stream to cancel before kGestureShowPress is generated, so
- // we'll dump the event stream that we actually see in this case.
- // https://crbug.com/833380.
- if (expected_type == blink::WebInputEvent::kGestureShowPress) {
- LOG(ERROR) << "Waiting for: kGestureShowPress: ack seen for "
- << blink::WebInputEvent::GetName(event.GetType());
- }
-#endif
if (event.GetType() != expected_type)
return false;
@@ -1455,17 +1578,6 @@ class SitePerProcessEmulatedTouchBrowserTest
simulated_event_time += simulated_event_time_delta;
mouse_up_event.SetTimeStamp(simulated_event_time);
-#if defined(OS_WIN)
- // Add temporary TouchMove event observer to detect spurious TouchMove
- // events leading to test flake.
- // https://crbug.com/833380.
- std::unique_ptr<EmulatedTouchTouchMoveInputObserver> touch_move_observer;
- if (test_type == ShowPressHasTouchID) {
- touch_move_observer.reset(new EmulatedTouchTouchMoveInputObserver(
- child_rwhv->GetRenderWidgetHost()));
- }
-#endif
-
// Send mouse events and wait for GesturePinchBegin.
router->RouteMouseEvent(root_rwhv, &mouse_move_event, ui::LatencyInfo());
router->RouteMouseEvent(root_rwhv, &mouse_down_event, ui::LatencyInfo());
@@ -1473,9 +1585,6 @@ class SitePerProcessEmulatedTouchBrowserTest
// Wait for child to receive GestureShowPress. If this test fails, it
// will either DCHECK or time out.
child_gesture_event_observer.Wait();
-#if defined(OS_WIN)
- touch_move_observer.reset();
-#endif
return;
}
router->RouteMouseEvent(root_rwhv, &mouse_drag_event, ui::LatencyInfo());
@@ -1515,35 +1624,12 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessEmulatedTouchBrowserTest,
RunTest(TouchActionBubbling);
}
-#if defined(OS_ANDROID) || defined(USE_AURA)
-namespace {
-// This function is used in TouchActionAckTimeout and
-// SubframeGestureEventRouting, which is defined either under Android or Aura.
-void OnSyntheticGestureCompleted(scoped_refptr<MessageLoopRunner> runner,
- SyntheticGesture::Result result) {
- EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
- runner->Quit();
-}
-
-#if defined(OS_ANDROID)
-void GiveItSomeTime(int t) {
- base::RunLoop run_loop;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMilliseconds(t));
- run_loop.Run();
-}
-#endif // defined(OS_ANDROID)
-
-} // namespace
-#endif // defined(OS_ANDROID) || defined(USE_AURA)
-
// Regression test for https://crbug.com/851644. The test passes as long as it
// doesn't crash.
// Touch action ack timeout is enabled on Android only.
-// Flaky, see https://crbug.com/871062.
#if defined(OS_ANDROID)
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- DISABLED_TouchActionAckTimeout) {
+ TouchActionAckTimeout) {
GURL main_url(
embedded_test_server()->GetURL("/frame_tree/page_with_janky_frame.html"));
ASSERT_TRUE(NavigateToURL(shell(), main_url));
@@ -1577,41 +1663,29 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
params.anchor = gfx::PointF(point_in_child.x(), point_in_child.y());
params.distances.push_back(gfx::Vector2dF(0, -10));
- // Make this scroll slow so that the second scroll will be queued even before
- // this one ends.
- params.speed_in_pixels_s = 1000;
+ // The JS jank from the "page_with_touch_start_janking_main_thread.html"
+ // causes the touch ack timeout. Set the speed high so that the gesture can be
+ // completed quickly and so does this test.
+ params.speed_in_pixels_s = 100000;
std::unique_ptr<SyntheticSmoothScrollGesture> gesture(
new SyntheticSmoothScrollGesture(params));
- scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner();
+ InputEventAckWaiter ack_observer(
+ child_frame_host->GetRenderWidgetHost(),
+ base::BindRepeating([](content::InputEventAckSource source,
+ content::InputEventAckState state,
+ const blink::WebInputEvent& event) {
+ return event.GetType() == blink::WebGestureEvent::kGestureScrollEnd;
+ }));
+ ack_observer.Reset();
+
RenderWidgetHostImpl* render_widget_host =
root->current_frame_host()->GetRenderWidgetHost();
render_widget_host->QueueSyntheticGesture(
- std::move(gesture), base::BindOnce(OnSyntheticGestureCompleted, runner));
- // The first gesture takes 100ms, so wait for 120ms to ensure that it has
- // finished.
- runner->Run();
- GiveItSomeTime(120);
-
- SyntheticSmoothScrollGestureParams params2;
- params2.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
- params2.anchor = gfx::PointF(point_in_child.x(), point_in_child.y());
- params2.distances.push_back(gfx::Vector2dF(0, -10));
- params2.speed_in_pixels_s = 100000;
- std::unique_ptr<SyntheticSmoothScrollGesture> gesture2(
- new SyntheticSmoothScrollGesture(params2));
- render_widget_host->QueueSyntheticGesture(
- std::move(gesture2), base::BindOnce(OnSyntheticGestureCompleted, runner));
-
- runner->Run();
- runner = nullptr;
-
- // Give enough time to make sure all gesture are flushed and handled.
- base::RunLoop run_loop;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, run_loop.QuitClosure(),
- base::TimeDelta::FromMilliseconds(2500));
- run_loop.Run();
+ std::move(gesture), base::BindOnce([](SyntheticGesture::Result result) {
+ EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
+ }));
+ ack_observer.Wait();
}
#endif // defined(OS_ANDROID)
@@ -1834,15 +1908,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// results in a scroll. This is only handled by RenderWidgetHostViewAura
// and is needed for trackpad scrolling on Chromebooks.
#if defined(USE_AURA)
-
-#if defined(THREAD_SANITIZER) || defined(OS_CHROMEOS)
-// Flaky: https://crbug.com/833380
-#define MAYBE_ScrollEventToOOPIF DISABLED_ScrollEventToOOPIF
-#else
-#define MAYBE_ScrollEventToOOPIF ScrollEventToOOPIF
-#endif
-IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- MAYBE_ScrollEventToOOPIF) {
+IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest, ScrollEventToOOPIF) {
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_positioned_frame.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -1890,17 +1956,8 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
blink::WebInputEvent::kMouseWheel));
}
-#if defined(THREAD_SANITIZER)
-// Flaky: https://crbug.com/833380
-#define MAYBE_InputEventRouterWheelCoalesceTest \
- DISABLED_InputEventRouterWheelCoalesceTest
-#else
-#define MAYBE_InputEventRouterWheelCoalesceTest \
- InputEventRouterWheelCoalesceTest
-#endif
-
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- MAYBE_InputEventRouterWheelCoalesceTest) {
+ InputEventRouterWheelCoalesceTest) {
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_positioned_frame.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -1989,16 +2046,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// Test that mouse events are being routed to the correct RenderWidgetHostView
// based on coordinates.
-#if defined(THREAD_SANITIZER) || defined(OS_CHROMEOS)
-// The test times out often on TSAN bot.
-// https://crbug.com/591170.
-// Also times out flakily on Chrome OS. crbug.com/833380
-#define MAYBE_SurfaceHitTestTest DISABLED_SurfaceHitTestTest
-#else
-#define MAYBE_SurfaceHitTestTest SurfaceHitTestTest
-#endif
-IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- MAYBE_SurfaceHitTestTest) {
+IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest, SurfaceHitTestTest) {
SurfaceHitTestTestHelper(shell(), embedded_test_server());
}
@@ -2011,9 +2059,6 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// coordinate calculations. Android uses fixed device scale factor.
// Windows is disabled because of https://crbug.com/545547.
#define MAYBE_HighDPISurfaceHitTestTest DISABLED_HighDPISurfaceHitTestTest
-#elif defined(THREAD_SANITIZER)
-// Flaky: https://crbug.com/833380
-#define MAYBE_HighDPISurfaceHitTestTest DISABLED_HighDPISurfaceHitTestTest
#else
#define MAYBE_HighDPISurfaceHitTestTest HighDPISurfaceHitTestTest
#endif
@@ -2075,46 +2120,32 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
OverlapSurfaceHitTestHelper(shell(), embedded_test_server());
}
-#if defined(OS_LINUX)
-// Flaky timeouts and failures: https://crbug.com/833380
-#define MAYBE_HitTestLayerSquashing DISABLED_HitTestLayerSquashing
-#else
-#define MAYBE_HitTestLayerSquashing HitTestLayerSquashing
-#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- MAYBE_HitTestLayerSquashing) {
+ HitTestLayerSquashing) {
HitTestLayerSquashing(shell(), embedded_test_server());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessHighDPIHitTestBrowserTest,
- MAYBE_HitTestLayerSquashing) {
+ HitTestLayerSquashing) {
HitTestLayerSquashing(shell(), embedded_test_server());
}
-#if defined(OS_LINUX)
-// Flaky timeouts and failures: https://crbug.com/833380
-#define MAYBE_HitTestWatermark DISABLED_HitTestWatermark
-#else
-#define MAYBE_HitTestWatermark HitTestWatermark
-#endif
-IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- MAYBE_HitTestWatermark) {
+IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest, HitTestWatermark) {
HitTestWatermark(shell(), embedded_test_server());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessHighDPIHitTestBrowserTest,
- MAYBE_HitTestWatermark) {
+ HitTestWatermark) {
HitTestWatermark(shell(), embedded_test_server());
}
#if defined(USE_AURA)
-IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- DISABLED_RootWindowTransform) {
+IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest, RootWindowTransform) {
HitTestRootWindowTransform(shell(), embedded_test_server());
}
IN_PROC_BROWSER_TEST_P(SitePerProcessHighDPIHitTestBrowserTest,
- DISABLED_RootWindowTransform) {
+ RootWindowTransform) {
HitTestRootWindowTransform(shell(), embedded_test_server());
}
#endif // defined(USE_AURA)
@@ -2199,43 +2230,34 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
EXPECT_EQ(result.target_location.value(), parent_location);
}
-#if defined(THREAD_SANITIZER) || defined(OS_LINUX)
-// Flaky: https://crbug.com/833380
-#define MAYBE_SurfaceHitTestPointerEventsNone \
- DISABLED_SurfaceHitTestPointerEventsNone
-#else
-#define MAYBE_SurfaceHitTestPointerEventsNone SurfaceHitTestPointerEventsNone
-#endif
-
// This test tests that browser process hittesting ignores frames with
// pointer-events: none.
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- MAYBE_SurfaceHitTestPointerEventsNone) {
- // TODO(sunxd): Fix pointer-events none for surface layer viz hit testing. See
- // https://crbug.com/841358.
- if (features::IsVizHitTestingSurfaceLayerEnabled()) {
- LOG(INFO) << "Skipping test due to https://crbug.com/841358";
- return;
- }
+ SurfaceHitTestPointerEventsNoneChanged) {
+ // In /2 hit testing, OOPIFs with pointer-events: none are ignored and no hit
+ // test data is submitted. To make sure we wait enough time until child frame
+ // fully loaded, we add a 1x1 pixel OOPIF for the test to track the process of
+ // /2 hit testing.
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_positioned_frame_pointer-events_none.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
// It is safe to obtain the root frame tree node here, as it doesn't change.
FrameTreeNode* root = web_contents()->GetFrameTree()->root();
- ASSERT_EQ(1U, root->child_count());
+ ASSERT_EQ(2U, root->child_count());
- FrameTreeNode* child_node = root->child_at(0);
- GURL site_url(embedded_test_server()->GetURL("baz.com", "/title1.html"));
- EXPECT_EQ(site_url, child_node->current_url());
+ FrameTreeNode* child_node1 = root->child_at(0);
+ FrameTreeNode* child_node2 = root->child_at(1);
+ GURL site_url(embedded_test_server()->GetURL("bar.com", "/title1.html"));
+ EXPECT_EQ(site_url, child_node2->current_url());
EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
- child_node->current_frame_host()->GetSiteInstance());
+ child_node2->current_frame_host()->GetSiteInstance());
// Create listeners for mouse events.
RenderWidgetHostMouseEventMonitor main_frame_monitor(
root->current_frame_host()->GetRenderWidgetHost());
RenderWidgetHostMouseEventMonitor child_frame_monitor(
- child_node->current_frame_host()->GetRenderWidgetHost());
+ child_node1->current_frame_host()->GetRenderWidgetHost());
RenderWidgetHostInputEventRouter* router =
web_contents()->GetInputEventRouter();
@@ -2243,9 +2265,9 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
root->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node2->current_frame_host());
- // Target input event to child frame.
+ // Target input event to child1 frame.
blink::WebMouseEvent child_event(
blink::WebInputEvent::kMouseDown, blink::WebInputEvent::kNoModifiers,
blink::WebInputEvent::GetStaticTimeStampForTests());
@@ -2263,20 +2285,49 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
EXPECT_NEAR(75, main_frame_monitor.event().PositionInWidget().x, 2);
EXPECT_NEAR(75, main_frame_monitor.event().PositionInWidget().y, 2);
EXPECT_FALSE(child_frame_monitor.EventWasReceived());
-}
-#if defined(OS_CHROMEOS)
-// Flaky on Chrome OS. crbug.com/833380
-#define MAYBE_AsynchronousHitTestChildTimeout \
- DISABLED_AsynchronousHitTestChildTimeout
-#else
-#define MAYBE_AsynchronousHitTestChildTimeout AsynchronousHitTestChildTimeout
-#endif
+ // Surface hit test can only learn about pointer-events changes when
+ // submitting compositing frame, so we disable the second half of the test for
+ // surface hit test.
+ if (!features::IsVizHitTestingEnabled())
+ return;
+
+ // Remove pointer-events: none property from iframe, also remove child2 to
+ // properly notify the observer the update.
+ // Wait for the confirmation of the deletion so that surface hit test is aware
+ // of the change of pointer-events property. When viz hit testing is enabled,
+ // we do not need to wait.
+ EXPECT_TRUE(ExecuteScript(web_contents(),
+ "document.getElementsByTagName('iframe')[0].style."
+ "pointerEvents = 'auto';\n"));
+
+ ASSERT_EQ(2U, root->child_count());
+
+ {
+ MainThreadFrameObserver observer(
+ root->current_frame_host()->GetRenderWidgetHost());
+ observer.Wait();
+ }
+
+ WaitForHitTestDataOrChildSurfaceReady(child_node1->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node2->current_frame_host());
+ main_frame_monitor.ResetEventReceived();
+ child_frame_monitor.ResetEventReceived();
+ InputEventAckWaiter child_waiter(
+ child_node1->current_frame_host()->GetRenderWidgetHost(),
+ blink::WebInputEvent::kMouseDown);
+ router->RouteMouseEvent(root_view, &child_event, ui::LatencyInfo());
+ child_waiter.Wait();
+
+ EXPECT_TRUE(child_frame_monitor.EventWasReceived());
+ EXPECT_NEAR(23, child_frame_monitor.event().PositionInWidget().x, 2);
+ EXPECT_NEAR(23, child_frame_monitor.event().PositionInWidget().y, 2);
+}
// Verify that an event is properly retargeted to the main frame when an
// asynchronous hit test to the child frame times out.
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- MAYBE_AsynchronousHitTestChildTimeout) {
+ AsynchronousHitTestChildTimeout) {
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_positioned_busy_frame.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -2684,12 +2735,10 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
EXPECT_TRUE(d_frame_monitor.EventWasReceived());
}
-// Verify that mouse capture works on a RenderWidgetHostView level, so that
-// dragging scroll bars and selecting text continues even when the mouse
-// cursor crosses over cross-process frame boundaries.
-// TODO(kenrb): This currently only works for scrollbar dragging.
-// Other reasons for a node to capture mouse input need to be addressed. See
-// https://crbug.com/647378.
+// Verify that mouse capture works on a RenderWidgetHostView level.
+// This test checks that a MouseDown triggers mouse capture when it hits
+// a scrollbar thumb or a subframe, and does not trigger mouse
+// capture if it hits an element in the main frame.
#if defined(OS_CHROMEOS)
// TODO: Flaky on Chrome OS. crbug.com/868409
#define MAYBE_CrossProcessMouseCapture DISABLED_CrossProcessMouseCapture
@@ -2746,6 +2795,10 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
int child_frame_target_y = gfx::ToCeiledInt(
(bounds.y() - root_view->GetViewBounds().y() + 5) * scale_factor);
+ scoped_refptr<SetMouseCaptureInterceptor> child_interceptor =
+ new SetMouseCaptureInterceptor(static_cast<RenderWidgetHostImpl*>(
+ child_node->current_frame_host()->GetRenderWidgetHost()));
+
// Target MouseDown to child frame.
blink::WebMouseEvent mouse_event(
blink::WebInputEvent::kMouseDown, blink::WebInputEvent::kNoModifiers,
@@ -2763,16 +2816,46 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
EXPECT_FALSE(main_frame_monitor.EventWasReceived());
EXPECT_TRUE(child_frame_monitor.EventWasReceived());
- // Target MouseMove to main frame. This should be routed to the main frame
- // because the child frame is not capturing input.
+ // Wait for the mouse capture message.
+ child_interceptor->Wait();
+ EXPECT_TRUE(child_interceptor->Capturing());
+ // Yield the thread, in order to let the capture message be processed by its
+ // actual handler.
+ base::RunLoop().RunUntilIdle();
+
+ // Target MouseMove at main frame. The child frame is now capturing input,
+ // so it should receive the event instead.
mouse_event.SetType(blink::WebInputEvent::kMouseMove);
mouse_event.SetModifiers(blink::WebInputEvent::kLeftButtonDown);
SetWebEventPositions(&mouse_event, gfx::Point(1, 1), root_view);
- RouteMouseEventAndWaitUntilDispatch(router, root_view, root_view,
+ RouteMouseEventAndWaitUntilDispatch(router, root_view, rwhv_child,
&mouse_event);
// Dispatch twice because the router generates an extra MouseLeave for the
- // child frame.
+ // main frame.
+ main_frame_monitor.ResetEventReceived();
+ child_frame_monitor.ResetEventReceived();
+ RouteMouseEventAndWaitUntilDispatch(router, root_view, rwhv_child,
+ &mouse_event);
+ EXPECT_FALSE(main_frame_monitor.EventWasReceived());
+ EXPECT_TRUE(child_frame_monitor.EventWasReceived());
+
+ // MouseUp releases capture.
+ mouse_event.SetType(blink::WebInputEvent::kMouseUp);
+ mouse_event.SetModifiers(blink::WebInputEvent::kNoModifiers);
+ SetWebEventPositions(&mouse_event, gfx::Point(1, 1), root_view);
+ RouteMouseEventAndWaitUntilDispatch(router, root_view, rwhv_child,
+ &mouse_event);
+
+ child_interceptor->Wait();
+ EXPECT_FALSE(child_interceptor->Capturing());
+
+ // Targeting a MouseDown to the main frame should not initiate capture.
+ mouse_event.SetType(blink::WebInputEvent::kMouseDown);
+ mouse_event.SetModifiers(blink::WebInputEvent::kLeftButtonDown);
+ mouse_event.button = blink::WebPointerProperties::Button::kLeft;
+ SetWebEventPositions(&mouse_event, gfx::Point(1, 1), root_view);
+ mouse_event.click_count = 1;
main_frame_monitor.ResetEventReceived();
child_frame_monitor.ResetEventReceived();
RouteMouseEventAndWaitUntilDispatch(router, root_view, root_view,
@@ -2781,32 +2864,55 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
EXPECT_TRUE(main_frame_monitor.EventWasReceived());
EXPECT_FALSE(child_frame_monitor.EventWasReceived());
+ // Target MouseMove at child frame. Without capture, this should be
+ // dispatched to the child frame.
+ mouse_event.SetType(blink::WebInputEvent::kMouseMove);
+ SetWebEventPositions(&mouse_event,
+ gfx::Point(child_frame_target_x, child_frame_target_y),
+ root_view);
+ RouteMouseEventAndWaitUntilDispatch(router, root_view, rwhv_child,
+ &mouse_event);
+
+ main_frame_monitor.ResetEventReceived();
+ child_frame_monitor.ResetEventReceived();
+ // Again, twice because of the transition MouseMove sent to the main
+ // frame.
+ RouteMouseEventAndWaitUntilDispatch(router, root_view, rwhv_child,
+ &mouse_event);
+ EXPECT_FALSE(main_frame_monitor.EventWasReceived());
+ EXPECT_TRUE(child_frame_monitor.EventWasReceived());
+
+ // A MouseUp sent anywhere should cancel the mouse capture.
+ mouse_event.SetType(blink::WebInputEvent::kMouseUp);
+ mouse_event.SetModifiers(blink::WebInputEvent::kNoModifiers);
+ SetWebEventPositions(&mouse_event,
+ gfx::Point(child_frame_target_x, child_frame_target_y),
+ root_view);
+ RouteMouseEventAndWaitUntilDispatch(router, root_view, rwhv_child,
+ &mouse_event);
+
+ child_interceptor->Wait();
+ base::RunLoop().RunUntilIdle();
+
// Targeting a scrollbar with a click doesn't work on Mac or Android.
#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
- scoped_refptr<SetMouseCaptureInterceptor> interceptor =
+ scoped_refptr<SetMouseCaptureInterceptor> root_interceptor =
new SetMouseCaptureInterceptor(static_cast<RenderWidgetHostImpl*>(
root->current_frame_host()->GetRenderWidgetHost()));
// Now send a MouseDown to target the thumb part of the scroll bar, which
// should initiate mouse capture for the main frame.
mouse_event.SetType(blink::WebInputEvent::kMouseDown);
+ mouse_event.SetModifiers(blink::WebInputEvent::kLeftButtonDown);
SetWebEventPositions(&mouse_event, gfx::Point(100, 25), root_view);
- router->RouteMouseEvent(root_view, &mouse_event, ui::LatencyInfo());
-
+ RouteMouseEventAndWaitUntilDispatch(router, root_view, root_view,
+ &mouse_event);
EXPECT_TRUE(main_frame_monitor.EventWasReceived());
// Wait for the mouse capture message.
- interceptor->Wait();
- EXPECT_TRUE(interceptor->Capturing());
-
- // Yield the thread, in order to let the capture message be processed by its
- // actual handler.
- {
- base::RunLoop loop;
- base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
- loop.QuitClosure());
- loop.Run();
- }
+ root_interceptor->Wait();
+ EXPECT_TRUE(root_interceptor->Capturing());
+ base::RunLoop().RunUntilIdle();
main_frame_monitor.ResetEventReceived();
child_frame_monitor.ResetEventReceived();
@@ -2819,21 +2925,24 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
root_view);
RouteMouseEventAndWaitUntilDispatch(router, root_view, root_view,
&mouse_event);
- EXPECT_TRUE(main_frame_monitor.EventWasReceived());
- EXPECT_FALSE(child_frame_monitor.EventWasReceived());
main_frame_monitor.ResetEventReceived();
child_frame_monitor.ResetEventReceived();
+ RouteMouseEventAndWaitUntilDispatch(router, root_view, root_view,
+ &mouse_event);
+ EXPECT_TRUE(main_frame_monitor.EventWasReceived());
+ EXPECT_FALSE(child_frame_monitor.EventWasReceived());
// A MouseUp sent anywhere should cancel the mouse capture.
mouse_event.SetType(blink::WebInputEvent::kMouseUp);
+ mouse_event.SetModifiers(blink::WebInputEvent::kNoModifiers);
SetWebEventPositions(&mouse_event,
gfx::Point(child_frame_target_x, child_frame_target_y),
root_view);
RouteMouseEventAndWaitUntilDispatch(router, root_view, root_view,
&mouse_event);
- interceptor->Wait();
- EXPECT_FALSE(interceptor->Capturing());
+ root_interceptor->Wait();
+ EXPECT_FALSE(root_interceptor->Capturing());
#endif // !defined(OS_MACOSX) && !defined(OS_ANDROID)
}
@@ -2949,16 +3058,15 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
class CursorMessageFilter : public content::BrowserMessageFilter {
public:
CursorMessageFilter()
- : content::BrowserMessageFilter(ViewMsgStart),
+ : content::BrowserMessageFilter(WidgetMsgStart),
message_loop_runner_(new content::MessageLoopRunner),
last_set_cursor_routing_id_(MSG_ROUTING_NONE) {}
bool OnMessageReceived(const IPC::Message& message) override {
- if (message.type() == ViewHostMsg_SetCursor::ID) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::BindOnce(&CursorMessageFilter::OnSetCursor, this,
- message.routing_id()));
+ if (message.type() == WidgetHostMsg_SetCursor::ID) {
+ base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
+ base::BindOnce(&CursorMessageFilter::OnSetCursor,
+ this, message.routing_id()));
}
return false;
}
@@ -3050,7 +3158,7 @@ void CursorUpdateReceivedFromCrossSiteIframeHelper(
EXPECT_EQ(60, root_monitor.event().PositionInWidget().y);
// CursorMessageFilter::Wait() implicitly tests whether we receive a
- // ViewHostMsg_SetCursor message from the renderer process, because it does
+ // WidgetHostMsg_SetCursor message from the renderer process, because it does
// does not return otherwise.
filter->Wait();
EXPECT_EQ(filter->last_set_cursor_routing_id(), rwh_child->GetRoutingID());
@@ -3078,16 +3186,22 @@ void CursorUpdateReceivedFromCrossSiteIframeHelper(
} // namespace
-// Flaky: https://crbug.com/833380
+#if defined(OS_WIN)
+// https://crbug.com/882458
+#define MAYBE_CursorUpdateReceivedFromCrossSiteIframe \
+ DISABLED_CursorUpdateReceivedFromCrossSiteIframe
+#else
+#define MAYBE_CursorUpdateReceivedFromCrossSiteIframe \
+ CursorUpdateReceivedFromCrossSiteIframe
+#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- DISABLED_CursorUpdateReceivedFromCrossSiteIframe) {
+ MAYBE_CursorUpdateReceivedFromCrossSiteIframe) {
CursorUpdateReceivedFromCrossSiteIframeHelper(shell(),
embedded_test_server());
}
-// Flaky: https://crbug.com/833380
IN_PROC_BROWSER_TEST_P(SitePerProcessHighDPIHitTestBrowserTest,
- DISABLED_CursorUpdateReceivedFromCrossSiteIframe) {
+ CursorUpdateReceivedFromCrossSiteIframe) {
CursorUpdateReceivedFromCrossSiteIframeHelper(shell(),
embedded_test_server());
}
@@ -3481,9 +3595,8 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
render_widget_host->input_router()->AllowedTouchAction());
}
-// https://crbug.com/592320
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- DISABLED_SubframeGestureEventRouting) {
+ SubframeGestureEventRouting) {
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_positioned_nested_frames.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -3517,19 +3630,19 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
params.duration_ms = 100;
std::unique_ptr<SyntheticTapGesture> gesture(new SyntheticTapGesture(params));
- scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner();
-
RenderWidgetHostImpl* render_widget_host =
root->current_frame_host()->GetRenderWidgetHost();
- // TODO(wjmaclean): Convert the call to base::Bind() to a lambda someday.
+ InputEventAckWaiter ack_waiter(child_frame_host->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureTap);
+
render_widget_host->QueueSyntheticGesture(
- std::move(gesture), base::BindOnce(OnSyntheticGestureCompleted, runner));
+ std::move(gesture), base::BindOnce([](SyntheticGesture::Result result) {
+ EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
+ }));
- // We need to run the message loop while we wait for the synthetic gesture
- // to be processed; the callback registered above will get us out of the
- // message loop when that happens.
- runner->Run();
- runner = nullptr;
+ // We must wait for the kGestureTap ack to come back before querying the click
+ // handler in the subframe.
+ ack_waiter.Wait();
// Verify click handler in subframe was invoked
{
@@ -3772,16 +3885,8 @@ void SendTouchpadFlingSequenceWithExpectedTarget(
} // anonymous namespace
-// Flaky, see https://crbug.com/823578
-#if defined(OS_WIN)
-#define MAYBE_InputEventRouterGestureTargetMapTest \
- DISABLED_InputEventRouterGestureTargetMapTest
-#else
-#define MAYBE_InputEventRouterGestureTargetMapTest \
- InputEventRouterGestureTargetMapTest
-#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- MAYBE_InputEventRouterGestureTargetMapTest) {
+ InputEventRouterGestureTargetMapTest) {
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_positioned_nested_frames.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -4047,7 +4152,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// wheel events to the child and causes the page scale factor to change for
// the main frame (given that the child did not consume the wheel).
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- MAYBE_TouchpadPinchOverOOPIF) {
+ TouchpadPinchOverOOPIF) {
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_positioned_frame.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -4209,13 +4314,9 @@ void CreateContextMenuTestHelper(
EXPECT_NEAR(point.y(), params.y, 2);
}
-#if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_LINUX)
+#if defined(OS_ANDROID) || defined(OS_WIN)
// High DPI tests don't work properly on Android, which has fixed scale factor.
// Windows is disabled because of https://crbug.com/545547.
-// The test is flaky on Linux: https://crbug.com/833380.
-#define MAYBE_CreateContextMenuTest DISABLED_CreateContextMenuTest
-#elif defined(THREAD_SANITIZER)
-// TSAN is flaky on both standard and High DPI: https://crbug.com/833380
#define MAYBE_CreateContextMenuTest DISABLED_CreateContextMenuTest
#else
#define MAYBE_CreateContextMenuTest CreateContextMenuTest
@@ -4984,7 +5085,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest, HitTestNestedFrames) {
DCHECK_NE(child_node->current_frame_host()->GetInputTargetClient(),
nullptr);
child_node->current_frame_host()->GetInputTargetClient()->FrameSinkIdAt(
- point_in_child,
+ point_in_child, 0,
base::BindLambdaForTesting(
[&](const viz::FrameSinkId& id, const gfx::PointF& point) {
received_frame_sink_id = id;
@@ -5006,7 +5107,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest, HitTestNestedFrames) {
DCHECK_NE(child_node->current_frame_host()->GetInputTargetClient(),
nullptr);
child_node->current_frame_host()->GetInputTargetClient()->FrameSinkIdAt(
- gfx::ToCeiledPoint(point_in_nested_child),
+ gfx::ToCeiledPoint(point_in_nested_child), 0,
base::BindLambdaForTesting(
[&](const viz::FrameSinkId& id, const gfx::PointF& point) {
received_frame_sink_id = id;
@@ -5029,7 +5130,8 @@ class SitePerProcessHitTestDataGenerationBrowserTest
protected:
// Load the page |host_name| and retrieve the hit test data from HitTestQuery.
std::vector<viz::AggregatedHitTestRegion> SetupAndGetHitTestData(
- const std::string& host_name) {
+ const std::string& host_name,
+ unsigned skipped_child = -1) {
GURL main_url(embedded_test_server()->GetURL(host_name));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -5042,8 +5144,12 @@ class SitePerProcessHitTestDataGenerationBrowserTest
root->current_frame_host()->GetRenderWidgetHost()->GetView());
for (unsigned i = 0; i < root->child_count(); i++) {
- WaitForHitTestDataOrChildSurfaceReady(
- root->child_at(i)->current_frame_host());
+ // Child with pointer-events: none property will never submit a hit test
+ // region in /2 hit testing.
+ if (i != skipped_child) {
+ WaitForHitTestDataOrChildSurfaceReady(
+ root->child_at(i)->current_frame_host());
+ }
}
HitTestRegionObserver observer(rwhv_root->GetRootFrameSinkId());
@@ -5351,6 +5457,74 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestDataGenerationBrowserTest,
EXPECT_EQ(kSlowHitTestFlags, hit_test_data[2].flags);
}
+IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestDataGenerationBrowserTest,
+ PointerEventsNoneOOPIF) {
+ if (!features::IsVizHitTestingSurfaceLayerEnabled())
+ return;
+ auto hit_test_data = SetupAndGetHitTestData(
+ "/frame_tree/page_with_positioned_frame_pointer-events_none.html", 0);
+ float device_scale_factor = current_device_scale_factor();
+ gfx::Transform expected_transform;
+ gfx::Rect expected_region = gfx::ScaleToEnclosingRect(
+ gfx::Rect(1, 1), device_scale_factor, device_scale_factor);
+ expected_transform.Translate(-2 * device_scale_factor,
+ -2 * device_scale_factor);
+
+ // We should not submit hit test region for iframes with pointer-events: none
+ // in /2 hit testing.
+ DCHECK(hit_test_data.size() == 3);
+ EXPECT_EQ(expected_region.ToString(), hit_test_data[2].rect.ToString());
+ EXPECT_TRUE(
+ expected_transform.ApproximatelyEqual(hit_test_data[2].transform()));
+ EXPECT_EQ(kFastHitTestFlags, hit_test_data[2].flags);
+
+ // Check that an update on the css property can trigger an update in submitted
+ // hit test data.
+ EXPECT_TRUE(ExecuteScript(web_contents(),
+ "document.getElementsByTagName('iframe')[0].style."
+ "pointerEvents = 'auto';\n"));
+
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ ASSERT_EQ(2U, root->child_count());
+ RenderWidgetHostViewBase* rwhv_root = static_cast<RenderWidgetHostViewBase*>(
+ root->current_frame_host()->GetRenderWidgetHost()->GetView());
+
+ {
+ MainThreadFrameObserver observer(
+ root->current_frame_host()->GetRenderWidgetHost());
+ observer.Wait();
+ }
+
+ WaitForHitTestDataOrChildSurfaceReady(
+ root->child_at(0)->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(
+ root->child_at(1)->current_frame_host());
+
+ HitTestRegionObserver observer(rwhv_root->GetRootFrameSinkId());
+ observer.WaitForHitTestData();
+ hit_test_data = observer.GetHitTestData();
+
+ gfx::Rect expected_region2 = gfx::ScaleToEnclosingRect(
+ gfx::Rect(100, 100), device_scale_factor, device_scale_factor);
+ gfx::Transform expected_transform2;
+ expected_transform2.Translate(-52 * device_scale_factor,
+ -52 * device_scale_factor);
+
+ DCHECK(hit_test_data.size() == 4);
+ EXPECT_EQ(expected_region.ToString(), hit_test_data[2].rect.ToString());
+ EXPECT_TRUE(
+ expected_transform.ApproximatelyEqual(hit_test_data[2].transform()));
+ EXPECT_EQ(kFastHitTestFlags, hit_test_data[2].flags);
+
+ EXPECT_EQ(expected_region2.ToString(), hit_test_data[3].rect.ToString());
+ EXPECT_TRUE(
+ expected_transform2.ApproximatelyEqual(hit_test_data[3].transform()));
+ EXPECT_EQ(kFastHitTestFlags, hit_test_data[3].flags);
+}
+
static const int kHitTestOption[] = {0, 1, 2};
static const float kOneScale[] = {1.f};
diff --git a/chromium/content/browser/site_per_process_mac_browsertest.mm b/chromium/content/browser/site_per_process_mac_browsertest.mm
index ca814f4d223..e2e97649a9d 100644
--- a/chromium/content/browser/site_per_process_mac_browsertest.mm
+++ b/chromium/content/browser/site_per_process_mac_browsertest.mm
@@ -7,8 +7,10 @@
#include <Cocoa/Cocoa.h>
#include "base/mac/mac_util.h"
+#include "base/task/post_task.h"
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/browser/renderer_host/render_widget_host_view_mac.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
@@ -49,8 +51,8 @@ class TextInputClientMacHelper {
private:
void OnResult(const std::string& string, const gfx::Point& point) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::Bind(&TextInputClientMacHelper::OnResult,
base::Unretained(this), string, point));
return;
diff --git a/chromium/content/browser/speech/speech_recognition_browsertest.cc b/chromium/content/browser/speech/speech_recognition_browsertest.cc
index 3288ddad032..2ccefdd702a 100644
--- a/chromium/content/browser/speech/speech_recognition_browsertest.cc
+++ b/chromium/content/browser/speech/speech_recognition_browsertest.cc
@@ -17,12 +17,14 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_byteorder.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/browser/speech/proto/google_streaming_api.pb.h"
#include "content/browser/speech/speech_recognition_engine.h"
#include "content/browser/speech/speech_recognition_manager_impl.h"
#include "content/browser/speech/speech_recognizer_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
@@ -58,8 +60,8 @@ class MockAudioSystem : public media::AudioSystem {
// Posting callback to allow current SpeechRecognizerImpl dispatching event
// to complete before transitioning to the next FSM state.
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(std::move(on_params_cb),
media::AudioParameters::UnavailableDeviceParams()));
}
@@ -227,8 +229,8 @@ class SpeechRecognitionBrowserTest : public ContentBrowserTest {
// AudioCaptureSourcer::Stop() again.
SpeechRecognizerImpl::SetAudioEnvironmentForTesting(nullptr, nullptr);
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&SpeechRecognitionBrowserTest::SendResponse,
base::Unretained(this)));
}
diff --git a/chromium/content/browser/speech/speech_recognition_dispatcher_host.cc b/chromium/content/browser/speech/speech_recognition_dispatcher_host.cc
index 1658119876a..e898a430e1d 100644
--- a/chromium/content/browser/speech/speech_recognition_dispatcher_host.cc
+++ b/chromium/content/browser/speech/speech_recognition_dispatcher_host.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/lazy_instance.h"
+#include "base/task/post_task.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/frame_host/frame_tree_node.h"
@@ -16,6 +17,7 @@
#include "content/browser/speech/speech_recognition_manager_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/speech_recognition_manager_delegate.h"
@@ -65,7 +67,7 @@ void SpeechRecognitionDispatcherHost::Start(
// Check that the origin specified by the renderer process is one
// that it is allowed to access.
- if (!params->origin.unique() &&
+ if (!params->origin.opaque() &&
!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL(
render_process_id_, params->origin.GetURL())) {
LOG(ERROR) << "SRDH::OnStartRequest, disallowed origin: "
@@ -73,8 +75,8 @@ void SpeechRecognitionDispatcherHost::Start(
return;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SpeechRecognitionDispatcherHost::StartRequestOnUI,
AsWeakPtr(), render_process_id_, render_frame_id_,
std::move(params)));
@@ -137,8 +139,8 @@ void SpeechRecognitionDispatcherHost::StartRequestOnUI(
StoragePartition* storage_partition = BrowserContext::GetStoragePartition(
browser_context, web_contents->GetSiteInstance());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&SpeechRecognitionDispatcherHost::StartSessionOnIO,
speech_recognition_dispatcher_host, std::move(params),
diff --git a/chromium/content/browser/speech/speech_recognition_engine_unittest.cc b/chromium/content/browser/speech/speech_recognition_engine_unittest.cc
index e67d2517559..a0ef4596294 100644
--- a/chromium/content/browser/speech/speech_recognition_engine_unittest.cc
+++ b/chromium/content/browser/speech/speech_recognition_engine_unittest.cc
@@ -11,10 +11,11 @@
#include "base/big_endian.h"
#include "base/containers/queue.h"
-#include "base/message_loop/message_loop.h"
#include "base/numerics/safe_conversions.h"
+#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_byteorder.h"
+#include "base/test/scoped_task_environment.h"
#include "content/browser/speech/audio_buffer.h"
#include "content/browser/speech/proto/google_streaming_api.pb.h"
#include "net/base/net_errors.h"
@@ -99,7 +100,7 @@ class SpeechRecognitionEngineTest
std::string ConsumeChunkedUploadData();
void CloseMockDownstream(DownstreamError error);
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
network::TestURLLoaderFactory url_loader_factory_;
mojo::ScopedDataPipeProducerHandle downstream_data_pipe_;
@@ -666,10 +667,8 @@ bool SpeechRecognitionEngineTest::ResultsAreEqual(
if (a.size() != b.size())
return false;
- std::vector<blink::mojom::SpeechRecognitionResultPtr>::const_iterator it_a =
- a.begin();
- std::vector<blink::mojom::SpeechRecognitionResultPtr>::const_iterator it_b =
- b.begin();
+ auto it_a = a.begin();
+ auto it_b = b.begin();
for (; it_a != a.end() && it_b != b.end(); ++it_a, ++it_b) {
if ((*it_a)->is_provisional != (*it_b)->is_provisional ||
(*it_a)->hypotheses.size() != (*it_b)->hypotheses.size()) {
diff --git a/chromium/content/browser/speech/speech_recognition_manager_impl.cc b/chromium/content/browser/speech/speech_recognition_manager_impl.cc
index 08bcec68559..08c233315c2 100644
--- a/chromium/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/chromium/content/browser/speech/speech_recognition_manager_impl.cc
@@ -14,6 +14,7 @@
#include "base/memory/ref_counted_delete_on_sequence.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/browser/browser_main_loop.h"
@@ -22,6 +23,7 @@
#include "content/browser/speech/speech_recognition_engine.h"
#include "content/browser/speech/speech_recognizer_impl.h"
#include "content/browser/storage_partition_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
@@ -190,7 +192,7 @@ void SpeechRecognitionManagerImpl::FrameDeletionObserver::ContentsObserver::
RenderFrameDeleted(RenderFrameHost* render_frame_host) {
auto iters = observed_frames_.equal_range(render_frame_host);
for (auto it = iters.first; it != iters.second; ++it) {
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})
->PostTask(FROM_HERE,
base::BindOnce(parent_observer_->frame_deleted_callback_,
it->second));
@@ -297,7 +299,7 @@ int SpeechRecognitionManagerImpl::CreateSession(
// The deletion observer is owned by this class, so it's safe to use
// Unretained.
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})
->PostTask(
FROM_HERE,
base::BindOnce(&SpeechRecognitionManagerImpl::FrameDeletionObserver::
@@ -407,7 +409,7 @@ void SpeechRecognitionManagerImpl::AbortSession(int session_id) {
// The deletion observer is owned by this class, so it's safe to use
// Unretained.
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI})
->PostTask(
FROM_HERE,
base::BindOnce(&SpeechRecognitionManagerImpl::FrameDeletionObserver::
diff --git a/chromium/content/browser/speech/speech_recognizer_impl.cc b/chromium/content/browser/speech/speech_recognizer_impl.cc
index 95b6834df4d..e915ff1d7a9 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl.cc
@@ -10,12 +10,14 @@
#include "base/bind.h"
#include "base/macros.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/media/media_internals.h"
#include "content/browser/service_manager/service_manager_context.h"
#include "content/browser/speech/audio_buffer.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/speech_recognition_event_listener.h"
#include "media/audio/audio_system.h"
@@ -229,20 +231,20 @@ void SpeechRecognizerImpl::StartRecognition(const std::string& device_id) {
DCHECK(!device_id.empty());
device_id_ = device_id;
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&SpeechRecognizerImpl::DispatchEvent,
- this, FSMEventArgs(EVENT_PREPARE)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&SpeechRecognizerImpl::DispatchEvent,
+ this, FSMEventArgs(EVENT_PREPARE)));
}
void SpeechRecognizerImpl::AbortRecognition() {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&SpeechRecognizerImpl::DispatchEvent,
- this, FSMEventArgs(EVENT_ABORT)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&SpeechRecognizerImpl::DispatchEvent,
+ this, FSMEventArgs(EVENT_ABORT)));
}
void SpeechRecognizerImpl::StopAudioCapture() {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImpl::DispatchEvent, this,
FSMEventArgs(EVENT_STOP_CAPTURE)));
}
@@ -282,15 +284,15 @@ void SpeechRecognizerImpl::Capture(const AudioBus* data,
// Convert audio from native format to fixed format used by WebSpeech.
FSMEventArgs event_args(EVENT_AUDIO_DATA);
event_args.audio_data = audio_converter_->Convert(data);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImpl::DispatchEvent, this, event_args));
// See http://crbug.com/506051 regarding why one extra convert call can
// sometimes be required. It should be a rare case.
if (!audio_converter_->data_was_converted()) {
event_args.audio_data = audio_converter_->Convert(data);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImpl::DispatchEvent, this, event_args));
}
// Something is seriously wrong here and we are most likely missing some
@@ -300,8 +302,8 @@ void SpeechRecognizerImpl::Capture(const AudioBus* data,
void SpeechRecognizerImpl::OnCaptureError(const std::string& message) {
FSMEventArgs event_args(EVENT_AUDIO_ERROR);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImpl::DispatchEvent, this, event_args));
}
@@ -309,8 +311,8 @@ void SpeechRecognizerImpl::OnSpeechRecognitionEngineResults(
const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results) {
FSMEventArgs event_args(EVENT_ENGINE_RESULT);
event_args.engine_results = mojo::Clone(results);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImpl::DispatchEvent, this, event_args));
}
@@ -323,8 +325,8 @@ void SpeechRecognizerImpl::OnSpeechRecognitionEngineError(
const blink::mojom::SpeechRecognitionError& error) {
FSMEventArgs event_args(EVENT_ENGINE_ERROR);
event_args.engine_error = error;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImpl::DispatchEvent, this, event_args));
}
@@ -782,8 +784,7 @@ SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::ProcessFinalResult(const FSMEventArgs& event_args) {
const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results =
event_args.engine_results;
- std::vector<blink::mojom::SpeechRecognitionResultPtr>::const_iterator i =
- results.begin();
+ auto i = results.begin();
bool provisional_results_pending = false;
bool results_are_empty = true;
for (; i != results.end(); ++i) {
diff --git a/chromium/content/browser/speech/speech_recognizer_impl_android.cc b/chromium/content/browser/speech/speech_recognizer_impl_android.cc
index a2f7a606f30..a4b95f678a0 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl_android.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl_android.cc
@@ -12,6 +12,8 @@
#include "base/android/scoped_java_ref.h"
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/speech_recognition_event_listener.h"
#include "content/public/browser/speech_recognition_manager.h"
@@ -40,14 +42,14 @@ void SpeechRecognizerImplAndroid::StartRecognition(
const std::string& device_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// TODO(xians): Open the correct device for speech on Android.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognitionEventListener::OnRecognitionStart,
base::Unretained(listener()), session_id()));
SpeechRecognitionSessionConfig config =
SpeechRecognitionManager::GetInstance()->GetSessionConfig(session_id());
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&content::SpeechRecognizerImplAndroid::StartRecognitionOnUIThread,
this, config.language, config.continuous, config.interim_results));
@@ -69,8 +71,8 @@ void SpeechRecognizerImplAndroid::StartRecognitionOnUIThread(
void SpeechRecognizerImplAndroid::AbortRecognition() {
if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
state_ = STATE_IDLE;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&content::SpeechRecognizerImplAndroid::AbortRecognition,
this));
return;
@@ -83,8 +85,8 @@ void SpeechRecognizerImplAndroid::AbortRecognition() {
void SpeechRecognizerImplAndroid::StopAudioCapture() {
if (BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&content::SpeechRecognizerImplAndroid::StopAudioCapture,
this));
return;
@@ -109,8 +111,8 @@ void SpeechRecognizerImplAndroid::OnAudioStart(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImplAndroid::OnAudioStart, this,
nullptr, nullptr));
return;
@@ -124,8 +126,8 @@ void SpeechRecognizerImplAndroid::OnSoundStart(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImplAndroid::OnSoundStart, this,
nullptr, nullptr));
return;
@@ -137,8 +139,8 @@ void SpeechRecognizerImplAndroid::OnSoundStart(
void SpeechRecognizerImplAndroid::OnSoundEnd(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImplAndroid::OnSoundEnd, this, nullptr,
nullptr));
return;
@@ -150,8 +152,8 @@ void SpeechRecognizerImplAndroid::OnSoundEnd(JNIEnv* env,
void SpeechRecognizerImplAndroid::OnAudioEnd(JNIEnv* env,
const JavaParamRef<jobject>& obj) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImplAndroid::OnAudioEnd, this, nullptr,
nullptr));
return;
@@ -183,8 +185,8 @@ void SpeechRecognizerImplAndroid::OnRecognitionResults(
options[i], static_cast<double>(scores[i])));
}
result->is_provisional = provisional;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&SpeechRecognizerImplAndroid::OnRecognitionResultsOnIOThread, this,
std::move(results)));
@@ -201,8 +203,8 @@ void SpeechRecognizerImplAndroid::OnRecognitionError(
const JavaParamRef<jobject>& obj,
jint error) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImplAndroid::OnRecognitionError, this,
nullptr, nullptr, error));
return;
@@ -219,8 +221,8 @@ void SpeechRecognizerImplAndroid::OnRecognitionEnd(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SpeechRecognizerImplAndroid::OnRecognitionEnd, this,
nullptr, nullptr));
return;
diff --git a/chromium/content/browser/ssl/ssl_client_auth_handler.cc b/chromium/content/browser/ssl/ssl_client_auth_handler.cc
index 34e9bb57534..29bafea3645 100644
--- a/chromium/content/browser/ssl/ssl_client_auth_handler.cc
+++ b/chromium/content/browser/ssl/ssl_client_auth_handler.cc
@@ -9,6 +9,8 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/task/post_task.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/content_browser_client.h"
@@ -29,8 +31,8 @@ class ClientCertificateDelegateImpl : public ClientCertificateDelegate {
~ClientCertificateDelegateImpl() override {
if (!continue_called_) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SSLClientAuthHandler::CancelCertificateSelection,
handler_));
}
@@ -41,8 +43,8 @@ class ClientCertificateDelegateImpl : public ClientCertificateDelegate {
scoped_refptr<net::SSLPrivateKey> key) override {
DCHECK(!continue_called_);
continue_called_ = true;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SSLClientAuthHandler::ContinueWithCertificate, handler_,
std::move(cert), std::move(key)));
}
@@ -175,15 +177,15 @@ void SSLClientAuthHandler::DidGetClientCerts(
// before checking ClientCertStore; ClientCertStore itself should probably
// be handled by the embedder (https://crbug.com/394131), especially since
// this doesn't work on Android (https://crbug.com/345641).
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&SSLClientAuthHandler::ContinueWithCertificate,
weak_factory_.GetWeakPtr(), nullptr, nullptr));
return;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&SelectCertificateOnUIThread, web_contents_getter_,
base::RetainedRef(cert_request_info_),
std::move(client_certs), weak_factory_.GetWeakPtr()));
diff --git a/chromium/content/browser/ssl/ssl_error_handler.cc b/chromium/content/browser/ssl/ssl_error_handler.cc
index 6145e9b7673..5fc0b3cae44 100644
--- a/chromium/content/browser/ssl/ssl_error_handler.cc
+++ b/chromium/content/browser/ssl/ssl_error_handler.cc
@@ -5,9 +5,11 @@
#include "content/browser/ssl/ssl_error_handler.h"
#include "base/bind.h"
+#include "base/task/post_task.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_request_info.h"
#include "net/base/net_errors.h"
@@ -68,9 +70,9 @@ void SSLErrorHandler::CancelRequest() {
delegate_->CancelSSLRequest(net::ERR_ABORTED, &ssl_info());
return;
}
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CompleteCancelRequest, delegate_,
- ssl_info(), net::ERR_ABORTED));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&CompleteCancelRequest, delegate_,
+ ssl_info(), net::ERR_ABORTED));
}
void SSLErrorHandler::DenyRequest() {
@@ -80,9 +82,9 @@ void SSLErrorHandler::DenyRequest() {
delegate_->CancelSSLRequest(cert_error_, &ssl_info());
return;
}
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CompleteCancelRequest, delegate_,
- ssl_info(), cert_error_));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&CompleteCancelRequest, delegate_,
+ ssl_info(), cert_error_));
}
void SSLErrorHandler::ContinueRequest() {
@@ -92,8 +94,8 @@ void SSLErrorHandler::ContinueRequest() {
delegate_->ContinueSSLRequest();
return;
}
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CompleteContinueRequest, delegate_));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&CompleteContinueRequest, delegate_));
}
} // namespace content
diff --git a/chromium/content/browser/ssl/ssl_manager.cc b/chromium/content/browser/ssl/ssl_manager.cc
index 235a0c00803..b669d0d339e 100644
--- a/chromium/content/browser/ssl/ssl_manager.cc
+++ b/chromium/content/browser/ssl/ssl_manager.cc
@@ -10,8 +10,10 @@
#include "base/bind.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
+#include "base/metrics/ukm_source_id.h"
#include "base/strings/utf_string_conversions.h"
#include "base/supports_user_data.h"
+#include "base/task/post_task.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
@@ -19,6 +21,7 @@
#include "content/browser/ssl/ssl_error_handler.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/certificate_request_result_type.h"
#include "content/public/browser/content_browser_client.h"
@@ -27,6 +30,8 @@
#include "content/public/browser/ssl_host_state_delegate.h"
#include "content/public/common/console_message_level.h"
#include "net/url_request/url_request.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
namespace content {
@@ -34,6 +39,17 @@ namespace {
const char kSSLManagerKeyName[] = "content_ssl_manager";
+// Used to log type of mixed content displayed/ran, matches histogram enum
+// (MixedContentType). DO NOT REORDER.
+enum class MixedContentType {
+ kDisplayMixedContent = 0,
+ kDisplayWithCertErrors = 1,
+ kMixedForm = 2,
+ kScriptingMixedContent = 3,
+ kScriptingWithCertErrors = 4,
+ kMaxValue = kScriptingWithCertErrors,
+};
+
void OnAllowCertificateWithRecordDecision(
bool record_decision,
const base::Callback<void(bool, content::CertificateRequestResultType)>&
@@ -121,6 +137,15 @@ void HandleSSLErrorOnUI(
manager->OnCertError(std::move(handler));
}
+void LogMixedContentMetrics(MixedContentType type,
+ ukm::SourceId source_id,
+ ukm::UkmRecorder* recorder) {
+ UMA_HISTOGRAM_ENUMERATION("SSL.MixedContentShown", type);
+ ukm::builders::SSL_MixedContentShown(source_id)
+ .SetType(static_cast<int64_t>(type))
+ .Record(recorder);
+}
+
} // namespace
// static
@@ -146,8 +171,8 @@ void SSLManager::OnSSLCertificateError(
// TODO(jam): remove the logic to call this from IO thread once the
// network service code path is the only one.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&HandleSSLErrorOnUI, web_contents_getter, delegate,
BrowserThread::IO, resource_type, url, ssl_info, fatal));
}
@@ -223,10 +248,28 @@ void SSLManager::DidCommitProvisionalLoad(const LoadCommittedDetails& details) {
}
void SSLManager::DidDisplayMixedContent() {
+ NavigationEntryImpl* entry = controller_->GetLastCommittedEntry();
+ if (entry && entry->GetURL().SchemeIsCryptographic() &&
+ entry->GetSSL().certificate) {
+ WebContentsImpl* contents = static_cast<WebContentsImpl*>(
+ controller_->delegate()->GetWebContents());
+ ukm::SourceId source_id = contents->GetUkmSourceIdForLastCommittedSource();
+ LogMixedContentMetrics(MixedContentType::kDisplayMixedContent, source_id,
+ ukm::UkmRecorder::Get());
+ }
UpdateLastCommittedEntry(SSLStatus::DISPLAYED_INSECURE_CONTENT, 0);
}
void SSLManager::DidContainInsecureFormAction() {
+ NavigationEntryImpl* entry = controller_->GetLastCommittedEntry();
+ if (entry && entry->GetURL().SchemeIsCryptographic() &&
+ entry->GetSSL().certificate) {
+ WebContentsImpl* contents = static_cast<WebContentsImpl*>(
+ controller_->delegate()->GetWebContents());
+ ukm::SourceId source_id = contents->GetUkmSourceIdForLastCommittedSource();
+ LogMixedContentMetrics(MixedContentType::kMixedForm, source_id,
+ ukm::UkmRecorder::Get());
+ }
UpdateLastCommittedEntry(SSLStatus::DISPLAYED_FORM_WITH_INSECURE_ACTION, 0);
}
@@ -237,6 +280,11 @@ void SSLManager::DidDisplayContentWithCertErrors() {
// Only record information about subresources with cert errors if the
// main page is HTTPS with a certificate.
if (entry->GetURL().SchemeIsCryptographic() && entry->GetSSL().certificate) {
+ WebContentsImpl* contents = static_cast<WebContentsImpl*>(
+ controller_->delegate()->GetWebContents());
+ ukm::SourceId source_id = contents->GetUkmSourceIdForLastCommittedSource();
+ LogMixedContentMetrics(MixedContentType::kDisplayWithCertErrors, source_id,
+ ukm::UkmRecorder::Get());
UpdateLastCommittedEntry(SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS, 0);
}
}
@@ -246,6 +294,14 @@ void SSLManager::DidRunMixedContent(const GURL& security_origin) {
if (!entry)
return;
+ if (entry->GetURL().SchemeIsCryptographic() && entry->GetSSL().certificate) {
+ WebContentsImpl* contents = static_cast<WebContentsImpl*>(
+ controller_->delegate()->GetWebContents());
+ ukm::SourceId source_id = contents->GetUkmSourceIdForLastCommittedSource();
+ LogMixedContentMetrics(MixedContentType::kScriptingMixedContent, source_id,
+ ukm::UkmRecorder::Get());
+ }
+
SiteInstance* site_instance = entry->site_instance();
if (!site_instance)
return;
@@ -264,6 +320,14 @@ void SSLManager::DidRunContentWithCertErrors(const GURL& security_origin) {
if (!entry)
return;
+ if (entry->GetURL().SchemeIsCryptographic() && entry->GetSSL().certificate) {
+ WebContentsImpl* contents = static_cast<WebContentsImpl*>(
+ controller_->delegate()->GetWebContents());
+ ukm::SourceId source_id = contents->GetUkmSourceIdForLastCommittedSource();
+ LogMixedContentMetrics(MixedContentType::kScriptingWithCertErrors,
+ source_id, ukm::UkmRecorder::Get());
+ }
+
SiteInstance* site_instance = entry->site_instance();
if (!site_instance)
return;
@@ -411,8 +475,7 @@ void SSLManager::NotifySSLInternalStateChanged(BrowserContext* context) {
SSLManagerSet* managers =
static_cast<SSLManagerSet*>(context->GetUserData(kSSLManagerKeyName));
- for (std::set<SSLManager*>::iterator i = managers->get().begin();
- i != managers->get().end(); ++i) {
+ for (auto i = managers->get().begin(); i != managers->get().end(); ++i) {
(*i)->UpdateEntry((*i)->controller()->GetLastCommittedEntry(), 0, 0);
}
}
diff --git a/chromium/content/browser/startup_helper.cc b/chromium/content/browser/startup_helper.cc
new file mode 100644
index 00000000000..204b3305a8c
--- /dev/null
+++ b/chromium/content/browser/startup_helper.cc
@@ -0,0 +1,110 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/startup_helper.h"
+
+#include "base/base_switches.h"
+#include "base/command_line.h"
+#include "base/sys_info.h"
+#include "base/task/task_scheduler/initialization_util.h"
+#include "base/task/task_scheduler/task_scheduler.h"
+#include "build/build_config.h"
+#include "content/common/task_scheduler.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/common/content_switches.h"
+
+namespace content {
+
+namespace {
+
+std::unique_ptr<base::TaskScheduler::InitParams>
+GetDefaultTaskSchedulerInitParams() {
+#if defined(OS_ANDROID)
+ // Mobile config, for iOS see ios/web/app/web_main_loop.cc.
+ return std::make_unique<base::TaskScheduler::InitParams>(
+ base::SchedulerWorkerPoolParams(
+ base::RecommendedMaxNumberOfThreadsInPool(2, 8, 0.1, 0),
+ base::TimeDelta::FromSeconds(30)),
+ base::SchedulerWorkerPoolParams(
+ base::RecommendedMaxNumberOfThreadsInPool(2, 8, 0.1, 0),
+ base::TimeDelta::FromSeconds(30)),
+ base::SchedulerWorkerPoolParams(
+ base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.3, 0),
+ base::TimeDelta::FromSeconds(30)),
+ base::SchedulerWorkerPoolParams(
+ base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.3, 0),
+ base::TimeDelta::FromSeconds(60)));
+#else
+ // Desktop config.
+ return std::make_unique<base::TaskScheduler::InitParams>(
+ base::SchedulerWorkerPoolParams(
+ base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0),
+ base::TimeDelta::FromSeconds(30)),
+ base::SchedulerWorkerPoolParams(
+ base::RecommendedMaxNumberOfThreadsInPool(3, 8, 0.1, 0),
+ base::TimeDelta::FromSeconds(40)),
+ base::SchedulerWorkerPoolParams(
+ base::RecommendedMaxNumberOfThreadsInPool(8, 32, 0.3, 0),
+ base::TimeDelta::FromSeconds(30)),
+ base::SchedulerWorkerPoolParams(
+ base::RecommendedMaxNumberOfThreadsInPool(8, 32, 0.3, 0),
+ base::TimeDelta::FromSeconds(60))
+#if defined(OS_WIN)
+ ,
+ base::TaskScheduler::InitParams::SharedWorkerPoolEnvironment::COM_MTA
+#endif // defined(OS_WIN)
+ );
+#endif
+}
+
+} // namespace
+
+std::unique_ptr<base::FieldTrialList> SetUpFieldTrialsAndFeatureList() {
+ auto field_trial_list = std::make_unique<base::FieldTrialList>(nullptr);
+ const base::CommandLine* command_line =
+ base::CommandLine::ForCurrentProcess();
+
+ // Ensure any field trials specified on the command line are initialized.
+ if (command_line->HasSwitch(::switches::kForceFieldTrials)) {
+ // Create field trials without activating them, so that this behaves in a
+ // consistent manner with field trials created from the server.
+ bool result = base::FieldTrialList::CreateTrialsFromString(
+ command_line->GetSwitchValueASCII(::switches::kForceFieldTrials),
+ std::set<std::string>());
+ CHECK(result) << "Invalid --" << ::switches::kForceFieldTrials
+ << " list specified.";
+ }
+
+ base::FeatureList::InitializeInstance(
+ command_line->GetSwitchValueASCII(switches::kEnableFeatures),
+ command_line->GetSwitchValueASCII(switches::kDisableFeatures));
+ return field_trial_list;
+}
+
+void StartBrowserTaskScheduler() {
+ auto task_scheduler_init_params =
+ GetContentClient()->browser()->GetTaskSchedulerInitParams();
+ if (!task_scheduler_init_params)
+ task_scheduler_init_params = GetDefaultTaskSchedulerInitParams();
+ DCHECK(task_scheduler_init_params);
+
+ // If a renderer lives in the browser process, adjust the number of
+ // threads in the foreground pool.
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSingleProcess)) {
+ const base::SchedulerWorkerPoolParams&
+ current_foreground_worker_pool_params(
+ task_scheduler_init_params->foreground_worker_pool_params);
+ task_scheduler_init_params->foreground_worker_pool_params =
+ base::SchedulerWorkerPoolParams(
+ std::max(GetMinThreadsInRendererTaskSchedulerForegroundPool(),
+ current_foreground_worker_pool_params.max_tasks()),
+ current_foreground_worker_pool_params.suggested_reclaim_time(),
+ current_foreground_worker_pool_params.backward_compatibility());
+ }
+
+ base::TaskScheduler::GetInstance()->Start(*task_scheduler_init_params.get());
+}
+
+} // namespace content
diff --git a/chromium/content/browser/startup_helper.h b/chromium/content/browser/startup_helper.h
new file mode 100644
index 00000000000..9259f9cabdc
--- /dev/null
+++ b/chromium/content/browser/startup_helper.h
@@ -0,0 +1,23 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_STARTUP_HELPER_H_
+#define CONTENT_BROWSER_STARTUP_HELPER_H_
+
+#include "base/metrics/field_trial.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// Setups fields trials and the FeatureList, and returns the unique pointer of
+// the field trials.
+std::unique_ptr<base::FieldTrialList> CONTENT_EXPORT
+SetUpFieldTrialsAndFeatureList();
+
+// Starts the task scheduler.
+void CONTENT_EXPORT StartBrowserTaskScheduler();
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_STARTUP_HELPER_H_
diff --git a/chromium/content/browser/startup_task_runner.cc b/chromium/content/browser/startup_task_runner.cc
index 319bc8f10b4..51c98506b14 100644
--- a/chromium/content/browser/startup_task_runner.cc
+++ b/chromium/content/browser/startup_task_runner.cc
@@ -37,9 +37,7 @@ void StartupTaskRunner::StartRunningTasksAsync() {
void StartupTaskRunner::RunAllTasksNow() {
int result = 0;
- for (std::list<StartupTask>::iterator it = task_list_.begin();
- it != task_list_.end();
- it++) {
+ for (auto it = task_list_.begin(); it != task_list_.end(); it++) {
result = it->Run();
if (result > 0) break;
}
diff --git a/chromium/content/browser/storage_partition_impl.cc b/chromium/content/browser/storage_partition_impl.cc
index ee48d130400..c5307b0a921 100644
--- a/chromium/content/browser/storage_partition_impl.cc
+++ b/chromium/content/browser/storage_partition_impl.cc
@@ -13,12 +13,15 @@
#include "base/barrier_closure.h"
#include "base/bind.h"
+#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/location.h"
+#include "base/optional.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/syslog_logging.h"
+#include "base/task/post_task.h"
#include "content/browser/background_fetch/background_fetch_context.h"
#include "content/browser/blob_storage/blob_registry_wrapper.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
@@ -35,6 +38,7 @@
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/dom_storage_context.h"
@@ -47,6 +51,7 @@
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "net/base/completion_callback.h"
+#include "net/base/features.h"
#include "net/base/net_errors.h"
#include "net/cookies/canonical_cookie.h"
#include "net/url_request/url_request_context.h"
@@ -85,8 +90,8 @@ base::LazyInstance<StoragePartitionImpl::CreateNetworkFactoryCallback>::Leaky
void OnClearedCookies(base::OnceClosure callback, uint32_t num_deleted) {
// The final callback needs to happen from UI thread.
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&OnClearedCookies, std::move(callback), num_deleted));
return;
}
@@ -95,18 +100,18 @@ void OnClearedCookies(base::OnceClosure callback, uint32_t num_deleted) {
}
void CheckQuotaManagedDataDeletionStatus(size_t* deletion_task_count,
- const base::Closure& callback) {
+ base::OnceClosure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (*deletion_task_count == 0) {
delete deletion_task_count;
- callback.Run();
+ std::move(callback).Run();
}
}
-void OnQuotaManagedOriginDeleted(const GURL& origin,
+void OnQuotaManagedOriginDeleted(const url::Origin& origin,
blink::mojom::StorageType type,
size_t* deletion_task_count,
- const base::Closure& callback,
+ base::OnceClosure callback,
blink::mojom::QuotaStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK_GT(*deletion_task_count, 0u);
@@ -117,25 +122,27 @@ void OnQuotaManagedOriginDeleted(const GURL& origin,
}
(*deletion_task_count)--;
- CheckQuotaManagedDataDeletionStatus(deletion_task_count, callback);
+ CheckQuotaManagedDataDeletionStatus(deletion_task_count, std::move(callback));
}
-void ClearedShaderCache(const base::Closure& callback) {
+void ClearedShaderCache(base::OnceClosure callback) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&ClearedShaderCache, callback));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&ClearedShaderCache, std::move(callback)));
return;
}
- callback.Run();
+ std::move(callback).Run();
}
void ClearShaderCacheOnIOThread(const base::FilePath& path,
const base::Time begin,
const base::Time end,
- const base::Closure& callback) {
+ base::OnceClosure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
GetShaderCacheFactorySingleton()->ClearByPath(
- path, begin, end, base::Bind(&ClearedShaderCache, callback));
+ path, begin, end,
+ base::BindOnce(&ClearedShaderCache, std::move(callback)));
}
void OnLocalStorageUsageInfo(
@@ -144,11 +151,12 @@ void OnLocalStorageUsageInfo(
const StoragePartition::OriginMatcherFunction& origin_matcher,
const base::Time delete_begin,
const base::Time delete_end,
- const base::Closure& callback,
+ base::OnceClosure callback,
const std::vector<LocalStorageUsageInfo>& infos) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- base::RepeatingClosure barrier = base::BarrierClosure(infos.size(), callback);
+ base::RepeatingClosure barrier =
+ base::BarrierClosure(infos.size(), std::move(callback));
for (size_t i = 0; i < infos.size(); ++i) {
if (!origin_matcher.is_null() &&
!origin_matcher.Run(infos[i].origin, special_storage_policy.get())) {
@@ -169,7 +177,7 @@ void OnSessionStorageUsageInfo(
const scoped_refptr<DOMStorageContextWrapper>& dom_storage_context,
const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
const StoragePartition::OriginMatcherFunction& origin_matcher,
- const base::Closure& callback,
+ base::OnceClosure callback,
const std::vector<SessionStorageUsageInfo>& infos) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -181,7 +189,7 @@ void OnSessionStorageUsageInfo(
dom_storage_context->DeleteSessionStorage(infos[i]);
}
- callback.Run();
+ std::move(callback).Run();
}
void ClearLocalStorageOnUIThread(
@@ -191,7 +199,7 @@ void ClearLocalStorageOnUIThread(
const GURL& storage_origin,
const base::Time begin,
const base::Time end,
- const base::Closure& callback) {
+ base::OnceClosure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!storage_origin.is_empty()) {
@@ -199,29 +207,29 @@ void ClearLocalStorageOnUIThread(
origin_matcher.Run(storage_origin,
special_storage_policy.get());
if (can_delete) {
- dom_storage_context->DeleteLocalStorage(storage_origin, callback);
+ dom_storage_context->DeleteLocalStorage(storage_origin,
+ std::move(callback));
} else {
- callback.Run();
+ std::move(callback).Run();
}
return;
}
- dom_storage_context->GetLocalStorageUsage(
- base::Bind(&OnLocalStorageUsageInfo,
- dom_storage_context, special_storage_policy, origin_matcher,
- begin, end, callback));
+ dom_storage_context->GetLocalStorageUsage(base::BindOnce(
+ &OnLocalStorageUsageInfo, dom_storage_context, special_storage_policy,
+ origin_matcher, begin, end, std::move(callback)));
}
void ClearSessionStorageOnUIThread(
const scoped_refptr<DOMStorageContextWrapper>& dom_storage_context,
const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
const StoragePartition::OriginMatcherFunction& origin_matcher,
- const base::Closure& callback) {
+ base::OnceClosure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- dom_storage_context->GetSessionStorageUsage(
- base::BindOnce(&OnSessionStorageUsageInfo, dom_storage_context,
- special_storage_policy, origin_matcher, callback));
+ dom_storage_context->GetSessionStorageUsage(base::BindOnce(
+ &OnSessionStorageUsageInfo, dom_storage_context, special_storage_policy,
+ origin_matcher, std::move(callback)));
}
} // namespace
@@ -349,15 +357,19 @@ void StoragePartitionImpl::
// Most of the operations in this class are done on IO thread.
class StoragePartitionImpl::QuotaManagedDataDeletionHelper {
public:
- QuotaManagedDataDeletionHelper(uint32_t remove_mask,
- uint32_t quota_storage_remove_mask,
- const GURL& storage_origin,
- const base::Closure& callback)
+ QuotaManagedDataDeletionHelper(
+ uint32_t remove_mask,
+ uint32_t quota_storage_remove_mask,
+ const base::Optional<url::Origin>& storage_origin,
+ base::OnceClosure callback)
: remove_mask_(remove_mask),
quota_storage_remove_mask_(quota_storage_remove_mask),
storage_origin_(storage_origin),
- callback_(callback),
- task_count_(0) {}
+ callback_(std::move(callback)),
+ task_count_(0) {
+ DCHECK(!storage_origin_.has_value() ||
+ !storage_origin_->GetURL().is_empty());
+ }
void IncrementTaskCountOnIO();
void DecrementTaskCountOnIO();
@@ -374,16 +386,16 @@ class StoragePartitionImpl::QuotaManagedDataDeletionHelper {
const scoped_refptr<storage::SpecialStoragePolicy>&
special_storage_policy,
const StoragePartition::OriginMatcherFunction& origin_matcher,
- const base::Closure& callback,
- const std::set<GURL>& origins,
+ base::OnceClosure callback,
+ const std::set<url::Origin>& origins,
blink::mojom::StorageType quota_storage_type);
private:
// All of these data are accessed on IO thread.
uint32_t remove_mask_;
uint32_t quota_storage_remove_mask_;
- GURL storage_origin_;
- const base::Closure callback_;
+ base::Optional<url::Origin> storage_origin_;
+ base::OnceClosure callback_;
int task_count_;
DISALLOW_COPY_AND_ASSIGN(QuotaManagedDataDeletionHelper);
@@ -459,7 +471,7 @@ class StoragePartitionImpl::DataDeletionHelper {
const scoped_refptr<storage::SpecialStoragePolicy>&
special_storage_policy,
const StoragePartition::OriginMatcherFunction& origin_matcher,
- const base::Closure& callback);
+ base::OnceClosure callback);
private:
uint32_t remove_mask_;
@@ -479,12 +491,16 @@ void StoragePartitionImpl::DataDeletionHelper::ClearQuotaManagedDataOnIOThread(
const GURL& storage_origin,
const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
const StoragePartition::OriginMatcherFunction& origin_matcher,
- const base::Closure& callback) {
+ base::OnceClosure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
StoragePartitionImpl::QuotaManagedDataDeletionHelper* helper =
new StoragePartitionImpl::QuotaManagedDataDeletionHelper(
- remove_mask_, quota_storage_remove_mask_, storage_origin, callback);
+ remove_mask_, quota_storage_remove_mask_,
+ storage_origin.is_empty()
+ ? base::nullopt
+ : base::make_optional(url::Origin::Create(storage_origin)),
+ std::move(callback));
helper->ClearDataOnIOThread(quota_manager, begin, special_storage_policy,
origin_matcher);
}
@@ -541,8 +557,8 @@ StoragePartitionImpl::~StoragePartitionImpl() {
GetBackgroundFetchContext()->Shutdown();
if (GetAppCacheService()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ChromeAppCacheService::Shutdown, appcache_service_));
}
@@ -577,10 +593,10 @@ std::unique_ptr<StoragePartitionImpl> StoragePartitionImpl::Create(
// that utilizes the QuotaManager.
partition->quota_manager_ = new storage::QuotaManager(
in_memory, partition_path,
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO).get(),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}).get(),
context->GetSpecialStoragePolicy(),
- base::Bind(&StoragePartitionImpl::GetQuotaSettings,
- partition->weak_factory_.GetWeakPtr()));
+ base::BindRepeating(&StoragePartitionImpl::GetQuotaSettings,
+ partition->weak_factory_.GetWeakPtr()));
scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy =
partition->quota_manager_->proxy();
@@ -675,7 +691,7 @@ std::unique_ptr<StoragePartitionImpl> StoragePartitionImpl::Create(
partition->cookie_store_context_->Initialize(
partition->service_worker_context_, base::DoNothing());
- if (base::FeatureList::IsEnabled(features::kIsolatedCodeCache)) {
+ if (base::FeatureList::IsEnabled(net::features::kIsolatedCodeCache)) {
// TODO(crbug.com/867552): Currently we misuse GetCachePath to check if
// code caching is enabled. Fix this by having a better API.
@@ -945,7 +961,7 @@ void StoragePartitionImpl::
if (task_count_)
return;
- callback_.Run();
+ std::move(callback_).Run();
delete this;
}
@@ -955,7 +971,7 @@ void StoragePartitionImpl::QuotaManagedDataDeletionHelper::ClearDataOnIOThread(
const scoped_refptr<storage::SpecialStoragePolicy>& special_storage_policy,
const StoragePartition::OriginMatcherFunction& origin_matcher) {
IncrementTaskCountOnIO();
- base::Closure decrement_callback = base::Bind(
+ base::RepeatingClosure decrement_callback = base::BindRepeating(
&QuotaManagedDataDeletionHelper::DecrementTaskCountOnIO,
base::Unretained(this));
@@ -991,7 +1007,7 @@ void StoragePartitionImpl::QuotaManagedDataDeletionHelper::ClearDataOnIOThread(
base::BindOnce(&QuotaManagedDataDeletionHelper::ClearOriginsOnIOThread,
base::Unretained(this), base::RetainedRef(quota_manager),
special_storage_policy, origin_matcher,
- std::move(decrement_callback)));
+ decrement_callback));
}
DecrementTaskCountOnIO();
@@ -1003,41 +1019,45 @@ void StoragePartitionImpl::QuotaManagedDataDeletionHelper::
const scoped_refptr<storage::SpecialStoragePolicy>&
special_storage_policy,
const StoragePartition::OriginMatcherFunction& origin_matcher,
- const base::Closure& callback,
- const std::set<GURL>& origins,
+ base::OnceClosure callback,
+ const std::set<url::Origin>& origins,
blink::mojom::StorageType quota_storage_type) {
// The QuotaManager manages all storage other than cookies, LocalStorage,
// and SessionStorage. This loop wipes out most HTML5 storage for the given
// origins.
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (origins.empty()) {
- callback.Run();
+ std::move(callback).Run();
return;
}
+ // The logic below (via CheckQuotaManagedDataDeletionStatus) only
+ // invokes the callback when all processing is complete.
+ base::RepeatingClosure completion =
+ base::AdaptCallbackForRepeating(std::move(callback));
+
size_t* deletion_task_count = new size_t(0u);
(*deletion_task_count)++;
- for (std::set<GURL>::const_iterator origin = origins.begin();
- origin != origins.end(); ++origin) {
+ for (const auto& origin : origins) {
// TODO(mkwst): Clean this up, it's slow. http://crbug.com/130746
- if (!storage_origin_.is_empty() && origin->GetOrigin() != storage_origin_)
+ if (storage_origin_.has_value() && origin != *storage_origin_)
continue;
if (!origin_matcher.is_null() &&
- !origin_matcher.Run(*origin, special_storage_policy.get())) {
+ !origin_matcher.Run(origin.GetURL(), special_storage_policy.get())) {
continue;
}
(*deletion_task_count)++;
quota_manager->DeleteOriginData(
- *origin, quota_storage_type,
+ origin, quota_storage_type,
StoragePartitionImpl::GenerateQuotaClientMask(remove_mask_),
- base::BindOnce(&OnQuotaManagedOriginDeleted, origin->GetOrigin(),
- quota_storage_type, deletion_task_count, callback));
+ base::BindOnce(&OnQuotaManagedOriginDeleted, origin, quota_storage_type,
+ deletion_task_count, completion));
}
(*deletion_task_count)--;
- CheckQuotaManagedDataDeletionStatus(deletion_task_count, callback);
+ CheckQuotaManagedDataDeletionStatus(deletion_task_count, completion);
}
void StoragePartitionImpl::DataDeletionHelper::IncrementTaskCountOnUI() {
@@ -1047,8 +1067,8 @@ void StoragePartitionImpl::DataDeletionHelper::IncrementTaskCountOnUI() {
void StoragePartitionImpl::DataDeletionHelper::DecrementTaskCount() {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&DataDeletionHelper::DecrementTaskCount,
base::Unretained(this)));
return;
@@ -1078,7 +1098,7 @@ void StoragePartitionImpl::DataDeletionHelper::ClearDataOnUIThread(
DCHECK(!callback_.is_null());
IncrementTaskCountOnUI();
- base::Closure decrement_callback = base::Bind(
+ base::RepeatingClosure decrement_callback = base::BindRepeating(
&DataDeletionHelper::DecrementTaskCount, base::Unretained(this));
if (remove_mask_ & REMOVE_DATA_MASK_COOKIES) {
@@ -1111,8 +1131,8 @@ void StoragePartitionImpl::DataDeletionHelper::ClearDataOnUIThread(
remove_mask_ & REMOVE_DATA_MASK_SERVICE_WORKERS ||
remove_mask_ & REMOVE_DATA_MASK_CACHE_STORAGE) {
IncrementTaskCountOnUI();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&DataDeletionHelper::ClearQuotaManagedDataOnIOThread,
base::Unretained(this), base::WrapRefCounted(quota_manager), begin,
@@ -1141,9 +1161,9 @@ void StoragePartitionImpl::DataDeletionHelper::ClearDataOnUIThread(
if (remove_mask_ & REMOVE_DATA_MASK_SHADER_CACHE) {
IncrementTaskCountOnUI();
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&ClearShaderCacheOnIOThread, path,
- begin, end, decrement_callback));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&ClearShaderCacheOnIOThread, path,
+ begin, end, decrement_callback));
}
#if BUILDFLAG(ENABLE_PLUGINS)
@@ -1297,8 +1317,8 @@ void StoragePartitionImpl::InitNetworkContext() {
DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
DCHECK(!network_context_owner_);
network_context_owner_ = std::make_unique<NetworkContextOwner>();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&NetworkContextOwner::Initialize,
base::Unretained(network_context_owner_.get()),
MakeRequest(&network_context_), url_request_context_));
@@ -1331,12 +1351,6 @@ StoragePartitionImpl::GetURLLoaderFactoryForBrowserProcessInternal() {
switches::kDisableWebSecurity);
if (g_url_loader_factory_callback_for_test.Get().is_null()) {
auto request = mojo::MakeRequest(&url_loader_factory_for_browser_process_);
-
- if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- GetContentClient()->browser()->WillCreateURLLoaderFactory(
- browser_context(), nullptr, false /* is_navigation */, GURL(),
- &request);
- }
GetNetworkContext()->CreateURLLoaderFactory(std::move(request),
std::move(params));
is_test_url_loader_factory_for_browser_process_ = false;
diff --git a/chromium/content/browser/storage_partition_impl_map.cc b/chromium/content/browser/storage_partition_impl_map.cc
index c93fd1e67ba..173d8a0d25d 100644
--- a/chromium/content/browser/storage_partition_impl_map.cc
+++ b/chromium/content/browser/storage_partition_impl_map.cc
@@ -41,6 +41,7 @@
#include "content/browser/webui/url_data_manager_backend.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/storage_partition.h"
@@ -187,9 +188,7 @@ void ObliterateOneDirectory(const base::FilePath& current_dir,
// Enum tracking which of the 3 possible actions to take for |to_delete|.
enum { kSkip, kEnqueue, kDelete } action = kDelete;
- for (std::vector<base::FilePath>::const_iterator to_keep =
- paths_to_keep.begin();
- to_keep != paths_to_keep.end();
+ for (auto to_keep = paths_to_keep.begin(); to_keep != paths_to_keep.end();
++to_keep) {
if (to_delete == *to_keep) {
action = kSkip;
@@ -245,9 +244,7 @@ void BlockingObliteratePath(
// Reduce |paths_to_keep| set to those under the root and actually on disk.
std::vector<base::FilePath> valid_paths_to_keep;
- for (std::vector<base::FilePath>::const_iterator it = paths_to_keep.begin();
- it != paths_to_keep.end();
- ++it) {
+ for (auto it = paths_to_keep.begin(); it != paths_to_keep.end(); ++it) {
if (root.IsParent(*it) && base::PathExists(*it))
valid_paths_to_keep.push_back(*it);
}
@@ -277,8 +274,7 @@ void NormalizeActivePaths(const base::FilePath& storage_root,
base::hash_set<base::FilePath>* active_paths) {
base::hash_set<base::FilePath> normalized_active_paths;
- for (base::hash_set<base::FilePath>::iterator iter = active_paths->begin();
- iter != active_paths->end(); ++iter) {
+ for (auto iter = active_paths->begin(); iter != active_paths->end(); ++iter) {
base::FilePath relative_path;
if (!storage_root.AppendRelativePath(*iter, &relative_path))
continue;
@@ -556,8 +552,8 @@ void StoragePartitionImplMap::PostCreateInitialization(
// Check first to avoid memory leak in unittests.
if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&ChromeAppCacheService::InitializeOnIOThread,
partition->GetAppCacheService(),
@@ -567,29 +563,29 @@ void StoragePartitionImplMap::PostCreateInitialization(
base::RetainedRef(partition->GetURLRequestContext()),
base::RetainedRef(browser_context_->GetSpecialStoragePolicy())));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&CacheStorageContextImpl::SetBlobParametersForCache,
partition->GetCacheStorageContext(),
base::RetainedRef(partition->GetURLRequestContext()),
base::RetainedRef(ChromeBlobStorageContext::GetFor(
browser_context_))));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ServiceWorkerContextWrapper::InitializeResourceContext,
partition->GetServiceWorkerContext(),
browser_context_->GetResourceContext()));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&PrefetchURLLoaderService::InitializeResourceContext,
partition->GetPrefetchURLLoaderService(),
browser_context_->GetResourceContext(),
base::RetainedRef(partition->GetURLRequestContext())));
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&BackgroundFetchContext::InitializeOnIOThread,
partition->GetBackgroundFetchContext()));
diff --git a/chromium/content/browser/storage_partition_impl_unittest.cc b/chromium/content/browser/storage_partition_impl_unittest.cc
index d58a94c0a62..d0942e106f5 100644
--- a/chromium/content/browser/storage_partition_impl_unittest.cc
+++ b/chromium/content/browser/storage_partition_impl_unittest.cc
@@ -10,6 +10,8 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
+#include "base/test/scoped_feature_list.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/services/leveldb/public/cpp/util.h"
@@ -18,13 +20,16 @@
#include "content/browser/dom_storage/local_storage_database.pb.h"
#include "content/browser/gpu/shader_cache_factory.h"
#include "content/browser/storage_partition_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/local_storage_usage_info.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_features.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_utils.h"
#include "content/test/fake_leveldb_database.h"
+#include "net/base/features.h"
#include "net/base/test_completion_callback.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_store.h"
@@ -68,10 +73,12 @@ const char kWidevineCdmPluginId[] = "application_x-ppapi-widevine-cdm";
const char kClearKeyCdmPluginId[] = "application_x-ppapi-clearkey-cdm";
#endif // BUILDFLAG(ENABLE_PLUGINS)
-const GURL kOrigin1(kTestOrigin1);
-const GURL kOrigin2(kTestOrigin2);
-const GURL kOrigin3(kTestOrigin3);
-const GURL kOriginDevTools(kTestOriginDevTools);
+// TODO(crbug.com/889590): Use helper for url::Origin creation from string.
+const url::Origin kOrigin1 = url::Origin::Create(GURL(kTestOrigin1));
+const url::Origin kOrigin2 = url::Origin::Create(GURL(kTestOrigin2));
+const url::Origin kOrigin3 = url::Origin::Create(GURL(kTestOrigin3));
+const url::Origin kOriginDevTools =
+ url::Origin::Create(GURL(kTestOriginDevTools));
const GURL kResourceURL(kTestURL);
const blink::mojom::StorageType kTemporary =
@@ -135,7 +142,7 @@ class RemoveCookieTester {
bool ContainsCookie() {
get_cookie_success_ = false;
cookie_store_->GetCookieListWithOptionsAsync(
- kOrigin1, net::CookieOptions(),
+ kOrigin1.GetURL(), net::CookieOptions(),
base::BindOnce(&RemoveCookieTester::GetCookieListCallback,
base::Unretained(this)));
await_completion_.BlockUntilNotified();
@@ -144,7 +151,7 @@ class RemoveCookieTester {
void AddCookie() {
cookie_store_->SetCookieWithOptionsAsync(
- kOrigin1, "A=1", net::CookieOptions(),
+ kOrigin1.GetURL(), "A=1", net::CookieOptions(),
base::BindOnce(&RemoveCookieTester::SetCookieCallback,
base::Unretained(this)));
await_completion_.BlockUntilNotified();
@@ -187,11 +194,11 @@ class RemoveLocalStorageTester {
}
// Returns true, if the given origin URL exists.
- bool DOMStorageExistsForOrigin(const GURL& origin) {
+ bool DOMStorageExistsForOrigin(const url::Origin& origin) {
GetLocalStorageUsage();
await_completion_.BlockUntilNotified();
for (size_t i = 0; i < infos_.size(); ++i) {
- if (origin == infos_[i].origin)
+ if (origin == url::Origin::Create(infos_[i].origin))
return true;
}
return false;
@@ -212,21 +219,21 @@ class RemoveLocalStorageTester {
base::Time now = base::Time::Now();
data.set_last_modified(now.ToInternalValue());
data.set_size_bytes(16);
- mock_data_[CreateMetaDataKey(url::Origin::Create(kOrigin1))] =
+ mock_data_[CreateMetaDataKey(kOrigin1)] =
leveldb::StdStringToUint8Vector(data.SerializeAsString());
- mock_data_[CreateDataKey(url::Origin::Create(kOrigin1))] = {};
+ mock_data_[CreateDataKey(kOrigin1)] = {};
base::Time one_day_ago = now - base::TimeDelta::FromDays(1);
data.set_last_modified(one_day_ago.ToInternalValue());
- mock_data_[CreateMetaDataKey(url::Origin::Create(kOrigin2))] =
+ mock_data_[CreateMetaDataKey(kOrigin2)] =
leveldb::StdStringToUint8Vector(data.SerializeAsString());
- mock_data_[CreateDataKey(url::Origin::Create(kOrigin2))] = {};
+ mock_data_[CreateDataKey(kOrigin2)] = {};
base::Time sixty_days_ago = now - base::TimeDelta::FromDays(60);
data.set_last_modified(sixty_days_ago.ToInternalValue());
- mock_data_[CreateMetaDataKey(url::Origin::Create(kOrigin3))] =
+ mock_data_[CreateMetaDataKey(kOrigin3)] =
leveldb::StdStringToUint8Vector(data.SerializeAsString());
- mock_data_[CreateDataKey(url::Origin::Create(kOrigin3))] = {};
+ mock_data_[CreateDataKey(kOrigin3)] = {};
}
private:
@@ -282,26 +289,39 @@ class RemoveCodeCacheTester {
explicit RemoveCodeCacheTester(GeneratedCodeCacheContext* code_cache_context)
: code_cache_context_(code_cache_context) {}
- bool ContainsEntry(GURL url, url::Origin origin) {
+ enum Cache { kJs, kWebAssembly };
+
+ bool ContainsEntry(Cache cache, GURL url, url::Origin origin) {
entry_exists_ = false;
GeneratedCodeCache::ReadDataCallback callback = base::BindRepeating(
&RemoveCodeCacheTester::FetchEntryCallback, base::Unretained(this));
- code_cache_context_->generated_code_cache()->FetchEntry(url, origin,
- callback);
+ GetCache(cache)->FetchEntry(url, origin, callback);
await_completion_.BlockUntilNotified();
return entry_exists_;
}
- void AddEntry(GURL url, url::Origin origin, const std::string& data) {
+ void AddEntry(Cache cache,
+ GURL url,
+ url::Origin origin,
+ const std::string& data) {
std::vector<uint8_t> data_vector(data.begin(), data.end());
- code_cache_context_->generated_code_cache()->WriteData(
- url, origin, base::Time::Now(), data_vector);
+ GetCache(cache)->WriteData(url, origin, base::Time::Now(), data_vector);
base::RunLoop().RunUntilIdle();
+ // TODO(crbug.com/886892): Remove this once we update GeneratedCodeCache
+ // to serialize operations corresponding to each entry.
+ content::RunAllTasksUntilIdle();
}
std::string received_data() { return received_data_; }
private:
+ GeneratedCodeCache* GetCache(Cache cache) {
+ if (cache == kJs)
+ return code_cache_context_->generated_js_code_cache();
+ else
+ return code_cache_context_->generated_wasm_code_cache();
+ }
+
void FetchEntryCallback(const base::Time& response_time,
const std::vector<uint8_t>& data) {
if (!response_time.is_null()) {
@@ -338,18 +358,18 @@ class RemovePluginPrivateDataTester {
// Create a PluginPrivateFileSystem for ClearKey and add a single file
// with a timestamp of 1 day ago.
std::string clearkey_fsid =
- CreateFileSystem(kClearKeyCdmPluginId, kOrigin1);
- clearkey_file_ = CreateFile(kOrigin1, clearkey_fsid, "foo");
+ CreateFileSystem(kClearKeyCdmPluginId, kOrigin1.GetURL());
+ clearkey_file_ = CreateFile(kOrigin1.GetURL(), clearkey_fsid, "foo");
SetFileTimestamp(clearkey_file_, ten_days_ago);
// Create a second PluginPrivateFileSystem for Widevine and add two files
// with different times.
std::string widevine_fsid =
- CreateFileSystem(kWidevineCdmPluginId, kOrigin2);
+ CreateFileSystem(kWidevineCdmPluginId, kOrigin2.GetURL());
storage::FileSystemURL widevine_file1 =
- CreateFile(kOrigin2, widevine_fsid, "bar1");
+ CreateFile(kOrigin2.GetURL(), widevine_fsid, "bar1");
storage::FileSystemURL widevine_file2 =
- CreateFile(kOrigin2, widevine_fsid, "bar2");
+ CreateFile(kOrigin2.GetURL(), widevine_fsid, "bar2");
SetFileTimestamp(widevine_file1, now);
SetFileTimestamp(widevine_file2, sixty_days_ago);
}
@@ -357,7 +377,7 @@ class RemovePluginPrivateDataTester {
void DeleteClearKeyTestData() { DeleteFile(clearkey_file_); }
// Returns true, if the given origin exists in a PluginPrivateFileSystem.
- bool DataExistsForOrigin(const GURL& origin) {
+ bool DataExistsForOrigin(const url::Origin& origin) {
AwaitCompletionHelper await_completion;
bool data_exists_for_origin = false;
filesystem_context_->default_file_task_runner()->PostTask(
@@ -505,7 +525,7 @@ class RemovePluginPrivateDataTester {
// If |origin| exists in the PluginPrivateFileSystem, set
// |data_exists_for_origin| to true, false otherwise.
void CheckIfDataExistsForOriginOnFileTaskRunner(
- const GURL& origin,
+ const url::Origin& origin,
bool* data_exists_for_origin,
AwaitCompletionHelper* await_completion) {
storage::FileSystemBackend* backend =
@@ -517,13 +537,14 @@ class RemovePluginPrivateDataTester {
std::set<GURL> origins;
quota_util->GetOriginsForTypeOnFileTaskRunner(
storage::kFileSystemTypePluginPrivate, &origins);
- *data_exists_for_origin = origins.find(origin) != origins.end();
+ *data_exists_for_origin = origins.find(origin.GetURL()) != origins.end();
// AwaitCompletionHelper and MessageLoop don't work on a
// SequencedTaskRunner, so post a task on the IO thread.
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AwaitCompletionHelper::Notify,
- base::Unretained(await_completion)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&AwaitCompletionHelper::Notify,
+ base::Unretained(await_completion)));
}
// We don't own this pointer.
@@ -693,7 +714,8 @@ class StoragePartitionImplTest : public testing::Test {
if (!quota_manager_.get()) {
quota_manager_ = new MockQuotaManager(
browser_context_->IsOffTheRecord(), browser_context_->GetPath(),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO).get(),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})
+ .get(),
browser_context_->GetSpecialStoragePolicy());
}
return quota_manager_.get();
@@ -795,7 +817,7 @@ TEST_F(StoragePartitionImplTest, QuotaClientMaskGeneration) {
void PopulateTestQuotaManagedPersistentData(MockQuotaManager* manager) {
manager->AddOrigin(kOrigin2, kPersistent, kClientFile, base::Time());
manager->AddOrigin(kOrigin3, kPersistent, kClientFile,
- base::Time::Now() - base::TimeDelta::FromDays(1));
+ base::Time::Now() - base::TimeDelta::FromDays(1));
EXPECT_FALSE(manager->OriginHasData(kOrigin1, kPersistent, kClientFile));
EXPECT_TRUE(manager->OriginHasData(kOrigin2, kPersistent, kClientFile));
@@ -805,7 +827,7 @@ void PopulateTestQuotaManagedPersistentData(MockQuotaManager* manager) {
void PopulateTestQuotaManagedTemporaryData(MockQuotaManager* manager) {
manager->AddOrigin(kOrigin1, kTemporary, kClientFile, base::Time::Now());
manager->AddOrigin(kOrigin3, kTemporary, kClientFile,
- base::Time::Now() - base::TimeDelta::FromDays(1));
+ base::Time::Now() - base::TimeDelta::FromDays(1));
EXPECT_TRUE(manager->OriginHasData(kOrigin1, kTemporary, kClientFile));
EXPECT_FALSE(manager->OriginHasData(kOrigin2, kTemporary, kClientFile));
@@ -839,18 +861,18 @@ TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForeverBoth) {
FROM_HERE, base::BindOnce(&ClearQuotaData, partition, &run_loop));
run_loop.Run();
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kPersistent,
- kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kPersistent, kClientFile));
}
TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForeverOnlyTemporary) {
@@ -866,18 +888,18 @@ TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForeverOnlyTemporary) {
FROM_HERE, base::BindOnce(&ClearQuotaData, partition, &run_loop));
run_loop.Run();
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kPersistent,
- kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kPersistent, kClientFile));
}
TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForeverOnlyPersistent) {
@@ -893,18 +915,18 @@ TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForeverOnlyPersistent) {
FROM_HERE, base::BindOnce(&ClearQuotaData, partition, &run_loop));
run_loop.Run();
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kPersistent,
- kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kPersistent, kClientFile));
}
TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForeverNeither) {
@@ -918,18 +940,18 @@ TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForeverNeither) {
FROM_HERE, base::BindOnce(&ClearQuotaData, partition, &run_loop));
run_loop.Run();
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kPersistent,
- kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kPersistent, kClientFile));
}
TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForeverSpecificOrigin) {
@@ -942,22 +964,22 @@ TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForeverSpecificOrigin) {
base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&ClearQuotaDataForOrigin, partition, kOrigin1,
- base::Time(), &run_loop));
+ FROM_HERE, base::BindOnce(&ClearQuotaDataForOrigin, partition,
+ kOrigin1.GetURL(), base::Time(), &run_loop));
run_loop.Run();
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kTemporary,
- kClientFile));
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin3, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kPersistent,
- kClientFile));
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin2, kPersistent,
- kClientFile));
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin3, kPersistent,
- kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin3, kPersistent, kClientFile));
}
TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForLastHour) {
@@ -976,18 +998,18 @@ TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForLastHour) {
&run_loop));
run_loop.Run();
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kTemporary,
- kClientFile));
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin3, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kPersistent,
- kClientFile));
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin2, kPersistent,
- kClientFile));
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin3, kPersistent,
- kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin3, kPersistent, kClientFile));
}
TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForLastWeek) {
@@ -1005,25 +1027,25 @@ TEST_F(StoragePartitionImplTest, RemoveQuotaManagedDataForLastWeek) {
&run_loop));
run_loop.Run();
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kPersistent,
- kClientFile));
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin2, kPersistent,
- kClientFile));
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin3, kPersistent,
- kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin3, kPersistent, kClientFile));
}
TEST_F(StoragePartitionImplTest, RemoveQuotaManagedUnprotectedOrigins) {
// Protect kOrigin1.
scoped_refptr<MockSpecialStoragePolicy> mock_policy =
new MockSpecialStoragePolicy;
- mock_policy->AddProtected(kOrigin1.GetOrigin());
+ mock_policy->AddProtected(kOrigin1.GetURL());
PopulateTestQuotaManagedData(GetMockManager());
@@ -1037,29 +1059,29 @@ TEST_F(StoragePartitionImplTest, RemoveQuotaManagedUnprotectedOrigins) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&ClearQuotaDataWithOriginMatcher, partition, GURL(),
- base::Bind(&DoesOriginMatchForUnprotectedWeb),
+ base::BindRepeating(&DoesOriginMatchForUnprotectedWeb),
base::Time(), &run_loop));
run_loop.Run();
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin1, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kPersistent,
- kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kPersistent, kClientFile));
}
TEST_F(StoragePartitionImplTest, RemoveQuotaManagedProtectedSpecificOrigin) {
// Protect kOrigin1.
scoped_refptr<MockSpecialStoragePolicy> mock_policy =
new MockSpecialStoragePolicy;
- mock_policy->AddProtected(kOrigin1.GetOrigin());
+ mock_policy->AddProtected(kOrigin1.GetURL());
PopulateTestQuotaManagedData(GetMockManager());
@@ -1073,30 +1095,31 @@ TEST_F(StoragePartitionImplTest, RemoveQuotaManagedProtectedSpecificOrigin) {
base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(&ClearQuotaDataWithOriginMatcher, partition, kOrigin1,
- base::Bind(&DoesOriginMatchForUnprotectedWeb),
+ base::BindOnce(&ClearQuotaDataWithOriginMatcher, partition,
+ kOrigin1.GetURL(),
+ base::BindRepeating(&DoesOriginMatchForUnprotectedWeb),
base::Time(), &run_loop));
run_loop.Run();
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin1, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kTemporary,
- kClientFile));
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin3, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kPersistent,
- kClientFile));
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin2, kPersistent,
- kClientFile));
- EXPECT_TRUE(GetMockManager()->OriginHasData(kOrigin3, kPersistent,
- kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
+ EXPECT_TRUE(
+ GetMockManager()->OriginHasData(kOrigin3, kPersistent, kClientFile));
}
TEST_F(StoragePartitionImplTest, RemoveQuotaManagedProtectedOrigins) {
// Protect kOrigin1.
scoped_refptr<MockSpecialStoragePolicy> mock_policy =
new MockSpecialStoragePolicy;
- mock_policy->AddProtected(kOrigin1.GetOrigin());
+ mock_policy->AddProtected(kOrigin1.GetURL());
PopulateTestQuotaManagedData(GetMockManager());
@@ -1109,24 +1132,24 @@ TEST_F(StoragePartitionImplTest, RemoveQuotaManagedProtectedOrigins) {
partition->OverrideSpecialStoragePolicyForTesting(mock_policy.get());
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(
- &ClearQuotaDataWithOriginMatcher, partition, GURL(),
- base::Bind(&DoesOriginMatchForBothProtectedAndUnprotectedWeb),
- base::Time(), &run_loop));
+ base::BindOnce(&ClearQuotaDataWithOriginMatcher, partition, GURL(),
+ base::BindRepeating(
+ &DoesOriginMatchForBothProtectedAndUnprotectedWeb),
+ base::Time(), &run_loop));
run_loop.Run();
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kTemporary,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin1, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin2, kPersistent,
- kClientFile));
- EXPECT_FALSE(GetMockManager()->OriginHasData(kOrigin3, kPersistent,
- kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kTemporary, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin1, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin2, kPersistent, kClientFile));
+ EXPECT_FALSE(
+ GetMockManager()->OriginHasData(kOrigin3, kPersistent, kClientFile));
}
TEST_F(StoragePartitionImplTest, RemoveQuotaManagedIgnoreDevTools) {
@@ -1138,16 +1161,17 @@ TEST_F(StoragePartitionImplTest, RemoveQuotaManagedIgnoreDevTools) {
partition->OverrideQuotaManagerForTesting(
GetMockManager());
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&ClearQuotaDataWithOriginMatcher, partition,
- GURL(), base::Bind(&DoesOriginMatchUnprotected),
- base::Time(), &run_loop));
+ FROM_HERE,
+ base::BindOnce(&ClearQuotaDataWithOriginMatcher, partition, GURL(),
+ base::BindRepeating(&DoesOriginMatchUnprotected),
+ base::Time(), &run_loop));
run_loop.Run();
// Check that devtools data isn't removed.
EXPECT_TRUE(GetMockManager()->OriginHasData(kOriginDevTools, kTemporary,
- kClientFile));
+ kClientFile));
EXPECT_TRUE(GetMockManager()->OriginHasData(kOriginDevTools, kPersistent,
- kClientFile));
+ kClientFile));
}
TEST_F(StoragePartitionImplTest, RemoveCookieForever) {
@@ -1211,7 +1235,7 @@ TEST_F(StoragePartitionImplTest, RemoveUnprotectedLocalStorageForever) {
// Protect kOrigin1.
scoped_refptr<MockSpecialStoragePolicy> mock_policy =
new MockSpecialStoragePolicy;
- mock_policy->AddProtected(kOrigin1.GetOrigin());
+ mock_policy->AddProtected(kOrigin1.GetURL());
RemoveLocalStorageTester tester(browser_context());
@@ -1227,10 +1251,10 @@ TEST_F(StoragePartitionImplTest, RemoveUnprotectedLocalStorageForever) {
base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(&ClearStuff,
- StoragePartitionImpl::REMOVE_DATA_MASK_LOCAL_STORAGE,
- partition, base::Time(), base::Time::Max(),
- base::Bind(&DoesOriginMatchForUnprotectedWeb), &run_loop));
+ base::BindOnce(
+ &ClearStuff, StoragePartitionImpl::REMOVE_DATA_MASK_LOCAL_STORAGE,
+ partition, base::Time(), base::Time::Max(),
+ base::BindRepeating(&DoesOriginMatchForUnprotectedWeb), &run_loop));
run_loop.Run();
// ClearData only guarantees that tasks to delete data are scheduled when its
// callback is invoked. It doesn't guarantee data has actually been cleared.
@@ -1246,7 +1270,7 @@ TEST_F(StoragePartitionImplTest, RemoveProtectedLocalStorageForever) {
// Protect kOrigin1.
scoped_refptr<MockSpecialStoragePolicy> mock_policy =
new MockSpecialStoragePolicy;
- mock_policy->AddProtected(kOrigin1.GetOrigin());
+ mock_policy->AddProtected(kOrigin1.GetURL());
RemoveLocalStorageTester tester(browser_context());
@@ -1262,11 +1286,12 @@ TEST_F(StoragePartitionImplTest, RemoveProtectedLocalStorageForever) {
base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(
- &ClearStuff, StoragePartitionImpl::REMOVE_DATA_MASK_LOCAL_STORAGE,
- partition, base::Time(), base::Time::Max(),
- base::Bind(&DoesOriginMatchForBothProtectedAndUnprotectedWeb),
- &run_loop));
+ base::BindOnce(&ClearStuff,
+ StoragePartitionImpl::REMOVE_DATA_MASK_LOCAL_STORAGE,
+ partition, base::Time(), base::Time::Max(),
+ base::BindRepeating(
+ &DoesOriginMatchForBothProtectedAndUnprotectedWeb),
+ &run_loop));
run_loop.Run();
// ClearData only guarantees that tasks to delete data are scheduled when its
// callback is invoked. It doesn't guarantee data has actually been cleared.
@@ -1295,11 +1320,12 @@ TEST_F(StoragePartitionImplTest, RemoveLocalStorageForLastWeek) {
base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(
- &ClearStuff, StoragePartitionImpl::REMOVE_DATA_MASK_LOCAL_STORAGE,
- partition, a_week_ago, base::Time::Max(),
- base::Bind(&DoesOriginMatchForBothProtectedAndUnprotectedWeb),
- &run_loop));
+ base::BindOnce(&ClearStuff,
+ StoragePartitionImpl::REMOVE_DATA_MASK_LOCAL_STORAGE,
+ partition, a_week_ago, base::Time::Max(),
+ base::BindRepeating(
+ &DoesOriginMatchForBothProtectedAndUnprotectedWeb),
+ &run_loop));
run_loop.Run();
// ClearData only guarantees that tasks to delete data are scheduled when its
// callback is invoked. It doesn't guarantee data has actually been cleared.
@@ -1313,29 +1339,83 @@ TEST_F(StoragePartitionImplTest, RemoveLocalStorageForLastWeek) {
}
TEST_F(StoragePartitionImplTest, ClearCodeCache) {
- // Run this test only when the IsolatedCodeCache feature is enabled
- if (!base::FeatureList::IsEnabled(features::kIsolatedCodeCache))
- return;
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(net::features::kIsolatedCodeCache);
+ ASSERT_TRUE(base::FeatureList::IsEnabled(net::features::kIsolatedCodeCache));
StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
BrowserContext::GetDefaultStoragePartition(browser_context()));
// Ensure code cache is initialized.
base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(partition->GetGeneratedCodeCacheContext() != nullptr);
RemoveCodeCacheTester tester(partition->GetGeneratedCodeCacheContext());
- url::Origin origin = url::Origin::Create(kOrigin1);
+ url::Origin origin = kOrigin1;
std::string data("SomeData");
- tester.AddEntry(kResourceURL, origin, data);
- EXPECT_TRUE(tester.ContainsEntry(kResourceURL, origin));
+ std::string data2("SomeData.wasm");
+ tester.AddEntry(RemoveCodeCacheTester::kJs, kResourceURL, origin, data);
+ tester.AddEntry(RemoveCodeCacheTester::kWebAssembly, kResourceURL, origin,
+ data2);
+ EXPECT_TRUE(
+ tester.ContainsEntry(RemoveCodeCacheTester::kJs, kResourceURL, origin));
EXPECT_EQ(tester.received_data(), data);
+ EXPECT_TRUE(tester.ContainsEntry(RemoveCodeCacheTester::kWebAssembly,
+ kResourceURL, origin));
+ EXPECT_EQ(tester.received_data(), data2);
base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&ClearCodeCache, partition, &run_loop));
run_loop.Run();
- EXPECT_FALSE(tester.ContainsEntry(kResourceURL, origin));
+ EXPECT_FALSE(
+ tester.ContainsEntry(RemoveCodeCacheTester::kJs, kResourceURL, origin));
+ EXPECT_FALSE(tester.ContainsEntry(RemoveCodeCacheTester::kWebAssembly,
+ kResourceURL, origin));
+
+ // Make sure there isn't a second invalid callback sitting in the queue.
+ // (this used to be a bug).
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(StoragePartitionImplTest, ClearCodeCacheNoIsolatedCodeCache) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndDisableFeature(net::features::kIsolatedCodeCache);
+ ASSERT_FALSE(base::FeatureList::IsEnabled(net::features::kIsolatedCodeCache));
+
+ StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+ BrowserContext::GetDefaultStoragePartition(browser_context()));
+ base::RunLoop().RunUntilIdle();
+ // We should not create GeneratedCodeCacheContext when IsolatedCodeCache
+ // is disabled.
+ EXPECT_EQ(nullptr, partition->GetGeneratedCodeCacheContext());
+
+ base::RunLoop run_loop;
+ // This shouldn't crash.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(&ClearCodeCache, partition, &run_loop));
+ run_loop.Run();
+}
+
+TEST_F(StoragePartitionImplTest, ClearCodeCacheIncognito) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(net::features::kIsolatedCodeCache);
+ ASSERT_TRUE(base::FeatureList::IsEnabled(net::features::kIsolatedCodeCache));
+
+ browser_context()->set_is_off_the_record(true);
+
+ StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+ BrowserContext::GetDefaultStoragePartition(browser_context()));
+ base::RunLoop().RunUntilIdle();
+ // We should not create GeneratedCodeCacheContext for off the record mode.
+ EXPECT_EQ(nullptr, partition->GetGeneratedCodeCacheContext());
+
+ base::RunLoop run_loop;
+ // This shouldn't crash.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(&ClearCodeCache, partition, &run_loop));
+ run_loop.Run();
}
#if BUILDFLAG(ENABLE_PLUGINS)
@@ -1392,8 +1472,9 @@ TEST_F(StoragePartitionImplTest, RemovePluginPrivateDataForOrigin) {
base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&ClearPluginPrivateData, partition, kOrigin1,
- base::Time(), base::Time::Max(), &run_loop));
+ FROM_HERE,
+ base::BindOnce(&ClearPluginPrivateData, partition, kOrigin1.GetURL(),
+ base::Time(), base::Time::Max(), &run_loop));
run_loop.Run();
// Only Origin1 should be deleted.
diff --git a/chromium/content/browser/streams/stream.cc b/chromium/content/browser/streams/stream.cc
index 8ce10de0d94..a0dcc1c87de 100644
--- a/chromium/content/browser/streams/stream.cc
+++ b/chromium/content/browser/streams/stream.cc
@@ -118,7 +118,8 @@ void Stream::AddData(const char* data, size_t size) {
if (!writer_.get())
return;
- scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(size));
+ scoped_refptr<net::IOBuffer> io_buffer =
+ base::MakeRefCounted<net::IOBuffer>(size);
memcpy(io_buffer->data(), data, size);
AddData(io_buffer, size);
}
diff --git a/chromium/content/browser/streams/stream_context.cc b/chromium/content/browser/streams/stream_context.cc
index 0ab6a2d6f96..9ed67fe1550 100644
--- a/chromium/content/browser/streams/stream_context.cc
+++ b/chromium/content/browser/streams/stream_context.cc
@@ -5,8 +5,10 @@
#include "content/browser/streams/stream_context.h"
#include "base/bind.h"
+#include "base/task/post_task.h"
#include "content/browser/streams/stream_registry.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
using base::UserDataAdapter;
@@ -29,8 +31,8 @@ StreamContext* StreamContext::GetFor(BrowserContext* context) {
std::make_unique<UserDataAdapter<StreamContext>>(stream.get()));
// Check first to avoid memory leak in unittests.
if (BrowserThread::IsThreadInitialized(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&StreamContext::InitializeOnIOThread, stream));
}
}
diff --git a/chromium/content/browser/streams/stream_registry.cc b/chromium/content/browser/streams/stream_registry.cc
index ca6baee32f1..a905f484891 100644
--- a/chromium/content/browser/streams/stream_registry.cc
+++ b/chromium/content/browser/streams/stream_registry.cc
@@ -63,7 +63,7 @@ bool StreamRegistry::CloneStream(const GURL& url, const GURL& src_url) {
void StreamRegistry::UnregisterStream(const GURL& url) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- StreamMap::iterator iter = streams_.find(url);
+ auto iter = streams_.find(url);
if (iter == streams_.end())
return;
@@ -83,7 +83,7 @@ bool StreamRegistry::UpdateMemoryUsage(const GURL& url,
size_t increase) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- StreamMap::iterator iter = streams_.find(url);
+ auto iter = streams_.find(url);
// A Stream must be registered with its parent registry to get memory.
if (iter == streams_.end())
return false;
diff --git a/chromium/content/browser/streams/stream_unittest.cc b/chromium/content/browser/streams/stream_unittest.cc
index b6a6be36ad2..e25694479e0 100644
--- a/chromium/content/browser/streams/stream_unittest.cc
+++ b/chromium/content/browser/streams/stream_unittest.cc
@@ -4,8 +4,8 @@
#include <stddef.h>
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "content/browser/streams/stream.h"
#include "content/browser/streams/stream_read_observer.h"
@@ -26,7 +26,8 @@ class StreamTest : public testing::Test {
// Create a new IO buffer of the given |buffer_size| and fill it with random
// data.
scoped_refptr<net::IOBuffer> NewIOBuffer(size_t buffer_size) {
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(buffer_size));
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(buffer_size);
char *bufferp = buffer->data();
for (size_t i = 0; i < buffer_size; i++)
bufferp[i] = (i + producing_seed_key_) % (1 << sizeof(char));
@@ -35,7 +36,7 @@ class StreamTest : public testing::Test {
}
protected:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
std::unique_ptr<StreamRegistry> registry_;
private:
@@ -44,12 +45,13 @@ class StreamTest : public testing::Test {
class TestStreamReader : public StreamReadObserver {
public:
- TestStreamReader() : buffer_(new net::GrowableIOBuffer()) {}
+ TestStreamReader() : buffer_(base::MakeRefCounted<net::GrowableIOBuffer>()) {}
~TestStreamReader() override {}
void Read(Stream* stream) {
const size_t kBufferSize = 32768;
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
+ scoped_refptr<net::IOBuffer> buffer =
+ base::MakeRefCounted<net::IOBuffer>(kBufferSize);
int bytes_read = 0;
while (true) {
diff --git a/chromium/content/browser/streams/stream_url_request_job_unittest.cc b/chromium/content/browser/streams/stream_url_request_job_unittest.cc
index 82fc52257da..6d3cd75dd3f 100644
--- a/chromium/content/browser/streams/stream_url_request_job_unittest.cc
+++ b/chromium/content/browser/streams/stream_url_request_job_unittest.cc
@@ -4,8 +4,8 @@
#include "content/browser/streams/stream_url_request_job.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "content/browser/streams/stream.h"
#include "content/browser/streams/stream_metadata.h"
@@ -55,7 +55,9 @@ class StreamURLRequestJobTest : public testing::Test {
StreamRegistry* registry_;
};
- StreamURLRequestJobTest() {}
+ StreamURLRequestJobTest()
+ : task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO) {}
void SetUp() override {
registry_.reset(new StreamRegistry());
@@ -107,7 +109,7 @@ class StreamURLRequestJobTest : public testing::Test {
}
protected:
- base::MessageLoopForIO message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
std::unique_ptr<StreamRegistry> registry_;
net::URLRequestContext url_request_context_;
@@ -120,8 +122,8 @@ TEST_F(StreamURLRequestJobTest, TestGetSimpleDataRequest) {
new Stream(registry_.get(), nullptr, kStreamURL));
stream->OnResponseStarted(*BuildResponseInfo());
- scoped_refptr<net::StringIOBuffer> buffer(
- new net::StringIOBuffer(kTestData1));
+ scoped_refptr<net::StringIOBuffer> buffer =
+ base::MakeRefCounted<net::StringIOBuffer>(kTestData1);
stream->AddData(buffer, buffer->size());
stream->Finalize(net::OK);
@@ -139,8 +141,8 @@ TEST_F(StreamURLRequestJobTest, TestGetLargeStreamRequest) {
for (int i = 0; i < kBufferSize * 5; ++i)
large_data.append(1, static_cast<char>(i % 256));
- scoped_refptr<net::StringIOBuffer> buffer(
- new net::StringIOBuffer(large_data));
+ scoped_refptr<net::StringIOBuffer> buffer =
+ base::MakeRefCounted<net::StringIOBuffer>(large_data);
stream->AddData(buffer, buffer->size());
stream->Finalize(net::OK);
@@ -166,8 +168,8 @@ TEST_F(StreamURLRequestJobTest, TestRangeDataRequest) {
new Stream(registry_.get(), nullptr, kStreamURL));
stream->OnResponseStarted(*BuildResponseInfo());
- scoped_refptr<net::StringIOBuffer> buffer(
- new net::StringIOBuffer(kTestData2));
+ scoped_refptr<net::StringIOBuffer> buffer =
+ base::MakeRefCounted<net::StringIOBuffer>(kTestData2);
stream->AddData(buffer, buffer->size());
stream->Finalize(net::OK);
@@ -183,8 +185,8 @@ TEST_F(StreamURLRequestJobTest, TestInvalidRangeDataRequest) {
scoped_refptr<Stream> stream(
new Stream(registry_.get(), nullptr, kStreamURL));
stream->OnResponseStarted(*BuildResponseInfo());
- scoped_refptr<net::StringIOBuffer> buffer(
- new net::StringIOBuffer(kTestData2));
+ scoped_refptr<net::StringIOBuffer> buffer =
+ base::MakeRefCounted<net::StringIOBuffer>(kTestData2);
stream->AddData(buffer, buffer->size());
stream->Finalize(net::OK);
diff --git a/chromium/content/browser/top_document_isolation_browsertest.cc b/chromium/content/browser/top_document_isolation_browsertest.cc
deleted file mode 100644
index 6f6e7bef494..00000000000
--- a/chromium/content/browser/top_document_isolation_browsertest.cc
+++ /dev/null
@@ -1,616 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string>
-
-#include "base/command_line.h"
-#include "base/test/scoped_feature_list.h"
-#include "content/browser/frame_host/frame_tree_node.h"
-#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/public/common/content_features.h"
-#include "content/public/test/browser_test_utils.h"
-#include "content/public/test/content_browser_test.h"
-#include "content/public/test/content_browser_test_utils.h"
-#include "content/public/test/test_frame_navigation_observer.h"
-#include "content/public/test/test_navigation_observer.h"
-#include "content/shell/browser/shell.h"
-#include "content/test/content_browser_test_utils_internal.h"
-#include "net/dns/mock_host_resolver.h"
-#include "net/test/embedded_test_server/embedded_test_server.h"
-#include "url/gurl.h"
-
-namespace content {
-
-class TopDocumentIsolationTest : public ContentBrowserTest {
- public:
- TopDocumentIsolationTest() {}
-
- protected:
- std::string DepictFrameTree(FrameTreeNode* node) {
- return visualizer_.DepictFrameTree(node);
- }
-
- void SetUp() override {
- scoped_feature_list_.InitAndEnableFeature(features::kTopDocumentIsolation);
- ContentBrowserTest::SetUp();
- }
-
- void SetUpOnMainThread() override {
- host_resolver()->AddRule("*", "127.0.0.1");
- SetupCrossSiteRedirector(embedded_test_server());
- ASSERT_TRUE(embedded_test_server()->Start());
- }
-
- FrameTreeNode* root() {
- return static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()
- ->root();
- }
-
- void GoBack() {
- TestNavigationObserver back_load_observer(shell()->web_contents());
- shell()->web_contents()->GetController().GoBack();
- back_load_observer.Wait();
- }
-
- Shell* OpenPopup(FrameTreeNode* opener, const std::string& url) {
- GURL gurl =
- opener->current_frame_host()->GetLastCommittedURL().Resolve(url);
- return content::OpenPopup(opener, gurl, "_blank");
- }
-
- void RendererInitiatedNavigateToURL(FrameTreeNode* node, const GURL& url) {
- TestFrameNavigationObserver nav_observer(node);
- ASSERT_TRUE(
- ExecuteScript(node, "window.location.href='" + url.spec() + "'"));
- nav_observer.Wait();
- }
-
- private:
- FrameTreeVisualizer visualizer_;
- base::test::ScopedFeatureList scoped_feature_list_;
-
- DISALLOW_COPY_AND_ASSIGN(TopDocumentIsolationTest);
-};
-
-IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, SameSiteDeeplyNested) {
- if (content::AreAllSitesIsolatedForTesting())
- return; // Top Document Isolation is disabled in this mode.
-
- GURL main_url(embedded_test_server()->GetURL(
- "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))"));
-
- NavigateToURL(shell(), main_url);
-
- EXPECT_EQ(
- " Site A\n"
- " |--Site A\n"
- " +--Site A\n"
- " |--Site A\n"
- " +--Site A\n"
- " +--Site A\n"
- "Where A = http://a.com/",
- DepictFrameTree(root()));
-}
-
-IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, CrossSiteDeeplyNested) {
- if (content::AreAllSitesIsolatedForTesting())
- return; // Top Document Isolation is disabled in this mode.
-
- GURL main_url(embedded_test_server()->GetURL(
- "a.com", "/cross_site_iframe_factory.html?a(b(c(d(b))))"));
-
- NavigateToURL(shell(), main_url);
-
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " +--Site B ------- proxies for A\n"
- " +--Site B -- proxies for A\n"
- " +--Site B -- proxies for A\n"
- " +--Site B -- proxies for A\n"
- "Where A = http://a.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-}
-
-IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, ReturnToTopSite) {
- if (content::AreAllSitesIsolatedForTesting())
- return; // Top Document Isolation is disabled in this mode.
-
- GURL main_url(embedded_test_server()->GetURL(
- "a.com", "/cross_site_iframe_factory.html?a(b(a(c)))"));
-
- NavigateToURL(shell(), main_url);
-
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " +--Site B ------- proxies for A\n"
- " +--Site A -- proxies for B\n"
- " +--Site B -- proxies for A\n"
- "Where A = http://a.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-}
-
-IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, NavigateSubframeToTopSite) {
- if (content::AreAllSitesIsolatedForTesting())
- return; // Top Document Isolation is disabled in this mode.
-
- GURL main_url(embedded_test_server()->GetURL(
- "a.com", "/cross_site_iframe_factory.html?a(b(c(d)))"));
-
- NavigateToURL(shell(), main_url);
-
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " +--Site B ------- proxies for A\n"
- " +--Site B -- proxies for A\n"
- " +--Site B -- proxies for A\n"
- "Where A = http://a.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-
- GURL ada_url(embedded_test_server()->GetURL(
- "a.com", "/cross_site_iframe_factory.html?a(d(a))"));
- RendererInitiatedNavigateToURL(root()->child_at(0)->child_at(0), ada_url);
-
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " +--Site B ------- proxies for A\n"
- " +--Site A -- proxies for B\n"
- " +--Site B -- proxies for A\n"
- " +--Site A -- proxies for B\n"
- "Where A = http://a.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-}
-
-IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, NavigateToSubframeSite) {
- if (content::AreAllSitesIsolatedForTesting())
- return; // Top Document Isolation is disabled in this mode.
-
- GURL ab_url(embedded_test_server()->GetURL(
- "a.com", "/cross_site_iframe_factory.html?a(b)"));
- GURL ba_url(embedded_test_server()->GetURL(
- "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
-
- NavigateToURL(shell(), ab_url);
-
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " +--Site B ------- proxies for A\n"
- "Where A = http://a.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-
- NavigateToURL(shell(), ba_url);
-
- EXPECT_EQ(
- " Site C ------------ proxies for D\n"
- " |--Site D ------- proxies for C\n"
- " +--Site D ------- proxies for C\n"
- "Where C = http://b.com/\n"
- " D = default subframe process",
- DepictFrameTree(root()));
-}
-
-IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest,
- NavigateToSubframeSiteWithPopup) {
- if (content::AreAllSitesIsolatedForTesting())
- return; // Top Document Isolation is disabled in this mode.
-
- // A(B) -> B(A), but while a separate B(A) popup exists.
- GURL ab_url(embedded_test_server()->GetURL(
- "a.com", "/cross_site_iframe_factory.html?a(b)"));
-
- NavigateToURL(shell(), ab_url);
-
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " +--Site B ------- proxies for A\n"
- "Where A = http://a.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-
- Shell* popup =
- OpenPopup(root()->child_at(0), "/cross_site_iframe_factory.html?b(a)");
- FrameTreeNode* popup_root =
- static_cast<WebContentsImpl*>(popup->web_contents())
- ->GetFrameTree()
- ->root();
-
- // This popup's main frame must stay in the default subframe siteinstance,
- // since its opener (the b.com subframe) may synchronously script it. Note
- // that the popup's subframe is same-site with window.top.opener.top, the
- // a.com main frame of the tab. But --top-document-isolation does not
- // currently place the popup subframe in the a.com process in this case.
- EXPECT_EQ(
- " Site B\n"
- " +--Site B\n"
- "Where B = default subframe process",
- DepictFrameTree(popup_root));
-
- GURL ba_url(embedded_test_server()->GetURL(
- "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
- EXPECT_TRUE(NavigateToURLInSameBrowsingInstance(shell(), ba_url));
-
- // This navigation destroys the popup's opener, so we allow the main frame to
- // commit in a top level process for b.com, in spite of the b.com popup in the
- // default subframe process.
- EXPECT_EQ(
- " Site C ------------ proxies for B\n"
- " |--Site B ------- proxies for C\n"
- " +--Site B ------- proxies for C\n"
- "Where B = default subframe process\n"
- " C = http://b.com/",
- DepictFrameTree(root()));
- EXPECT_EQ(
- " Site B\n"
- " +--Site B\n"
- "Where B = default subframe process",
- DepictFrameTree(popup_root));
-
- // Navigate the popup to a new site.
- GURL c_url(embedded_test_server()->GetURL(
- "c.com", "/cross_site_iframe_factory.html?c(c, c, c, c)"));
- EXPECT_TRUE(NavigateToURLInSameBrowsingInstance(popup, c_url));
- EXPECT_EQ(
- " Site D ------------ proxies for B\n"
- " |--Site D ------- proxies for B\n"
- " |--Site D ------- proxies for B\n"
- " |--Site D ------- proxies for B\n"
- " +--Site D ------- proxies for B\n"
- "Where B = default subframe process\n"
- " D = http://c.com/",
- DepictFrameTree(popup_root));
- EXPECT_TRUE(NavigateToURLInSameBrowsingInstance(shell(), c_url));
- EXPECT_EQ(
- " Site D\n"
- " |--Site D\n"
- " |--Site D\n"
- " |--Site D\n"
- " +--Site D\n"
- "Where D = http://c.com/",
- DepictFrameTree(popup_root));
- EXPECT_EQ(
- " Site D\n"
- " |--Site D\n"
- " |--Site D\n"
- " |--Site D\n"
- " +--Site D\n"
- "Where D = http://c.com/",
- DepictFrameTree(root()));
-}
-
-IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest,
- NavigateToSubframeSiteWithPopup2) {
- if (content::AreAllSitesIsolatedForTesting())
- return; // Top Document Isolation is disabled in this mode.
-
- // A(B, C) -> C(A, B), but while a separate C(A) popup exists.
- //
- // This test is constructed so that c.com is the second site to commit in the
- // default subframe SiteInstance, so the default subframe SiteInstance does
- // not have a "c.com" as the value of GetSiteURL().
- GURL abb_url(embedded_test_server()->GetURL(
- "a.com", "/cross_site_iframe_factory.html?a(b, b)"));
-
- NavigateToURL(shell(), abb_url);
-
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " |--Site B ------- proxies for A\n"
- " +--Site B ------- proxies for A\n"
- "Where A = http://a.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-
- // A(B, B) -> A(B, C)
- GURL c_url(embedded_test_server()->GetURL(
- "c.com", "/cross_site_iframe_factory.html?c"));
- NavigateFrameToURL(root()->child_at(1), c_url);
-
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " |--Site B ------- proxies for A\n"
- " +--Site B ------- proxies for A\n"
- "Where A = http://a.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-
- // This test exercises what happens when the SiteURL of the default subframe
- // siteinstance doesn't match the subframe site.
- EXPECT_NE("c.com", root()
- ->child_at(1)
- ->current_frame_host()
- ->GetSiteInstance()
- ->GetSiteURL()
- .host());
-
- // Subframe C creates C(A) popup.
- Shell* popup =
- OpenPopup(root()->child_at(1), "/cross_site_iframe_factory.html?c(a)");
-
- FrameTreeNode* popup_root =
- static_cast<WebContentsImpl*>(popup->web_contents())
- ->GetFrameTree()
- ->root();
-
- // The popup must stay with its opener, in the default subframe process.
- EXPECT_EQ(
- " Site B\n"
- " +--Site B\n"
- "Where B = default subframe process",
- DepictFrameTree(popup_root));
-
- GURL cab_url(embedded_test_server()->GetURL(
- "c.com", "/cross_site_iframe_factory.html?c(a, b)"));
- {
- RenderFrameDeletedObserver deleted_observer(root()->current_frame_host());
- EXPECT_TRUE(NavigateToURLInSameBrowsingInstance(shell(), cab_url));
- deleted_observer.WaitUntilDeleted();
- }
-
- // This c.com navigation currently breaks out of the default subframe process,
- // even though that process houses a c.com pop-up.
- EXPECT_EQ(
- " Site C ------------ proxies for B\n"
- " |--Site B ------- proxies for C\n"
- " +--Site B ------- proxies for C\n"
- "Where B = default subframe process\n"
- " C = http://c.com/",
- DepictFrameTree(root()));
-
- // c.com popup should remain where it was, in the subframe process.
- EXPECT_EQ(
- " Site B\n"
- " +--Site B\n"
- "Where B = default subframe process",
- DepictFrameTree(popup_root));
- EXPECT_EQ(nullptr, popup_root->opener());
-
- // If we navigate the popup to a new site, it ought to transfer processes.
- GURL d_url(embedded_test_server()->GetURL(
- "d.com", "/cross_site_iframe_factory.html?d"));
- {
- RenderFrameDeletedObserver deleted_observer(
- popup_root->current_frame_host());
- EXPECT_TRUE(NavigateToURLInSameBrowsingInstance(popup, d_url));
- deleted_observer.WaitUntilDeleted();
- }
- EXPECT_EQ(
- " Site D ------------ proxies for B\n"
- "Where B = default subframe process\n"
- " D = http://d.com/",
- DepictFrameTree(popup_root));
- {
- RenderFrameDeletedObserver deleted_observer(root()->current_frame_host());
- EXPECT_TRUE(NavigateToURLInSameBrowsingInstance(shell(), d_url));
- deleted_observer.WaitUntilDeleted();
- }
- EXPECT_EQ(
- " Site D\n"
- "Where D = http://d.com/",
- DepictFrameTree(popup_root));
- EXPECT_EQ(
- " Site D\n"
- "Where D = http://d.com/",
- DepictFrameTree(root()));
-}
-
-IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, FramesForSitesInHistory) {
- if (content::AreAllSitesIsolatedForTesting())
- return; // Top Document Isolation is disabled in this mode.
-
- // First, do a series of navigations.
- GURL a_url = embedded_test_server()->GetURL(
- "a.com", "/cross_site_iframe_factory.html?a");
- GURL b_url = embedded_test_server()->GetURL(
- "b.com", "/cross_site_iframe_factory.html?b");
- GURL c_url = embedded_test_server()->GetURL(
- "c.com", "/cross_site_iframe_factory.html?c");
-
- // Browser-initiated navigation to a.com.
- NavigateToURL(shell(), a_url);
- EXPECT_EQ(
- " Site A\n"
- "Where A = http://a.com/",
- DepictFrameTree(root()));
-
- // Browser-initiated navigation to b.com.
- {
- // For any cross-process navigations, we must wait for the old RenderFrame
- // to be deleted before calling DepictFrameTree, or else there's a chance
- // the old SiteInstance could be listed while pending deletion.
- RenderFrameDeletedObserver deleted_observer(root()->current_frame_host());
- NavigateToURL(shell(), b_url);
- deleted_observer.WaitUntilDeleted();
- }
- EXPECT_EQ(
- " Site B\n"
- "Where B = http://b.com/",
- DepictFrameTree(root()));
-
- // Renderer-initiated navigation back to a.com. This shouldn't swap processes.
- RendererInitiatedNavigateToURL(root(), a_url);
- EXPECT_EQ(
- " Site B\n"
- "Where B = http://b.com/",
- DepictFrameTree(root()));
-
- // Browser-initiated navigation to c.com.
- {
- RenderFrameDeletedObserver deleted_observer(root()->current_frame_host());
- NavigateToURL(shell(), c_url);
- deleted_observer.WaitUntilDeleted();
- }
- EXPECT_EQ(
- " Site C\n"
- "Where C = http://c.com/",
- DepictFrameTree(root()));
-
- // Now, navigate to a fourth site with iframes to the sites in the history.
- {
- RenderFrameDeletedObserver deleted_observer(root()->current_frame_host());
- NavigateToURL(shell(),
- embedded_test_server()->GetURL(
- "d.com", "/cross_site_iframe_factory.html?d(a,b,c)"));
- deleted_observer.WaitUntilDeleted();
- }
-
- EXPECT_EQ(
- " Site D ------------ proxies for E\n"
- " |--Site E ------- proxies for D\n"
- " |--Site E ------- proxies for D\n"
- " +--Site E ------- proxies for D\n"
- "Where D = http://d.com/\n"
- " E = default subframe process",
- DepictFrameTree(root()));
-
- // Now try going back.
- {
- RenderFrameDeletedObserver deleted_observer(root()->current_frame_host());
- GoBack();
- deleted_observer.WaitUntilDeleted();
- }
- EXPECT_EQ(
- " Site C\n"
- "Where C = http://c.com/",
- DepictFrameTree(root()));
- {
- RenderFrameDeletedObserver deleted_observer(root()->current_frame_host());
- GoBack();
- deleted_observer.WaitUntilDeleted();
- }
- EXPECT_EQ(
- " Site B\n"
- "Where B = http://b.com/",
- DepictFrameTree(root()));
- GoBack();
- EXPECT_EQ(
- " Site B\n"
- "Where B = http://b.com/",
- DepictFrameTree(root()));
- {
- RenderFrameDeletedObserver deleted_observer(root()->current_frame_host());
- GoBack();
- deleted_observer.WaitUntilDeleted();
- }
- EXPECT_EQ(
- " Site A\n"
- "Where A = http://a.com/",
- DepictFrameTree(root()));
-}
-
-IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, CrossSiteAtLevelTwo) {
- if (content::AreAllSitesIsolatedForTesting())
- return; // Top Document Isolation is disabled in this mode.
-
- GURL main_url(embedded_test_server()->GetURL(
- "a.com", "/cross_site_iframe_factory.html?a(a(b, a))"));
-
- NavigateToURL(shell(), main_url);
-
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " +--Site A ------- proxies for B\n"
- " |--Site B -- proxies for A\n"
- " +--Site A -- proxies for B\n"
- "Where A = http://a.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-
- GURL c_url(embedded_test_server()->GetURL(
- "c.com", "/cross_site_iframe_factory.html?c"));
- NavigateFrameToURL(root()->child_at(0)->child_at(1), c_url);
-
- // This navigation should complete in the default subframe siteinstance.
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " +--Site A ------- proxies for B\n"
- " |--Site B -- proxies for A\n"
- " +--Site B -- proxies for A\n"
- "Where A = http://a.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-}
-
-IN_PROC_BROWSER_TEST_F(TopDocumentIsolationTest, PopupAndRedirection) {
- if (content::AreAllSitesIsolatedForTesting())
- return; // Top Document Isolation is disabled in this mode.
-
- GURL main_url(embedded_test_server()->GetURL(
- "page.com", "/cross_site_iframe_factory.html?page(adnetwork)"));
-
- // User opens page on page.com which contains a subframe from adnetwork.com.
- NavigateToURL(shell(), main_url);
-
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " +--Site B ------- proxies for A\n"
- "Where A = http://page.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-
- GURL ad_url(embedded_test_server()->GetURL(
- "ad.com", "/cross_site_iframe_factory.html?ad"));
-
- // adnetwork.com retrieves an ad from advertiser (ad.com) and redirects the
- // subframe to ad.com.
- RendererInitiatedNavigateToURL(root()->child_at(0), ad_url);
-
- // The subframe still uses the default subframe SiteInstance after navigation.
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " +--Site B ------- proxies for A\n"
- "Where A = http://page.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
-
- // User clicks the ad in the subframe, which opens a popup on the ad
- // network's domain.
- GURL popup_url(embedded_test_server()->GetURL(
- "adnetwork.com", "/cross_site_iframe_factory.html?adnetwork"));
- Shell* popup = OpenPopup(root()->child_at(0), popup_url.spec());
-
- FrameTreeNode* popup_root =
- static_cast<WebContentsImpl*>(popup->web_contents())
- ->GetFrameTree()
- ->root();
-
- // It's ok for the popup to break out of the subframe process because it's
- // currently cross-site from its opener frame.
- EXPECT_EQ(
- " Site C ------------ proxies for B\n"
- "Where B = default subframe process\n"
- " C = http://adnetwork.com/",
- DepictFrameTree(popup_root));
-
- EXPECT_EQ(
- " Site A ------------ proxies for B C\n"
- " +--Site B ------- proxies for A C\n"
- "Where A = http://page.com/\n"
- " B = default subframe process\n"
- " C = http://adnetwork.com/",
- DepictFrameTree(root()));
-
- // The popup redirects itself to the advertiser's website (ad.com).
- RenderFrameDeletedObserver deleted_observer(popup_root->current_frame_host());
- RendererInitiatedNavigateToURL(popup_root, ad_url);
- deleted_observer.WaitUntilDeleted();
-
- // This must join its same-site opener, in the default subframe SiteInstance.
- EXPECT_EQ(
- " Site A ------------ proxies for B\n"
- " +--Site B ------- proxies for A\n"
- "Where A = http://page.com/\n"
- " B = default subframe process",
- DepictFrameTree(root()));
- EXPECT_EQ(
- " Site B\n"
- "Where B = default subframe process",
- DepictFrameTree(popup_root));
-}
-
-} // namespace content
diff --git a/chromium/content/browser/tracing/background_startup_tracing_observer.cc b/chromium/content/browser/tracing/background_startup_tracing_observer.cc
index 307e5e5f44e..da485b3d1a5 100644
--- a/chromium/content/browser/tracing/background_startup_tracing_observer.cc
+++ b/chromium/content/browser/tracing/background_startup_tracing_observer.cc
@@ -4,8 +4,10 @@
#include "content/browser/tracing/background_startup_tracing_observer.h"
+#include "base/task/post_task.h"
#include "components/tracing/common/trace_startup_config.h"
#include "content/browser/tracing/background_tracing_rule.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@@ -63,8 +65,8 @@ void BackgroundStartupTracingObserver::OnScenarioActivated(
const BackgroundTracingRule* startup_rule = FindStartupRuleInConfig(*config);
DCHECK(startup_rule);
// Post task to avoid reentrancy.
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(
&BackgroundTracingManagerImpl::OnRuleTriggered,
base::Unretained(BackgroundTracingManagerImpl::GetInstance()),
diff --git a/chromium/content/browser/tracing/background_tracing_config_unittest.cc b/chromium/content/browser/tracing/background_tracing_config_unittest.cc
index 12de19fa40d..3d2520c42e9 100644
--- a/chromium/content/browser/tracing/background_tracing_config_unittest.cc
+++ b/chromium/content/browser/tracing/background_tracing_config_unittest.cc
@@ -6,7 +6,7 @@
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/values.h"
#include "content/browser/tracing/background_tracing_config_impl.h"
#include "content/browser/tracing/background_tracing_rule.h"
@@ -18,10 +18,11 @@ namespace content {
class BackgroundTracingConfigTest : public testing::Test {
public:
BackgroundTracingConfigTest()
- : ui_thread_(BrowserThread::UI, &message_loop_) {}
+ : ui_thread_(BrowserThread::UI,
+ task_environment_.GetMainThreadTaskRunner()) {}
protected:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
TestBrowserThread ui_thread_;
};
diff --git a/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc b/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
index cea17d06e49..9dd2cb9c00f 100644
--- a/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
+++ b/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
@@ -15,10 +15,12 @@
#include "base/metrics/histogram_macros.h"
#include "base/run_loop.h"
#include "base/strings/pattern.h"
+#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/tracing/background_startup_tracing_observer.h"
#include "content/browser/tracing/background_tracing_manager_impl.h"
#include "content/browser/tracing/background_tracing_rule.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/content_browser_test.h"
@@ -152,10 +154,11 @@ class BackgroundTracingManagerUploadConfigWrapper {
EXPECT_EQ(Z_STREAM_END, result);
last_file_contents_.assign(output_str.data(), bytes_written);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(done_callback), true));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(std::move(done_callback), true));
CHECK(callback_);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(callback_));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ std::move(callback_));
}
void SetUploadCallback(base::OnceClosure callback) {
@@ -583,6 +586,18 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
MAYBE_ToggleBlinkScenarios) {
{
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ ASSERT_TRUE(command_line);
+
+ // Early bailout in the case command line arguments have been explicitly set
+ // for the runner.
+ if (!command_line->GetSwitchValueASCII(switches::kEnableBlinkFeatures)
+ .empty() ||
+ !command_line->GetSwitchValueASCII(switches::kDisableBlinkFeatures)
+ .empty()) {
+ return;
+ }
+
SetupBackgroundTracingManager();
base::RunLoop run_loop;
@@ -616,10 +631,6 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
BackgroundTracingManager::NO_DATA_FILTERING);
EXPECT_TRUE(scenario_activated);
-
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- EXPECT_TRUE(command_line);
-
EXPECT_EQ(command_line->GetSwitchValueASCII(switches::kEnableBlinkFeatures),
"FasterWeb1,FasterWeb2");
EXPECT_EQ(
diff --git a/chromium/content/browser/tracing/background_tracing_manager_impl.cc b/chromium/content/browser/tracing/background_tracing_manager_impl.cc
index 444fb27438d..5f488fcd064 100644
--- a/chromium/content/browser/tracing/background_tracing_manager_impl.cc
+++ b/chromium/content/browser/tracing/background_tracing_manager_impl.cc
@@ -13,6 +13,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
#include "base/single_thread_task_runner.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/values.h"
@@ -22,6 +23,7 @@
#include "content/browser/tracing/background_tracing_rule.h"
#include "content/browser/tracing/trace_message_filter.h"
#include "content/browser/tracing/tracing_controller_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/tracing_delegate.h"
@@ -343,8 +345,8 @@ BackgroundTracingManagerImpl::GetRuleAbleToTriggerTracing(
void BackgroundTracingManagerImpl::OnHistogramTrigger(
const std::string& histogram_name) {
if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&BackgroundTracingManagerImpl::OnHistogramTrigger,
base::Unretained(this), histogram_name));
return;
@@ -363,8 +365,8 @@ void BackgroundTracingManagerImpl::TriggerNamedEvent(
BackgroundTracingManagerImpl::TriggerHandle handle,
StartedFinalizingCallback callback) {
if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&BackgroundTracingManagerImpl::TriggerNamedEvent,
base::Unretained(this), handle, std::move(callback)));
return;
@@ -532,8 +534,8 @@ void BackgroundTracingManagerImpl::OnFinalizeStarted(
void BackgroundTracingManagerImpl::OnFinalizeComplete(bool success) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&BackgroundTracingManagerImpl::OnFinalizeComplete,
base::Unretained(this), success));
return;
@@ -652,7 +654,10 @@ TraceConfig BackgroundTracingManagerImpl::GetConfigForCategoryPreset(
"disabled-by-default-v8.runtime_stats",
record_mode);
case BackgroundTracingConfigImpl::CategoryPreset::BENCHMARK_GPU:
- return TraceConfig("benchmark,toplevel,gpu", record_mode);
+ return TraceConfig(
+ "benchmark,toplevel,gpu,base,mojom,ipc,"
+ "disabled-by-default-system_stats,disabled-by-default-cpu_profiler",
+ record_mode);
case BackgroundTracingConfigImpl::CategoryPreset::BENCHMARK_IPC:
return TraceConfig("benchmark,toplevel,ipc", record_mode);
case BackgroundTracingConfigImpl::CategoryPreset::BENCHMARK_STARTUP: {
@@ -668,8 +673,10 @@ TraceConfig BackgroundTracingManagerImpl::GetConfigForCategoryPreset(
return TraceConfig("blink.console,v8", record_mode);
case BackgroundTracingConfigImpl::CategoryPreset::BENCHMARK_NAVIGATION: {
auto config = TraceConfig(
- "benchmark,toplevel,ipc,base,browser,navigation,omnibox,"
- "safe_browsing,disabled-by-default-system_stats",
+ "benchmark,toplevel,ipc,base,browser,navigation,omnibox,ui,shutdown,"
+ "safe_browsing,task_scheduler,"
+ "disabled-by-default-task_scheduler_diagnostics,"
+ "disabled-by-default-system_stats,disabled-by-default-cpu_profiler",
record_mode);
// Filter only browser process events.
base::trace_event::TraceConfig::ProcessFilterConfig process_config(
diff --git a/chromium/content/browser/tracing/background_tracing_rule.cc b/chromium/content/browser/tracing/background_tracing_rule.cc
index 88b260a0bcf..a262e9000b7 100644
--- a/chromium/content/browser/tracing/background_tracing_rule.cc
+++ b/chromium/content/browser/tracing/background_tracing_rule.cc
@@ -11,10 +11,12 @@
#include "base/metrics/statistics_recorder.h"
#include "base/rand_util.h"
#include "base/strings/safe_sprintf.h"
+#include "base/task/post_task.h"
#include "base/values.h"
#include "components/tracing/common/tracing_messages.h"
#include "content/browser/tracing/background_tracing_manager_impl.h"
#include "content/browser/tracing/trace_message_filter.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace {
@@ -228,8 +230,8 @@ class HistogramRule
if (histogram_name != histogram_name_)
return;
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(
&BackgroundTracingManagerImpl::OnRuleTriggered,
base::Unretained(BackgroundTracingManagerImpl::GetInstance()), this,
@@ -237,8 +239,8 @@ class HistogramRule
}
void AbortTracing() {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(
&BackgroundTracingManagerImpl::AbortScenario,
base::Unretained(BackgroundTracingManagerImpl::GetInstance())));
diff --git a/chromium/content/browser/tracing/etw_tracing_agent_win.cc b/chromium/content/browser/tracing/etw_tracing_agent_win.cc
index 94dba186e96..eaeac5f5b3f 100644
--- a/chromium/content/browser/tracing/etw_tracing_agent_win.cc
+++ b/chromium/content/browser/tracing/etw_tracing_agent_win.cc
@@ -13,11 +13,13 @@
#include "base/lazy_instance.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_config.h"
#include "base/trace_event/trace_event_impl.h"
#include "base/values.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "services/service_manager/public/cpp/connector.h"
@@ -250,9 +252,9 @@ void EtwTracingAgent::FlushOnThread() {
// Tracing agents, e.g. this, live as long as BrowserMainLoop lives and so
// using base::Unretained here is safe.
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&EtwTracingAgent::OnStopSystemTracingDone,
- base::Unretained(this), output));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::Bind(&EtwTracingAgent::OnStopSystemTracingDone,
+ base::Unretained(this), output));
}
} // namespace content
diff --git a/chromium/content/browser/tracing/trace_message_filter.cc b/chromium/content/browser/tracing/trace_message_filter.cc
index 5716a8bbf7b..dbc18f8a87a 100644
--- a/chromium/content/browser/tracing/trace_message_filter.cc
+++ b/chromium/content/browser/tracing/trace_message_filter.cc
@@ -6,9 +6,11 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/task/post_task.h"
#include "components/tracing/common/tracing_messages.h"
#include "content/browser/tracing/background_tracing_manager_impl.h"
#include "content/common/child_process_host_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace content {
@@ -28,9 +30,9 @@ void TraceMessageFilter::OnChannelConnected(int32_t peer_pid) {
void TraceMessageFilter::OnChannelClosing() {
if (has_child_) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&TraceMessageFilter::Unregister,
- base::RetainedRef(this)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&TraceMessageFilter::Unregister,
+ base::RetainedRef(this)));
}
}
@@ -51,8 +53,8 @@ bool TraceMessageFilter::OnMessageReceived(const IPC::Message& message) {
void TraceMessageFilter::OnChildSupportsTracing() {
has_child_ = true;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&TraceMessageFilter::Register, base::RetainedRef(this)));
}
diff --git a/chromium/content/browser/tracing/tracing_controller_browsertest.cc b/chromium/content/browser/tracing/tracing_controller_browsertest.cc
index 40ee6778dd5..24677e65902 100644
--- a/chromium/content/browser/tracing/tracing_controller_browsertest.cc
+++ b/chromium/content/browser/tracing/tracing_controller_browsertest.cc
@@ -11,10 +11,12 @@
#include "base/memory/ref_counted_memory.h"
#include "base/run_loop.h"
#include "base/strings/pattern.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/browser/tracing/tracing_controller_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/trace_uploader.h"
#include "content/public/browser/tracing_controller.h"
@@ -81,9 +83,9 @@ class TracingControllerTestEndpoint
scoped_refptr<base::RefCountedString> chunk_ptr =
base::RefCountedString::TakeString(&trace_);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(done_callback_, std::move(metadata),
- base::RetainedRef(chunk_ptr)));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(done_callback_, std::move(metadata),
+ base::RetainedRef(chunk_ptr)));
}
protected:
diff --git a/chromium/content/browser/tracing/tracing_controller_impl.cc b/chromium/content/browser/tracing/tracing_controller_impl.cc
index 424c2447cc0..f6d26a83c09 100644
--- a/chromium/content/browser/tracing/tracing_controller_impl.cc
+++ b/chromium/content/browser/tracing/tracing_controller_impl.cc
@@ -193,21 +193,11 @@ TracingControllerImpl::GenerateMetadataDict() const {
// OS
#if defined(OS_CHROMEOS)
metadata_dict->SetString("os-name", "CrOS");
- int32_t major_version;
- int32_t minor_version;
- int32_t bugfix_version;
- // OperatingSystemVersion only has a POSIX implementation which returns the
- // wrong versions for CrOS.
- base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version,
- &bugfix_version);
- metadata_dict->SetString(
- "os-version", base::StringPrintf("%d.%d.%d", major_version, minor_version,
- bugfix_version));
#else
metadata_dict->SetString("os-name", base::SysInfo::OperatingSystemName());
+#endif
metadata_dict->SetString("os-version",
base::SysInfo::OperatingSystemVersion());
-#endif
metadata_dict->SetString("os-arch",
base::SysInfo::OperatingSystemArchitecture());
@@ -284,11 +274,10 @@ TracingControllerImpl* TracingControllerImpl::GetInstance() {
return g_tracing_controller;
}
-bool TracingControllerImpl::GetCategories(
- const GetCategoriesDoneCallback& callback) {
+bool TracingControllerImpl::GetCategories(GetCategoriesDoneCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- coordinator_->GetCategories(base::BindRepeating(
- [](const GetCategoriesDoneCallback& callback, bool success,
+ coordinator_->GetCategories(base::BindOnce(
+ [](GetCategoriesDoneCallback callback, bool success,
const std::string& categories) {
const std::vector<std::string> split = base::SplitString(
categories, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
@@ -296,9 +285,9 @@ bool TracingControllerImpl::GetCategories(
for (const auto& category : split) {
category_set.insert(category);
}
- callback.Run(category_set);
+ std::move(callback).Run(category_set);
},
- callback));
+ std::move(callback)));
// TODO(chiniforooshan): The actual success value should be sent by the
// callback asynchronously.
return true;
@@ -306,7 +295,7 @@ bool TracingControllerImpl::GetCategories(
bool TracingControllerImpl::StartTracing(
const base::trace_event::TraceConfig& trace_config,
- const StartTracingDoneCallback& callback) {
+ StartTracingDoneCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// TODO(chiniforooshan): The actual value should be received by callback and
// this function should return void.
@@ -331,12 +320,12 @@ bool TracingControllerImpl::StartTracing(
std::make_unique<base::trace_event::TraceConfig>(trace_config);
coordinator_->StartTracing(
trace_config.ToString(),
- base::BindRepeating(
- [](const StartTracingDoneCallback& callback, bool success) {
+ base::BindOnce(
+ [](StartTracingDoneCallback callback, bool success) {
if (!callback.is_null())
- callback.Run();
+ std::move(callback).Run();
},
- callback));
+ std::move(callback)));
// TODO(chiniforooshan): The actual success value should be sent by the
// callback asynchronously.
return true;
@@ -379,15 +368,15 @@ bool TracingControllerImpl::StopTracing(
}
bool TracingControllerImpl::GetTraceBufferUsage(
- const GetTraceBufferUsageCallback& callback) {
+ GetTraceBufferUsageCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- coordinator_->RequestBufferUsage(base::BindRepeating(
- [](const GetTraceBufferUsageCallback& callback, bool success,
- float percent_full, uint32_t approximate_count) {
- callback.Run(percent_full, approximate_count);
+ coordinator_->RequestBufferUsage(base::BindOnce(
+ [](GetTraceBufferUsageCallback callback, bool success, float percent_full,
+ uint32_t approximate_count) {
+ std::move(callback).Run(percent_full, approximate_count);
},
- callback));
+ std::move(callback)));
// TODO(chiniforooshan): The actual success value should be sent by the
// callback asynchronously.
return true;
@@ -403,7 +392,7 @@ void TracingControllerImpl::RegisterTracingUI(TracingUI* tracing_ui) {
}
void TracingControllerImpl::UnregisterTracingUI(TracingUI* tracing_ui) {
- std::set<TracingUI*>::iterator it = tracing_uis_.find(tracing_ui);
+ auto it = tracing_uis_.find(tracing_ui);
DCHECK(it != tracing_uis_.end());
tracing_uis_.erase(it);
}
diff --git a/chromium/content/browser/tracing/tracing_controller_impl.h b/chromium/content/browser/tracing/tracing_controller_impl.h
index 356253a594b..cd8cca3e80e 100644
--- a/chromium/content/browser/tracing/tracing_controller_impl.h
+++ b/chromium/content/browser/tracing/tracing_controller_impl.h
@@ -53,14 +53,13 @@ class TracingControllerImpl : public TracingController,
TracingControllerImpl();
// TracingController implementation.
- bool GetCategories(const GetCategoriesDoneCallback& callback) override;
+ bool GetCategories(GetCategoriesDoneCallback callback) override;
bool StartTracing(const base::trace_event::TraceConfig& trace_config,
- const StartTracingDoneCallback& callback) override;
+ StartTracingDoneCallback callback) override;
bool StopTracing(const scoped_refptr<TraceDataEndpoint>& endpoint) override;
bool StopTracing(const scoped_refptr<TraceDataEndpoint>& endpoint,
const std::string& agent_label) override;
- bool GetTraceBufferUsage(
- const GetTraceBufferUsageCallback& callback) override;
+ bool GetTraceBufferUsage(GetTraceBufferUsageCallback callback) override;
bool IsTracing() const override;
void RegisterTracingUI(TracingUI* tracing_ui);
diff --git a/chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc b/chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc
index 6f3d4facd74..32670ed9627 100644
--- a/chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc
+++ b/chromium/content/browser/tracing/tracing_controller_impl_data_endpoint.cc
@@ -12,6 +12,7 @@
#include "base/strings/pattern.h"
#include "base/task/post_task.h"
#include "content/browser/tracing/tracing_controller_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/tracing_controller.h"
#include "third_party/zlib/zlib.h"
@@ -37,8 +38,8 @@ class StringTraceDataEndpoint : public TracingController::TraceDataEndpoint {
scoped_refptr<base::RefCountedString> str =
base::RefCountedString::TakeString(&tmp);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(completion_callback_, std::move(metadata),
base::RetainedRef(str)));
}
@@ -106,8 +107,8 @@ class FileTraceDataEndpoint : public TracingController::TraceDataEndpoint {
file_ = nullptr;
}
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&FileTraceDataEndpoint::FinalizeOnUIThread, this));
}
diff --git a/chromium/content/browser/tracing/tracing_ui.cc b/chromium/content/browser/tracing/tracing_ui.cc
index dec9a194057..aa9a16917fb 100644
--- a/chromium/content/browser/tracing/tracing_ui.cc
+++ b/chromium/content/browser/tracing/tracing_ui.cc
@@ -46,8 +46,7 @@ namespace {
void OnGotCategories(const WebUIDataSource::GotDataCallback& callback,
const std::set<std::string>& categorySet) {
base::ListValue category_list;
- for (std::set<std::string>::const_iterator it = categorySet.begin();
- it != categorySet.end(); it++) {
+ for (auto it = categorySet.begin(); it != categorySet.end(); it++) {
category_list.AppendString(*it);
}
diff --git a/chromium/content/browser/url_loader_factory_getter.cc b/chromium/content/browser/url_loader_factory_getter.cc
index abcd580a115..972e2652e60 100644
--- a/chromium/content/browser/url_loader_factory_getter.cc
+++ b/chromium/content/browser/url_loader_factory_getter.cc
@@ -11,8 +11,10 @@
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/lazy_instance.h"
+#include "base/task/post_task.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/common/content_switches.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -131,8 +133,8 @@ void URLLoaderFactoryGetter::Initialize(StoragePartitionImpl* partition) {
if (base::FeatureList::IsEnabled(network::features::kNetworkService))
HandleFactoryRequests();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&URLLoaderFactoryGetter::InitializeOnIOThread, this,
network_factory.PassInterface()));
}
@@ -171,8 +173,8 @@ URLLoaderFactoryGetter::GetURLLoaderFactory() {
// is only needed by unit tests.
if (network_factory_.encountered_error() || !network_factory_.is_bound()) {
network::mojom::URLLoaderFactoryPtr network_factory;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&URLLoaderFactoryGetter::HandleNetworkFactoryRequestOnUIThread,
this, mojo::MakeRequest(&network_factory)));
@@ -213,8 +215,8 @@ void URLLoaderFactoryGetter::SetGetNetworkFactoryCallbackForTesting(
void URLLoaderFactoryGetter::FlushNetworkInterfaceOnIOThreadForTesting() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::RunLoop run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&URLLoaderFactoryGetter::FlushNetworkInterfaceForTesting,
this, run_loop.QuitClosure()));
run_loop.Run();
diff --git a/chromium/content/browser/url_loader_factory_getter.h b/chromium/content/browser/url_loader_factory_getter.h
index dc998f3e6ad..99db7e64592 100644
--- a/chromium/content/browser/url_loader_factory_getter.h
+++ b/chromium/content/browser/url_loader_factory_getter.h
@@ -60,9 +60,16 @@ class URLLoaderFactoryGetter
CONTENT_EXPORT std::unique_ptr<network::SharedURLLoaderFactoryInfo>
GetNetworkFactoryInfo();
- // Called on the IO thread. Will clone the internal factory to the network
- // service which doesn't support auto-reconnect after crash. Useful for
- // one-off requests (e.g. A single navigation) to avoid additional mojo hop.
+ // Called on the IO thread. The factory obtained from here can only be used
+ // from the browser process. It must NOT be sent to a renderer process.
+ //
+ // When NetworkService is enabled, this clones the internal factory to the
+ // network service, which doesn't support auto-reconnect after crash. Useful
+ // for one-off requests (e.g. a single navigation) to avoid an additional Mojo
+ // hop.
+ //
+ // When NetworkService is disabled, this clones the non-NetworkService direct
+ // network factory.
CONTENT_EXPORT void CloneNetworkFactory(
network::mojom::URLLoaderFactoryRequest network_factory_request);
diff --git a/chromium/content/browser/utility_process_host.cc b/chromium/content/browser/utility_process_host.cc
index da650c76a0a..a17f803d6c6 100644
--- a/chromium/content/browser/utility_process_host.cc
+++ b/chromium/content/browser/utility_process_host.cc
@@ -14,6 +14,7 @@
#include "base/i18n/base_i18n_switches.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
@@ -22,6 +23,7 @@
#include "content/common/child_process_host_impl.h"
#include "content/common/in_process_child_thread_params.h"
#include "content/common/service_manager/child_connection.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_switches.h"
@@ -34,6 +36,7 @@
#include "services/network/public/cpp/network_switches.h"
#include "services/service_manager/embedder/switches.h"
#include "services/service_manager/public/cpp/interface_provider.h"
+#include "services/service_manager/sandbox/features.h"
#include "services/service_manager/sandbox/sandbox_type.h"
#include "services/service_manager/sandbox/switches.h"
#include "services/service_manager/zygote/common/zygote_buildflags.h"
@@ -59,18 +62,21 @@ class UtilitySandboxedProcessLauncherDelegate
public:
UtilitySandboxedProcessLauncherDelegate(
service_manager::SandboxType sandbox_type,
- const base::EnvironmentMap& env)
+ const base::EnvironmentMap& env,
+ const base::CommandLine& cmd_line)
:
#if defined(OS_POSIX)
env_(env),
#endif
- sandbox_type_(sandbox_type) {
+ sandbox_type_(sandbox_type),
+ cmd_line_(cmd_line) {
#if DCHECK_IS_ON()
bool supported_sandbox_type =
sandbox_type_ == service_manager::SANDBOX_TYPE_NO_SANDBOX ||
#if defined(OS_WIN)
sandbox_type_ ==
service_manager::SANDBOX_TYPE_NO_SANDBOX_AND_ELEVATED_PRIVILEGES ||
+ sandbox_type_ == service_manager::SANDBOX_TYPE_XRCOMPOSITING ||
#endif
sandbox_type_ == service_manager::SANDBOX_TYPE_UTILITY ||
sandbox_type_ == service_manager::SANDBOX_TYPE_NETWORK ||
@@ -86,10 +92,27 @@ class UtilitySandboxedProcessLauncherDelegate
~UtilitySandboxedProcessLauncherDelegate() override {}
#if defined(OS_WIN)
+ bool GetAppContainerId(std::string* appcontainer_id) override {
+ if (sandbox_type_ == service_manager::SANDBOX_TYPE_XRCOMPOSITING &&
+ base::FeatureList::IsEnabled(service_manager::features::kXRSandbox)) {
+ *appcontainer_id = base::WideToUTF8(cmd_line_.GetProgram().value());
+ return true;
+ }
+ return false;
+ }
+
bool DisableDefaultPolicy() override {
- // Default policy is disabled for audio process to allow audio drivers
- // to read device properties (https://crbug.com/883326).
- return sandbox_type_ == service_manager::SANDBOX_TYPE_AUDIO;
+ switch (sandbox_type_) {
+ case service_manager::SANDBOX_TYPE_AUDIO:
+ // Default policy is disabled for audio process to allow audio drivers
+ // to read device properties (https://crbug.com/883326).
+ return true;
+ case service_manager::SANDBOX_TYPE_XRCOMPOSITING:
+ return base::FeatureList::IsEnabled(
+ service_manager::features::kXRSandbox);
+ default:
+ return false;
+ }
}
bool ShouldLaunchElevated() override {
@@ -104,6 +127,32 @@ class UtilitySandboxedProcessLauncherDelegate
if (sandbox_type_ == service_manager::SANDBOX_TYPE_AUDIO)
return audio::AudioPreSpawnTarget(policy);
+ if (sandbox_type_ == service_manager::SANDBOX_TYPE_XRCOMPOSITING &&
+ base::FeatureList::IsEnabled(service_manager::features::kXRSandbox)) {
+ // There were issues with some mitigations, causing an inability
+ // to load OpenVR and Oculus APIs.
+ // TODO(https://crbug.com/881919): Try to harden the XR Compositor sandbox
+ // to use mitigations and restrict the token.
+ policy->SetProcessMitigations(0);
+ policy->SetDelayedProcessMitigations(0);
+
+ std::string appcontainer_id;
+ if (!GetAppContainerId(&appcontainer_id)) {
+ return false;
+ }
+ sandbox::ResultCode result =
+ service_manager::SandboxWin::AddAppContainerProfileToPolicy(
+ cmd_line_, sandbox_type_, appcontainer_id, policy);
+ if (result != sandbox::SBOX_ALL_OK) {
+ return false;
+ }
+
+ // Unprotected token/job.
+ policy->SetTokenLevel(sandbox::USER_UNPROTECTED,
+ sandbox::USER_UNPROTECTED);
+ service_manager::SandboxWin::SetJobLevel(
+ cmd_line_, sandbox::JOB_UNPROTECTED, 0, policy);
+ }
return true;
}
#endif // OS_WIN
@@ -132,6 +181,7 @@ class UtilitySandboxedProcessLauncherDelegate
base::EnvironmentMap env_;
#endif // OS_WIN
service_manager::SandboxType sandbox_type_;
+ base::CommandLine cmd_line_;
};
UtilityMainThreadFactoryFunction g_utility_main_thread_factory = nullptr;
@@ -235,7 +285,7 @@ bool UtilityProcessHost::StartProcess() {
// support single process mode this way.
in_process_thread_.reset(
g_utility_main_thread_factory(InProcessChildThreadParams(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}),
process_->GetInProcessMojoInvitation(),
process_->child_connection()->service_token())));
in_process_thread_->Start();
@@ -298,9 +348,11 @@ bool UtilityProcessHost::StartProcess() {
#if defined(OS_MACOSX)
service_manager::switches::kEnableSandboxLogging,
#endif
+ switches::kEnableLogging,
switches::kForceTextDirection,
switches::kForceUIDirection,
switches::kIgnoreCertificateErrors,
+ switches::kLoggingLevel,
switches::kOverrideUseSoftwareGLForTests,
switches::kOverrideEnabledCdmInterfaceVersion,
switches::kProxyServer,
@@ -311,6 +363,8 @@ bool UtilityProcessHost::StartProcess() {
switches::kUseMockCertVerifierForTesting,
switches::kUtilityStartupDialog,
switches::kUseGL,
+ switches::kV,
+ switches::kVModule,
#if defined(OS_ANDROID)
switches::kOrderfileMemoryOptimization,
#endif
@@ -332,6 +386,7 @@ bool UtilityProcessHost::StartProcess() {
switches::kForceWaveAudio,
switches::kTrySupportedChannelLayouts,
switches::kWaveOutBuffers,
+ service_manager::switches::kAddXrAppContainerCaps,
#endif
};
cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames,
@@ -353,9 +408,10 @@ bool UtilityProcessHost::StartProcess() {
*service_identity_, cmd_line.get());
}
- process_->Launch(std::make_unique<UtilitySandboxedProcessLauncherDelegate>(
- sandbox_type_, env_),
- std::move(cmd_line), true);
+ std::unique_ptr<UtilitySandboxedProcessLauncherDelegate> delegate =
+ std::make_unique<UtilitySandboxedProcessLauncherDelegate>(
+ sandbox_type_, env_, *cmd_line);
+ process_->Launch(std::move(delegate), std::move(cmd_line), true);
}
return true;
diff --git a/chromium/content/browser/utility_process_host_browsertest.cc b/chromium/content/browser/utility_process_host_browsertest.cc
index 670a457de87..efbc93a631d 100644
--- a/chromium/content/browser/utility_process_host_browsertest.cc
+++ b/chromium/content/browser/utility_process_host_browsertest.cc
@@ -5,10 +5,12 @@
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/utility_process_host.h"
#include "content/browser/utility_process_host_client.h"
#include "content/public/browser/browser_child_process_observer.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/child_process_termination_info.h"
@@ -45,8 +47,8 @@ class UtilityProcessHostBrowserTest : public BrowserChildProcessObserver,
done_closure_ =
base::BindOnce(&UtilityProcessHostBrowserTest::DoneRunning,
base::Unretained(this), run_loop.QuitClosure(), crash);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&UtilityProcessHostBrowserTest::RunUtilityProcessOnIOThread,
base::Unretained(this), elevated, crash));
@@ -98,8 +100,8 @@ class UtilityProcessHostBrowserTest : public BrowserChildProcessObserver,
// If service crashes then this never gets called.
ASSERT_EQ(false, expect_crash);
ResetServiceOnIOThread();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- std::move(done_closure_));
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
+ std::move(done_closure_));
}
mojom::TestServicePtr service_;
@@ -138,8 +140,8 @@ class UtilityProcessHostBrowserTest : public BrowserChildProcessObserver,
EXPECT_EQ(kTestProcessName, data.metrics_name);
EXPECT_EQ(false, has_crashed);
has_crashed = true;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&UtilityProcessHostBrowserTest::ResetServiceOnIOThread,
base::Unretained(this)));
std::move(done_closure_).Run();
@@ -160,7 +162,14 @@ IN_PROC_BROWSER_TEST_F(UtilityProcessHostBrowserTest, LaunchProcess) {
RunUtilityProcess(false, false);
}
-IN_PROC_BROWSER_TEST_F(UtilityProcessHostBrowserTest, LaunchProcessAndCrash) {
+// Flaky on Windows, crbug.com/879555
+#if defined(OS_WIN)
+#define MAYBE_LaunchProcessAndCrash DISABLED_LaunchProcessAndCrash
+#else
+#define MAYBE_LaunchProcessAndCrash LaunchProcessAndCrash
+#endif
+IN_PROC_BROWSER_TEST_F(UtilityProcessHostBrowserTest,
+ MAYBE_LaunchProcessAndCrash) {
RunUtilityProcess(false, true);
}
diff --git a/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc b/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
index dd4de01dc30..ac90d333381 100644
--- a/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
+++ b/chromium/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
@@ -38,9 +38,7 @@ bool DoesEntryMatchURL(NavigationEntry* entry, const GURL& url) {
if (entry->GetURL() == url)
return true;
const std::vector<GURL>& redirect_chain = entry->GetRedirectChain();
- for (std::vector<GURL>::const_iterator it = redirect_chain.begin();
- it != redirect_chain.end();
- it++) {
+ for (auto it = redirect_chain.begin(); it != redirect_chain.end(); it++) {
if (*it == url)
return true;
}
diff --git a/chromium/content/browser/web_contents/web_contents_android.cc b/chromium/content/browser/web_contents/web_contents_android.cc
index b0d3fea4d0f..7a4d8d9d248 100644
--- a/chromium/content/browser/web_contents/web_contents_android.cc
+++ b/chromium/content/browser/web_contents/web_contents_android.cc
@@ -470,13 +470,23 @@ void WebContentsAndroid::ScrollFocusedEditableNodeIntoView(
frame->GetFrameInputHandler()->ScrollFocusedEditableNodeIntoRect(gfx::Rect());
}
+void WebContentsAndroid::SelectWordAroundCaretAck(bool did_select,
+ int start_adjust,
+ int end_adjust) {
+ RenderWidgetHostViewAndroid* rwhva = GetRenderWidgetHostViewAndroid();
+ if (rwhva)
+ rwhva->SelectWordAroundCaretAck(did_select, start_adjust, end_adjust);
+}
+
void WebContentsAndroid::SelectWordAroundCaret(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
- RenderViewHost* host = web_contents_->GetRenderViewHost();
- if (!host)
+ RenderFrameHostImpl* frame = web_contents_->GetFocusedFrame();
+ if (!frame)
return;
- host->SelectWordAroundCaret();
+ frame->GetFrameInputHandler()->SelectWordAroundCaret(
+ base::BindOnce(&WebContentsAndroid::SelectWordAroundCaretAck,
+ weak_factory_.GetWeakPtr()));
}
void WebContentsAndroid::AdjustSelectionByCharacterOffset(
diff --git a/chromium/content/browser/web_contents/web_contents_android.h b/chromium/content/browser/web_contents/web_contents_android.h
index 6e55efc61f7..6223f76ee0b 100644
--- a/chromium/content/browser/web_contents/web_contents_android.h
+++ b/chromium/content/browser/web_contents/web_contents_android.h
@@ -265,6 +265,9 @@ class CONTENT_EXPORT WebContentsAndroid
const GURL& url,
const std::vector<SkBitmap>& bitmaps,
const std::vector<gfx::Size>& sizes);
+ void SelectWordAroundCaretAck(bool did_select,
+ int start_adjust,
+ int end_adjust);
WebContentsImpl* web_contents_;
diff --git a/chromium/content/browser/web_contents/web_contents_getter_registry.cc b/chromium/content/browser/web_contents/web_contents_getter_registry.cc
new file mode 100644
index 00000000000..ec363066a5d
--- /dev/null
+++ b/chromium/content/browser/web_contents/web_contents_getter_registry.cc
@@ -0,0 +1,51 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_contents/web_contents_getter_registry.h"
+
+#include "base/no_destructor.h"
+
+namespace content {
+
+using WebContentsGetter = WebContentsGetterRegistry::WebContentsGetter;
+
+// static
+WebContentsGetterRegistry* WebContentsGetterRegistry::GetInstance() {
+ static base::NoDestructor<WebContentsGetterRegistry> instance;
+ return instance.get();
+}
+
+void WebContentsGetterRegistry::Add(
+ const base::UnguessableToken& id,
+ const WebContentsGetter& web_contents_getter) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ bool inserted = (map_.emplace(id, web_contents_getter)).second;
+ CHECK(inserted);
+}
+
+void WebContentsGetterRegistry::Remove(const base::UnguessableToken& id) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ map_.erase(id);
+}
+
+const WebContentsGetter& WebContentsGetterRegistry::Get(
+ const base::UnguessableToken& id) const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ auto iter = map_.find(id);
+ if (iter == map_.end())
+ return GetNullGetter();
+ return iter->second;
+}
+
+WebContentsGetterRegistry::WebContentsGetterRegistry() = default;
+
+WebContentsGetterRegistry::~WebContentsGetterRegistry() = default;
+
+// static
+const WebContentsGetter& WebContentsGetterRegistry::GetNullGetter() {
+ static const base::NoDestructor<WebContentsGetter> null_getter;
+ return *null_getter;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/web_contents/web_contents_getter_registry.h b/chromium/content/browser/web_contents/web_contents_getter_registry.h
new file mode 100644
index 00000000000..de6ad4491de
--- /dev/null
+++ b/chromium/content/browser/web_contents/web_contents_getter_registry.h
@@ -0,0 +1,49 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_GETTER_REGISTRY_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_GETTER_REGISTRY_H_
+
+#include "base/callback_forward.h"
+#include "base/containers/flat_map.h"
+#include "base/sequence_checker.h"
+#include "base/unguessable_token.h"
+#include "content/public/browser/web_contents.h"
+
+namespace content {
+
+// A global map of UnguessableToken to WebContentsGetter. Unlike most other
+// WebContents related objects, this registry lives and is used only on the IO
+// thread, as it's convenient for the current user of the class
+// (ServiceWorkerProviderHost, which should move to the UI thread eventually).
+// However, the WebContentsGetter callbacks must only be run on the UI thread.
+class WebContentsGetterRegistry {
+ public:
+ using WebContentsGetter = base::RepeatingCallback<WebContents*()>;
+
+ static WebContentsGetterRegistry* GetInstance();
+
+ void Add(const base::UnguessableToken& id,
+ const WebContentsGetter& web_contents_getter);
+ void Remove(const base::UnguessableToken&);
+ // Returns null getter if not found.
+ const WebContentsGetter& Get(const base::UnguessableToken& id) const;
+
+ private:
+ friend class base::NoDestructor<WebContentsGetterRegistry>;
+
+ WebContentsGetterRegistry();
+ ~WebContentsGetterRegistry();
+
+ static const WebContentsGetter& GetNullGetter();
+
+ base::flat_map<base::UnguessableToken, WebContentsGetter> map_;
+
+ SEQUENCE_CHECKER(sequence_checker_);
+ DISALLOW_COPY_AND_ASSIGN(WebContentsGetterRegistry);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_GETTER_REGISTRY_H_
diff --git a/chromium/content/browser/web_contents/web_contents_impl.cc b/chromium/content/browser/web_contents/web_contents_impl.cc
index 499c8c0a2e8..c9d8ca8da49 100644
--- a/chromium/content/browser/web_contents/web_contents_impl.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl.cc
@@ -22,12 +22,16 @@
#include "base/memory/ref_counted.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
+#include "base/no_destructor.h"
#include "base/process/process.h"
#include "base/single_thread_task_runner.h"
+#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
@@ -39,6 +43,7 @@
#include "content/browser/accessibility/accessibility_tree_formatter_blink.h"
#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/browser/bad_message.h"
+#include "content/browser/browser_main_loop.h"
#include "content/browser/browser_plugin/browser_plugin_embedder.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/child_process_security_policy_impl.h"
@@ -93,12 +98,15 @@
#include "content/common/page_state_serialization.h"
#include "content/common/render_message_filter.mojom.h"
#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/browser/ax_event_notification_details.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/download_manager.h"
+#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/focused_node_details.h"
#include "content/public/browser/guest_mode.h"
#include "content/public/browser/invalidate_type.h"
@@ -129,6 +137,7 @@
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/url_utils.h"
#include "content/public/common/web_preferences.h"
+#include "media/base/user_input_monitor.h"
#include "net/base/url_util.h"
#include "net/http/http_cache.h"
#include "net/http/http_transaction_factory.h"
@@ -286,6 +295,50 @@ class CloseDialogCallbackWrapper
CloseCallback callback_;
};
+bool FrameCompareDepth(RenderFrameHostImpl* a, RenderFrameHostImpl* b) {
+ return a->frame_tree_node()->depth() < b->frame_tree_node()->depth();
+}
+
+// TODO(tkent): This will be merged into FileChooserImpl in
+// render_frame_host_impl.cc.
+class ViewFileSelectListener : public FileSelectListener,
+ private WebContentsObserver {
+ public:
+ ViewFileSelectListener(WebContents* web_contents, int request_id)
+ : web_contents_(web_contents), request_id_(request_id) {
+ Observe(web_contents);
+ }
+ ~ViewFileSelectListener() override = default;
+
+ private:
+ // content::FileSelectListener overrides:
+
+ void FileSelected(std::vector<blink::mojom::FileChooserFileInfoPtr> files,
+ blink::mojom::FileChooserParams::Mode mode) override {
+ if (!web_contents_)
+ return;
+ std::vector<base::FilePath> file_path_list;
+ for (const auto& file_info : files) {
+ file_path_list.push_back(file_info->get_native_file()->file_path);
+ }
+ web_contents_->GetRenderViewHost()->DirectoryEnumerationFinished(
+ request_id_, file_path_list);
+ }
+
+ void FileSelectionCanceled() override {
+ if (!web_contents_)
+ return;
+ web_contents_->GetRenderViewHost()->DirectoryEnumerationFinished(
+ request_id_, std::vector<base::FilePath>());
+ }
+
+ // content::WebContentsObserver override:
+ void WebContentsDestroyed() override { web_contents_ = nullptr; }
+
+ WebContents* web_contents_;
+ int request_id_;
+};
+
} // namespace
std::unique_ptr<WebContents> WebContents::Create(
@@ -304,10 +357,8 @@ std::unique_ptr<WebContents> WebContents::CreateWithSessionStorage(
opener = opener_rfh->frame_tree_node();
new_contents->SetOpenerForNewContents(opener, params.opener_suppressed);
- for (SessionStorageNamespaceMap::const_iterator it =
- session_storage_namespace_map.begin();
- it != session_storage_namespace_map.end();
- ++it) {
+ for (auto it = session_storage_namespace_map.begin();
+ it != session_storage_namespace_map.end(); ++it) {
new_contents->GetController()
.SetSessionStorageNamespace(it->first, it->second.get());
}
@@ -625,6 +676,7 @@ WebContentsImpl::~WebContentsImpl() {
}
color_chooser_.reset();
+ find_request_manager_.reset();
NotifyDisconnected();
@@ -1388,6 +1440,10 @@ const std::string& WebContentsImpl::GetEncoding() const {
return canonical_encoding_;
}
+bool WebContentsImpl::WasDiscarded() {
+ return GetFrameTree()->root()->was_discarded();
+}
+
void WebContentsImpl::SetWasDiscarded(bool was_discarded) {
GetFrameTree()->root()->set_was_discarded();
}
@@ -1619,12 +1675,7 @@ void WebContentsImpl::WasShown() {
if (!parent)
continue;
- if (parent->cross_process_frame_connector()->IsVisible()) {
- // MaybeLogCrash will check 1) if there was a crash or not and 2) if the
- // crash might have been already logged earlier as kCrashedWhileVisible.
- parent->cross_process_frame_connector()->MaybeLogCrash(
- CrossProcessFrameConnector::CrashVisibility::kShownAfterCrashing);
- }
+ parent->cross_process_frame_connector()->DelegateWasShown();
}
}
@@ -1724,9 +1775,11 @@ bool WebContentsImpl::NeedToFireBeforeUnload() {
true /* check_subframes_only */);
}
-void WebContentsImpl::DispatchBeforeUnload() {
- GetMainFrame()->DispatchBeforeUnload(
- RenderFrameHostImpl::BeforeUnloadType::TAB_CLOSE, false);
+void WebContentsImpl::DispatchBeforeUnload(bool auto_cancel) {
+ auto before_unload_type =
+ auto_cancel ? RenderFrameHostImpl::BeforeUnloadType::DISCARD
+ : RenderFrameHostImpl::BeforeUnloadType::TAB_CLOSE;
+ GetMainFrame()->DispatchBeforeUnload(before_unload_type, false);
}
void WebContentsImpl::AttachToOuterWebContentsFrame(
@@ -2084,6 +2137,32 @@ ukm::SourceId WebContentsImpl::GetUkmSourceIdForLastCommittedSource() const {
return last_committed_source_id_;
}
+void WebContentsImpl::SetTopControlsShownRatio(
+ RenderWidgetHostImpl* render_widget_host,
+ float ratio) {
+ if (!delegate_)
+ return;
+
+ RenderFrameHostImpl* rfh = GetMainFrame();
+ if (!rfh || render_widget_host != rfh->GetRenderWidgetHost())
+ return;
+
+ delegate_->SetTopControlsShownRatio(this, ratio);
+}
+
+bool WebContentsImpl::DoBrowserControlsShrinkRendererSize() const {
+ return delegate_ && delegate_->DoBrowserControlsShrinkRendererSize(this);
+}
+
+int WebContentsImpl::GetTopControlsHeight() const {
+ return delegate_ ? delegate_->GetTopControlsHeight() : 0;
+}
+
+void WebContentsImpl::SetTopControlsGestureScrollInProgress(bool in_progress) {
+ if (delegate_)
+ delegate_->SetTopControlsGestureScrollInProgress(in_progress);
+}
+
void WebContentsImpl::RenderWidgetCreated(
RenderWidgetHostImpl* render_widget_host) {
created_widgets_.insert(render_widget_host);
@@ -2176,7 +2255,7 @@ bool WebContentsImpl::HandleWheelEvent(
// (i.e. control+tab) then the OS's buffered scroll events will come in
// with control key set which isn't what the user wants
if (delegate_ && event.wheel_ticks_y &&
- !ui::WebInputEventTraits::CanCauseScroll(event)) {
+ event.event_action == blink::WebMouseWheelEvent::EventAction::kPageZoom) {
// Count only integer cumulative scrolls as zoom events; this handles
// smooth scroll and regular scroll device behavior.
zoom_scroll_remainder_ += event.wheel_ticks_y;
@@ -2328,8 +2407,7 @@ void WebContentsImpl::ExitFullscreenMode(bool will_cause_resize) {
}
}
- // Clear the current fullscreen frame ID.
- current_fullscreen_frame_tree_node_id_ = RenderFrameHost::kNoFrameTreeNodeId;
+ current_fullscreen_frame_ = nullptr;
for (auto& observer : observers_) {
observer.DidToggleFullscreenModeForTab(IsFullscreenForCurrentTab(),
@@ -2342,75 +2420,59 @@ void WebContentsImpl::ExitFullscreenMode(bool will_cause_resize) {
void WebContentsImpl::FullscreenStateChanged(RenderFrameHost* rfh,
bool is_fullscreen) {
- int frame_tree_node_id = rfh->GetFrameTreeNodeId();
- auto it = fullscreen_frame_tree_nodes_.find(frame_tree_node_id);
- bool changed = false;
+ RenderFrameHostImpl* frame = static_cast<RenderFrameHostImpl*>(rfh);
if (is_fullscreen) {
- // If we are fullscreen then add the FrameTreeNode ID to the set.
- if (it == fullscreen_frame_tree_nodes_.end()) {
- fullscreen_frame_tree_nodes_.insert(frame_tree_node_id);
- changed = true;
- }
- } else {
- FrameTreeNode* ancestor =
- static_cast<RenderFrameHostImpl*>(rfh)->frame_tree_node();
- DCHECK(ancestor);
-
- // If we are not fullscreen then remove this frame and any descendants
- // from the set.
- for (it = fullscreen_frame_tree_nodes_.begin();
- it != fullscreen_frame_tree_nodes_.end();) {
- FrameTreeNode* node = FrameTreeNode::GloballyFindByID(*it);
-
- if (!node || frame_tree_node_id == *it ||
- node->IsDescendantOf(ancestor)) {
- it = fullscreen_frame_tree_nodes_.erase(it);
- changed = true;
- } else {
- ++it;
- }
+ if (!base::ContainsKey(fullscreen_frames_, frame)) {
+ fullscreen_frames_.insert(frame);
+ FullscreenFrameSetUpdated();
}
+ return;
}
- // If we have changed then find the current fullscreen FrameTreeNode
- // and call the observers. If we have exited fullscreen then this
- // will be the last frame that was fullscreen.
- if (changed && fullscreen_frame_tree_nodes_.size() > 0) {
- unsigned int max_depth = 0;
- RenderFrameHost* max_depth_rfh = nullptr;
+ // If |frame| is no longer in fullscreen, remove it and any descendants.
+ // See https://fullscreen.spec.whatwg.org.
+ size_t size_before_deletion = fullscreen_frames_.size();
+ base::EraseIf(fullscreen_frames_, [&](RenderFrameHostImpl* current) {
+ return (current == frame || current->IsDescendantOf(frame));
+ });
- for (auto node_id : fullscreen_frame_tree_nodes_) {
- FrameTreeNode* fullscreen_node = FrameTreeNode::GloballyFindByID(node_id);
- DCHECK(fullscreen_node);
+ if (size_before_deletion != fullscreen_frames_.size())
+ FullscreenFrameSetUpdated();
+}
- if (max_depth_rfh == nullptr || fullscreen_node->depth() > max_depth) {
- max_depth = fullscreen_node->depth();
- max_depth_rfh = fullscreen_node->current_frame_host();
- }
- }
+void WebContentsImpl::FullscreenFrameSetUpdated() {
+ if (fullscreen_frames_.empty()) {
+ current_fullscreen_frame_ = nullptr;
+ return;
+ }
- // If we have already notified observers about this frame then we should not
- // fire the observers again.
- DCHECK(max_depth_rfh);
- if (max_depth_rfh->GetFrameTreeNodeId() ==
- current_fullscreen_frame_tree_node_id_)
- return;
+ // Find the current fullscreen frame and call the observers.
+ // If frame A is fullscreen, then frame B goes into inner fullscreen, then B
+ // exits fullscreen - that will result in A being fullscreen.
+ RenderFrameHostImpl* new_fullscreen_frame = *std::max_element(
+ fullscreen_frames_.begin(), fullscreen_frames_.end(), FrameCompareDepth);
- current_fullscreen_frame_tree_node_id_ =
- max_depth_rfh->GetFrameTreeNodeId();
+ // If we have already notified observers about this frame then we should not
+ // fire the observers again.
+ if (new_fullscreen_frame == current_fullscreen_frame_)
+ return;
+ current_fullscreen_frame_ = new_fullscreen_frame;
- for (auto& observer : observers_)
- observer.DidAcquireFullscreen(max_depth_rfh);
+ for (auto& observer : observers_)
+ observer.DidAcquireFullscreen(new_fullscreen_frame);
- if (display_cutout_host_impl_)
- display_cutout_host_impl_->DidAcquireFullscreen(max_depth_rfh);
- } else if (fullscreen_frame_tree_nodes_.size() == 0) {
- current_fullscreen_frame_tree_node_id_ =
- RenderFrameHost::kNoFrameTreeNodeId;
- }
+ if (display_cutout_host_impl_)
+ display_cutout_host_impl_->DidAcquireFullscreen(new_fullscreen_frame);
}
+#if defined(OS_ANDROID)
+void WebContentsImpl::UpdateUserGestureCarryoverInfo() {
+ if (delegate_)
+ delegate_->UpdateUserGestureCarryoverInfo(this);
+}
+#endif
+
bool WebContentsImpl::IsFullscreenForCurrentTab() const {
return delegate_ ? delegate_->IsFullscreenForTabOrPending(this) : false;
}
@@ -2489,15 +2551,18 @@ bool WebContentsImpl::HasMouseLock(RenderWidgetHostImpl* render_widget_host) {
// To verify if the mouse is locked, the mouse_lock_widget_ needs to be
// assigned to the widget that requested the mouse lock, and the top-level
// platform RenderWidgetHostView needs to hold the mouse lock from the OS.
- return mouse_lock_widget_ == render_widget_host &&
- GetTopLevelRenderWidgetHostView()->IsMouseLocked();
+ auto* widget_host = GetTopLevelRenderWidgetHostView();
+ return mouse_lock_widget_ == render_widget_host && widget_host &&
+ widget_host->IsMouseLocked();
}
RenderWidgetHostImpl* WebContentsImpl::GetMouseLockWidget() {
- if (GetTopLevelRenderWidgetHostView()->IsMouseLocked() ||
+ auto* widget_host = GetTopLevelRenderWidgetHostView();
+ if ((widget_host && widget_host->IsMouseLocked()) ||
(GetFullscreenRenderWidgetHostView() &&
- GetFullscreenRenderWidgetHostView()->IsMouseLocked()))
+ GetFullscreenRenderWidgetHostView()->IsMouseLocked())) {
return mouse_lock_widget_;
+ }
return nullptr;
}
@@ -2646,9 +2711,11 @@ void WebContentsImpl::CreateNewWindow(
new_contents = base::WrapUnique(
GetBrowserPluginGuest()->CreateNewGuestWindow(create_params));
}
- WebContentsImpl* raw_new_contents =
- static_cast<WebContentsImpl*>(new_contents.get());
- raw_new_contents->GetController().SetSessionStorageNamespace(
+ auto owning_contents_impl =
+ base::WrapUnique(static_cast<WebContentsImpl*>(new_contents.release()));
+ auto* new_contents_impl = owning_contents_impl.get();
+
+ new_contents_impl->GetController().SetSessionStorageNamespace(
partition_id, session_storage_namespace);
// If the new frame has a name, make sure any SiteInstances that can find
@@ -2656,18 +2723,18 @@ void WebContentsImpl::CreateNewWindow(
// SetSessionStorageNamespace, since this calls CreateRenderView, which uses
// GetSessionStorageNamespace.
if (!params.frame_name.empty())
- raw_new_contents->GetRenderManager()->CreateProxiesForNewNamedFrame();
+ new_contents_impl->GetRenderManager()->CreateProxiesForNewNamedFrame();
// Save the window for later if we're not suppressing the opener (since it
// will be shown immediately).
if (!params.opener_suppressed) {
if (!is_guest) {
- WebContentsView* new_view = raw_new_contents->view_.get();
+ WebContentsView* new_view = new_contents_impl->view_.get();
// TODO(brettw): It seems bogus that we have to call this function on the
// newly created object and give it one of its own member variables.
new_view->CreateViewForWidget(
- new_contents->GetRenderViewHost()->GetWidget(), false);
+ new_contents_impl->GetRenderViewHost()->GetWidget(), false);
}
// Save the created window associated with the route so we can show it
// later.
@@ -2676,20 +2743,19 @@ void WebContentsImpl::CreateNewWindow(
// FrameTreeNode id instead of the routing id of the Widget for the main
// frame. https://crbug.com/545684
DCHECK_NE(MSG_ROUTING_NONE, main_frame_widget_route_id);
- pending_contents_[GlobalRoutingID(render_process_id,
- main_frame_widget_route_id)] =
- std::move(new_contents);
- AddDestructionObserver(raw_new_contents);
+ GlobalRoutingID id(render_process_id, main_frame_widget_route_id);
+ pending_contents_[id] = std::move(owning_contents_impl);
+ AddDestructionObserver(new_contents_impl);
}
if (delegate_) {
delegate_->WebContentsCreated(this, render_process_id,
opener->GetRoutingID(), params.frame_name,
- params.target_url, raw_new_contents);
+ params.target_url, new_contents_impl);
}
for (auto& observer : observers_) {
- observer.DidOpenRequestedURL(raw_new_contents, opener, params.target_url,
+ observer.DidOpenRequestedURL(new_contents_impl, opener, params.target_url,
params.referrer, params.disposition,
ui::PAGE_TRANSITION_LINK,
false, // started_from_context_menu
@@ -2705,16 +2771,17 @@ void WebContentsImpl::CreateNewWindow(
// new window. As a result, we need to show and navigate the window here.
bool was_blocked = false;
- base::WeakPtr<WebContentsImpl> weak_new_contents =
- raw_new_contents->weak_factory_.GetWeakPtr();
if (delegate_) {
- gfx::Rect initial_rect;
+ base::WeakPtr<WebContentsImpl> weak_new_contents =
+ new_contents_impl->weak_factory_.GetWeakPtr();
- delegate_->AddNewContents(this, std::move(new_contents),
+ gfx::Rect initial_rect; // Report an empty initial rect.
+ delegate_->AddNewContents(this, std::move(owning_contents_impl),
params.disposition, initial_rect,
params.mimic_user_gesture, &was_blocked);
+ // The delegate may delete |new_contents_impl| during AddNewContents().
if (!weak_new_contents)
- return; // The delegate deleted |new_contents| during AddNewContents().
+ return;
}
if (!was_blocked) {
@@ -2726,37 +2793,34 @@ void WebContentsImpl::CreateNewWindow(
if (delegate_ && !is_guest &&
!delegate_->ShouldResumeRequestsForCreatedWindow()) {
- DCHECK(weak_new_contents);
// We are in asynchronous add new contents path, delay opening url
- weak_new_contents->delayed_open_url_params_.reset(
+ new_contents_impl->delayed_open_url_params_.reset(
new OpenURLParams(open_params));
} else {
- weak_new_contents->OpenURL(open_params);
+ new_contents_impl->OpenURL(open_params);
}
}
}
}
void WebContentsImpl::CreateNewWidget(int32_t render_process_id,
- int32_t route_id,
- mojom::WidgetPtr widget,
- blink::WebPopupType popup_type) {
- CreateNewWidget(render_process_id, route_id, false, std::move(widget),
- popup_type);
+ int32_t widget_route_id,
+ mojom::WidgetPtr widget) {
+ CreateNewWidget(render_process_id, widget_route_id, /*is_fullscreen=*/false,
+ std::move(widget));
}
void WebContentsImpl::CreateNewFullscreenWidget(int32_t render_process_id,
- int32_t route_id,
+ int32_t widget_route_id,
mojom::WidgetPtr widget) {
- CreateNewWidget(render_process_id, route_id, true, std::move(widget),
- blink::kWebPopupTypeNone);
+ CreateNewWidget(render_process_id, widget_route_id, /*is_fullscreen=*/true,
+ std::move(widget));
}
void WebContentsImpl::CreateNewWidget(int32_t render_process_id,
int32_t route_id,
bool is_fullscreen,
- mojom::WidgetPtr widget,
- blink::WebPopupType popup_type) {
+ mojom::WidgetPtr widget) {
RenderProcessHost* process = RenderProcessHost::FromID(render_process_id);
// A message to create a new widget can only come from an active process for
// this WebContentsImpl instance. If any other process sends the request,
@@ -2771,13 +2835,13 @@ void WebContentsImpl::CreateNewWidget(int32_t render_process_id,
RenderWidgetHostViewBase* widget_view =
static_cast<RenderWidgetHostViewBase*>(
- view_->CreateViewForPopupWidget(widget_host));
+ view_->CreateViewForChildWidget(widget_host));
if (!widget_view)
return;
- if (!is_fullscreen) {
- // Popups should not get activated.
- widget_view->SetPopupType(popup_type);
- }
+ // Fullscreen child widgets are frames, other child widgets are popups, and
+ // popups should not get activated.
+ if (!is_fullscreen)
+ widget_view->SetWidgetType(WidgetType::kPopup);
// Save the created widget associated with the route so we can show it later.
pending_widget_views_[GlobalRoutingID(render_process_id, route_id)] =
widget_view;
@@ -2788,40 +2852,57 @@ void WebContentsImpl::ShowCreatedWindow(int process_id,
WindowOpenDisposition disposition,
const gfx::Rect& initial_rect,
bool user_gesture) {
- std::unique_ptr<WebContents> popup =
+ // This method is the renderer requesting an existing top level window to
+ // show a new top level window that the renderer created. Each top level
+ // window is associated with a WebContents. In this case it was created
+ // earlier but showing it was deferred until the renderer requested for it
+ // to be shown. We find that previously created WebContents here.
+ // TODO(danakj): Why do we defer this show step until the renderer asks for it
+ // when it will always do so. What needs to happen in the renderer before we
+ // reach here?
+ std::unique_ptr<WebContentsImpl> owned_created =
GetCreatedWindow(process_id, main_frame_widget_route_id);
- if (popup) {
- WebContentsImpl* raw_popup = static_cast<WebContentsImpl*>(popup.get());
- WebContentsDelegate* delegate = GetDelegate();
- raw_popup->is_resume_pending_ = true;
- if (!delegate || delegate->ShouldResumeRequestsForCreatedWindow())
- raw_popup->ResumeLoadingCreatedWebContents();
-
- base::WeakPtr<WebContentsImpl> weak_popup =
- raw_popup->weak_factory_.GetWeakPtr();
- if (delegate) {
- delegate->AddNewContents(this, std::move(popup), disposition,
- initial_rect, user_gesture, nullptr);
- if (!weak_popup)
- return; // The delegate deleted |popup| during AddNewContents().
- }
+ WebContentsImpl* created = owned_created.get();
+ // The browser may have rejected the request to make a new window, or the
+ // renderer could be sending an invalid route id. Ignore the request then.
+ if (!created)
+ return;
- RenderWidgetHostImpl* rwh =
- weak_popup->GetMainFrame()->GetRenderWidgetHost();
- DCHECK_EQ(main_frame_widget_route_id, rwh->GetRoutingID());
- rwh->Send(new ViewMsg_SetBounds_ACK(rwh->GetRoutingID()));
+ // This uses the delegate for the WebContents where the window was created
+ // from, to control how to show the newly created window.
+ WebContentsDelegate* delegate = GetDelegate();
+
+ // The delegate can be null in tests, so we must check for it :(.
+ if (delegate) {
+ // Mark the web contents as pending resume, then immediately do
+ // the resume if the delegate wants it.
+ created->is_resume_pending_ = true;
+ if (delegate->ShouldResumeRequestsForCreatedWindow())
+ created->ResumeLoadingCreatedWebContents();
+
+ base::WeakPtr<WebContentsImpl> weak_created =
+ created->weak_factory_.GetWeakPtr();
+ delegate->AddNewContents(this, std::move(owned_created), disposition,
+ initial_rect, user_gesture, nullptr);
+ // The delegate may delete |created| during AddNewContents().
+ if (!weak_created)
+ return;
}
+
+ RenderWidgetHostImpl* rwh = created->GetMainFrame()->GetRenderWidgetHost();
+ DCHECK_EQ(main_frame_widget_route_id, rwh->GetRoutingID());
+ rwh->Send(new WidgetMsg_SetBounds_ACK(rwh->GetRoutingID()));
}
void WebContentsImpl::ShowCreatedWidget(int process_id,
- int route_id,
+ int widget_route_id,
const gfx::Rect& initial_rect) {
- ShowCreatedWidget(process_id, route_id, false, initial_rect);
+ ShowCreatedWidget(process_id, widget_route_id, false, initial_rect);
}
void WebContentsImpl::ShowCreatedFullscreenWidget(int process_id,
- int route_id) {
- ShowCreatedWidget(process_id, route_id, true, gfx::Rect());
+ int widget_route_id) {
+ ShowCreatedWidget(process_id, widget_route_id, true, gfx::Rect());
}
void WebContentsImpl::ShowCreatedWidget(int process_id,
@@ -2841,6 +2922,7 @@ void WebContentsImpl::ShowCreatedWidget(int process_id,
view = GetRenderWidgetHostView();
}
+ // Fullscreen child widgets are frames, other child widgets are popups.
if (is_fullscreen) {
DCHECK_EQ(MSG_ROUTING_NONE, fullscreen_widget_routing_id_);
view_->StoreFocus();
@@ -2869,7 +2951,7 @@ void WebContentsImpl::ShowCreatedWidget(int process_id,
render_widget_host_impl->set_allow_privileged_mouse_lock(is_fullscreen);
}
-std::unique_ptr<WebContents> WebContentsImpl::GetCreatedWindow(
+std::unique_ptr<WebContentsImpl> WebContentsImpl::GetCreatedWindow(
int process_id,
int main_frame_widget_route_id) {
auto key = GlobalRoutingID(process_id, main_frame_widget_route_id);
@@ -2880,14 +2962,12 @@ std::unique_ptr<WebContents> WebContentsImpl::GetCreatedWindow(
if (iter == pending_contents_.end())
return nullptr;
- std::unique_ptr<WebContents> new_contents = std::move(iter->second);
+ std::unique_ptr<WebContentsImpl> new_contents = std::move(iter->second);
pending_contents_.erase(key);
- WebContentsImpl* raw_new_contents =
- static_cast<WebContentsImpl*>(new_contents.get());
- RemoveDestructionObserver(raw_new_contents);
+ RemoveDestructionObserver(new_contents.get());
// Don't initialize the guest WebContents immediately.
- if (BrowserPluginGuest::IsGuest(raw_new_contents))
+ if (BrowserPluginGuest::IsGuest(new_contents.get()))
return new_contents;
if (!new_contents->GetMainFrame()->GetProcess()->IsInitializedAndNotDead() ||
@@ -3403,6 +3483,8 @@ void WebContentsImpl::ReloadFocusedFrame(bool bypass_cache) {
void WebContentsImpl::ReloadLoFiImages() {
SendToAllFrames(new FrameMsg_ReloadLoFiImages(MSG_ROUTING_NONE));
+ for (auto& observer : observers_)
+ observer.DidReloadLoFiImages();
}
std::vector<blink::mojom::PauseSubresourceLoadingHandlePtr>
@@ -3672,8 +3754,6 @@ void WebContentsImpl::SaveFrameWithHeaders(
bool is_main_frame = (url == GetLastCommittedURL());
RenderFrameHost* frame_host = GetMainFrame();
- StoragePartition* storage_partition = BrowserContext::GetStoragePartition(
- GetBrowserContext(), frame_host->GetSiteInstance());
int64_t post_id = -1;
if (is_main_frame) {
const NavigationEntry* entry = controller_.GetLastCommittedEntry();
@@ -3703,8 +3783,7 @@ void WebContentsImpl::SaveFrameWithHeaders(
auto params = std::make_unique<download::DownloadUrlParameters>(
url, frame_host->GetProcess()->GetID(),
frame_host->GetRenderViewHost()->GetRoutingID(),
- frame_host->GetRoutingID(), storage_partition->GetURLRequestContext(),
- traffic_annotation);
+ frame_host->GetRoutingID(), traffic_annotation);
params->set_referrer(referrer.url);
params->set_referrer_policy(
Referrer::ReferrerPolicyForUrlRequest(referrer.policy));
@@ -3935,8 +4014,8 @@ int WebContentsImpl::DownloadImage(
// Android), the downloader service will be invalid. Pre-Mojo, this would
// hang the callback indefinitely since the IPC would be dropped. Now,
// respond with a 400 HTTP error code to indicate that something went wrong.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&WebContentsImpl::OnDidDownloadImage,
weak_factory_.GetWeakPtr(), std::move(callback),
download_id, url, 400, std::vector<SkBitmap>(),
@@ -3954,14 +4033,15 @@ int WebContentsImpl::DownloadImage(
void WebContentsImpl::Find(int request_id,
const base::string16& search_text,
- const blink::WebFindOptions& options) {
+ blink::mojom::FindOptionsPtr options) {
// Cowardly refuse to search for no text.
if (search_text.empty()) {
NOTREACHED();
return;
}
- GetOrCreateFindRequestManager()->Find(request_id, search_text, options);
+ GetOrCreateFindRequestManager()->Find(request_id, search_text,
+ std::move(options));
}
void WebContentsImpl::StopFinding(StopFindAction action) {
@@ -4283,8 +4363,8 @@ void WebContentsImpl::OnDidLoadResourceFromMemoryCache(
resource_type == RESOURCE_TYPE_MEDIA
? partition->GetMediaURLRequestContext()
: partition->GetURLRequestContext());
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&NotifyCacheOnIO, request_context, url, http_method));
}
}
@@ -4498,7 +4578,23 @@ void WebContentsImpl::OnDidFinishLoad(RenderFrameHostImpl* source,
}
void WebContentsImpl::OnGoToEntryAtOffset(RenderViewHostImpl* source,
- int offset) {
+ int offset,
+ bool has_user_gesture) {
+ // Non-user initiated navigations coming from the renderer should be ignored
+ // if there is an ongoing browser-initiated navigation.
+ // See https://crbug.com/879965.
+ // TODO(arthursonzogni): See if this should check for ongoing navigations in
+ // the frame(s) affected by the session history navigation, rather than just
+ // the main frame.
+ if (!has_user_gesture) {
+ NavigationRequest* ongoing_navigation_request =
+ frame_tree_.root()->navigation_request();
+ if (ongoing_navigation_request &&
+ ongoing_navigation_request->browser_initiated()) {
+ return;
+ }
+ }
+
// All frames are allowed to navigate the global history.
if (!delegate_ || delegate_->OnGoToEntryOffset(offset))
controller_.GoToOffset(offset);
@@ -4543,10 +4639,11 @@ void WebContentsImpl::OnEnumerateDirectory(RenderViewHostImpl* source,
ChildProcessSecurityPolicyImpl* policy =
ChildProcessSecurityPolicyImpl::GetInstance();
- if (policy->CanReadFile(source->GetProcess()->GetID(), path)) {
- // TODO(nick): |this| param in the call below ought to be a RenderFrameHost.
- delegate_->EnumerateDirectory(this, request_id, path);
- }
+ if (!policy->CanReadFile(source->GetProcess()->GetID(), path))
+ return;
+ auto listener = std::make_unique<ViewFileSelectListener>(this, request_id);
+ // TODO(nick): |this| param in the call below ought to be a RenderFrameHost.
+ delegate_->EnumerateDirectory(this, std::move(listener), path);
}
void WebContentsImpl::OnRegisterProtocolHandler(RenderFrameHostImpl* source,
@@ -4663,7 +4760,7 @@ void WebContentsImpl::OnPepperPluginHung(RenderFrameHostImpl* source,
int plugin_child_id,
const base::FilePath& path,
bool is_hung) {
- UMA_HISTOGRAM_COUNTS("Pepper.PluginHung", 1);
+ UMA_HISTOGRAM_COUNTS_1M("Pepper.PluginHung", 1);
for (auto& observer : observers_)
observer.PluginHungStatusChanged(plugin_child_id, path, is_hung);
@@ -5046,6 +5143,31 @@ void WebContentsImpl::ShowContextMenu(RenderFrameHost* render_frame_host,
context_menu_params);
}
+namespace {
+// Normalizes the line endings: \r\n -> \n, lone \r -> \n.
+base::string16 NormalizeLineBreaks(const base::string16& source) {
+ static const base::NoDestructor<base::string16> kReturnNewline(
+ base::ASCIIToUTF16("\r\n"));
+ static const base::NoDestructor<base::string16> kReturn(
+ base::ASCIIToUTF16("\r"));
+ static const base::NoDestructor<base::string16> kNewline(
+ base::ASCIIToUTF16("\n"));
+
+ std::vector<base::StringPiece16> pieces;
+
+ for (const auto& rn_line : base::SplitStringPieceUsingSubstr(
+ source, *kReturnNewline, base::KEEP_WHITESPACE,
+ base::SPLIT_WANT_ALL)) {
+ auto r_lines = base::SplitStringPieceUsingSubstr(
+ rn_line, *kReturn, base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+ std::move(std::begin(r_lines), std::end(r_lines),
+ std::back_inserter(pieces));
+ }
+
+ return base::JoinString(pieces, *kNewline);
+}
+} // namespace
+
void WebContentsImpl::RunJavaScriptDialog(RenderFrameHost* render_frame_host,
const base::string16& message,
const base::string16& default_prompt,
@@ -5095,16 +5217,19 @@ void WebContentsImpl::RunJavaScriptDialog(RenderFrameHost* render_frame_host,
is_showing_javascript_dialog_ = true;
+ base::string16 normalized_message = NormalizeLineBreaks(message);
+
for (auto* handler : page_handlers) {
handler->DidRunJavaScriptDialog(
- render_frame_host->GetLastCommittedURL(), message, default_prompt,
- dialog_type, has_non_devtools_handlers,
+ render_frame_host->GetLastCommittedURL(), normalized_message,
+ default_prompt, dialog_type, has_non_devtools_handlers,
base::BindOnce(&CloseDialogCallbackWrapper::Run, wrapper, false));
}
if (dialog_manager_) {
dialog_manager_->RunJavaScriptDialog(
- this, render_frame_host, dialog_type, message, default_prompt,
+ this, render_frame_host, dialog_type, normalized_message,
+ default_prompt,
base::BindOnce(&CloseDialogCallbackWrapper::Run, wrapper, false),
&suppress_this_message);
}
@@ -5178,14 +5303,18 @@ void WebContentsImpl::RunBeforeUnloadConfirm(
}
}
-void WebContentsImpl::RunFileChooser(RenderFrameHost* render_frame_host,
- const FileChooserParams& params) {
+void WebContentsImpl::RunFileChooser(
+ RenderFrameHost* render_frame_host,
+ std::unique_ptr<content::FileSelectListener> listener,
+ const blink::mojom::FileChooserParams& params) {
// Any explicit focusing of another window while this WebContents is in
// fullscreen can be used to confuse the user, so drop fullscreen.
ForSecurityDropFullscreen();
if (delegate_)
- delegate_->RunFileChooser(render_frame_host, params);
+ delegate_->RunFileChooser(render_frame_host, std::move(listener), params);
+ else
+ listener->FileSelectionCanceled();
}
WebContents* WebContentsImpl::GetAsWebContents() {
@@ -5543,7 +5672,6 @@ WebContentsImpl::CreateThrottlesForNavigation(
std::unique_ptr<NavigationUIData> WebContentsImpl::GetNavigationUIData(
NavigationHandle* navigation_handle) {
- DCHECK(IsBrowserSideNavigationEnabled());
return GetContentClient()->browser()->GetNavigationUIData(navigation_handle);
}
@@ -5958,7 +6086,7 @@ void WebContentsImpl::BeforeUnloadFiredFromRenderManager(
bool proceed, const base::TimeTicks& proceed_time,
bool* proceed_to_fire_unload) {
for (auto& observer : observers_)
- observer.BeforeUnloadFired(proceed_time);
+ observer.BeforeUnloadFired(proceed, proceed_time);
if (delegate_)
delegate_->BeforeUnloadFired(this, proceed, proceed_to_fire_unload);
// Note: |this| might be deleted at this point.
@@ -6155,16 +6283,6 @@ service_manager::InterfaceProvider* WebContentsImpl::GetJavaInterfaces() {
return java_interfaces_.get();
}
-#elif defined(OS_MACOSX)
-
-void WebContentsImpl::SetAllowOtherViews(bool allow) {
- view_->SetAllowOtherViews(allow);
-}
-
-bool WebContentsImpl::GetAllowOtherViews() {
- return view_->GetAllowOtherViews();
-}
-
#endif
bool WebContentsImpl::CompletedFirstVisuallyNonEmptyPaint() const {
@@ -6462,6 +6580,11 @@ ForwardingAudioStreamFactory* WebContentsImpl::GetAudioStreamFactory() {
if (!audio_stream_factory_) {
audio_stream_factory_.emplace(
this,
+ // BrowserMainLoop::GetInstance() may be null in unit tests.
+ BrowserMainLoop::GetInstance()
+ ? static_cast<media::UserInputMonitorBase*>(
+ BrowserMainLoop::GetInstance()->user_input_monitor())
+ : nullptr,
content::ServiceManagerConnection::GetForProcess()
->GetConnector()
->Clone(),
diff --git a/chromium/content/browser/web_contents/web_contents_impl.h b/chromium/content/browser/web_contents/web_contents_impl.h
index 2687e87ea2d..83f287513d9 100644
--- a/chromium/content/browser/web_contents/web_contents_impl.h
+++ b/chromium/content/browser/web_contents/web_contents_impl.h
@@ -60,7 +60,7 @@
#include "third_party/blink/public/mojom/color_chooser/color_chooser.mojom.h"
#include "third_party/blink/public/mojom/page/display_cutout.mojom.h"
#include "third_party/blink/public/platform/web_drag_operation.h"
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
#include "ui/base/page_transition_types.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
@@ -333,6 +333,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
uint64_t GetUploadSize() const override;
uint64_t GetUploadPosition() const override;
const std::string& GetEncoding() const override;
+ bool WasDiscarded() override;
void SetWasDiscarded(bool was_discarded) override;
void IncrementCapturerCount(const gfx::Size& capture_size) override;
void DecrementCapturerCount() override;
@@ -355,7 +356,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void WasOccluded() override;
Visibility GetVisibility() const override;
bool NeedToFireBeforeUnload() override;
- void DispatchBeforeUnload() override;
+ void DispatchBeforeUnload(bool auto_cancel) override;
void AttachToOuterWebContentsFrame(
WebContents* outer_web_contents,
RenderFrameHost* outer_contents_frame) override;
@@ -441,7 +442,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
ImageDownloadCallback callback) override;
void Find(int request_id,
const base::string16& search_text,
- const blink::WebFindOptions& options) override;
+ blink::mojom::FindOptionsPtr options) override;
void StopFinding(StopFindAction action) override;
bool WasEverAudible() override;
void GetManifest(GetManifestCallback callback) override;
@@ -463,9 +464,6 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void ActivateNearestFindResult(float x, float y) override;
void RequestFindMatchRects(int current_version) override;
service_manager::InterfaceProvider* GetJavaInterfaces() override;
-#elif defined(OS_MACOSX)
- void SetAllowOtherViews(bool allow) override;
- bool GetAllowOtherViews() override;
#endif
bool HasRecentInteractiveInputEvent() const override;
@@ -500,7 +498,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
bool is_reload,
IPC::Message* reply_msg) override;
void RunFileChooser(RenderFrameHost* render_frame_host,
- const FileChooserParams& params) override;
+ std::unique_ptr<content::FileSelectListener> listener,
+ const blink::mojom::FileChooserParams& params) override;
void DidCancelLoading() override;
void DidAccessInitialDocument() override;
void DidChangeName(RenderFrameHost* render_frame_host,
@@ -537,6 +536,9 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void ExitFullscreenMode(bool will_cause_resize) override;
void FullscreenStateChanged(RenderFrameHost* rfh,
bool is_fullscreen) override;
+#if defined(OS_ANDROID)
+ void UpdateUserGestureCarryoverInfo() override;
+#endif
bool ShouldRouteMessageEvent(
RenderFrameHost* target_rfh,
SiteInstance* source_site_instance) const override;
@@ -625,15 +627,15 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void UpdatePreferredSize(const gfx::Size& pref_size) override;
void CreateNewWidget(int32_t render_process_id,
int32_t route_id,
- mojom::WidgetPtr widget,
- blink::WebPopupType popup_type) override;
+ mojom::WidgetPtr widget) override;
void CreateNewFullscreenWidget(int32_t render_process_id,
- int32_t route_id,
+ int32_t widget_route_id,
mojom::WidgetPtr widget) override;
void ShowCreatedWidget(int process_id,
- int route_id,
+ int widget_route_id,
const gfx::Rect& initial_rect) override;
- void ShowCreatedFullscreenWidget(int process_id, int route_id) override;
+ void ShowCreatedFullscreenWidget(int process_id,
+ int widget_route_id) override;
void RequestMediaAccessPermission(const MediaStreamRequest& request,
MediaResponseCallback callback) override;
bool CheckMediaAccessPermission(RenderFrameHost* render_frame_host,
@@ -689,6 +691,11 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// RenderWidgetHostDelegate --------------------------------------------------
ukm::SourceId GetUkmSourceIdForLastCommittedSource() const override;
+ void SetTopControlsShownRatio(RenderWidgetHostImpl* render_widget_host,
+ float ratio) override;
+ bool DoBrowserControlsShrinkRendererSize() const override;
+ int GetTopControlsHeight() const override;
+ void SetTopControlsGestureScrollInProgress(bool in_progress) override;
void RenderWidgetCreated(RenderWidgetHostImpl* render_widget_host) override;
void RenderWidgetDeleted(RenderWidgetHostImpl* render_widget_host) override;
void RenderWidgetGotFocus(RenderWidgetHostImpl* render_widget_host) override;
@@ -1031,6 +1038,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
JavaScriptDialogsInMainAndSubframes);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
+ JavaScriptDialogsNormalizeText);
+ FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
DialogsFromJavaScriptEndFullscreen);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
DialogsFromJavaScriptEndFullscreenEvenInInnerWC);
@@ -1046,6 +1055,10 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
BeforeUnloadDialogRequiresGesture);
FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest,
CancelBeforeUnloadResetsURL);
+ FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest,
+ BeforeUnloadDialogSuppressedForDiscard);
+ FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBrowserTest,
+ PendingDialogMakesDiscardUnloadReturnFalse);
FRIEND_TEST_ALL_PREFIXES(DevToolsProtocolTest, JavaScriptDialogNotifications);
FRIEND_TEST_ALL_PREFIXES(DevToolsProtocolTest, JavaScriptDialogInterop);
FRIEND_TEST_ALL_PREFIXES(DevToolsProtocolTest, BeforeUnloadDialog);
@@ -1054,6 +1067,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
PageDisableWithNoDialogManager);
FRIEND_TEST_ALL_PREFIXES(PointerLockBrowserTest,
PointerLockInnerContentsCrashes);
+ FRIEND_TEST_ALL_PREFIXES(PointerLockBrowserTest, PointerLockOopifCrashes);
// So |find_request_manager_| can be accessed for testing.
friend class FindRequestManagerTest;
@@ -1180,7 +1194,9 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void OnDidRunContentWithCertificateErrors(RenderFrameHostImpl* source);
void OnDocumentLoadedInFrame(RenderFrameHostImpl* source);
void OnDidFinishLoad(RenderFrameHostImpl* source, const GURL& url);
- void OnGoToEntryAtOffset(RenderViewHostImpl* source, int offset);
+ void OnGoToEntryAtOffset(RenderViewHostImpl* source,
+ int offset,
+ bool has_user_gesture);
void OnUpdateZoomLimits(RenderViewHostImpl* source,
int minimum_percent,
int maximum_percent);
@@ -1288,8 +1304,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void CreateNewWidget(int32_t render_process_id,
int32_t route_id,
bool is_fullscreen,
- mojom::WidgetPtr widget,
- blink::WebPopupType popup_type);
+ mojom::WidgetPtr widget);
// Helper for ShowCreatedWidget/ShowCreatedFullscreenWidget.
void ShowCreatedWidget(int process_id,
@@ -1304,8 +1319,9 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// Finds the new WebContentsImpl by |main_frame_widget_route_id|, initializes
// it for renderer-initiated creation, and returns it. Note that this can only
// be called once as this call also removes it from the internal map.
- std::unique_ptr<WebContents> GetCreatedWindow(int process_id,
- int main_frame_widget_route_id);
+ std::unique_ptr<WebContentsImpl> GetCreatedWindow(
+ int process_id,
+ int main_frame_widget_route_id);
// Sends a Page message IPC.
void SendPageMessage(IPC::Message* msg);
@@ -1407,6 +1423,10 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
AXTreeSnapshotCombiner* combiner,
ui::AXMode ax_mode);
+ // Called each time |fullscreen_frames_| is updated. Find the new
+ // |current_fullscreen_frame_| and notify observers whenever it changes.
+ void FullscreenFrameSetUpdated();
+
// Data for core operation ---------------------------------------------------
// Delegate for notifying our owner about stuff. Not owned by us.
@@ -1425,7 +1445,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// Tracks created WebContentsImpl objects that have not been shown yet. They
// are identified by the process ID and routing ID passed to CreateNewWindow.
- std::map<GlobalRoutingID, std::unique_ptr<WebContents>> pending_contents_;
+ std::map<GlobalRoutingID, std::unique_ptr<WebContentsImpl>> pending_contents_;
// This map holds widgets that were created on behalf of the renderer but
// haven't been shown yet.
@@ -1773,14 +1793,12 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// Gets notified about changes in viewport fit events.
std::unique_ptr<DisplayCutoutHostImpl> display_cutout_host_impl_;
- // Stores a set of FrameTreeNode ids that are fullscreen.
- using FullscreenFrameNodes = std::set<int>;
- FullscreenFrameNodes fullscreen_frame_tree_nodes_;
+ // Stores a set of frames that are fullscreen.
+ // See https://fullscreen.spec.whatwg.org.
+ std::set<RenderFrameHostImpl*> fullscreen_frames_;
- // Stores the ID of the current fullscreen |FrameTreeNode| or
- // |kNoFrameTreeNodeId| if the tab is not currently fullscreen.
- int current_fullscreen_frame_tree_node_id_ =
- RenderFrameHost::kNoFrameTreeNodeId;
+ // Store the frame that is currently fullscreen, nullptr if there is none.
+ RenderFrameHostImpl* current_fullscreen_frame_ = nullptr;
base::WeakPtrFactory<WebContentsImpl> loading_weak_factory_;
base::WeakPtrFactory<WebContentsImpl> weak_factory_;
diff --git a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc
index 78857bccaea..b814f649123 100644
--- a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -27,6 +27,7 @@
#include "content/browser/web_contents/web_contents_view.h"
#include "content/common/frame_messages.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "content/public/browser/load_notification_details.h"
@@ -37,7 +38,6 @@
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
-#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
@@ -124,11 +124,10 @@ class WebContentsImplBrowserTest : public ContentBrowserTest {
host_resolver()->AddRule("*", "127.0.0.1");
}
- bool CurrentFullscreenFrameTreeNodeIsEmpty() {
+ bool IsInFullscreen() {
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
- return web_contents->current_fullscreen_frame_tree_node_id_ ==
- RenderFrameHost::kNoFrameTreeNodeId;
+ return web_contents->current_fullscreen_frame_;
}
private:
@@ -1109,11 +1108,11 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
// Simulate a navigation that has not completed.
const GURL kURL2 = embedded_test_server()->GetURL("/title2.html");
- NavigationStallDelegate stall_delegate(kURL2);
- ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate);
+ TestNavigationManager navigation(shell()->web_contents(), kURL2);
std::unique_ptr<LoadProgressDelegateAndObserver> delegate(
new LoadProgressDelegateAndObserver(shell()));
shell()->LoadURL(kURL2);
+ EXPECT_TRUE(navigation.WaitForResponse());
EXPECT_TRUE(delegate->did_start_loading);
EXPECT_FALSE(delegate->did_stop_loading);
@@ -1135,8 +1134,6 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
// We should have gotten to DidStopLoading.
EXPECT_TRUE(delegate->did_stop_loading);
-
- ResourceDispatcherHost::Get()->SetDelegate(nullptr);
}
struct FirstVisuallyNonEmptyPaintObserver : public WebContentsObserver {
@@ -1641,6 +1638,14 @@ class TestWCDelegateForDialogsAndFullscreen : public JavaScriptDialogManager,
DISALLOW_COPY_AND_ASSIGN(TestWCDelegateForDialogsAndFullscreen);
};
+class MockFileSelectListener : public FileSelectListener {
+ public:
+ MockFileSelectListener() {}
+ void FileSelected(std::vector<blink::mojom::FileChooserFileInfoPtr> files,
+ blink::mojom::FileChooserParams::Mode mode) override {}
+ void FileSelectionCanceled() override {}
+};
+
} // namespace
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
@@ -1734,6 +1739,26 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
}
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
+ JavaScriptDialogsNormalizeText) {
+ WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
+ TestWCDelegateForDialogsAndFullscreen test_delegate;
+ wc->SetDelegate(&test_delegate);
+
+ GURL url("about:blank");
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+
+ // A dialog with mixed linebreaks.
+ std::string alert = "alert('1\\r2\\r\\n3\\n4')";
+ test_delegate.WillWaitForDialog();
+ EXPECT_TRUE(content::ExecuteScript(wc, alert));
+ test_delegate.Wait();
+ EXPECT_EQ("1\n2\n3\n4", test_delegate.last_message());
+
+ wc->SetDelegate(nullptr);
+ wc->SetJavaScriptDialogManagerForTesting(nullptr);
+}
+
+IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
CreateWebContentsWithRendererProcess) {
ASSERT_TRUE(embedded_test_server()->Start());
WebContents* base_web_contents = shell()->web_contents();
@@ -2200,7 +2225,9 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, FileChooserEndsFullscreen) {
wc->EnterFullscreenMode(url, blink::WebFullscreenOptions());
EXPECT_TRUE(wc->IsFullscreenForCurrentTab());
- wc->RunFileChooser(wc->GetMainFrame(), FileChooserParams());
+ wc->RunFileChooser(wc->GetMainFrame(),
+ std::make_unique<MockFileSelectListener>(),
+ blink::mojom::FileChooserParams());
EXPECT_FALSE(wc->IsFullscreenForCurrentTab());
wc->SetDelegate(nullptr);
@@ -2659,15 +2686,13 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, NotifyFullscreenAcquired) {
GURL url = embedded_test_server()->GetURL(
"a.com", "/cross_site_iframe_factory.html?a(b{allowfullscreen})");
EXPECT_TRUE(NavigateToURL(shell(), url));
- RenderFrameHost* main_frame = web_contents->GetMainFrame();
- int main_frame_id = main_frame->GetFrameTreeNodeId();
-
- RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
- int child_frame_id = child_frame->GetFrameTreeNodeId();
+ RenderFrameHostImpl* main_frame = web_contents->GetMainFrame();
+ RenderFrameHostImpl* child_frame =
+ static_cast<RenderFrameHostImpl*>(ChildFrameAt(main_frame, 0));
- WebContentsImpl::FullscreenFrameNodes nodes;
- EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
- EXPECT_TRUE(CurrentFullscreenFrameTreeNodeIsEmpty());
+ std::set<RenderFrameHostImpl*> fullscreen_frames;
+ EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
+ EXPECT_FALSE(IsInFullscreen());
// Make the top page fullscreen.
{
@@ -2677,10 +2702,9 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, NotifyFullscreenAcquired) {
observer.Wait();
}
- nodes.insert(main_frame_id);
- EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
- EXPECT_EQ(main_frame_id,
- web_contents->current_fullscreen_frame_tree_node_id_);
+ fullscreen_frames.insert(main_frame);
+ EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
+ EXPECT_EQ(main_frame, web_contents->current_fullscreen_frame_);
// Make the child frame fullscreen.
{
@@ -2690,10 +2714,9 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, NotifyFullscreenAcquired) {
observer.Wait();
}
- nodes.insert(child_frame_id);
- EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
- EXPECT_EQ(child_frame_id,
- web_contents->current_fullscreen_frame_tree_node_id_);
+ fullscreen_frames.insert(child_frame);
+ EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
+ EXPECT_EQ(child_frame, web_contents->current_fullscreen_frame_);
// Exit fullscreen on the child frame.
// This will not work with --site-per-process until crbug.com/617369
@@ -2706,10 +2729,9 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, NotifyFullscreenAcquired) {
observer.Wait();
}
- nodes.erase(child_frame_id);
- EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
- EXPECT_EQ(main_frame_id,
- web_contents->current_fullscreen_frame_tree_node_id_);
+ fullscreen_frames.erase(child_frame);
+ EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
+ EXPECT_EQ(main_frame, web_contents->current_fullscreen_frame_);
}
}
@@ -2727,14 +2749,14 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, FullscreenAfterFrameSwap) {
EXPECT_TRUE(NavigateToURL(shell(), url_a));
RenderFrameHostImpl* main_frame =
static_cast<RenderFrameHostImpl*>(web_contents->GetMainFrame());
- EXPECT_EQ(0u, web_contents->fullscreen_frame_tree_nodes_.size());
+ EXPECT_EQ(0u, web_contents->fullscreen_frames_.size());
// 2) Make it fullscreen.
FullscreenWebContentsObserver observer(web_contents, main_frame);
EXPECT_TRUE(
ExecuteScript(main_frame, "document.body.webkitRequestFullscreen();"));
observer.Wait();
- EXPECT_EQ(1u, web_contents->fullscreen_frame_tree_nodes_.size());
+ EXPECT_EQ(1u, web_contents->fullscreen_frames_.size());
// 3) Navigate cross origin. Act as if the old frame was very slow delivering
// the swapout ack and stayed in pending deletion for a while. Even if the
@@ -2744,7 +2766,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, FullscreenAfterFrameSwap) {
main_frame->GetProcess()->AddFilter(filter.get());
main_frame->DisableSwapOutTimerForTesting();
EXPECT_TRUE(NavigateToURL(shell(), url_b));
- EXPECT_EQ(0u, web_contents->fullscreen_frame_tree_nodes_.size());
+ EXPECT_EQ(0u, web_contents->fullscreen_frames_.size());
}
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
@@ -2759,15 +2781,13 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
GURL url = embedded_test_server()->GetURL(
"a.com", "/cross_site_iframe_factory.html?a(b{allowfullscreen})");
EXPECT_TRUE(NavigateToURL(shell(), url));
- RenderFrameHost* main_frame = web_contents->GetMainFrame();
- int main_frame_id = main_frame->GetFrameTreeNodeId();
+ RenderFrameHostImpl* main_frame = web_contents->GetMainFrame();
+ RenderFrameHostImpl* child_frame =
+ static_cast<RenderFrameHostImpl*>(ChildFrameAt(main_frame, 0));
- RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
- int child_frame_id = child_frame->GetFrameTreeNodeId();
-
- WebContentsImpl::FullscreenFrameNodes nodes;
- EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
- EXPECT_TRUE(CurrentFullscreenFrameTreeNodeIsEmpty());
+ std::set<RenderFrameHostImpl*> nodes;
+ EXPECT_EQ(nodes, web_contents->fullscreen_frames_);
+ EXPECT_FALSE(IsInFullscreen());
// Make the top page fullscreen.
{
@@ -2777,10 +2797,9 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
observer.Wait();
}
- nodes.insert(main_frame_id);
- EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
- EXPECT_EQ(main_frame_id,
- web_contents->current_fullscreen_frame_tree_node_id_);
+ nodes.insert(main_frame);
+ EXPECT_EQ(nodes, web_contents->fullscreen_frames_);
+ EXPECT_EQ(main_frame, web_contents->current_fullscreen_frame_);
// Make the child frame fullscreen.
{
@@ -2790,17 +2809,16 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
observer.Wait();
}
- nodes.insert(child_frame_id);
- EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
- EXPECT_EQ(child_frame_id,
- web_contents->current_fullscreen_frame_tree_node_id_);
+ nodes.insert(child_frame);
+ EXPECT_EQ(nodes, web_contents->fullscreen_frames_);
+ EXPECT_EQ(child_frame, web_contents->current_fullscreen_frame_);
// Perform a cross origin navigation on the main frame.
EXPECT_TRUE(
NavigateToURL(shell(), embedded_test_server()->GetURL(
"c.com", "/cross_site_iframe_factory.html")));
- EXPECT_EQ(0u, web_contents->fullscreen_frame_tree_nodes_.size());
- EXPECT_TRUE(CurrentFullscreenFrameTreeNodeIsEmpty());
+ EXPECT_EQ(0u, web_contents->fullscreen_frames_.size());
+ EXPECT_FALSE(IsInFullscreen());
}
IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
@@ -2814,15 +2832,13 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
GURL url = embedded_test_server()->GetURL(
"a.com", "/cross_site_iframe_factory.html?a(a{allowfullscreen})");
EXPECT_TRUE(NavigateToURL(shell(), url));
- RenderFrameHost* main_frame = web_contents->GetMainFrame();
- int main_frame_id = main_frame->GetFrameTreeNodeId();
-
- RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
- int child_frame_id = child_frame->GetFrameTreeNodeId();
+ RenderFrameHostImpl* main_frame = web_contents->GetMainFrame();
+ RenderFrameHostImpl* child_frame =
+ static_cast<RenderFrameHostImpl*>(ChildFrameAt(main_frame, 0));
- WebContentsImpl::FullscreenFrameNodes nodes;
- EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
- EXPECT_TRUE(CurrentFullscreenFrameTreeNodeIsEmpty());
+ std::set<RenderFrameHostImpl*> fullscreen_frames;
+ EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
+ EXPECT_FALSE(IsInFullscreen());
// Make the top page fullscreen.
{
@@ -2832,10 +2848,9 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
observer.Wait();
}
- nodes.insert(main_frame_id);
- EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
- EXPECT_EQ(main_frame_id,
- web_contents->current_fullscreen_frame_tree_node_id_);
+ fullscreen_frames.insert(main_frame);
+ EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
+ EXPECT_EQ(main_frame, web_contents->current_fullscreen_frame_);
// Make the child frame fullscreen.
{
@@ -2845,10 +2860,9 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
observer.Wait();
}
- nodes.insert(child_frame_id);
- EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
- EXPECT_EQ(child_frame_id,
- web_contents->current_fullscreen_frame_tree_node_id_);
+ fullscreen_frames.insert(child_frame);
+ EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
+ EXPECT_EQ(child_frame, web_contents->current_fullscreen_frame_);
// Exit fullscreen on the child frame.
{
@@ -2857,10 +2871,9 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
observer.Wait();
}
- nodes.erase(child_frame_id);
- EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
- EXPECT_EQ(main_frame_id,
- web_contents->current_fullscreen_frame_tree_node_id_);
+ fullscreen_frames.erase(child_frame);
+ EXPECT_EQ(fullscreen_frames, web_contents->fullscreen_frames_);
+ EXPECT_EQ(main_frame, web_contents->current_fullscreen_frame_);
}
class MockDidOpenRequestedURLObserver : public WebContentsObserver {
diff --git a/chromium/content/browser/web_contents/web_contents_impl_unittest.cc b/chromium/content/browser/web_contents/web_contents_impl_unittest.cc
index aa74c714540..d712e197d9c 100644
--- a/chromium/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -455,10 +455,6 @@ TEST_F(WebContentsImplTest, DirectNavigationToViewSourceWebUI) {
InitNavigateParams(&params, entry_id, true, kRewrittenURL,
ui::PAGE_TRANSITION_TYPED);
main_test_rfh()->PrepareForCommit();
- main_test_rfh()->OnMessageReceived(
- FrameHostMsg_DidStartProvisionalLoad(1, kRewrittenURL,
- std::vector<GURL>(),
- base::TimeTicks::Now()));
main_test_rfh()->SimulateCommitProcessed(
request->navigation_handle()->GetNavigationId(),
true /* was_successful */);
@@ -2003,15 +1999,7 @@ TEST_F(WebContentsImplTest, CreateInterstitialForClosingTab) {
DeleteContents();
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
- // The interstitial page triggers a DidStartNavigation after the tab is gone,
- // but before the interstitial page itself is deleted. This should not crash.
- Navigator* interstitial_navigator =
- interstitial_rfh->frame_tree_node()->navigator();
- interstitial_navigator->DidStartProvisionalLoad(
- interstitial_rfh, url2, std::vector<GURL>(), base::TimeTicks::Now());
- EXPECT_FALSE(deleted);
-
- // Simulate a commit in the interstitial page, which should also not crash.
+ // Simulate a commit in the interstitial page, which should not crash.
interstitial_rfh->SimulateNavigationCommit(url2);
RunAllPendingInMessageLoop();
@@ -2518,28 +2506,25 @@ TEST_F(WebContentsImplTest, FilterURLs) {
// Test that if a pending contents is deleted before it is shown, we don't
// crash.
TEST_F(WebContentsImplTest, PendingContentsDestroyed) {
- std::unique_ptr<WebContentsImpl> other_contents(
- static_cast<WebContentsImpl*>(CreateTestWebContents().release()));
- content::TestWebContents* raw_other_contents =
- static_cast<TestWebContents*>(other_contents.get());
+ auto other_contents = base::WrapUnique(
+ static_cast<TestWebContents*>(CreateTestWebContents().release()));
+ content::TestWebContents* test_web_contents = other_contents.get();
contents()->AddPendingContents(std::move(other_contents));
RenderWidgetHost* widget =
- raw_other_contents->GetMainFrame()->GetRenderWidgetHost();
+ test_web_contents->GetMainFrame()->GetRenderWidgetHost();
int process_id = widget->GetProcess()->GetID();
int widget_id = widget->GetRoutingID();
// TODO(erikchen): Fix ownership semantics of WebContents. Nothing should be
// able to delete it beside from the owner. https://crbug.com/832879.
- delete raw_other_contents;
+ delete test_web_contents;
EXPECT_EQ(nullptr, contents()->GetCreatedWindow(process_id, widget_id));
}
TEST_F(WebContentsImplTest, PendingContentsShown) {
- std::unique_ptr<WebContents> other_contents(
- static_cast<WebContents*>(CreateTestWebContents().release()));
- content::WebContents* raw_other_contents = other_contents.get();
- content::TestWebContents* test_web_contents =
- static_cast<content::TestWebContents*>(other_contents.get());
+ auto other_contents = base::WrapUnique(
+ static_cast<TestWebContents*>(CreateTestWebContents().release()));
+ content::TestWebContents* test_web_contents = other_contents.get();
contents()->AddPendingContents(std::move(other_contents));
RenderWidgetHost* widget =
@@ -2548,7 +2533,7 @@ TEST_F(WebContentsImplTest, PendingContentsShown) {
int widget_id = widget->GetRoutingID();
// The first call to GetCreatedWindow pops it off the pending list.
- EXPECT_EQ(raw_other_contents,
+ EXPECT_EQ(test_web_contents,
contents()->GetCreatedWindow(process_id, widget_id).get());
// A second call should return nullptr, verifying that it's been forgotten.
EXPECT_EQ(nullptr, contents()->GetCreatedWindow(process_id, widget_id));
@@ -3152,59 +3137,51 @@ TEST_F(WebContentsImplTestWithSiteIsolation, IsLoadingToDifferentDocument) {
// Ensure that WebContentsImpl does not stop loading too early when there still
// is a pending renderer. This can happen if a same-process non user-initiated
// navigation completes while there is an ongoing cross-process navigation.
-// TODO(fdegans): Rewrite the test for PlzNavigate when DidStartLoading and
-// DidStopLoading are properly called.
-TEST_F(WebContentsImplTest, NoEarlyStop) {
+// TODO(clamy): Rewrite that test when the renderer-initiated non-user-initiated
+// navigation no longer kills the speculative RenderFrameHost. See
+// https://crbug.com/889039.
+TEST_F(WebContentsImplTest, DISABLED_NoEarlyStop) {
const GURL kUrl1("http://www.chromium.org");
const GURL kUrl2("http://www.google.com");
- const GURL kUrl3("http://www.wikipedia.org");
+ const GURL kUrl3("http://www.chromium.org/foo");
contents()->NavigateAndCommit(kUrl1);
TestRenderFrameHost* current_rfh = main_test_rfh();
- // Start a browser-initiated cross-process navigation to |kUrl2|. There should
- // be a pending RenderFrameHost and the WebContents should be loading.
- controller().LoadURL(
- kUrl2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- EXPECT_TRUE(contents()->CrossProcessNavigationPending());
+ // Start a browser-initiated cross-process navigation to |kUrl2|. The
+ // WebContents should be loading.
+ auto cross_process_navigation =
+ NavigationSimulator::CreateBrowserInitiated(kUrl2, contents());
+ cross_process_navigation->ReadyToCommit();
TestRenderFrameHost* pending_rfh = contents()->GetPendingMainFrame();
- ASSERT_TRUE(pending_rfh);
EXPECT_TRUE(contents()->IsLoading());
// The current RenderFrameHost starts a non user-initiated render-initiated
- // navigation and sends a DidStartLoading IPC. The WebContents should still be
- // loading.
- current_rfh->OnMessageReceived(
- FrameHostMsg_DidStartLoading(current_rfh->GetRoutingID(), false));
- EXPECT_TRUE(contents()->IsLoading());
-
- // Simulate the pending RenderFrameHost DidStartLoading. There should still be
- // a pending RenderFrameHost and the WebContents should still be loading.
- pending_rfh->PrepareForCommit();
- pending_rfh->OnMessageReceived(
- FrameHostMsg_DidStartLoading(pending_rfh->GetRoutingID(), false));
- EXPECT_EQ(contents()->GetPendingMainFrame(), pending_rfh);
+ // navigation. The WebContents should still be loading.
+ auto same_process_navigation =
+ NavigationSimulator::CreateRendererInitiated(kUrl3, current_rfh);
+ same_process_navigation->SetHasUserGesture(false);
+ same_process_navigation->Start();
EXPECT_TRUE(contents()->IsLoading());
// Simulate the commit and DidStopLoading from the renderer-initiated
// navigation in the current RenderFrameHost. There should still be a pending
// RenderFrameHost and the WebContents should still be loading.
- current_rfh->SendNavigateWithModificationCallback(
- 0, true, kUrl3, base::Bind(SetAsNonUserGesture));
+ same_process_navigation->Commit();
current_rfh->OnMessageReceived(
FrameHostMsg_DidStopLoading(current_rfh->GetRoutingID()));
EXPECT_EQ(contents()->GetPendingMainFrame(), pending_rfh);
EXPECT_TRUE(contents()->IsLoading());
- // It should commit.
+
+ // The same-process navigation should have committed.
ASSERT_EQ(2, controller().GetEntryCount());
EXPECT_EQ(kUrl3, controller().GetLastCommittedEntry()->GetURL());
- // Commit the navigation. The formerly pending RenderFrameHost should now be
- // the current RenderFrameHost and the WebContents should still be loading.
- contents()->TestDidNavigate(pending_rfh, entry_id, true, kUrl2,
- ui::PAGE_TRANSITION_TYPED);
+ // Commit the cross-process navigation. The formerly pending RenderFrameHost
+ // should now be the current RenderFrameHost and the WebContents should still
+ // be loading.
+ cross_process_navigation->Commit();
EXPECT_FALSE(contents()->GetPendingMainFrame());
TestRenderFrameHost* new_current_rfh = main_test_rfh();
EXPECT_EQ(new_current_rfh, pending_rfh);
@@ -3332,7 +3309,7 @@ TEST_F(WebContentsImplTest, MediaWakeLock) {
// on.
rfh->OnMessageReceived(
MediaPlayerDelegateHostMsg_OnPictureInPictureModeStarted(
- 0, kPlayerAudioVideoId, surface_id, gfx::Size(), 0));
+ 0, kPlayerAudioVideoId, surface_id, gfx::Size(), 0, true));
EXPECT_TRUE(has_video_wake_lock());
EXPECT_FALSE(has_audio_wake_lock());
@@ -3424,6 +3401,7 @@ class TestOverlayWindow : public OverlayWindow {
gfx::Rect GetBounds() const override { return gfx::Rect(); }
void UpdateVideoSize(const gfx::Size& natural_size) override {}
void SetPlaybackState(PlaybackState playback_state) override {}
+ void SetAlwaysHidePlayPauseButton(bool is_visible) override {}
ui::Layer* GetWindowBackgroundLayer() override { return nullptr; }
ui::Layer* GetVideoLayer() override { return nullptr; }
gfx::Rect GetVideoBounds() override { return gfx::Rect(); }
@@ -3478,7 +3456,8 @@ TEST_F(WebContentsImplTest, EnterPictureInPicture) {
rfh->OnMessageReceived(
MediaPlayerDelegateHostMsg_OnPictureInPictureModeStarted(
rfh->GetRoutingID(), kPlayerVideoOnlyId, surface_id /* surface_id */,
- gfx::Size(42, 42) /* natural_size */, 1 /* request_id */));
+ gfx::Size(42, 42) /* natural_size */, 1 /* request_id */,
+ true /* show_play_pause_button */));
EXPECT_TRUE(observer->GetPictureInPictureVideoMediaPlayerId().has_value());
EXPECT_EQ(kPlayerVideoOnlyId,
observer->GetPictureInPictureVideoMediaPlayerId()->delegate_id);
diff --git a/chromium/content/browser/web_contents/web_contents_ns_view_bridge.h b/chromium/content/browser/web_contents/web_contents_ns_view_bridge.h
new file mode 100644
index 00000000000..cb9f1f75093
--- /dev/null
+++ b/chromium/content/browser/web_contents/web_contents_ns_view_bridge.h
@@ -0,0 +1,54 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_NS_VIEW_BRIDGE_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_NS_VIEW_BRIDGE_H_
+
+#import <Cocoa/Cocoa.h>
+
+#include <memory>
+
+#import "base/mac/scoped_nsobject.h"
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "content/public/common/web_contents_ns_view_bridge.mojom.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "ui/base/cocoa/ns_view_ids.h"
+
+namespace content {
+
+// A C++ wrapper around a WebContentsView's NSView in a non-browser process.
+class CONTENT_EXPORT WebContentsNSViewBridge
+ : public mojom::WebContentsNSViewBridge {
+ public:
+ // Create a bridge that will access its client in another process via a mojo
+ // interface. This object will be deleted when |bridge_request|'s connection
+ // closes.
+ WebContentsNSViewBridge(
+ uint64_t view_id,
+ mojom::WebContentsNSViewClientAssociatedPtr client,
+ mojom::WebContentsNSViewBridgeAssociatedRequest bridge_request);
+
+ // mojom::WebContentsNSViewBridge:
+ void SetParentViewsNSView(uint64_t parent_ns_view_id) override;
+ void Show(const gfx::Rect& bounds_in_window) override;
+ void Hide() override;
+ void MakeFirstResponder() override;
+
+ private:
+ ~WebContentsNSViewBridge() override;
+ void OnConnectionError();
+
+ base::scoped_nsobject<NSView> cocoa_view_;
+ mojom::WebContentsNSViewClientAssociatedPtr client_;
+ mojo::AssociatedBinding<mojom::WebContentsNSViewBridge> binding_;
+
+ std::unique_ptr<ui::ScopedNSViewIdMapping> view_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebContentsNSViewBridge);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_WEB_CONTENTS_NS_VIEW_BRIDGE_H_
diff --git a/chromium/content/browser/web_contents/web_contents_ns_view_bridge.mm b/chromium/content/browser/web_contents/web_contents_ns_view_bridge.mm
new file mode 100644
index 00000000000..90181ae5896
--- /dev/null
+++ b/chromium/content/browser/web_contents/web_contents_ns_view_bridge.mm
@@ -0,0 +1,65 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_contents/web_contents_ns_view_bridge.h"
+
+#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
+
+namespace content {
+
+WebContentsNSViewBridge::WebContentsNSViewBridge(
+ uint64_t view_id,
+ mojom::WebContentsNSViewClientAssociatedPtr client,
+ mojom::WebContentsNSViewBridgeAssociatedRequest bridge_request)
+ : client_(std::move(client)), binding_(this) {
+ binding_.Bind(std::move(bridge_request),
+ ui::WindowResizeHelperMac::Get()->task_runner());
+ // This object will be destroyed when its connection is closed.
+ binding_.set_connection_error_handler(base::BindOnce(
+ &WebContentsNSViewBridge::OnConnectionError, base::Unretained(this)));
+
+ // Note that this is an ordinary NSView (as opposed to a full
+ // WebContentsViewCocoa).
+ cocoa_view_.reset([[NSView alloc] initWithFrame:NSZeroRect]);
+ view_id_ =
+ std::make_unique<ui::ScopedNSViewIdMapping>(view_id, cocoa_view_.get());
+}
+
+WebContentsNSViewBridge::~WebContentsNSViewBridge() {
+ [cocoa_view_ removeFromSuperview];
+}
+
+void WebContentsNSViewBridge::OnConnectionError() {
+ delete this;
+}
+
+void WebContentsNSViewBridge::SetParentViewsNSView(uint64_t parent_ns_view_id) {
+ NSView* parent_ns_view = ui::NSViewIds::GetNSView(parent_ns_view_id);
+ // If the browser passed an invalid handle, then there is no recovery.
+ CHECK(parent_ns_view);
+ [parent_ns_view addSubview:cocoa_view_];
+}
+
+void WebContentsNSViewBridge::Show(const gfx::Rect& bounds_in_window) {
+ NSRect ns_bounds_in_window =
+ NSMakeRect(bounds_in_window.x(),
+ [[[cocoa_view_ window] contentView] frame].size.height -
+ bounds_in_window.y() - bounds_in_window.height(),
+ bounds_in_window.width(), bounds_in_window.height());
+ NSRect ns_bounds_in_superview =
+ [[cocoa_view_ superview] convertRect:ns_bounds_in_window fromView:nil];
+ [cocoa_view_ setFrame:ns_bounds_in_superview];
+ [cocoa_view_ setHidden:NO];
+}
+
+void WebContentsNSViewBridge::Hide() {
+ [cocoa_view_ setHidden:YES];
+}
+
+void WebContentsNSViewBridge::MakeFirstResponder() {
+ if ([cocoa_view_ acceptsFirstResponder])
+ [[cocoa_view_ window] makeFirstResponder:cocoa_view_];
+}
+
+} // namespace content
diff --git a/chromium/content/browser/web_contents/web_contents_view.h b/chromium/content/browser/web_contents/web_contents_view.h
index 41e44d5d658..5426d600906 100644
--- a/chromium/content/browser/web_contents/web_contents_view.h
+++ b/chromium/content/browser/web_contents/web_contents_view.h
@@ -96,8 +96,9 @@ class WebContentsView {
virtual RenderWidgetHostViewBase* CreateViewForWidget(
RenderWidgetHost* render_widget_host, bool is_guest_view_hack) = 0;
- // Creates a new View that holds a popup and receives messages for it.
- virtual RenderWidgetHostViewBase* CreateViewForPopupWidget(
+ // Creates a new View that holds a non-top-level widget and receives messages
+ // for it.
+ virtual RenderWidgetHostViewBase* CreateViewForChildWidget(
RenderWidgetHost* render_widget_host) = 0;
// Sets the page title for the native widgets corresponding to the view. This
@@ -122,13 +123,6 @@ class WebContentsView {
virtual void SetOverscrollControllerEnabled(bool enabled) = 0;
#if defined(OS_MACOSX)
- // Allowing other views disables optimizations which assume that only a single
- // WebContents is present.
- virtual void SetAllowOtherViews(bool allow) = 0;
-
- // Returns true if other views are allowed, false otherwise.
- virtual bool GetAllowOtherViews() const = 0;
-
// If we close the tab while a UI control is in an event-tracking
// loop, the control may message freed objects and crash.
// WebContents::Close() calls IsEventTracking(), and if it returns
diff --git a/chromium/content/browser/web_contents/web_contents_view_android.cc b/chromium/content/browser/web_contents/web_contents_view_android.cc
index fe977804cb8..097eb030c7e 100644
--- a/chromium/content/browser/web_contents/web_contents_view_android.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_android.cc
@@ -255,7 +255,7 @@ RenderWidgetHostViewBase* WebContentsViewAndroid::CreateViewForWidget(
return rwhv;
}
-RenderWidgetHostViewBase* WebContentsViewAndroid::CreateViewForPopupWidget(
+RenderWidgetHostViewBase* WebContentsViewAndroid::CreateViewForChildWidget(
RenderWidgetHost* render_widget_host) {
RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(render_widget_host);
return new RenderWidgetHostViewAndroid(rwhi, nullptr);
@@ -521,9 +521,10 @@ int WebContentsViewAndroid::GetBottomControlsHeight() const {
return delegate ? delegate->GetBottomControlsHeight() : 0;
}
-bool WebContentsViewAndroid::DoBrowserControlsShrinkBlinkSize() const {
+bool WebContentsViewAndroid::DoBrowserControlsShrinkRendererSize() const {
auto* delegate = web_contents_->GetDelegate();
- return delegate ? delegate->DoBrowserControlsShrinkBlinkSize() : false;
+ return delegate &&
+ delegate->DoBrowserControlsShrinkRendererSize(web_contents_);
}
bool WebContentsViewAndroid::OnTouchEvent(const ui::MotionEventAndroid& event) {
diff --git a/chromium/content/browser/web_contents/web_contents_view_android.h b/chromium/content/browser/web_contents/web_contents_view_android.h
index 53d1898347c..37358129a48 100644
--- a/chromium/content/browser/web_contents/web_contents_view_android.h
+++ b/chromium/content/browser/web_contents/web_contents_view_android.h
@@ -73,7 +73,7 @@ class WebContentsViewAndroid : public WebContentsView,
RenderWidgetHostViewBase* CreateViewForWidget(
RenderWidgetHost* render_widget_host,
bool is_guest_view_hack) override;
- RenderWidgetHostViewBase* CreateViewForPopupWidget(
+ RenderWidgetHostViewBase* CreateViewForChildWidget(
RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override;
void RenderViewCreated(RenderViewHost* host) override;
@@ -107,7 +107,7 @@ class WebContentsViewAndroid : public WebContentsView,
void TakeFocus(bool reverse) override;
int GetTopControlsHeight() const override;
int GetBottomControlsHeight() const override;
- bool DoBrowserControlsShrinkBlinkSize() const override;
+ bool DoBrowserControlsShrinkRendererSize() const override;
// ui::EventHandlerAndroid implementation.
bool OnTouchEvent(const ui::MotionEventAndroid& event) override;
diff --git a/chromium/content/browser/web_contents/web_contents_view_aura.cc b/chromium/content/browser/web_contents/web_contents_view_aura.cc
index e471459007a..ce5602b1cc3 100644
--- a/chromium/content/browser/web_contents/web_contents_view_aura.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_aura.cc
@@ -12,6 +12,7 @@
#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/message_loop/message_loop_current.h"
+#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "components/viz/common/features.h"
@@ -59,7 +60,6 @@
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
-#include "ui/aura/window_occlusion_tracker.h"
#include "ui/aura/window_tree_host.h"
#include "ui/aura/window_tree_host_observer.h"
#include "ui/base/clipboard/clipboard.h"
@@ -230,11 +230,9 @@ void PrepareDragForDownload(
// Returns the FormatType to store file system files.
const ui::Clipboard::FormatType& GetFileSystemFileFormatType() {
- static const char kFormatString[] = "chromium/x-file-system-files";
- CR_DEFINE_STATIC_LOCAL(ui::Clipboard::FormatType,
- format,
- (ui::Clipboard::GetFormatType(kFormatString)));
- return format;
+ static base::NoDestructor<ui::Clipboard::FormatType> format(
+ ui::Clipboard::GetFormatType("chromium/x-file-system-files"));
+ return *format;
}
@@ -480,7 +478,7 @@ WebContentsViewAura::WebContentsViewAura(WebContentsImpl* web_contents,
WebContentsViewDelegate* delegate)
: is_mus_browser_plugin_guest_(web_contents->GetBrowserPluginGuest() !=
nullptr &&
- features::IsUsingWindowService()),
+ features::IsMultiProcessMash()),
web_contents_(web_contents),
delegate_(delegate),
current_drag_op_(blink::kWebDragOperationNone),
@@ -763,7 +761,7 @@ void WebContentsViewAura::CreateAuraWindow(aura::Window* context) {
root_window->GetBoundsInScreen());
}
window_->layer()->SetMasksToBounds(true);
- aura::WindowOcclusionTracker::Track(window_.get());
+ window_->TrackOcclusionState();
// WindowObserver is not interesting and is problematic for Browser Plugin
// guests.
@@ -852,7 +850,7 @@ RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget(
return view;
}
-RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForPopupWidget(
+RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForChildWidget(
RenderWidgetHost* render_widget_host) {
// Popups are not created as embedded windows in mus, so
// |is_mus_browser_plugin_guest| is always false for them.
diff --git a/chromium/content/browser/web_contents/web_contents_view_aura.h b/chromium/content/browser/web_contents/web_contents_view_aura.h
index 212da86e253..0c4a3d2e0d7 100644
--- a/chromium/content/browser/web_contents/web_contents_view_aura.h
+++ b/chromium/content/browser/web_contents/web_contents_view_aura.h
@@ -122,7 +122,7 @@ class CONTENT_EXPORT WebContentsViewAura
RenderWidgetHostViewBase* CreateViewForWidget(
RenderWidgetHost* render_widget_host,
bool is_guest_view_hack) override;
- RenderWidgetHostViewBase* CreateViewForPopupWidget(
+ RenderWidgetHostViewBase* CreateViewForChildWidget(
RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override;
void RenderViewCreated(RenderViewHost* host) override;
diff --git a/chromium/content/browser/web_contents/web_contents_view_child_frame.cc b/chromium/content/browser/web_contents/web_contents_view_child_frame.cc
index 688540cea25..7b339bf9407 100644
--- a/chromium/content/browser/web_contents/web_contents_view_child_frame.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_child_frame.cc
@@ -88,9 +88,9 @@ RenderWidgetHostViewBase* WebContentsViewChildFrame::CreateViewForWidget(
return RenderWidgetHostViewChildFrame::Create(render_widget_host);
}
-RenderWidgetHostViewBase* WebContentsViewChildFrame::CreateViewForPopupWidget(
+RenderWidgetHostViewBase* WebContentsViewChildFrame::CreateViewForChildWidget(
RenderWidgetHost* render_widget_host) {
- return GetOuterView()->CreateViewForPopupWidget(render_widget_host);
+ return GetOuterView()->CreateViewForChildWidget(render_widget_host);
}
void WebContentsViewChildFrame::SetPageTitle(const base::string16& title) {
@@ -117,15 +117,6 @@ bool WebContentsViewChildFrame::IsEventTracking() const {
void WebContentsViewChildFrame::CloseTabAfterEventTracking() {
NOTREACHED();
}
-
-void WebContentsViewChildFrame::SetAllowOtherViews(bool allow) {
- NOTREACHED();
-}
-
-bool WebContentsViewChildFrame::GetAllowOtherViews() const {
- NOTREACHED();
- return false;
-}
#endif
void WebContentsViewChildFrame::RestoreFocus() {
diff --git a/chromium/content/browser/web_contents/web_contents_view_child_frame.h b/chromium/content/browser/web_contents/web_contents_view_child_frame.h
index e5485f5609c..e82cced4364 100644
--- a/chromium/content/browser/web_contents/web_contents_view_child_frame.h
+++ b/chromium/content/browser/web_contents/web_contents_view_child_frame.h
@@ -41,7 +41,7 @@ class WebContentsViewChildFrame : public WebContentsView,
RenderWidgetHostViewBase* CreateViewForWidget(
RenderWidgetHost* render_widget_host,
bool is_guest_view_hack) override;
- RenderWidgetHostViewBase* CreateViewForPopupWidget(
+ RenderWidgetHostViewBase* CreateViewForChildWidget(
RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override;
void RenderViewCreated(RenderViewHost* host) override;
@@ -50,8 +50,6 @@ class WebContentsViewChildFrame : public WebContentsView,
RenderViewHost* new_host) override;
void SetOverscrollControllerEnabled(bool enabled) override;
#if defined(OS_MACOSX)
- void SetAllowOtherViews(bool allow) override;
- bool GetAllowOtherViews() const override;
bool IsEventTracking() const override;
void CloseTabAfterEventTracking() override;
#endif
diff --git a/chromium/content/browser/web_contents/web_contents_view_guest.cc b/chromium/content/browser/web_contents/web_contents_view_guest.cc
index 12f6817499e..5de4d7cf8a7 100644
--- a/chromium/content/browser/web_contents/web_contents_view_guest.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_guest.cc
@@ -17,6 +17,7 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/drag_messages.h"
+#include "content/public/browser/guest_mode.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/context_menu_params.h"
#include "content/public/common/drop_data.h"
@@ -45,6 +46,7 @@ WebContentsViewGuest::WebContentsViewGuest(
platform_view_(std::move(platform_view)),
platform_view_delegate_view_(*delegate_view) {
*delegate_view = this;
+ DCHECK(!GuestMode::IsCrossProcessFrameGuest(web_contents));
}
WebContentsViewGuest::~WebContentsViewGuest() {
@@ -72,14 +74,14 @@ void WebContentsViewGuest::OnGuestAttached(WebContentsView* parent_view) {
// view hierarchy. We add this view as embedder's child here.
// This would go in WebContentsViewGuest::CreateView, but that is too early to
// access embedder_web_contents(). Therefore, we do it here.
- if (!features::IsUsingWindowService())
+ if (!features::IsMultiProcessMash())
parent_view->GetNativeView()->AddChild(platform_view_->GetNativeView());
#endif // defined(USE_AURA)
}
void WebContentsViewGuest::OnGuestDetached(WebContentsView* old_parent_view) {
#if defined(USE_AURA)
- if (!features::IsUsingWindowService()) {
+ if (!features::IsMultiProcessMash()) {
old_parent_view->GetNativeView()->RemoveChild(
platform_view_->GetNativeView());
}
@@ -115,16 +117,6 @@ gfx::Rect WebContentsViewGuest::GetViewBounds() const {
return gfx::Rect(size_);
}
-#if defined(OS_MACOSX)
-void WebContentsViewGuest::SetAllowOtherViews(bool allow) {
- platform_view_->SetAllowOtherViews(allow);
-}
-
-bool WebContentsViewGuest::GetAllowOtherViews() const {
- return platform_view_->GetAllowOtherViews();
-}
-#endif
-
void WebContentsViewGuest::CreateView(const gfx::Size& initial_size,
gfx::NativeView context) {
platform_view_->CreateView(initial_size, context);
@@ -151,9 +143,9 @@ RenderWidgetHostViewBase* WebContentsViewGuest::CreateViewForWidget(
platform_widget->GetWeakPtr());
}
-RenderWidgetHostViewBase* WebContentsViewGuest::CreateViewForPopupWidget(
+RenderWidgetHostViewBase* WebContentsViewGuest::CreateViewForChildWidget(
RenderWidgetHost* render_widget_host) {
- return platform_view_->CreateViewForPopupWidget(render_widget_host);
+ return platform_view_->CreateViewForChildWidget(render_widget_host);
}
void WebContentsViewGuest::SetPageTitle(const base::string16& title) {
diff --git a/chromium/content/browser/web_contents/web_contents_view_guest.h b/chromium/content/browser/web_contents/web_contents_view_guest.h
index 9e3511a9dab..1f0e661628a 100644
--- a/chromium/content/browser/web_contents/web_contents_view_guest.h
+++ b/chromium/content/browser/web_contents/web_contents_view_guest.h
@@ -59,7 +59,7 @@ class WebContentsViewGuest : public WebContentsView,
RenderWidgetHostViewBase* CreateViewForWidget(
RenderWidgetHost* render_widget_host,
bool is_guest_view_hack) override;
- RenderWidgetHostViewBase* CreateViewForPopupWidget(
+ RenderWidgetHostViewBase* CreateViewForChildWidget(
RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override;
void RenderViewCreated(RenderViewHost* host) override;
@@ -68,8 +68,6 @@ class WebContentsViewGuest : public WebContentsView,
RenderViewHost* new_host) override;
void SetOverscrollControllerEnabled(bool enabled) override;
#if defined(OS_MACOSX)
- void SetAllowOtherViews(bool allow) override;
- bool GetAllowOtherViews() const override;
bool IsEventTracking() const override;
void CloseTabAfterEventTracking() override;
#endif
diff --git a/chromium/content/browser/web_contents/web_contents_view_mac.h b/chromium/content/browser/web_contents/web_contents_view_mac.h
index 7f80c1b1d82..d08876fc503 100644
--- a/chromium/content/browser/web_contents/web_contents_view_mac.h
+++ b/chromium/content/browser/web_contents/web_contents_view_mac.h
@@ -19,8 +19,10 @@
#include "content/browser/web_contents/web_contents_view.h"
#include "content/common/content_export.h"
#include "content/common/drag_event_source_info.h"
-#import "ui/base/cocoa/accessibility_hostable.h"
+#include "content/public/common/web_contents_ns_view_bridge.mojom.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
#import "ui/base/cocoa/base_view.h"
+#import "ui/base/cocoa/views_hostable.h"
#include "ui/gfx/geometry/size.h"
@class WebDragDest;
@@ -37,12 +39,8 @@ namespace gfx {
class Vector2d;
}
-namespace ui {
-class Layer;
-}
-
CONTENT_EXPORT
-@interface WebContentsViewCocoa : BaseView<AccessibilityHostable> {
+@interface WebContentsViewCocoa : BaseView<ViewsHostable> {
@private
// Instances of this class are owned by both webContentsView_ and AppKit. It
// is possible for an instance to outlive its webContentsView_. The
@@ -56,6 +54,12 @@ CONTENT_EXPORT
- (void)setMouseDownCanMoveWindow:(BOOL)canMove;
+// Sets |accessibilityParent| as the object returned when the
+// receiver is queried for its accessibility parent.
+// TODO(lgrey/ellyjones): Remove this in favor of setAccessibilityParent:
+// when we switch to the new accessibility API.
+- (void)setAccessibilityParentElement:(id)accessibilityParent;
+
// Returns the available drag operations. This is a required method for
// NSDraggingSource. It is supposedly deprecated, but the non-deprecated API
// -[NSWindow dragImage:...] still relies on it.
@@ -69,7 +73,9 @@ namespace content {
// contains all of the contents of the tab and associated child views.
class WebContentsViewMac : public WebContentsView,
public RenderViewHostDelegateView,
- public PopupMenuHelper::Delegate {
+ public PopupMenuHelper::Delegate,
+ public mojom::WebContentsNSViewClient,
+ public ui::ViewsHostableView {
public:
// The corresponding WebContentsImpl is passed in the constructor, and manages
// our lifetime. This doesn't need to be the case, but is this way currently
@@ -91,14 +97,12 @@ class WebContentsViewMac : public WebContentsView,
void FocusThroughTabTraversal(bool reverse) override;
DropData* GetDropData() const override;
gfx::Rect GetViewBounds() const override;
- void SetAllowOtherViews(bool allow) override;
- bool GetAllowOtherViews() const override;
void CreateView(const gfx::Size& initial_size,
gfx::NativeView context) override;
RenderWidgetHostViewBase* CreateViewForWidget(
RenderWidgetHost* render_widget_host,
bool is_guest_view_hack) override;
- RenderWidgetHostViewBase* CreateViewForPopupWidget(
+ RenderWidgetHostViewBase* CreateViewForChildWidget(
RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override;
void RenderViewCreated(RenderViewHost* host) override;
@@ -134,12 +138,17 @@ class WebContentsViewMac : public WebContentsView,
// PopupMenuHelper::Delegate:
void OnMenuClosed() override;
+ // ViewsHostableView:
+ void OnViewsHostableAttached(ViewsHostableView::Host* host) override;
+ void OnViewsHostableDetached() override;
+ void OnViewsHostableShow(const gfx::Rect& bounds_in_window) override;
+ void OnViewsHostableHide() override;
+ void OnViewsHostableMakeFirstResponder() override;
+
// A helper method for closing the tab in the
// CloseTabAfterEventTracking() implementation.
void CloseTab();
- void SetParentUiLayer(ui::Layer* parent_ui_layer);
-
WebContentsImpl* web_contents() { return web_contents_; }
WebContentsViewDelegate* delegate() { return delegate_.get(); }
@@ -151,6 +160,10 @@ class WebContentsViewMac : public WebContentsView,
RenderWidgetHostViewCreateFunction create_render_widget_host_view);
private:
+ // Return the list of child RenderWidgetHostViewMacs. This will remove any
+ // destroyed instances before returning.
+ std::list<RenderWidgetHostViewMac*> GetChildViews();
+
// Returns the fullscreen view, if one exists; otherwise, returns the content
// native view. This ensures that the view currently attached to a NSWindow is
// being used to query or set first responder state.
@@ -165,9 +178,6 @@ class WebContentsViewMac : public WebContentsView,
// Our optional delegate.
std::unique_ptr<WebContentsViewDelegate> delegate_;
- // Whether to allow other views.
- bool allow_other_views_;
-
// This contains all RenderWidgetHostViewMacs that have been added as child
// NSViews to this NSView. Note that this list may contain RWHVMacs besides
// just |web_contents_->GetRenderWidgetHostView()|. The only time that the
@@ -175,10 +185,19 @@ class WebContentsViewMac : public WebContentsView,
// destroyed.
std::list<base::WeakPtr<RenderWidgetHostViewBase>> child_views_;
- ui::Layer* parent_ui_layer_ = nullptr;
+ // Interface to the views::View host of this view.
+ ViewsHostableView::Host* views_host_ = nullptr;
std::unique_ptr<PopupMenuHelper> popup_menu_helper_;
+ // The id that may be used to look up this NSView.
+ const uint64_t ns_view_id_;
+
+ // Mojo bindings for an out of process instance of this NSView.
+ mojom::WebContentsNSViewBridgeAssociatedPtr ns_view_bridge_remote_;
+ mojo::AssociatedBinding<mojom::WebContentsNSViewClient>
+ ns_view_client_binding_;
+
DISALLOW_COPY_AND_ASSIGN(WebContentsViewMac);
};
diff --git a/chromium/content/browser/web_contents/web_contents_view_mac.mm b/chromium/content/browser/web_contents/web_contents_view_mac.mm
index 94848b56836..3374d2b122d 100644
--- a/chromium/content/browser/web_contents/web_contents_view_mac.mm
+++ b/chromium/content/browser/web_contents/web_contents_view_mac.mm
@@ -23,12 +23,15 @@
#import "content/browser/web_contents/web_drag_source_mac.h"
#include "content/common/view_messages.h"
#include "content/public/browser/interstitial_page.h"
+#include "content/public/browser/ns_view_bridge_factory_host.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_view_delegate.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
#include "skia/ext/skia_utils_mac.h"
#import "third_party/mozilla/NSPasteboard+Utils.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/cocoa/cocoa_base_utils.h"
+#include "ui/base/cocoa/ns_view_ids.h"
#include "ui/base/dragdrop/cocoa_dnd_util.h"
#include "ui/display/screen.h"
#include "ui/gfx/image/image_skia_util_mac.h"
@@ -107,10 +110,13 @@ WebContentsViewMac::WebContentsViewMac(WebContentsImpl* web_contents,
WebContentsViewDelegate* delegate)
: web_contents_(web_contents),
delegate_(delegate),
- allow_other_views_(false) {
-}
+ ns_view_id_(ui::NSViewIds::GetNewId()),
+ ns_view_client_binding_(this) {}
WebContentsViewMac::~WebContentsViewMac() {
+ if (views_host_)
+ views_host_->OnHostableViewDestroying();
+ DCHECK(!views_host_);
// This handles the case where a renderer close call was deferred
// while the user was operating a UI control which resulted in a
// close. In that case, the Cocoa view outlives the
@@ -322,21 +328,6 @@ gfx::Rect WebContentsViewMac::GetViewBounds() const {
return gfx::ScreenRectFromNSRect(window_bounds);
}
-void WebContentsViewMac::SetAllowOtherViews(bool allow) {
- if (allow_other_views_ == allow)
- return;
-
- allow_other_views_ = allow;
- RenderWidgetHostViewMac* view = static_cast<RenderWidgetHostViewMac*>(
- web_contents_->GetRenderWidgetHostView());
- if (view)
- view->SetAllowPauseForResizeOrRepaint(!allow_other_views_);
-}
-
-bool WebContentsViewMac::GetAllowOtherViews() const {
- return allow_other_views_;
-}
-
void WebContentsViewMac::CreateView(
const gfx::Size& initial_size, gfx::NativeView context) {
WebContentsViewCocoa* view =
@@ -369,11 +360,17 @@ RenderWidgetHostViewBase* WebContentsViewMac::CreateViewForWidget(
view->SetDelegate(rw_delegate.get());
}
- view->SetAllowPauseForResizeOrRepaint(!allow_other_views_);
// Add the RenderWidgetHostView to the ui::Layer heirarchy.
child_views_.push_back(view->GetWeakPtr());
- SetParentUiLayer(parent_ui_layer_);
+ if (views_host_) {
+ NSViewBridgeFactoryHost* factory_host =
+ NSViewBridgeFactoryHost::GetFromHostId(
+ views_host_->GetViewsFactoryHostId());
+
+ view->MigrateNSViewBridge(factory_host, ns_view_id_);
+ view->SetParentUiLayer(views_host_->GetUiLayer());
+ }
// Fancy layout comes later; for now just make it our size and resize it
// with us. In case there are other siblings of the content area, we want
@@ -397,7 +394,7 @@ RenderWidgetHostViewBase* WebContentsViewMac::CreateViewForWidget(
return view;
}
-RenderWidgetHostViewBase* WebContentsViewMac::CreateViewForPopupWidget(
+RenderWidgetHostViewBase* WebContentsViewMac::CreateViewForChildWidget(
RenderWidgetHost* render_widget_host) {
RenderWidgetHostViewMac* view =
new RenderWidgetHostViewMac(render_widget_host, false);
@@ -449,19 +446,91 @@ void WebContentsViewMac::CloseTab() {
web_contents_->Close(web_contents_->GetRenderViewHost());
}
-void WebContentsViewMac::SetParentUiLayer(ui::Layer* parent_ui_layer) {
- parent_ui_layer_ = parent_ui_layer;
+std::list<RenderWidgetHostViewMac*> WebContentsViewMac::GetChildViews() {
// Remove any child NSViews that have been destroyed.
+ std::list<RenderWidgetHostViewMac*> result;
for (auto iter = child_views_.begin(); iter != child_views_.end();) {
- if (*iter)
- (*iter++)->SetParentUiLayer(parent_ui_layer);
- else
+ if (*iter) {
+ result.push_back(reinterpret_cast<RenderWidgetHostViewMac*>(iter->get()));
+ iter++;
+ } else {
iter = child_views_.erase(iter);
+ }
+ }
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WebContentsViewMac, ViewsHostableView:
+
+void WebContentsViewMac::OnViewsHostableAttached(
+ ViewsHostableView::Host* host) {
+ views_host_ = host;
+ [cocoa_view_
+ setAccessibilityParentElement:views_host_->GetAccessibilityElement()];
+
+ // Create an NSView in the target process, if one exists.
+ uint64_t factory_host_id = views_host_->GetViewsFactoryHostId();
+ NSViewBridgeFactoryHost* factory_host =
+ NSViewBridgeFactoryHost::GetFromHostId(factory_host_id);
+ if (factory_host) {
+ mojom::WebContentsNSViewClientAssociatedPtr client;
+ ns_view_client_binding_.Bind(mojo::MakeRequest(&client));
+ mojom::WebContentsNSViewBridgeAssociatedRequest bridge_request =
+ mojo::MakeRequest(&ns_view_bridge_remote_);
+
+ factory_host->GetFactory()->CreateWebContentsNSViewBridge(
+ ns_view_id_, client.PassInterface(), std::move(bridge_request));
+
+ ns_view_bridge_remote_->SetParentViewsNSView(views_host_->GetNSViewId());
+ } else if (factory_host_id != NSViewBridgeFactoryHost::kLocalDirectHostId) {
+ LOG(ERROR) << "Failed to look up NSViewBridgeFactoryHost!";
+ }
+
+ for (auto* rwhv_mac : GetChildViews()) {
+ rwhv_mac->MigrateNSViewBridge(factory_host, ns_view_id_);
+ rwhv_mac->SetParentUiLayer(views_host_->GetUiLayer());
}
}
+void WebContentsViewMac::OnViewsHostableDetached() {
+ DCHECK(views_host_);
+ views_host_ = nullptr;
+
+ for (auto* rwhv_mac : GetChildViews()) {
+ rwhv_mac->MigrateNSViewBridge(nullptr, 0);
+ rwhv_mac->SetParentUiLayer(nullptr);
+ }
+
+ [cocoa_view_ setAccessibilityParentElement:nil];
+
+ // Disconnect from the bridge. This will have the effect of destroying the
+ // associated bridge instance with its NSView.
+ ns_view_client_binding_.Close();
+ ns_view_bridge_remote_.reset();
+}
+
+void WebContentsViewMac::OnViewsHostableShow(
+ const gfx::Rect& bounds_in_window) {
+ if (ns_view_bridge_remote_)
+ ns_view_bridge_remote_->Show(bounds_in_window);
+}
+
+void WebContentsViewMac::OnViewsHostableHide() {
+ if (ns_view_bridge_remote_)
+ ns_view_bridge_remote_->Hide();
+}
+
+void WebContentsViewMac::OnViewsHostableMakeFirstResponder() {
+ if (ns_view_bridge_remote_)
+ ns_view_bridge_remote_->MakeFirstResponder();
+}
+
} // namespace content
+////////////////////////////////////////////////////////////////////////////////
+// WebContentsViewCocoa
+
@implementation WebContentsViewCocoa
- (id)initWithWebContentsViewMac:(WebContentsViewMac*)w {
@@ -674,11 +743,6 @@ void WebContentsViewMac::SetParentUiLayer(ui::Layer* parent_ui_layer) {
FocusThroughTabTraversal(direction == NSSelectingPrevious);
}
-- (void)cr_setParentUiLayer:(ui::Layer*)parentUiLayer {
- if (webContentsView_)
- webContentsView_->SetParentUiLayer(parentUiLayer);
-}
-
- (void)updateWebContentsVisibility {
WebContentsImpl* webContents = [self webContents];
if (!webContents || webContents->IsBeingDestroyed())
@@ -743,11 +807,15 @@ void WebContentsViewMac::SetParentUiLayer(ui::Layer* parent_ui_layer) {
[self updateWebContentsVisibility];
}
-// AccessibilityHostable protocol implementation.
- (void)setAccessibilityParentElement:(id)accessibilityParent {
accessibilityParent_.reset([accessibilityParent retain]);
}
+// ViewsHostable protocol implementation.
+- (ui::ViewsHostableView*)viewsHostableView {
+ return webContentsView_;
+}
+
// NSAccessibility informal protocol implementation.
- (id)accessibilityAttributeValue:(NSString*)attribute {
if (accessibilityParent_ &&
diff --git a/chromium/content/browser/web_contents/web_drag_source_mac.mm b/chromium/content/browser/web_contents/web_drag_source_mac.mm
index 1ebcedb0875..32f12c77378 100644
--- a/chromium/content/browser/web_contents/web_drag_source_mac.mm
+++ b/chromium/content/browser/web_contents/web_drag_source_mac.mm
@@ -31,6 +31,7 @@
#include "net/base/escape.h"
#include "net/base/filename_util.h"
#include "net/base/mime_util.h"
+#include "ui/base/clipboard/clipboard_util_mac.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/cocoa/cocoa_base_utils.h"
#include "ui/base/dragdrop/cocoa_dnd_util.h"
@@ -49,10 +50,6 @@ using content::RenderViewHostImpl;
namespace {
-// An unofficial standard pasteboard title type to be provided alongside the
-// |NSURLPboardType|.
-NSString* const kNSURLTitlePboardType = @"public.url-name";
-
// This helper's sole task is to write out data for a promised file; the caller
// is responsible for opening the file. It takes the drop data and an open file
// stream.
@@ -154,9 +151,9 @@ void PromiseWriterHelper(const DropData& drop_data,
}
[url writeToPasteboard:pboard];
// URL title.
- } else if ([type isEqualToString:kNSURLTitlePboardType]) {
+ } else if ([type isEqualToString:ui::kUTTypeURLName]) {
[pboard setString:SysUTF16ToNSString(dropData_->url_title)
- forType:kNSURLTitlePboardType];
+ forType:ui::kUTTypeURLName];
// File contents.
} else if ([type isEqualToString:base::mac::CFToNSCast(fileUTI_)]) {
@@ -348,7 +345,7 @@ void PromiseWriterHelper(const DropData& drop_data,
// URL (and title).
if (dropData_->url.is_valid()) {
- [pasteboard_ addTypes:@[ NSURLPboardType, kNSURLTitlePboardType ]
+ [pasteboard_ addTypes:@[ NSURLPboardType, ui::kUTTypeURLName ]
owner:contentsView_];
}
diff --git a/chromium/content/browser/web_package/mock_signed_exchange_handler.cc b/chromium/content/browser/web_package/mock_signed_exchange_handler.cc
index 2381c3b9e62..808e695ec5a 100644
--- a/chromium/content/browser/web_package/mock_signed_exchange_handler.cc
+++ b/chromium/content/browser/web_package/mock_signed_exchange_handler.cc
@@ -14,6 +14,7 @@
namespace content {
MockSignedExchangeHandler::MockSignedExchangeHandler(
+ SignedExchangeLoadResult result,
net::Error error,
const GURL& request_url,
const std::string& mime_type,
@@ -31,18 +32,20 @@ MockSignedExchangeHandler::MockSignedExchangeHandler(
head.headers->AddHeader(header);
}
base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(headers_callback), error, request_url,
- "GET", head, std::move(body)));
+ FROM_HERE, base::BindOnce(std::move(headers_callback), result, error,
+ request_url, "GET", head, std::move(body)));
}
MockSignedExchangeHandler::~MockSignedExchangeHandler() {}
MockSignedExchangeHandlerFactory::MockSignedExchangeHandlerFactory(
+ SignedExchangeLoadResult result,
net::Error error,
const GURL& request_url,
const std::string& mime_type,
std::vector<std::string> response_headers)
- : error_(error),
+ : result_(result),
+ error_(error),
request_url_(request_url),
mime_type_(mime_type),
response_headers_(std::move(response_headers)) {}
@@ -54,8 +57,8 @@ std::unique_ptr<SignedExchangeHandler> MockSignedExchangeHandlerFactory::Create(
ExchangeHeadersCallback headers_callback,
std::unique_ptr<SignedExchangeCertFetcherFactory> cert_fetcher_factory) {
return std::make_unique<MockSignedExchangeHandler>(
- error_, request_url_, mime_type_, response_headers_, std::move(body),
- std::move(headers_callback));
+ result_, error_, request_url_, mime_type_, response_headers_,
+ std::move(body), std::move(headers_callback));
}
} // namespace content
diff --git a/chromium/content/browser/web_package/mock_signed_exchange_handler.h b/chromium/content/browser/web_package/mock_signed_exchange_handler.h
index 6c7bf97cd14..2b8d6e4042f 100644
--- a/chromium/content/browser/web_package/mock_signed_exchange_handler.h
+++ b/chromium/content/browser/web_package/mock_signed_exchange_handler.h
@@ -17,7 +17,8 @@ class SignedExchangeCertFetcherFactory;
class MockSignedExchangeHandler final : public SignedExchangeHandler {
public:
- MockSignedExchangeHandler(net::Error error,
+ MockSignedExchangeHandler(SignedExchangeLoadResult result,
+ net::Error error,
const GURL& request_url,
const std::string& mime_type,
const std::vector<std::string>& response_headers,
@@ -36,11 +37,12 @@ class MockSignedExchangeHandlerFactory final
SignedExchangeHandler::ExchangeHeadersCallback;
// Creates a factory that creates SignedExchangeHandler which always fires
- // a headers callback with the given |error|, |request_url|, |mime_type|
- // and |response_headers|.
+ // a headers callback with the given |result|, |error|, |request_url|,
+ // |mime_type| and |response_headers|.
// |mime_type| and |response_headers| are ignored if |error| is not
// net::OK.
- MockSignedExchangeHandlerFactory(net::Error error,
+ MockSignedExchangeHandlerFactory(SignedExchangeLoadResult result,
+ net::Error error,
const GURL& request_url,
const std::string& mime_type,
std::vector<std::string> response_headers);
@@ -53,6 +55,7 @@ class MockSignedExchangeHandlerFactory final
override;
private:
+ const SignedExchangeLoadResult result_;
const net::Error error_;
const GURL request_url_;
const std::string mime_type_;
diff --git a/chromium/content/browser/web_package/origins_list.cc b/chromium/content/browser/web_package/origins_list.cc
new file mode 100644
index 00000000000..05faed760c2
--- /dev/null
+++ b/chromium/content/browser/web_package/origins_list.cc
@@ -0,0 +1,82 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_package/origins_list.h"
+
+#include "base/strings/string_split.h"
+#include "url/gurl.h"
+
+namespace content {
+namespace signed_exchange_utils {
+
+constexpr char kSubdomainMatchPrefix[] = "*.";
+
+OriginsList::OriginsList() = default;
+
+OriginsList::OriginsList(base::StringPiece str) {
+ std::vector<base::StringPiece> elements = base::SplitStringPiece(
+ str, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+
+ for (base::StringPiece element : elements) {
+ bool subdomain_match = false;
+ if (base::StartsWith(element, kSubdomainMatchPrefix,
+ base::CompareCase::SENSITIVE)) {
+ subdomain_match = true;
+ element.remove_prefix(sizeof(kSubdomainMatchPrefix) - 1);
+ }
+ if (base::StartsWith(element,
+ "https:", base::CompareCase::INSENSITIVE_ASCII)) {
+ LOG(ERROR) << "OriginsList entry should omit https scheme: \"" << element
+ << "\"";
+ continue;
+ }
+
+ std::string url_str("https://");
+ element.AppendToString(&url_str);
+ GURL url(url_str);
+ if (!url.is_valid()) {
+ LOG(ERROR) << "Failed to parse an OriginsList entry to a valid Origin: \""
+ << element << "\"";
+ continue;
+ }
+ DCHECK(url.SchemeIs("https"));
+
+ url::Origin origin = url::Origin::Create(url);
+ if (subdomain_match) {
+ subdomain_match_origins_.push_back(origin);
+ } else {
+ exact_match_origins_.insert(origin);
+ }
+ }
+}
+
+OriginsList::OriginsList(OriginsList&&) = default;
+OriginsList::~OriginsList() = default;
+
+bool OriginsList::IsEmpty() const {
+ return exact_match_origins_.empty() && subdomain_match_origins_.empty();
+}
+
+bool OriginsList::Match(const url::Origin& origin) const {
+ // OriginsList only contains HTTPS scheme origins.
+ if (origin.scheme() != url::kHttpsScheme) {
+ return false;
+ }
+
+ if (exact_match_origins_.find(origin) != exact_match_origins_.end()) {
+ return true;
+ }
+
+ for (const auto& subdomain_match_origin : subdomain_match_origins_) {
+ if (origin.DomainIs(subdomain_match_origin.host()) &&
+ origin.port() == subdomain_match_origin.port()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace signed_exchange_utils
+} // namespace content
diff --git a/chromium/content/browser/web_package/origins_list.h b/chromium/content/browser/web_package/origins_list.h
new file mode 100644
index 00000000000..4bd3cff8cac
--- /dev/null
+++ b/chromium/content/browser/web_package/origins_list.h
@@ -0,0 +1,52 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_PACKAGE_ORIGINS_LIST_H_
+#define CONTENT_BROWSER_WEB_PACKAGE_ORIGINS_LIST_H_
+
+#include <vector>
+
+#include "base/containers/flat_set.h"
+#include "base/strings/string_piece.h"
+#include "content/common/content_export.h"
+#include "url/origin.h"
+
+namespace content {
+namespace signed_exchange_utils {
+
+// OriginsList can query if a particular origin |Match|.
+// OriginsList can only match HTTPS origins.
+class CONTENT_EXPORT OriginsList {
+ public:
+ OriginsList();
+
+ // Creates an OriginsList from comma-separated list of hosts.
+ //
+ // Entries starting with "*." will match with subdomains.
+ //
+ // For example, "example.com,*.google.com" will create an
+ // OriginsList that match exactly "example.com" but not its
+ // subdomains, and all subdomains of "google.com".
+ //
+ // Note: Entries should NOT start with "https://", but start from hostname.
+ explicit OriginsList(base::StringPiece str);
+
+ OriginsList(OriginsList&&);
+ ~OriginsList();
+
+ // Returns true when |this| has an empty list to match
+ // (i.e. no origins would match).
+ bool IsEmpty() const;
+
+ bool Match(const url::Origin& origin) const;
+
+ private:
+ base::flat_set<url::Origin> exact_match_origins_;
+ std::vector<url::Origin> subdomain_match_origins_;
+};
+
+} // namespace signed_exchange_utils
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_PACKAGE_ORIGINS_LIST_H_
diff --git a/chromium/content/browser/web_package/origins_list_unittest.cc b/chromium/content/browser/web_package/origins_list_unittest.cc
new file mode 100644
index 00000000000..3338a3b978d
--- /dev/null
+++ b/chromium/content/browser/web_package/origins_list_unittest.cc
@@ -0,0 +1,77 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_package/origins_list.h"
+
+#include "base/callback.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace content {
+namespace signed_exchange_utils {
+
+TEST(OriginsList, IsEmpty) {
+ OriginsList origins_list;
+ EXPECT_TRUE(origins_list.IsEmpty());
+}
+
+TEST(OriginsList, ExactMatch) {
+ OriginsList origins_list(
+ "example.com,test.example.com,https://invalid.entry,example.net:1234");
+
+ EXPECT_FALSE(origins_list.IsEmpty());
+
+ static constexpr const char* kShouldMatchList[] = {
+ "https://example.com", "https://test.example.com",
+ "https://example.net:1234",
+ };
+
+ for (const char* should_match : kShouldMatchList) {
+ EXPECT_TRUE(origins_list.Match(url::Origin::Create(GURL(should_match))))
+ << "OriginList should match url: " << should_match;
+ }
+
+ static constexpr const char* kShouldNotMatchList[] = {
+ "http://example.com", "https://subdomain.example.com",
+ "https://notexample.com", "https://invalid.entry",
+ "https://example.net", "https://example.net:5432",
+ };
+
+ for (const char* should_not_match : kShouldNotMatchList) {
+ EXPECT_FALSE(
+ origins_list.Match(url::Origin::Create(GURL(should_not_match))))
+ << "OriginList should not match url: " << should_not_match;
+ }
+}
+
+TEST(OriginsList, SubdomainMatch) {
+ OriginsList origins_list("*.example.com,*.example.net:1234");
+
+ EXPECT_FALSE(origins_list.IsEmpty());
+
+ static constexpr const char* kShouldMatchList[] = {
+ "https://example.com", "https://test.example.com",
+ "https://test.test2.example.com", "https://test.example.net:1234",
+ };
+
+ for (const char* should_match : kShouldMatchList) {
+ EXPECT_TRUE(origins_list.Match(url::Origin::Create(GURL(should_match))))
+ << "OriginList should match url: " << should_match;
+ }
+
+ static constexpr const char* kShouldNotMatchList[] = {
+ "http://example.com", "https://notexample.com",
+ "https://test.example.net", "https://test.example.net:5432",
+ };
+
+ for (const char* should_not_match : kShouldNotMatchList) {
+ EXPECT_FALSE(
+ origins_list.Match(url::Origin::Create(GURL(should_not_match))))
+ << "OriginList should not match url: " << should_not_match;
+ }
+}
+
+} // namespace signed_exchange_utils
+} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_cert_fetcher.cc b/chromium/content/browser/web_package/signed_exchange_cert_fetcher.cc
index 90dd7610d3e..123e653bff7 100644
--- a/chromium/content/browser/web_package/signed_exchange_cert_fetcher.cc
+++ b/chromium/content/browser/web_package/signed_exchange_cert_fetcher.cc
@@ -5,6 +5,7 @@
#include "content/browser/web_package/signed_exchange_cert_fetcher.h"
#include "base/format_macros.h"
+#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
@@ -147,7 +148,7 @@ void SignedExchangeCertFetcher::Abort() {
handle_watcher_ = nullptr;
body_string_.clear();
devtools_proxy_ = nullptr;
- std::move(callback_).Run(nullptr);
+ std::move(callback_).Run(SignedExchangeLoadResult::kCertFetchError, nullptr);
}
void SignedExchangeCertFetcher::OnHandleReady(MojoResult result) {
@@ -191,10 +192,12 @@ void SignedExchangeCertFetcher::OnDataComplete() {
if (!cert_chain) {
signed_exchange_utils::ReportErrorAndTraceEvent(
devtools_proxy_, "Failed to get certificate chain from message.");
- std::move(callback_).Run(nullptr);
+ std::move(callback_).Run(SignedExchangeLoadResult::kCertParseError,
+ nullptr);
return;
}
- std::move(callback_).Run(std::move(cert_chain));
+ std::move(callback_).Run(SignedExchangeLoadResult::kSuccess,
+ std::move(cert_chain));
}
// network::mojom::URLLoaderClient
@@ -243,6 +246,9 @@ void SignedExchangeCertFetcher::OnReceiveResponse(
}
body_string_.reserve(head.content_length);
}
+
+ UMA_HISTOGRAM_BOOLEAN("SignedExchange.CertificateFetch.CacheHit",
+ head.was_fetched_via_cache);
}
void SignedExchangeCertFetcher::OnReceiveRedirect(
diff --git a/chromium/content/browser/web_package/signed_exchange_cert_fetcher.h b/chromium/content/browser/web_package/signed_exchange_cert_fetcher.h
index 679ed5f7eba..d3fdbc631fe 100644
--- a/chromium/content/browser/web_package/signed_exchange_cert_fetcher.h
+++ b/chromium/content/browser/web_package/signed_exchange_cert_fetcher.h
@@ -14,6 +14,7 @@
#include "base/optional.h"
#include "base/unguessable_token.h"
#include "content/browser/web_package/signed_exchange_certificate_chain.h"
+#include "content/browser/web_package/signed_exchange_error.h"
#include "content/common/content_export.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "url/origin.h"
@@ -36,7 +37,8 @@ class CONTENT_EXPORT SignedExchangeCertFetcher
: public network::mojom::URLLoaderClient {
public:
using CertificateCallback =
- base::OnceCallback<void(std::unique_ptr<SignedExchangeCertificateChain>)>;
+ base::OnceCallback<void(SignedExchangeLoadResult,
+ std::unique_ptr<SignedExchangeCertificateChain>)>;
// Starts fetching the certificate using a ThrottlingURLLoader created with
// the |shared_url_loader_factory| and the |throttles|. The |callback| will
diff --git a/chromium/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc b/chromium/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
index 104dbe1498c..f25ee99ca6f 100644
--- a/chromium/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
+++ b/chromium/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
@@ -137,8 +137,11 @@ class URLLoaderFactoryForMockLoader final
void ForwardCertificateCallback(
bool* called,
+ SignedExchangeLoadResult* out_result,
std::unique_ptr<SignedExchangeCertificateChain>* out_cert,
+ SignedExchangeLoadResult result,
std::unique_ptr<SignedExchangeCertificateChain> cert_chain) {
+ *out_result = result;
*called = true;
*out_cert = std::move(cert_chain);
}
@@ -206,7 +209,7 @@ class SignedExchangeCertFetcherTest : public testing::Test {
bool force_fetch) {
SignedExchangeCertFetcher::CertificateCallback callback = base::BindOnce(
&ForwardCertificateCallback, base::Unretained(&callback_called_),
- base::Unretained(&cert_result_));
+ base::Unretained(&result_), base::Unretained(&cert_result_));
return SignedExchangeCertFetcher::CreateAndStart(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
@@ -240,6 +243,7 @@ class SignedExchangeCertFetcherTest : public testing::Test {
const GURL url_;
const url::Origin request_initiator_;
bool callback_called_ = false;
+ SignedExchangeLoadResult result_;
std::unique_ptr<SignedExchangeCertificateChain> cert_result_;
URLLoaderFactoryForMockLoader mock_loader_factory_;
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles_;
@@ -275,6 +279,7 @@ TEST_F(SignedExchangeCertFetcherTest, Simple) {
network::URLLoaderCompletionStatus(net::OK));
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result_);
ASSERT_TRUE(cert_result_);
EXPECT_EQ(GetTestDataCertFingerprint256(),
cert_result_->cert()->CalculateChainFingerprint256());
@@ -301,6 +306,7 @@ TEST_F(SignedExchangeCertFetcherTest, MultipleChunked) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result_);
ASSERT_TRUE(cert_result_);
EXPECT_EQ(certificate->CalculateChainFingerprint256(),
cert_result_->cert()->CalculateChainFingerprint256());
@@ -325,6 +331,7 @@ TEST_F(SignedExchangeCertFetcherTest, ForceFetchAndFail) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -348,6 +355,7 @@ TEST_F(SignedExchangeCertFetcherTest, MaxCertSize_Exceeds) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -371,6 +379,7 @@ TEST_F(SignedExchangeCertFetcherTest, MaxCertSize_SameSize) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result_);
EXPECT_TRUE(cert_result_);
}
@@ -398,6 +407,7 @@ TEST_F(SignedExchangeCertFetcherTest, MaxCertSize_MultipleChunked) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -425,6 +435,7 @@ TEST_F(SignedExchangeCertFetcherTest, MaxCertSize_ContentLengthCheck) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -438,6 +449,7 @@ TEST_F(SignedExchangeCertFetcherTest, Abort_Redirect) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -451,6 +463,7 @@ TEST_F(SignedExchangeCertFetcherTest, Abort_404) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -467,6 +480,7 @@ TEST_F(SignedExchangeCertFetcherTest, WrongMimeType) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -485,6 +499,7 @@ TEST_F(SignedExchangeCertFetcherTest, Invalid_CertData) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertParseError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -506,6 +521,7 @@ TEST_F(SignedExchangeCertFetcherTest, Invalid_CertMessage) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertParseError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -541,6 +557,7 @@ TEST_F(SignedExchangeCertFetcherTest, Throttle_Simple) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result_);
ASSERT_TRUE(cert_result_);
EXPECT_EQ(GetTestDataCertFingerprint256(),
cert_result_->cert()->CalculateChainFingerprint256());
@@ -557,6 +574,7 @@ TEST_F(SignedExchangeCertFetcherTest, Throttle_AbortsOnRequest) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -583,6 +601,7 @@ TEST_F(SignedExchangeCertFetcherTest, Throttle_AbortsOnRedirect) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -615,6 +634,7 @@ TEST_F(SignedExchangeCertFetcherTest, Throttle_AbortsOnResponse) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -694,6 +714,7 @@ TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_BeforeReceiveResponse) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -706,6 +727,7 @@ TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_BeforeResponseBody) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -727,6 +749,8 @@ TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_WhileReceivingBody) {
data_pipe.producer_handle.reset();
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ // SignedExchangeCertFetcher receives a truncated cert cbor.
+ EXPECT_EQ(SignedExchangeLoadResult::kCertParseError, result_);
EXPECT_FALSE(cert_result_);
}
@@ -748,6 +772,7 @@ TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_AfterReceivingBody) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result_);
ASSERT_TRUE(cert_result_);
EXPECT_EQ(certificate->CalculateChainFingerprint256(),
cert_result_->cert()->CalculateChainFingerprint256());
@@ -769,6 +794,7 @@ TEST_F(SignedExchangeCertFetcherTest, DataURL) {
network::URLLoaderCompletionStatus(net::OK));
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result_);
ASSERT_TRUE(cert_result_);
EXPECT_EQ(GetTestDataCertFingerprint256(),
cert_result_->cert()->CalculateChainFingerprint256());
@@ -786,6 +812,7 @@ TEST_F(SignedExchangeCertFetcherTest, DataURLWithWrongMimeType) {
RunUntilIdle();
EXPECT_TRUE(callback_called_);
+ EXPECT_EQ(SignedExchangeLoadResult::kCertFetchError, result_);
}
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_certificate_chain.h b/chromium/content/browser/web_package/signed_exchange_certificate_chain.h
index b20f7349a38..62ce9d5178d 100644
--- a/chromium/content/browser/web_package/signed_exchange_certificate_chain.h
+++ b/chromium/content/browser/web_package/signed_exchange_certificate_chain.h
@@ -46,7 +46,6 @@ class CONTENT_EXPORT SignedExchangeCertificateChain {
private:
scoped_refptr<net::X509Certificate> cert_;
- // Version b1 specific fields:
std::string ocsp_;
std::string sct_;
};
diff --git a/chromium/content/browser/web_package/signed_exchange_consts.h b/chromium/content/browser/web_package/signed_exchange_consts.h
index 4f18d332992..34335031540 100644
--- a/chromium/content/browser/web_package/signed_exchange_consts.h
+++ b/chromium/content/browser/web_package/signed_exchange_consts.h
@@ -10,7 +10,7 @@ namespace content {
constexpr char kAcceptHeaderSignedExchangeSuffix[] =
",application/signed-exchange;v=b2";
-enum class SignedExchangeVersion { kB2 };
+enum class SignedExchangeVersion { kUnknown, kB2 };
// Field names defined in the application/signed-exchange content type:
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#application-signed-exchange
diff --git a/chromium/content/browser/web_package/signed_exchange_devtools_proxy.cc b/chromium/content/browser/web_package/signed_exchange_devtools_proxy.cc
index 44f40ccf461..918b99c9e8d 100644
--- a/chromium/content/browser/web_package/signed_exchange_devtools_proxy.cc
+++ b/chromium/content/browser/web_package/signed_exchange_devtools_proxy.cc
@@ -4,11 +4,13 @@
#include "content/browser/web_package/signed_exchange_devtools_proxy.h"
+#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/web_package/signed_exchange_envelope.h"
#include "content/browser/web_package/signed_exchange_error.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -112,8 +114,8 @@ void SignedExchangeDevToolsProxy::ReportError(
base::Optional<SignedExchangeError::FieldIndexPair> error_field) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
errors_.push_back(SignedExchangeError(message, std::move(error_field)));
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&AddErrorMessageToConsoleOnUI, frame_tree_node_id_getter_,
std::move(message)));
}
@@ -124,8 +126,8 @@ void SignedExchangeDevToolsProxy::CertificateRequestSent(
if (!devtools_enabled_)
return;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&CertificateRequestSentOnUI, frame_tree_node_id_getter_, request_id,
devtools_navigation_token_ ? *devtools_navigation_token_ : request_id,
@@ -143,8 +145,8 @@ void SignedExchangeDevToolsProxy::CertificateResponseReceived(
auto resource_response = base::MakeRefCounted<network::ResourceResponse>();
resource_response->head = head;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(
&CertificateResponseReceivedOnUI, frame_tree_node_id_getter_,
request_id,
@@ -157,8 +159,8 @@ void SignedExchangeDevToolsProxy::CertificateRequestCompleted(
const network::URLLoaderCompletionStatus& status) {
if (!devtools_enabled_)
return;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&CertificateRequestCompletedOnUI,
frame_tree_node_id_getter_, request_id, status));
}
@@ -178,8 +180,8 @@ void SignedExchangeDevToolsProxy::OnSignedExchangeReceived(
auto resource_response = base::MakeRefCounted<network::ResourceResponse>();
resource_response->head = outer_response_;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&OnSignedExchangeReceivedOnUI, frame_tree_node_id_getter_,
outer_request_url_, resource_response->DeepCopy(),
devtools_navigation_token_, envelope, certificate,
diff --git a/chromium/content/browser/web_package/signed_exchange_envelope.cc b/chromium/content/browser/web_package/signed_exchange_envelope.cc
index 96f2750eadc..1b2d42e855c 100644
--- a/chromium/content/browser/web_package/signed_exchange_envelope.cc
+++ b/chromium/content/browser/web_package/signed_exchange_envelope.cc
@@ -23,7 +23,7 @@ namespace content {
namespace {
-// IsStateful{Request,Response}Header return true if |name| is a stateful
+// IsStateful{Request,Response}Header returns true if |name| is a stateful
// header field. Stateful header fields will cause validation failure of
// signed exchanges.
// Note that |name| must be lower-cased.
@@ -180,20 +180,6 @@ bool ParseResponseMap(const cbor::CBORValue& value,
devtools_proxy, "Failed to parse status code to integer.");
return false;
}
- // https://wicg.github.io/webpackage/loading.html#parsing-b1
- // Step 26. If parsedExchange’s response's status is a redirect status or the
- // signed exchange version of parsedExchange’s response is not
- // undefined, return a failure. [spec text]
- // TODO(crbug.com/803774): Reject if inner response is a signed exchange.
- if (net::HttpResponseHeaders::IsRedirectResponseCode(response_code)) {
- signed_exchange_utils::ReportErrorAndTraceEvent(
- devtools_proxy,
- base::StringPrintf(
- "Exchange's response status must not be a redirect status. "
- "status: %d",
- response_code));
- return false;
- }
out->set_response_code(static_cast<net::HttpStatusCode>(response_code));
for (const auto& it : response_map) {
@@ -224,7 +210,7 @@ bool ParseResponseMap(const cbor::CBORValue& value,
return false;
}
- // 4. If exchange’s headers contain a stateful header field, as defined in
+ // 4. If exchange’s headers contains a stateful header field, as defined in
// Section 4.1, return “invalid”. [spec text]
if (IsStatefulResponseHeader(name_str)) {
signed_exchange_utils::ReportErrorAndTraceEvent(
@@ -249,6 +235,37 @@ bool ParseResponseMap(const cbor::CBORValue& value,
return false;
}
}
+
+ // https://wicg.github.io/webpackage/loading.html#parsing-b1
+ // Step 26. If parsedExchange’s response's status is a redirect status or the
+ // signed exchange version of parsedExchange’s response is not
+ // undefined, return a failure. [spec text]
+ if (net::HttpResponseHeaders::IsRedirectResponseCode(out->response_code())) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
+ base::StringPrintf(
+ "Exchange's response status must not be a redirect status. "
+ "status: %d",
+ response_code));
+ return false;
+ }
+ // Note: This does not reject content-type like "application/signed-exchange"
+ // (no "v=" parameter). In that case, SignedExchangeRequestHandler does not
+ // handle the inner response and UA just downloads it.
+ // See https://github.com/WICG/webpackage/issues/299 for details.
+ auto found = out->response_headers().find("content-type");
+ if (found != out->response_headers().end() &&
+ signed_exchange_utils::GetSignedExchangeVersion(found->second)
+ .has_value()) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
+ base::StringPrintf(
+ "Exchange's inner response must not be a signed-exchange. "
+ "conetent-type: %s",
+ found->second.c_str()));
+ return false;
+ }
+
return true;
}
diff --git a/chromium/content/browser/web_package/signed_exchange_envelope.h b/chromium/content/browser/web_package/signed_exchange_envelope.h
index 6903b8eb536..1b7026dd8e7 100644
--- a/chromium/content/browser/web_package/signed_exchange_envelope.h
+++ b/chromium/content/browser/web_package/signed_exchange_envelope.h
@@ -33,7 +33,7 @@ class CONTENT_EXPORT SignedExchangeEnvelope {
// Parse headers from the application/signed-exchange;v=b2 format.
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#application-signed-exchange
//
- // This also performs the step 1, 3 and 4 of "Cross-origin trust" validation.
+ // This also performs the steps 1, 3 and 4 of "Cross-origin trust" validation.
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#cross-origin-trust
static base::Optional<SignedExchangeEnvelope> Parse(
const GURL& fallback_url,
diff --git a/chromium/content/browser/web_package/signed_exchange_envelope_unittest.cc b/chromium/content/browser/web_package/signed_exchange_envelope_unittest.cc
index 919019bdfdf..99c7963f889 100644
--- a/chromium/content/browser/web_package/signed_exchange_envelope_unittest.cc
+++ b/chromium/content/browser/web_package/signed_exchange_envelope_unittest.cc
@@ -229,4 +229,15 @@ TEST(SignedExchangeEnvelopeTest, InvalidValidityURLHeader) {
ASSERT_FALSE(header.has_value());
}
+TEST(SignedExchangeEnvelopeTest, InnerResponseIsSXG) {
+ auto header = GenerateHeaderAndParse(
+ GURL("https://test.example.org/test/"), kSignatureString,
+ {
+ {kMethodKey, "GET"},
+ },
+ {{kStatusKey, "200"},
+ {"content-type", "application/signed-exchange;v=b2"}});
+ ASSERT_FALSE(header.has_value());
+}
+
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_error.h b/chromium/content/browser/web_package/signed_exchange_error.h
index 50856c66d4b..36343ce4c77 100644
--- a/chromium/content/browser/web_package/signed_exchange_error.h
+++ b/chromium/content/browser/web_package/signed_exchange_error.h
@@ -13,6 +13,37 @@
namespace content {
+// This enum is used for recording histograms. Treat as append-only.
+enum class SignedExchangeLoadResult {
+ kSuccess,
+ // SXG was served from non-secure origin.
+ kSXGServedFromNonHTTPS,
+ // SXG parse error (couldn't extract fallback URL).
+ kFallbackURLParseError,
+ // Unsupported version of SXG (could extract fallback URL).
+ kVersionMismatch,
+ // SXG parse error (could extract fallback URL).
+ kHeaderParseError,
+ // Network error occurred while loading SXG header.
+ kSXGHeaderNetError,
+ // Failed to fetch certificate chain.
+ kCertFetchError,
+ // Failed to parse certificate chain.
+ kCertParseError,
+ // Signature verification failed.
+ kSignatureVerificationError,
+ // Cert verification failed.
+ kCertVerificationError,
+ // CT verification failed.
+ kCTVerificationError,
+ // OCSP check failed.
+ kOCSPError,
+ // Certificate Requirements aren't met.
+ // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#cross-origin-cert-req
+ kCertRequirementsNotMet,
+ kMaxValue = kCertRequirementsNotMet
+};
+
struct SignedExchangeError {
public:
enum class Field {
diff --git a/chromium/content/browser/web_package/signed_exchange_handler.cc b/chromium/content/browser/web_package/signed_exchange_handler.cc
index a2c5fb82f99..cca3568de10 100644
--- a/chromium/content/browser/web_package/signed_exchange_handler.cc
+++ b/chromium/content/browser/web_package/signed_exchange_handler.cc
@@ -4,7 +4,10 @@
#include "content/browser/web_package/signed_exchange_handler.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
+#include "base/task/post_task.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/frame_host/frame_tree_node.h"
@@ -18,6 +21,7 @@
#include "content/browser/web_package/signed_exchange_prologue.h"
#include "content/browser/web_package/signed_exchange_signature_verifier.h"
#include "content/browser/web_package/signed_exchange_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/storage_partition.h"
@@ -46,6 +50,16 @@ namespace content {
namespace {
constexpr char kDigestHeader[] = "Digest";
+constexpr char kHistogramSignatureVerificationResult[] =
+ "SignedExchange.SignatureVerificationResult";
+constexpr char kHistogramCertVerificationResult[] =
+ "SignedExchange.CertVerificationResult";
+constexpr char kHistogramCTVerificationResult[] =
+ "SignedExchange.CTVerificationResult";
+constexpr char kHistogramOCSPResponseStatus[] =
+ "SignedExchange.OCSPResponseStatus";
+constexpr char kHistogramOCSPRevocationStatus[] =
+ "SignedExchange.OCSPRevocationStatus";
network::mojom::NetworkContext* g_network_context_for_testing = nullptr;
@@ -70,8 +84,8 @@ void OnVerifyCertUI(VerifyCallback callback,
int32_t error_code,
const net::CertVerifyResult& cv_result,
const net::ct::CTVerifyResult& ct_result) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(std::move(callback), error_code, cv_result, ct_result));
}
@@ -103,6 +117,43 @@ void VerifyCert(const scoped_refptr<net::X509Certificate>& certificate,
certificate, url, ocsp_result, sct_list, std::move(wrapped_callback));
}
+std::string OCSPErrorToString(const net::OCSPVerifyResult& ocsp_result) {
+ switch (ocsp_result.response_status) {
+ case net::OCSPVerifyResult::PROVIDED:
+ break;
+ case net::OCSPVerifyResult::NOT_CHECKED:
+ // This happens only in tests.
+ return "OCSP verification was not performed.";
+ case net::OCSPVerifyResult::MISSING:
+ return "No OCSP Response was stapled.";
+ case net::OCSPVerifyResult::ERROR_RESPONSE:
+ return "OCSP response did not have a SUCCESSFUL status.";
+ case net::OCSPVerifyResult::BAD_PRODUCED_AT:
+ return "OCSP Response was produced at outside the certificate "
+ "validity period.";
+ case net::OCSPVerifyResult::NO_MATCHING_RESPONSE:
+ return "OCSP Response did not match the certificate.";
+ case net::OCSPVerifyResult::INVALID_DATE:
+ return "OCSP Response was expired or not yet valid.";
+ case net::OCSPVerifyResult::PARSE_RESPONSE_ERROR:
+ return "OCSPResponse structure could not be parsed.";
+ case net::OCSPVerifyResult::PARSE_RESPONSE_DATA_ERROR:
+ return "OCSP ResponseData structure could not be parsed.";
+ }
+
+ switch (ocsp_result.revocation_status) {
+ case net::OCSPRevocationStatus::GOOD:
+ NOTREACHED();
+ break;
+ case net::OCSPRevocationStatus::REVOKED:
+ return "OCSP response indicates that the certificate is revoked.";
+ case net::OCSPRevocationStatus::UNKNOWN:
+ return "OCSP responder doesn't know about the certificate.";
+ }
+ NOTREACHED();
+ return std::string();
+}
+
} // namespace
// static
@@ -136,12 +187,11 @@ SignedExchangeHandler::SignedExchangeHandler(
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
"SignedExchangeHandler::SignedExchangeHandler");
- if (!SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
- content_type, &version_) ||
- !IsSupportedSignedExchangeVersion(version_)) {
+ version_ = signed_exchange_utils::GetSignedExchangeVersion(content_type);
+ if (!IsSupportedSignedExchangeVersion(version_)) {
signed_exchange_utils::ReportErrorAndTraceEvent(
devtools_proxy_.get(),
- base::StringPrintf("Unsupported version of the content type. Currentry "
+ base::StringPrintf("Unsupported version of the content type. Currently "
"content type must be "
"\"application/signed-exchange;v=b2\". But the "
"response content type was \"%s\"",
@@ -184,53 +234,56 @@ void SignedExchangeHandler::DoHeaderLoop() {
DidReadHeader(true /* sync */, rv);
}
-void SignedExchangeHandler::DidReadHeader(bool completed_syncly, int result) {
+void SignedExchangeHandler::DidReadHeader(bool completed_syncly,
+ int read_result) {
DCHECK(state_ == State::kReadingPrologueBeforeFallbackUrl ||
state_ == State::kReadingPrologueFallbackUrlAndAfter ||
state_ == State::kReadingHeaders);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
"SignedExchangeHandler::DidReadHeader");
- if (result < 0) {
+ if (read_result < 0) {
signed_exchange_utils::ReportErrorAndTraceEvent(
devtools_proxy_.get(),
- base::StringPrintf("Error reading body stream. result: %d", result));
- RunErrorCallback(static_cast<net::Error>(result));
+ base::StringPrintf("Error reading body stream. result: %d",
+ read_result));
+ RunErrorCallback(SignedExchangeLoadResult::kSXGHeaderNetError,
+ static_cast<net::Error>(read_result));
return;
}
- if (result == 0) {
+ if (read_result == 0) {
signed_exchange_utils::ReportErrorAndTraceEvent(
devtools_proxy_.get(),
"Stream ended while reading signed exchange header.");
- RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
+ SignedExchangeLoadResult result =
+ GetFallbackUrl().is_valid()
+ ? SignedExchangeLoadResult::kHeaderParseError
+ : SignedExchangeLoadResult::kFallbackURLParseError;
+ RunErrorCallback(result, net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
- header_read_buf_->DidConsume(result);
+ header_read_buf_->DidConsume(read_result);
if (header_read_buf_->BytesRemaining() == 0) {
+ SignedExchangeLoadResult result = SignedExchangeLoadResult::kSuccess;
switch (state_) {
case State::kReadingPrologueBeforeFallbackUrl:
- if (!ParsePrologueBeforeFallbackUrl()) {
- RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
- return;
- }
+ result = ParsePrologueBeforeFallbackUrl();
break;
case State::kReadingPrologueFallbackUrlAndAfter:
- if (!ParsePrologueFallbackUrlAndAfter()) {
- RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
- return;
- }
+ result = ParsePrologueFallbackUrlAndAfter();
break;
case State::kReadingHeaders:
- if (!ParseHeadersAndFetchCertificate()) {
- RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
- return;
- }
+ result = ParseHeadersAndFetchCertificate();
break;
default:
NOTREACHED();
}
+ if (result != SignedExchangeLoadResult::kSuccess) {
+ RunErrorCallback(result, net::ERR_INVALID_SIGNED_EXCHANGE);
+ return;
+ }
}
// We have finished reading headers, so return without queueing the next read.
@@ -250,7 +303,8 @@ void SignedExchangeHandler::DidReadHeader(bool completed_syncly, int result) {
}
}
-bool SignedExchangeHandler::ParsePrologueBeforeFallbackUrl() {
+SignedExchangeLoadResult
+SignedExchangeHandler::ParsePrologueBeforeFallbackUrl() {
DCHECK_EQ(state_, State::kReadingPrologueBeforeFallbackUrl);
prologue_before_fallback_url_ =
@@ -268,10 +322,11 @@ bool SignedExchangeHandler::ParsePrologueBeforeFallbackUrl() {
SetupBuffers(
prologue_before_fallback_url_.ComputeFallbackUrlAndAfterLength());
state_ = State::kReadingPrologueFallbackUrlAndAfter;
- return true;
+ return SignedExchangeLoadResult::kSuccess;
}
-bool SignedExchangeHandler::ParsePrologueFallbackUrlAndAfter() {
+SignedExchangeLoadResult
+SignedExchangeHandler::ParsePrologueFallbackUrlAndAfter() {
DCHECK_EQ(state_, State::kReadingPrologueFallbackUrlAndAfter);
prologue_fallback_url_and_after_ =
@@ -280,24 +335,30 @@ bool SignedExchangeHandler::ParsePrologueFallbackUrlAndAfter() {
reinterpret_cast<uint8_t*>(header_buf_->data()),
prologue_before_fallback_url_.ComputeFallbackUrlAndAfterLength()),
prologue_before_fallback_url_, devtools_proxy_.get());
- if (!prologue_fallback_url_and_after_.is_valid()) {
- return false;
- }
- // If the signed exchange version from content-type is unsupported, abort
- // parsing and redirect to the fallback URL.
- if (!IsSupportedSignedExchangeVersion(version_))
- return false;
+ if (!GetFallbackUrl().is_valid())
+ return SignedExchangeLoadResult::kFallbackURLParseError;
+
+ // If the signed exchange version from content-type is unsupported or the
+ // prologue's magic string is incorrect, abort parsing and redirect to the
+ // fallback URL.
+ if (!IsSupportedSignedExchangeVersion(version_) ||
+ !prologue_before_fallback_url_.is_valid())
+ return SignedExchangeLoadResult::kVersionMismatch;
+
+ if (!prologue_fallback_url_and_after_.is_valid())
+ return SignedExchangeLoadResult::kHeaderParseError;
// Set up a new buffer for reading the Signature header field and CBOR-encoded
// headers.
SetupBuffers(
prologue_fallback_url_and_after_.ComputeFollowingSectionsLength());
state_ = State::kReadingHeaders;
- return true;
+ return SignedExchangeLoadResult::kSuccess;
}
-bool SignedExchangeHandler::ParseHeadersAndFetchCertificate() {
+SignedExchangeLoadResult
+SignedExchangeHandler::ParseHeadersAndFetchCertificate() {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
"SignedExchangeHandler::ParseHeadersAndFetchCertificate");
DCHECK_EQ(state_, State::kReadingHeaders);
@@ -317,7 +378,7 @@ bool SignedExchangeHandler::ParseHeadersAndFetchCertificate() {
if (!envelope_) {
signed_exchange_utils::ReportErrorAndTraceEvent(
devtools_proxy_.get(), "Failed to parse SignedExchange header.");
- return false;
+ return SignedExchangeLoadResult::kHeaderParseError;
}
const GURL cert_url = envelope_->signature().cert_url;
@@ -330,6 +391,7 @@ bool SignedExchangeHandler::ParseHeadersAndFetchCertificate() {
const bool force_fetch = load_flags_ & net::LOAD_BYPASS_CACHE;
+ cert_fetch_start_time_ = base::TimeTicks::Now();
cert_fetcher_ = std::move(cert_fetcher_factory_)
->CreateFetcherAndStart(
cert_url, force_fetch, *version_,
@@ -338,10 +400,11 @@ bool SignedExchangeHandler::ParseHeadersAndFetchCertificate() {
devtools_proxy_.get());
state_ = State::kFetchingCertificate;
- return true;
+ return SignedExchangeLoadResult::kSuccess;
}
-void SignedExchangeHandler::RunErrorCallback(net::Error error) {
+void SignedExchangeHandler::RunErrorCallback(SignedExchangeLoadResult result,
+ net::Error error) {
DCHECK_NE(state_, State::kHeadersCallbackCalled);
if (devtools_proxy_) {
devtools_proxy_->OnSignedExchangeReceived(
@@ -351,31 +414,41 @@ void SignedExchangeHandler::RunErrorCallback(net::Error error) {
nullptr);
}
std::move(headers_callback_)
- .Run(error, GetFallbackUrl(), std::string(),
+ .Run(result, error, GetFallbackUrl(), std::string(),
network::ResourceResponseHead(), nullptr);
state_ = State::kHeadersCallbackCalled;
}
void SignedExchangeHandler::OnCertReceived(
+ SignedExchangeLoadResult result,
std::unique_ptr<SignedExchangeCertificateChain> cert_chain) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
"SignedExchangeHandler::OnCertReceived");
+ base::TimeDelta cert_fetch_duration =
+ base::TimeTicks::Now() - cert_fetch_start_time_;
DCHECK_EQ(state_, State::kFetchingCertificate);
- if (!cert_chain) {
+ if (result != SignedExchangeLoadResult::kSuccess) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("SignedExchange.Time.CertificateFetch.Failure",
+ cert_fetch_duration);
+
signed_exchange_utils::ReportErrorAndTraceEvent(
devtools_proxy_.get(), "Failed to fetch the certificate.",
std::make_pair(0 /* signature_index */,
SignedExchangeError::Field::kSignatureCertUrl));
- RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
+ RunErrorCallback(result, net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
+ UMA_HISTOGRAM_MEDIUM_TIMES("SignedExchange.Time.CertificateFetch.Success",
+ cert_fetch_duration);
unverified_cert_chain_ = std::move(cert_chain);
const SignedExchangeSignatureVerifier::Result verify_result =
SignedExchangeSignatureVerifier::Verify(
*envelope_, unverified_cert_chain_->cert(), GetVerificationTime(),
devtools_proxy_.get());
+ UMA_HISTOGRAM_ENUMERATION(kHistogramSignatureVerificationResult,
+ verify_result);
if (verify_result != SignedExchangeSignatureVerifier::Result::kSuccess) {
base::Optional<SignedExchangeError::Field> error_field =
SignedExchangeError::GetFieldFromSignatureVerifierResult(verify_result);
@@ -384,7 +457,8 @@ void SignedExchangeHandler::OnCertReceived(
error_field ? base::make_optional(
std::make_pair(0 /* signature_index */, *error_field))
: base::nullopt);
- RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
+ RunErrorCallback(SignedExchangeLoadResult::kSignatureVerificationError,
+ net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
@@ -401,8 +475,8 @@ void SignedExchangeHandler::OnCertReceived(
// property, or
const std::string& stapled_ocsp_response = unverified_cert_chain_->ocsp();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&VerifyCert, certificate, url, stapled_ocsp_response,
sct_list_from_cert_cbor, frame_tree_node_id_getter_,
base::BindOnce(&SignedExchangeHandler::OnVerifyCert,
@@ -431,12 +505,21 @@ bool SignedExchangeHandler::CheckOCSPStatus(
//
// OCSP verification is done in CertVerifier::Verify(), so we just check the
// result here.
-
- if (ocsp_result.response_status != net::OCSPVerifyResult::PROVIDED ||
- ocsp_result.revocation_status != net::OCSPRevocationStatus::GOOD)
- return false;
-
- return true;
+ UMA_HISTOGRAM_ENUMERATION(kHistogramOCSPResponseStatus,
+ ocsp_result.response_status,
+ static_cast<base::HistogramBase::Sample>(
+ net::OCSPVerifyResult::RESPONSE_STATUS_MAX) +
+ 1);
+ if (ocsp_result.response_status == net::OCSPVerifyResult::PROVIDED) {
+ UMA_HISTOGRAM_ENUMERATION(kHistogramOCSPRevocationStatus,
+ ocsp_result.revocation_status,
+ static_cast<base::HistogramBase::Sample>(
+ net::OCSPRevocationStatus::MAX_VALUE) +
+ 1);
+ if (ocsp_result.revocation_status == net::OCSPRevocationStatus::GOOD)
+ return true;
+ }
+ return false;
}
void SignedExchangeHandler::OnVerifyCert(
@@ -445,24 +528,32 @@ void SignedExchangeHandler::OnVerifyCert(
const net::ct::CTVerifyResult& ct_result) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
"SignedExchangeHandler::OnCertVerifyComplete");
+ // net::Error codes are negative, so we put - in front of it.
+ base::UmaHistogramSparse(kHistogramCertVerificationResult, -error_code);
+ UMA_HISTOGRAM_ENUMERATION(kHistogramCTVerificationResult,
+ ct_result.policy_compliance,
+ net::ct::CTPolicyCompliance::CT_POLICY_COUNT);
if (error_code != net::OK) {
+ SignedExchangeLoadResult result;
std::string error_message;
if (error_code == net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED) {
error_message = base::StringPrintf(
"CT verification failed. result: %s, policy compliance: %d",
net::ErrorToShortString(error_code).c_str(),
ct_result.policy_compliance);
+ result = SignedExchangeLoadResult::kCTVerificationError;
} else {
error_message =
base::StringPrintf("Certificate verification error: %s",
net::ErrorToShortString(error_code).c_str());
+ result = SignedExchangeLoadResult::kCertVerificationError;
}
signed_exchange_utils::ReportErrorAndTraceEvent(
devtools_proxy_.get(), error_message,
std::make_pair(0 /* signature_index */,
SignedExchangeError::Field::kSignatureCertUrl));
- RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
+ RunErrorCallback(result, net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
@@ -474,24 +565,26 @@ void SignedExchangeHandler::OnVerifyCert(
"chrome://flags/#allow-sxg-certs-without-extension.",
std::make_pair(0 /* signature_index */,
SignedExchangeError::Field::kSignatureCertUrl));
- RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
+ RunErrorCallback(SignedExchangeLoadResult::kCertRequirementsNotMet,
+ net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
if (!CheckOCSPStatus(cv_result.ocsp_result)) {
signed_exchange_utils::ReportErrorAndTraceEvent(
devtools_proxy_.get(),
- base::StringPrintf(
- "OCSP check failed. response status: %d, revocation status: %d",
- cv_result.ocsp_result.response_status,
- cv_result.ocsp_result.revocation_status),
+ base::StringPrintf("OCSP check failed: %s",
+ OCSPErrorToString(cv_result.ocsp_result).c_str()),
std::make_pair(0 /* signature_index */,
SignedExchangeError::Field::kSignatureCertUrl));
- RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
+ RunErrorCallback(SignedExchangeLoadResult::kOCSPError,
+ net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
network::ResourceResponseHead response_head;
+ response_head.is_signed_exchange_inner_response = true;
+
response_head.headers = envelope_->BuildHttpResponseHeaders();
response_head.headers->GetMimeTypeAndCharset(&response_head.mime_type,
&response_head.charset);
@@ -508,9 +601,12 @@ void SignedExchangeHandler::OnVerifyCert(
std::string digest_header_value;
if (!response_head.headers->EnumerateHeader(nullptr, kDigestHeader,
&digest_header_value)) {
+ // TODO(https://crbug.com/803774): Detect this error in
+ // SignedExchangeEnvelope::Parse().
signed_exchange_utils::ReportErrorAndTraceEvent(
devtools_proxy_.get(), "Signed exchange has no Digest: header");
- RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
+ RunErrorCallback(SignedExchangeLoadResult::kHeaderParseError,
+ net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
auto mi_stream = std::make_unique<MerkleIntegritySourceStream>(
@@ -535,8 +631,9 @@ void SignedExchangeHandler::OnVerifyCert(
response_head.ssl_info = std::move(ssl_info);
std::move(headers_callback_)
- .Run(net::OK, envelope_->request_url(), envelope_->request_method(),
- response_head, std::move(mi_stream));
+ .Run(SignedExchangeLoadResult::kSuccess, net::OK,
+ envelope_->request_url(), envelope_->request_method(), response_head,
+ std::move(mi_stream));
state_ = State::kHeadersCallbackCalled;
}
diff --git a/chromium/content/browser/web_package/signed_exchange_handler.h b/chromium/content/browser/web_package/signed_exchange_handler.h
index 122ac720be3..0465a06ea97 100644
--- a/chromium/content/browser/web_package/signed_exchange_handler.h
+++ b/chromium/content/browser/web_package/signed_exchange_handler.h
@@ -12,6 +12,7 @@
#include "base/time/time.h"
#include "content/browser/web_package/signed_exchange_consts.h"
#include "content/browser/web_package/signed_exchange_envelope.h"
+#include "content/browser/web_package/signed_exchange_error.h"
#include "content/browser/web_package/signed_exchange_prologue.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/system/data_pipe.h"
@@ -45,20 +46,33 @@ class SignedExchangeCertificateChain;
class SignedExchangeDevToolsProxy;
// SignedExchangeHandler reads "application/signed-exchange" format from a
-// net::SourceStream, parse and verify the signed exchange, and report
+// net::SourceStream, parses and verifies the signed exchange, and reports
// the result asynchronously via SignedExchangeHandler::ExchangeHeadersCallback.
//
// Note that verifying a signed exchange requires an associated certificate
// chain. SignedExchangeHandler creates a SignedExchangeCertFetcher to
-// fetch the certificate chain over network, and verify it with the
+// fetch the certificate chain over the network, and verifies it with the
// net::CertVerifier.
class CONTENT_EXPORT SignedExchangeHandler {
public:
+ // Callback that will be called when SXG header is parsed and its signature is
+ // validated against a verified certificate, or on failure.
+ // On success:
+ // - |result| is kSuccess.
+ // - |request_url| and |request_method| are the exchange's request's URL and
+ // method.
+ // - |resource_response| contains inner response's headers.
+ // - The payload stream can be read from |payload_stream|.
+ // On failure:
+ // - |result| indicates the failure reason.
+ // - |error| indicates the net::Error if |result| is kSXGHeaderNetError.
+ // - |request_url| may refer to the fallback URL.
using ExchangeHeadersCallback = base::OnceCallback<void(
+ SignedExchangeLoadResult result,
net::Error error,
const GURL& request_url,
const std::string& request_method,
- const network::ResourceResponseHead&,
+ const network::ResourceResponseHead& resource_response,
std::unique_ptr<net::SourceStream> payload_stream)>;
static void SetNetworkContextForTesting(
@@ -98,12 +112,13 @@ class CONTENT_EXPORT SignedExchangeHandler {
void SetupBuffers(size_t size);
void DoHeaderLoop();
void DidReadHeader(bool completed_syncly, int result);
- bool ParsePrologueBeforeFallbackUrl();
- bool ParsePrologueFallbackUrlAndAfter();
- bool ParseHeadersAndFetchCertificate();
- void RunErrorCallback(net::Error);
+ SignedExchangeLoadResult ParsePrologueBeforeFallbackUrl();
+ SignedExchangeLoadResult ParsePrologueFallbackUrlAndAfter();
+ SignedExchangeLoadResult ParseHeadersAndFetchCertificate();
+ void RunErrorCallback(SignedExchangeLoadResult result, net::Error);
void OnCertReceived(
+ SignedExchangeLoadResult result,
std::unique_ptr<SignedExchangeCertificateChain> cert_chain);
bool CheckCertExtension(const net::X509Certificate* verified_cert);
bool CheckOCSPStatus(const net::OCSPVerifyResult& ocsp_result);
@@ -137,6 +152,8 @@ class CONTENT_EXPORT SignedExchangeHandler {
base::RepeatingCallback<int(void)> frame_tree_node_id_getter_;
+ base::TimeTicks cert_fetch_start_time_;
+
base::WeakPtrFactory<SignedExchangeHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SignedExchangeHandler);
diff --git a/chromium/content/browser/web_package/signed_exchange_handler_unittest.cc b/chromium/content/browser/web_package/signed_exchange_handler_unittest.cc
index 43578473a64..d4661c46d38 100644
--- a/chromium/content/browser/web_package/signed_exchange_handler_unittest.cc
+++ b/chromium/content/browser/web_package/signed_exchange_handler_unittest.cc
@@ -11,9 +11,11 @@
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "content/browser/web_package/signed_exchange_cert_fetcher_factory.h"
#include "content/browser/web_package/signed_exchange_devtools_proxy.h"
+#include "content/browser/web_package/signed_exchange_signature_verifier.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -100,7 +102,9 @@ class MockSignedExchangeCertFetcherFactory
EXPECT_TRUE(cert_chain);
base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), std::move(cert_chain)));
+ FROM_HERE,
+ base::BindOnce(std::move(callback), SignedExchangeLoadResult::kSuccess,
+ std::move(cert_chain)));
return nullptr;
}
@@ -207,7 +211,7 @@ class SignedExchangeHandlerTest
// read to it.
int ReadStream(net::SourceStream* stream, std::string* output) {
scoped_refptr<net::IOBuffer> output_buffer =
- new net::IOBuffer(kOutputBufferSize);
+ base::MakeRefCounted<net::IOBuffer>(kOutputBufferSize);
int bytes_read = 0;
while (true) {
net::TestCompletionCallback callback;
@@ -235,6 +239,7 @@ class SignedExchangeHandlerTest
}
bool read_header() const { return read_header_; }
+ SignedExchangeLoadResult result() const { return result_; }
net::Error error() const { return error_; }
const GURL& inner_url() const { return inner_url_; }
const network::ResourceResponseHead& resource_response() const {
@@ -276,7 +281,30 @@ class SignedExchangeHandlerTest
}
}
+ void ExpectHistogramValues(
+ base::Optional<SignedExchangeSignatureVerifier::Result> signature_result,
+ base::Optional<int32_t> cert_result,
+ base::Optional<net::ct::CTPolicyCompliance> ct_result,
+ base::Optional<net::OCSPVerifyResult::ResponseStatus>
+ ocsp_response_status,
+ base::Optional<net::OCSPRevocationStatus> ocsp_revocation_status) {
+ // CertVerificationResult histogram records negated net::Error code.
+ if (cert_result.has_value())
+ *cert_result = -*cert_result;
+
+ ExpectZeroOrUniqueSample("SignedExchange.SignatureVerificationResult",
+ signature_result);
+ ExpectZeroOrUniqueSample("SignedExchange.CertVerificationResult",
+ cert_result);
+ ExpectZeroOrUniqueSample("SignedExchange.CTVerificationResult", ct_result);
+ ExpectZeroOrUniqueSample("SignedExchange.OCSPResponseStatus",
+ ocsp_response_status);
+ ExpectZeroOrUniqueSample("SignedExchange.OCSPRevocationStatus",
+ ocsp_revocation_status);
+ }
+
protected:
+ const base::HistogramTester histogram_tester_;
MockSignedExchangeCertFetcherFactory* mock_cert_fetcher_factory_;
std::unique_ptr<net::CertVerifier> cert_verifier_;
std::unique_ptr<MockCTVerifier> mock_ct_verifier_;
@@ -285,18 +313,29 @@ class SignedExchangeHandlerTest
std::unique_ptr<SignedExchangeHandler> handler_;
private:
- void OnHeaderFound(net::Error error,
+ void OnHeaderFound(SignedExchangeLoadResult result,
+ net::Error error,
const GURL& url,
const std::string&,
const network::ResourceResponseHead& resource_response,
std::unique_ptr<net::SourceStream> payload_stream) {
read_header_ = true;
+ result_ = result;
error_ = error;
inner_url_ = url;
resource_response_ = resource_response;
payload_stream_ = std::move(payload_stream);
}
+ template <typename T>
+ void ExpectZeroOrUniqueSample(const std::string& histogram_name,
+ base::Optional<T> expected_value) {
+ if (expected_value.has_value())
+ histogram_tester_.ExpectUniqueSample(histogram_name, *expected_value, 1);
+ else
+ histogram_tester_.ExpectTotalCount(histogram_name, 0);
+ }
+
base::test::ScopedFeatureList feature_list_;
content::TestBrowserThreadBundle browser_thread_bundle_;
std::unique_ptr<net::TestURLRequestContext> url_request_context_;
@@ -307,6 +346,7 @@ class SignedExchangeHandlerTest
std::unique_ptr<MockSignedExchangeCertFetcherFactory> cert_fetcher_factory_;
bool read_header_ = false;
+ SignedExchangeLoadResult result_;
net::Error error_;
GURL inner_url_;
network::ResourceResponseHead resource_response_;
@@ -320,6 +360,7 @@ TEST_P(SignedExchangeHandlerTest, Empty) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kFallbackURLParseError, result());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
EXPECT_TRUE(inner_url().is_empty());
}
@@ -351,6 +392,7 @@ TEST_P(SignedExchangeHandlerTest, Simple) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result());
EXPECT_EQ(net::OK, error());
EXPECT_EQ(kTestSxgInnerURL, inner_url());
EXPECT_EQ(200, resource_response().headers->response_code());
@@ -369,6 +411,10 @@ TEST_P(SignedExchangeHandlerTest, Simple) {
EXPECT_EQ(payload, expected_payload);
EXPECT_EQ(rv, static_cast<int>(expected_payload.size()));
+ ExpectHistogramValues(
+ SignedExchangeSignatureVerifier::Result::kSuccess, net::OK,
+ net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
+ net::OCSPVerifyResult::PROVIDED, net::OCSPRevocationStatus::GOOD);
}
TEST_P(SignedExchangeHandlerTest, MimeType) {
@@ -398,6 +444,7 @@ TEST_P(SignedExchangeHandlerTest, MimeType) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result());
EXPECT_EQ(net::OK, error());
EXPECT_EQ(200, resource_response().headers->response_code());
EXPECT_EQ("text/plain", resource_response().mime_type);
@@ -421,13 +468,14 @@ TEST_P(SignedExchangeHandlerTest, HeaderParseError) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kFallbackURLParseError, result());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
EXPECT_TRUE(inner_url().is_empty());
}
-TEST_P(SignedExchangeHandlerTest, TruncatedInHeader) {
+TEST_P(SignedExchangeHandlerTest, TruncatedAfterFallbackUrl) {
std::string contents = GetTestFileContents("test.example.org_test.sxg");
- contents.resize(30);
+ contents.resize(50);
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
@@ -435,8 +483,9 @@ TEST_P(SignedExchangeHandlerTest, TruncatedInHeader) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kHeaderParseError, result());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
- EXPECT_TRUE(inner_url().is_empty());
+ EXPECT_TRUE(inner_url().is_valid());
}
TEST_P(SignedExchangeHandlerTest, CertWithoutExtensionShouldBeRejected) {
@@ -466,6 +515,7 @@ TEST_P(SignedExchangeHandlerTest, CertWithoutExtensionShouldBeRejected) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kCertRequirementsNotMet, result());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
EXPECT_EQ(kTestSxgInnerURL, inner_url());
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
@@ -503,6 +553,7 @@ TEST_P(SignedExchangeHandlerTest, CertWithoutExtensionAllowedByFeatureFlag) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result());
EXPECT_EQ(net::OK, error());
std::string payload;
int rv = ReadPayloadStream(&payload);
@@ -534,8 +585,15 @@ TEST_P(SignedExchangeHandlerTest, CertSha256Mismatch) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kSignatureVerificationError, result());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
EXPECT_EQ(kTestSxgInnerURL, inner_url());
+ ExpectHistogramValues(
+ SignedExchangeSignatureVerifier::Result::kErrCertificateSHA256Mismatch,
+ base::nullopt /* cert_result */, base::nullopt /* ct_result */,
+ base::nullopt /* ocsp_response_status */,
+ base::nullopt /* ocsp_revocation_status */);
+
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
ReadStream(source_, nullptr);
}
@@ -569,8 +627,15 @@ TEST_P(SignedExchangeHandlerTest, VerifyCertFailure) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kCertVerificationError, result());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
EXPECT_EQ("https://test.example.com/test/", inner_url());
+ ExpectHistogramValues(
+ SignedExchangeSignatureVerifier::Result::kSuccess, net::ERR_CERT_INVALID,
+ net::ct::CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE,
+ base::nullopt /* ocsp_response_status */,
+ base::nullopt /* ocsp_revocation_status */);
+
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
ReadStream(source_, nullptr);
}
@@ -601,6 +666,7 @@ TEST_P(SignedExchangeHandlerTest, OCSPNotChecked) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kOCSPError, result());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
EXPECT_EQ(kTestSxgInnerURL, inner_url());
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
@@ -633,6 +699,7 @@ TEST_P(SignedExchangeHandlerTest, OCSPNotProvided) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kOCSPError, result());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
EXPECT_EQ(kTestSxgInnerURL, inner_url());
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
@@ -666,6 +733,7 @@ TEST_P(SignedExchangeHandlerTest, OCSPInvalid) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kOCSPError, result());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
EXPECT_EQ(kTestSxgInnerURL, inner_url());
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
@@ -700,6 +768,7 @@ TEST_P(SignedExchangeHandlerTest, OCSPRevoked) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kOCSPError, result());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
EXPECT_EQ(kTestSxgInnerURL, inner_url());
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
@@ -745,6 +814,7 @@ TEST_P(SignedExchangeHandlerTest, CertVerifierParams) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result());
EXPECT_EQ(net::OK, error());
std::string payload;
int rv = ReadPayloadStream(&payload);
@@ -786,8 +856,14 @@ TEST_P(SignedExchangeHandlerTest, NotEnoughSCTsFromPubliclyTrustedCert) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kCTVerificationError, result());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
EXPECT_EQ(kTestSxgInnerURL, inner_url());
+ ExpectHistogramValues(SignedExchangeSignatureVerifier::Result::kSuccess,
+ net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED,
+ net::ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ base::nullopt /* ocsp_response_status */,
+ base::nullopt /* ocsp_revocation_status */);
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
ReadStream(source_, nullptr);
}
@@ -823,6 +899,7 @@ TEST_P(SignedExchangeHandlerTest, CTRequirementsMetForPubliclyTrustedCert) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result());
EXPECT_EQ(net::OK, error());
// EV status should be preserved.
EXPECT_TRUE(resource_response().ssl_info->cert_status &
@@ -832,6 +909,10 @@ TEST_P(SignedExchangeHandlerTest, CTRequirementsMetForPubliclyTrustedCert) {
EXPECT_TRUE(resource_response().ssl_info->ct_policy_compliance_required);
EXPECT_EQ(net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
resource_response().ssl_info->ct_policy_compliance);
+ ExpectHistogramValues(
+ SignedExchangeSignatureVerifier::Result::kSuccess, net::OK,
+ net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
+ net::OCSPVerifyResult::PROVIDED, net::OCSPRevocationStatus::GOOD);
std::string payload;
int rv = ReadPayloadStream(&payload);
@@ -874,6 +955,7 @@ TEST_P(SignedExchangeHandlerTest, CTNotRequiredForLocalAnchors) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result());
EXPECT_EQ(net::OK, error());
// EV status should be removed.
EXPECT_FALSE(resource_response().ssl_info->cert_status &
@@ -883,6 +965,10 @@ TEST_P(SignedExchangeHandlerTest, CTNotRequiredForLocalAnchors) {
EXPECT_FALSE(resource_response().ssl_info->ct_policy_compliance_required);
EXPECT_EQ(net::ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
resource_response().ssl_info->ct_policy_compliance);
+ ExpectHistogramValues(
+ SignedExchangeSignatureVerifier::Result::kSuccess, net::OK,
+ net::ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ net::OCSPVerifyResult::PROVIDED, net::OCSPRevocationStatus::GOOD);
std::string payload;
int rv = ReadPayloadStream(&payload);
@@ -948,6 +1034,7 @@ TEST_P(SignedExchangeHandlerTest, CTVerifierParams) {
WaitForHeader();
ASSERT_TRUE(read_header());
+ EXPECT_EQ(SignedExchangeLoadResult::kSuccess, result());
EXPECT_EQ(net::OK, error());
std::string payload;
int rv = ReadPayloadStream(&payload);
diff --git a/chromium/content/browser/web_package/signed_exchange_loader.cc b/chromium/content/browser/web_package/signed_exchange_loader.cc
index d03dd7f2947..85a3ced159b 100644
--- a/chromium/content/browser/web_package/signed_exchange_loader.cc
+++ b/chromium/content/browser/web_package/signed_exchange_loader.cc
@@ -8,15 +8,18 @@
#include "base/callback.h"
#include "base/feature_list.h"
+#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
#include "content/browser/loader/data_pipe_to_source_stream.h"
#include "content/browser/loader/source_stream_to_data_pipe.h"
#include "content/browser/web_package/signed_exchange_cert_fetcher_factory.h"
#include "content/browser/web_package/signed_exchange_devtools_proxy.h"
#include "content/browser/web_package/signed_exchange_handler.h"
+#include "content/browser/web_package/signed_exchange_prefetch_metric_recorder.h"
#include "content/browser/web_package/signed_exchange_utils.h"
#include "content/public/common/content_features.h"
#include "content/public/common/origin_util.h"
+#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_status_flags.h"
#include "net/http/http_util.h"
@@ -29,6 +32,8 @@ namespace content {
namespace {
+constexpr char kLoadResultHistogram[] = "SignedExchange.LoadResult";
+
net::RedirectInfo CreateRedirectInfo(const GURL& new_url,
const GURL& outer_request_url) {
net::RedirectInfo redirect_info;
@@ -102,7 +107,8 @@ SignedExchangeLoader::SignedExchangeLoader(
std::unique_ptr<SignedExchangeDevToolsProxy> devtools_proxy,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
URLLoaderThrottlesGetter url_loader_throttles_getter,
- base::RepeatingCallback<int(void)> frame_tree_node_id_getter)
+ base::RepeatingCallback<int(void)> frame_tree_node_id_getter,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder> metric_recorder)
: outer_request_url_(outer_request_url),
outer_response_timing_info_(
std::make_unique<ResponseTimingInfo>(outer_response)),
@@ -118,6 +124,7 @@ SignedExchangeLoader::SignedExchangeLoader(
url_loader_factory_(std::move(url_loader_factory)),
url_loader_throttles_getter_(std::move(url_loader_throttles_getter)),
frame_tree_node_id_getter_(frame_tree_node_id_getter),
+ metric_recorder_(std::move(metric_recorder)),
weak_factory_(this) {
DCHECK(signed_exchange_utils::IsSignedExchangeHandlingEnabled());
DCHECK(outer_request_url_.is_valid());
@@ -129,6 +136,8 @@ SignedExchangeLoader::SignedExchangeLoader(
// transport layer, and MUST NOT accept exchanges transferred over plain HTTP
// without TLS. [spec text]
if (!IsOriginSecure(outer_request_url)) {
+ UMA_HISTOGRAM_ENUMERATION(kLoadResultHistogram,
+ SignedExchangeLoadResult::kSXGServedFromNonHTTPS);
devtools_proxy_->ReportError(
"Signed exchange response from non secure origin is not supported.",
base::nullopt /* error_field */);
@@ -266,11 +275,18 @@ void SignedExchangeLoader::ConnectToClient(
}
void SignedExchangeLoader::OnHTTPExchangeFound(
+ SignedExchangeLoadResult result,
net::Error error,
const GURL& request_url,
const std::string& request_method,
const network::ResourceResponseHead& resource_response,
std::unique_ptr<net::SourceStream> payload_stream) {
+ UMA_HISTOGRAM_ENUMERATION(kLoadResultHistogram, result);
+
+ if (load_flags_ & net::LOAD_PREFETCH) {
+ metric_recorder_->OnSignedExchangePrefetchFinished(request_url, error);
+ }
+
if (error) {
if (error != net::ERR_INVALID_SIGNED_EXCHANGE ||
!should_redirect_on_failure_ || !request_url.is_valid()) {
@@ -305,15 +321,15 @@ void SignedExchangeLoader::OnHTTPExchangeFound(
!net::IsCertStatusMinorError(ssl_info->cert_status)) {
ssl_info_ = ssl_info;
}
+
+ network::ResourceResponseHead inner_response_head_shown_to_client =
+ resource_response;
if (ssl_info.has_value() &&
!(url_loader_options_ &
network::mojom::kURLLoadOptionSendSSLInfoWithResponse)) {
- network::ResourceResponseHead response_info = resource_response;
- response_info.ssl_info = base::nullopt;
- client_->OnReceiveResponse(response_info);
- } else {
- client_->OnReceiveResponse(resource_response);
+ inner_response_head_shown_to_client.ssl_info = base::nullopt;
}
+ client_->OnReceiveResponse(inner_response_head_shown_to_client);
// Currently we always assume that we have body.
// TODO(https://crbug.com/80374): Add error handling and bail out
diff --git a/chromium/content/browser/web_package/signed_exchange_loader.h b/chromium/content/browser/web_package/signed_exchange_loader.h
index 47cdeccf490..210c3bc13d2 100644
--- a/chromium/content/browser/web_package/signed_exchange_loader.h
+++ b/chromium/content/browser/web_package/signed_exchange_loader.h
@@ -8,6 +8,7 @@
#include "base/callback.h"
#include "base/optional.h"
#include "base/unguessable_token.h"
+#include "content/browser/web_package/signed_exchange_error.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/simple_watcher.h"
@@ -30,6 +31,7 @@ namespace content {
class SignedExchangeDevToolsProxy;
class SignedExchangeHandler;
class SignedExchangeHandlerFactory;
+class SignedExchangePrefetchMetricRecorder;
class URLLoaderThrottle;
class SourceStreamToDataPipe;
@@ -59,7 +61,8 @@ class SignedExchangeLoader final : public network::mojom::URLLoaderClient,
std::unique_ptr<SignedExchangeDevToolsProxy> devtools_proxy,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
URLLoaderThrottlesGetter url_loader_throttles_getter,
- base::RepeatingCallback<int(void)> frame_tree_node_id_getter);
+ base::RepeatingCallback<int(void)> frame_tree_node_id_getter,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder> metric_recorder);
~SignedExchangeLoader() override;
bool HasRedirectedToFallbackURL() const {
@@ -105,6 +108,7 @@ class SignedExchangeLoader final : public network::mojom::URLLoaderClient,
// Called from |signed_exchange_handler_| when it finds an origin-signed HTTP
// exchange.
void OnHTTPExchangeFound(
+ SignedExchangeLoadResult result,
net::Error error,
const GURL& request_url,
const std::string& request_method,
@@ -152,6 +156,7 @@ class SignedExchangeLoader final : public network::mojom::URLLoaderClient,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
URLLoaderThrottlesGetter url_loader_throttles_getter_;
base::RepeatingCallback<int(void)> frame_tree_node_id_getter_;
+ scoped_refptr<SignedExchangePrefetchMetricRecorder> metric_recorder_;
base::Optional<net::SSLInfo> ssl_info_;
diff --git a/chromium/content/browser/web_package/signed_exchange_prefetch_handler.cc b/chromium/content/browser/web_package/signed_exchange_prefetch_handler.cc
index abf10c2ed0a..46efa0e5150 100644
--- a/chromium/content/browser/web_package/signed_exchange_prefetch_handler.cc
+++ b/chromium/content/browser/web_package/signed_exchange_prefetch_handler.cc
@@ -8,6 +8,7 @@
#include "base/feature_list.h"
#include "content/browser/web_package/signed_exchange_devtools_proxy.h"
#include "content/browser/web_package/signed_exchange_loader.h"
+#include "content/browser/web_package/signed_exchange_prefetch_metric_recorder.h"
#include "content/browser/web_package/signed_exchange_url_loader_factory_for_non_network_service.h"
#include "content/public/common/content_features.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
@@ -32,8 +33,11 @@ SignedExchangePrefetchHandler::SignedExchangePrefetchHandler(
URLLoaderThrottlesGetter loader_throttles_getter,
ResourceContext* resource_context,
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
- network::mojom::URLLoaderClient* forwarding_client)
- : loader_client_binding_(this), forwarding_client_(forwarding_client) {
+ network::mojom::URLLoaderClient* forwarding_client,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder> metric_recorder)
+ : loader_client_binding_(this),
+ forwarding_client_(forwarding_client),
+ outer_request_url_(outer_request_url) {
network::mojom::URLLoaderClientEndpointsPtr endpoints =
network::mojom::URLLoaderClientEndpoints::New(
std::move(network_loader).PassInterface(),
@@ -49,15 +53,15 @@ SignedExchangePrefetchHandler::SignedExchangePrefetchHandler(
url_loader_factory = std::move(network_loader_factory);
}
signed_exchange_loader_ = std::make_unique<SignedExchangeLoader>(
- outer_request_url, response, std::move(client), std::move(endpoints),
+ outer_request_url_, response, std::move(client), std::move(endpoints),
std::move(request_initiator), network::mojom::kURLLoadOptionNone,
load_flags, false /* should_redirect_to_fallback */,
throttling_profile_id,
std::make_unique<SignedExchangeDevToolsProxy>(
- outer_request_url, response, frame_tree_node_id_getter,
+ outer_request_url_, response, frame_tree_node_id_getter,
base::nullopt /* devtools_navigation_token */, report_raw_headers),
std::move(url_loader_factory), loader_throttles_getter,
- frame_tree_node_id_getter);
+ frame_tree_node_id_getter, std::move(metric_recorder));
}
SignedExchangePrefetchHandler::~SignedExchangePrefetchHandler() = default;
@@ -109,6 +113,10 @@ void SignedExchangePrefetchHandler::OnStartLoadingResponseBody(
void SignedExchangePrefetchHandler::OnComplete(
const network::URLLoaderCompletionStatus& status) {
+ // We only reach here on error, since successful completion of the
+ // outer sxg load should trigger redirect and land on ::OnReceiveRedirect.
+ DCHECK_NE(net::OK, status.error_code);
+
forwarding_client_->OnComplete(status);
}
diff --git a/chromium/content/browser/web_package/signed_exchange_prefetch_handler.h b/chromium/content/browser/web_package/signed_exchange_prefetch_handler.h
index 0c3551f4108..200ce6b9a5d 100644
--- a/chromium/content/browser/web_package/signed_exchange_prefetch_handler.h
+++ b/chromium/content/browser/web_package/signed_exchange_prefetch_handler.h
@@ -25,6 +25,7 @@ namespace content {
class ResourceContext;
class URLLoaderThrottle;
class SignedExchangeLoader;
+class SignedExchangePrefetchMetricRecorder;
// Attached to each PrefetchURLLoader if the prefetch is for a signed exchange.
class SignedExchangePrefetchHandler final
@@ -51,7 +52,8 @@ class SignedExchangePrefetchHandler final
URLLoaderThrottlesGetter loader_throttles_getter,
ResourceContext* resource_context,
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
- network::mojom::URLLoaderClient* forwarding_client);
+ network::mojom::URLLoaderClient* forwarding_client,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder> metric_recorder);
~SignedExchangePrefetchHandler() override;
@@ -83,6 +85,8 @@ class SignedExchangePrefetchHandler final
network::mojom::URLLoaderClient* forwarding_client_;
+ const GURL outer_request_url_;
+
DISALLOW_COPY_AND_ASSIGN(SignedExchangePrefetchHandler);
};
diff --git a/chromium/content/browser/web_package/signed_exchange_prefetch_metric_recorder.cc b/chromium/content/browser/web_package/signed_exchange_prefetch_metric_recorder.cc
new file mode 100644
index 00000000000..e83902c7e3c
--- /dev/null
+++ b/chromium/content/browser/web_package/signed_exchange_prefetch_metric_recorder.cc
@@ -0,0 +1,23 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_package/signed_exchange_prefetch_metric_recorder.h"
+
+#include "content/public/browser/browser_thread.h"
+
+namespace content {
+
+SignedExchangePrefetchMetricRecorder::SignedExchangePrefetchMetricRecorder() =
+ default;
+SignedExchangePrefetchMetricRecorder::~SignedExchangePrefetchMetricRecorder() =
+ default;
+
+void SignedExchangePrefetchMetricRecorder::OnSignedExchangePrefetchFinished(
+ const GURL& outer_url,
+ net::Error error) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // TODO(crbug.com/890180): Actually Report UMA.
+}
+
+} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_prefetch_metric_recorder.h b/chromium/content/browser/web_package/signed_exchange_prefetch_metric_recorder.h
new file mode 100644
index 00000000000..00566617c65
--- /dev/null
+++ b/chromium/content/browser/web_package/signed_exchange_prefetch_metric_recorder.h
@@ -0,0 +1,35 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_PREFETCH_METRIC_RECORDER_H_
+#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_PREFETCH_METRIC_RECORDER_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "net/base/net_errors.h"
+
+class GURL;
+
+namespace content {
+
+// SignedExchangePrefetchMetricRecorder records signed exchange prefetch and
+// its usage metrics.
+class SignedExchangePrefetchMetricRecorder final
+ : public base::RefCountedThreadSafe<SignedExchangePrefetchMetricRecorder> {
+ public:
+ SignedExchangePrefetchMetricRecorder();
+
+ void OnSignedExchangePrefetchFinished(const GURL& outer_url,
+ net::Error error);
+
+ private:
+ friend class base::RefCountedThreadSafe<SignedExchangePrefetchMetricRecorder>;
+ ~SignedExchangePrefetchMetricRecorder();
+
+ DISALLOW_COPY_AND_ASSIGN(SignedExchangePrefetchMetricRecorder);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_PREFETCH_METRIC_RECORDER_H_
diff --git a/chromium/content/browser/web_package/signed_exchange_request_handler.cc b/chromium/content/browser/web_package/signed_exchange_request_handler.cc
index 97e0b1e0765..921124aae28 100644
--- a/chromium/content/browser/web_package/signed_exchange_request_handler.cc
+++ b/chromium/content/browser/web_package/signed_exchange_request_handler.cc
@@ -10,6 +10,7 @@
#include "base/feature_list.h"
#include "content/browser/web_package/signed_exchange_devtools_proxy.h"
#include "content/browser/web_package/signed_exchange_loader.h"
+#include "content/browser/web_package/signed_exchange_prefetch_metric_recorder.h"
#include "content/browser/web_package/signed_exchange_utils.h"
#include "content/common/throttling_url_loader.h"
#include "content/public/common/content_features.h"
@@ -38,7 +39,8 @@ SignedExchangeRequestHandler::SignedExchangeRequestHandler(
bool report_raw_headers,
int load_flags,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- URLLoaderThrottlesGetter url_loader_throttles_getter)
+ URLLoaderThrottlesGetter url_loader_throttles_getter,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder> metric_recorder)
: request_initiator_(std::move(request_initiator)),
url_(url),
url_loader_options_(url_loader_options),
@@ -49,6 +51,7 @@ SignedExchangeRequestHandler::SignedExchangeRequestHandler(
load_flags_(load_flags),
url_loader_factory_(url_loader_factory),
url_loader_throttles_getter_(std::move(url_loader_throttles_getter)),
+ metric_recorder_(std::move(metric_recorder)),
weak_factory_(this) {
DCHECK(signed_exchange_utils::IsSignedExchangeHandlingEnabled());
}
@@ -66,7 +69,8 @@ void SignedExchangeRequestHandler::MaybeCreateLoader(
}
if (signed_exchange_loader_->HasRedirectedToFallbackURL()) {
signed_exchange_loader_ = nullptr;
- std::move(callback).Run({});
+ std::move(fallback_callback)
+ .Run(false /* reset_subresource_loader_params */);
return;
}
@@ -79,7 +83,8 @@ bool SignedExchangeRequestHandler::MaybeCreateLoaderForResponse(
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr* loader,
network::mojom::URLLoaderClientRequest* client_request,
- ThrottlingURLLoader* url_loader) {
+ ThrottlingURLLoader* url_loader,
+ bool* skip_other_interceptors) {
DCHECK(!signed_exchange_loader_);
if (!signed_exchange_utils::ShouldHandleAsSignedHTTPExchange(
request_initiator_.GetURL(), response)) {
@@ -103,7 +108,10 @@ bool SignedExchangeRequestHandler::MaybeCreateLoaderForResponse(
base::BindRepeating([](int id) { return id; }, frame_tree_node_id_),
devtools_navigation_token_, report_raw_headers_),
url_loader_factory_, url_loader_throttles_getter_,
- base::BindRepeating([](int id) { return id; }, frame_tree_node_id_));
+ base::BindRepeating([](int id) { return id; }, frame_tree_node_id_),
+ metric_recorder_);
+
+ *skip_other_interceptors = true;
return true;
}
diff --git a/chromium/content/browser/web_package/signed_exchange_request_handler.h b/chromium/content/browser/web_package/signed_exchange_request_handler.h
index b0037c69d84..5b9548429a9 100644
--- a/chromium/content/browser/web_package/signed_exchange_request_handler.h
+++ b/chromium/content/browser/web_package/signed_exchange_request_handler.h
@@ -20,6 +20,7 @@ namespace content {
class URLLoaderThrottle;
class SignedExchangeLoader;
+class SignedExchangePrefetchMetricRecorder;
class SignedExchangeRequestHandler final : public NavigationLoaderInterceptor {
public:
@@ -38,7 +39,8 @@ class SignedExchangeRequestHandler final : public NavigationLoaderInterceptor {
bool report_raw_headers,
int load_flags,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- URLLoaderThrottlesGetter url_loader_throttles_getter);
+ URLLoaderThrottlesGetter url_loader_throttles_getter,
+ scoped_refptr<SignedExchangePrefetchMetricRecorder> metric_recorder);
~SignedExchangeRequestHandler() override;
// NavigationLoaderInterceptor implementation
@@ -51,7 +53,8 @@ class SignedExchangeRequestHandler final : public NavigationLoaderInterceptor {
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr* loader,
network::mojom::URLLoaderClientRequest* client_request,
- ThrottlingURLLoader* url_loader) override;
+ ThrottlingURLLoader* url_loader,
+ bool* skip_other_interceptors) override;
private:
void StartResponse(const network::ResourceRequest& resource_request,
@@ -73,6 +76,7 @@ class SignedExchangeRequestHandler final : public NavigationLoaderInterceptor {
const int load_flags_;
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
URLLoaderThrottlesGetter url_loader_throttles_getter_;
+ scoped_refptr<SignedExchangePrefetchMetricRecorder> metric_recorder_;
base::WeakPtrFactory<SignedExchangeRequestHandler> weak_factory_;
diff --git a/chromium/content/browser/web_package/signed_exchange_request_handler_browsertest.cc b/chromium/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
index 03a54596795..b2d7d4825b8 100644
--- a/chromium/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
+++ b/chromium/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
@@ -6,10 +6,15 @@
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/task/post_task.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
+#include "content/browser/frame_host/navigation_handle_impl.h"
#include "content/browser/web_package/signed_exchange_handler.h"
+#include "content/browser/web_package/signed_exchange_utils.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
@@ -28,21 +33,30 @@
#include "content/shell/browser/shell.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/mock_cert_verifier.h"
+#include "net/dns/mock_host_resolver.h"
#include "net/test/cert_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
#include "net/test/test_data_directory.h"
#include "net/test/url_request/url_request_mock_http_job.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_interceptor.h"
+#include "services/network/loader_util.h"
#include "services/network/public/cpp/features.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
namespace {
const uint64_t kSignatureHeaderDate = 1520834000; // 2018-03-12T05:53:20Z
+const uint64_t kSignatureHeaderExpires = 1520837600; // 2018-03-12T06:53:20Z
+
+constexpr char kExpectedSXGEnabledAcceptHeaderForPrefetch[] =
+ "application/signed-exchange;v=b2;q=0.9,*/*;q=0.8";
class RedirectObserver : public WebContentsObserver {
public:
@@ -64,11 +78,26 @@ class RedirectObserver : public WebContentsObserver {
DISALLOW_COPY_AND_ASSIGN(RedirectObserver);
};
+class AssertNavigationHandleFlagObserver : public WebContentsObserver {
+ public:
+ explicit AssertNavigationHandleFlagObserver(WebContents* web_contents)
+ : WebContentsObserver(web_contents) {}
+ ~AssertNavigationHandleFlagObserver() override = default;
+
+ void DidFinishNavigation(NavigationHandle* handle) override {
+ EXPECT_TRUE(static_cast<NavigationHandleImpl*>(handle)->IsSignedExchangeInnerResponse());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AssertNavigationHandleFlagObserver);
+};
+
} // namespace
-class SignedExchangeRequestHandlerBrowserTest : public CertVerifierBrowserTest {
+class SignedExchangeRequestHandlerBrowserTestBase
+ : public CertVerifierBrowserTest {
public:
- SignedExchangeRequestHandlerBrowserTest() {
+ SignedExchangeRequestHandlerBrowserTestBase() {
// This installs "root_ca_cert.pem" from which our test certificates are
// created. (Needed for the tests that use real certificate, i.e.
// RealCertVerifier)
@@ -79,7 +108,7 @@ class SignedExchangeRequestHandlerBrowserTest : public CertVerifierBrowserTest {
SignedExchangeHandler::SetVerificationTimeForTesting(
base::Time::UnixEpoch() +
base::TimeDelta::FromSeconds(kSignatureHeaderDate));
- SetUpFeatures();
+ feature_list_.InitWithFeatures({features::kSignedHTTPExchange}, {});
CertVerifierBrowserTest::SetUp();
}
@@ -90,10 +119,6 @@ class SignedExchangeRequestHandlerBrowserTest : public CertVerifierBrowserTest {
}
protected:
- virtual void SetUpFeatures() {
- feature_list_.InitWithFeatures({features::kSignedHTTPExchange}, {});
- }
-
static scoped_refptr<net::X509Certificate> LoadCertificate(
const std::string& cert_file) {
base::ScopedAllowBlockingForTesting allow_io;
@@ -108,20 +133,45 @@ class SignedExchangeRequestHandlerBrowserTest : public CertVerifierBrowserTest {
void InstallUrlInterceptor(const GURL& url, const std::string& data_path) {
if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
if (!interceptor_) {
- interceptor_ =
- std::make_unique<URLLoaderInterceptor>(base::BindRepeating(
- &SignedExchangeRequestHandlerBrowserTest::OnInterceptCallback,
- base::Unretained(this)));
+ interceptor_ = std::make_unique<
+ URLLoaderInterceptor>(base::BindRepeating(
+ &SignedExchangeRequestHandlerBrowserTestBase::OnInterceptCallback,
+ base::Unretained(this)));
}
interceptor_data_path_map_[url] = data_path;
} else {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&InstallMockInterceptors, url, data_path));
}
}
- base::test::ScopedFeatureList feature_list_;
+ void InstallMockCert() {
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
+ scoped_refptr<net::X509Certificate> original_cert =
+ LoadCertificate("prime256v1-sha256.public.pem");
+ net::CertVerifyResult dummy_result;
+ dummy_result.verified_cert = original_cert;
+ dummy_result.cert_status = net::OK;
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status =
+ net::OCSPRevocationStatus::GOOD;
+ mock_cert_verifier()->AddResultForCertAndHost(
+ original_cert, "test.example.org", dummy_result, net::OK);
+ }
+
+ void TriggerPrefetch(const GURL& url, bool expect_success) {
+ const GURL prefetch_html_url = embedded_test_server()->GetURL(
+ std::string("/sxg/prefetch.html#") + url.spec());
+ base::string16 expected_title =
+ base::ASCIIToUTF16(expect_success ? "OK" : "FAIL");
+ TitleWatcher title_watcher(shell()->web_contents(), expected_title);
+ NavigateToURL(shell(), prefetch_html_url);
+ EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
+ }
+
+ const base::HistogramTester histogram_tester_;
private:
static void InstallMockInterceptors(const GURL& url,
@@ -141,43 +191,52 @@ class SignedExchangeRequestHandlerBrowserTest : public CertVerifierBrowserTest {
return true;
}
+ base::test::ScopedFeatureList feature_list_;
std::unique_ptr<URLLoaderInterceptor> interceptor_;
std::map<GURL, std::string> interceptor_data_path_map_;
+ DISALLOW_COPY_AND_ASSIGN(SignedExchangeRequestHandlerBrowserTestBase);
+};
+
+enum class SignedExchangeRequestHandlerBrowserTestPrefetchParam {
+ kPrefetchDisabled,
+ kPrefetchEnabled
+};
+
+class SignedExchangeRequestHandlerBrowserTest
+ : public SignedExchangeRequestHandlerBrowserTestBase,
+ public testing::WithParamInterface<
+ SignedExchangeRequestHandlerBrowserTestPrefetchParam> {
+ public:
+ SignedExchangeRequestHandlerBrowserTest() = default;
+
+ protected:
+ bool PrefetchIsEnabled() {
+ return GetParam() == SignedExchangeRequestHandlerBrowserTestPrefetchParam::
+ kPrefetchEnabled;
+ }
+
+ private:
DISALLOW_COPY_AND_ASSIGN(SignedExchangeRequestHandlerBrowserTest);
};
-IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest, Simple) {
+IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerBrowserTest, Simple) {
InstallUrlInterceptor(
GURL("https://cert.example.org/cert.msg"),
"content/test/data/sxg/test.example.org.public.pem.cbor");
+ InstallMockCert();
- // Make the MockCertVerifier treat the certificate
- // "prime256v1-sha256.public.pem" as valid for "test.example.org".
- scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("prime256v1-sha256.public.pem");
- net::CertVerifyResult dummy_result;
- dummy_result.verified_cert = original_cert;
- dummy_result.cert_status = net::OK;
- dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
- dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
- mock_cert_verifier()->AddResultForCertAndHost(
- original_cert, "test.example.org", dummy_result, net::OK);
-
- embedded_test_server()->RegisterRequestMonitor(
- base::BindRepeating([](const net::test_server::HttpRequest& request) {
- if (request.relative_url == "/sxg/test.example.org_test.sxg") {
- const auto& accept_value = request.headers.find("accept")->second;
- EXPECT_THAT(accept_value,
- ::testing::HasSubstr("application/signed-exchange;v=b2"));
- }
- }));
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(embedded_test_server()->Start());
GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");
+ if (PrefetchIsEnabled())
+ TriggerPrefetch(url, true);
+
base::string16 title = base::ASCIIToUTF16("https://test.example.org/test/");
TitleWatcher title_watcher(shell()->web_contents(), title);
RedirectObserver redirect_observer(shell()->web_contents());
+ AssertNavigationHandleFlagObserver assert_navigation_handle_flag_observer(
+ shell()->web_contents());
NavigateToURL(shell(), url);
EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
@@ -196,36 +255,35 @@ IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest, Simple) {
const net::SHA256HashValue fingerprint =
net::X509Certificate::CalculateFingerprint256(
entry->GetSSL().certificate->cert_buffer());
+ scoped_refptr<net::X509Certificate> original_cert =
+ LoadCertificate("prime256v1-sha256.public.pem");
const net::SHA256HashValue original_fingerprint =
net::X509Certificate::CalculateFingerprint256(
original_cert->cert_buffer());
EXPECT_EQ(original_fingerprint, fingerprint);
+ histogram_tester_.ExpectUniqueSample("SignedExchange.LoadResult",
+ SignedExchangeLoadResult::kSuccess,
+ PrefetchIsEnabled() ? 2 : 1);
+ histogram_tester_.ExpectTotalCount(
+ "SignedExchange.Time.CertificateFetch.Success",
+ PrefetchIsEnabled() ? 2 : 1);
}
-IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest,
+IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerBrowserTest,
InvalidContentType) {
InstallUrlInterceptor(
GURL("https://cert.example.org/cert.msg"),
"content/test/data/sxg/test.example.org.public.pem.cbor");
InstallUrlInterceptor(GURL("https://test.example.org/test/"),
"content/test/data/sxg/fallback.html");
-
- // Make the MockCertVerifier treat the certificate
- // "prime256v1-sha256.public.pem" as valid for "test.example.org".
- scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("prime256v1-sha256.public.pem");
- net::CertVerifyResult dummy_result;
- dummy_result.verified_cert = original_cert;
- dummy_result.cert_status = net::OK;
- dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
- dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
- mock_cert_verifier()->AddResultForCertAndHost(
- original_cert, "test.example.org", dummy_result, net::OK);
+ InstallMockCert();
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(embedded_test_server()->Start());
GURL url = embedded_test_server()->GetURL(
"/sxg/test.example.org_test_invalid_content_type.sxg");
+ if (PrefetchIsEnabled())
+ TriggerPrefetch(url, false);
base::string16 title = base::ASCIIToUTF16("Fallback URL response");
TitleWatcher title_watcher(shell()->web_contents(), title);
@@ -233,9 +291,42 @@ IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest,
NavigateToURL(shell(), url);
EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
EXPECT_EQ(303, redirect_observer.response_code());
+ histogram_tester_.ExpectUniqueSample(
+ "SignedExchange.LoadResult", SignedExchangeLoadResult::kVersionMismatch,
+ PrefetchIsEnabled() ? 2 : 1);
}
-IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest,
+IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerBrowserTest, Expired) {
+ SignedExchangeHandler::SetVerificationTimeForTesting(
+ base::Time::UnixEpoch() +
+ base::TimeDelta::FromSeconds(kSignatureHeaderExpires + 1));
+
+ InstallUrlInterceptor(
+ GURL("https://cert.example.org/cert.msg"),
+ "content/test/data/sxg/test.example.org.public.pem.cbor");
+ InstallUrlInterceptor(GURL("https://test.example.org/test/"),
+ "content/test/data/sxg/fallback.html");
+ InstallMockCert();
+
+ embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");
+
+ base::string16 title = base::ASCIIToUTF16("Fallback URL response");
+ TitleWatcher title_watcher(shell()->web_contents(), title);
+ RedirectObserver redirect_observer(shell()->web_contents());
+ NavigateToURL(shell(), url);
+ EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
+ EXPECT_EQ(303, redirect_observer.response_code());
+ histogram_tester_.ExpectUniqueSample(
+ "SignedExchange.LoadResult",
+ SignedExchangeLoadResult::kSignatureVerificationError, 1);
+ histogram_tester_.ExpectUniqueSample(
+ "SignedExchange.SignatureVerificationResult",
+ SignedExchangeSignatureVerifier::Result::kErrInvalidTimestamp, 1);
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerBrowserTest,
RedirectBrokenSignedExchanges) {
InstallUrlInterceptor(GURL("https://test.example.org/test/"),
"content/test/data/sxg/fallback.html");
@@ -254,14 +345,25 @@ IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest,
GURL url = embedded_test_server()->GetURL(broken_exchange);
+ if (PrefetchIsEnabled())
+ TriggerPrefetch(url, false);
+
base::string16 title = base::ASCIIToUTF16("Fallback URL response");
TitleWatcher title_watcher(shell()->web_contents(), title);
NavigateToURL(shell(), url);
EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
}
+ histogram_tester_.ExpectTotalCount("SignedExchange.LoadResult",
+ PrefetchIsEnabled() ? 4 : 2);
+ histogram_tester_.ExpectBucketCount(
+ "SignedExchange.LoadResult", SignedExchangeLoadResult::kVersionMismatch,
+ PrefetchIsEnabled() ? 2 : 1);
+ histogram_tester_.ExpectBucketCount(
+ "SignedExchange.LoadResult", SignedExchangeLoadResult::kHeaderParseError,
+ PrefetchIsEnabled() ? 2 : 1);
}
-IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest, CertNotFound) {
+IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerBrowserTest, CertNotFound) {
InstallUrlInterceptor(GURL("https://cert.example.org/cert.msg"),
"content/test/data/sxg/404.msg");
InstallUrlInterceptor(GURL("https://test.example.org/test/"),
@@ -271,14 +373,31 @@ IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest, CertNotFound) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");
+ if (PrefetchIsEnabled())
+ TriggerPrefetch(url, false);
+
base::string16 title = base::ASCIIToUTF16("Fallback URL response");
TitleWatcher title_watcher(shell()->web_contents(), title);
NavigateToURL(shell(), url);
EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
+ histogram_tester_.ExpectUniqueSample(
+ "SignedExchange.LoadResult", SignedExchangeLoadResult::kCertFetchError,
+ PrefetchIsEnabled() ? 2 : 1);
+ histogram_tester_.ExpectTotalCount(
+ "SignedExchange.Time.CertificateFetch.Failure",
+ PrefetchIsEnabled() ? 2 : 1);
}
+INSTANTIATE_TEST_CASE_P(
+ SignedExchangeRequestHandlerBrowserTest,
+ SignedExchangeRequestHandlerBrowserTest,
+ testing::Values(
+ SignedExchangeRequestHandlerBrowserTestPrefetchParam::kPrefetchDisabled,
+ SignedExchangeRequestHandlerBrowserTestPrefetchParam::
+ kPrefetchEnabled));
+
class SignedExchangeRequestHandlerRealCertVerifierBrowserTest
- : public SignedExchangeRequestHandlerBrowserTest {
+ : public SignedExchangeRequestHandlerBrowserTestBase {
public:
SignedExchangeRequestHandlerRealCertVerifierBrowserTest() {
// Use "real" CertVerifier.
@@ -294,14 +413,6 @@ IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerRealCertVerifierBrowserTest,
InstallUrlInterceptor(GURL("https://test.example.org/test/"),
"content/test/data/sxg/fallback.html");
- embedded_test_server()->RegisterRequestMonitor(
- base::BindRepeating([](const net::test_server::HttpRequest& request) {
- if (request.relative_url == "/sxg/test.example.org_test.sxg") {
- const auto& accept_value = request.headers.find("accept")->second;
- EXPECT_THAT(accept_value,
- ::testing::HasSubstr("application/signed-exchange;v=b2"));
- }
- }));
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(embedded_test_server()->Start());
GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");
@@ -312,23 +423,666 @@ IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerRealCertVerifierBrowserTest,
// TODO(https://crbug.com/815024): Make this test pass the OCSP check. We'll
// need to either generate an OCSP response on the fly, or override the OCSP
// verification time.
- content::ConsoleObserverDelegate console_observer(shell()->web_contents(),
- "*OCSP*");
- shell()->web_contents()->SetDelegate(&console_observer);
-
base::string16 title = base::ASCIIToUTF16("Fallback URL response");
TitleWatcher title_watcher(shell()->web_contents(), title);
NavigateToURL(shell(), url);
EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
-
// Verify that it failed at the OCSP check step.
- // TODO(https://crbug.com/803774): Find a better way than matching against the
- // error message. We can probably make DevToolsProxy derive some context from
- // StoragePartition so that we can record and extract the detailed error
- // status for testing via that.
- console_observer.Wait();
- EXPECT_TRUE(base::StartsWith(console_observer.message(), "OCSP check failed.",
- base::CompareCase::SENSITIVE));
+ histogram_tester_.ExpectUniqueSample("SignedExchange.LoadResult",
+ SignedExchangeLoadResult::kOCSPError, 1);
+}
+
+enum class SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam {
+ kLegacy,
+ kServiceWorkerServicification,
+ kNetworkService
+};
+
+class SignedExchangeRequestHandlerWithServiceWorkerBrowserTest
+ : public SignedExchangeRequestHandlerBrowserTestBase,
+ public testing::WithParamInterface<
+ SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam> {
+ public:
+ SignedExchangeRequestHandlerWithServiceWorkerBrowserTest() = default;
+ void SetUp() override {
+ switch (GetParam()) {
+ case SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam::
+ kLegacy:
+ feature_list_.InitWithFeatures(
+ {}, {blink::features::kServiceWorkerServicification,
+ network::features::kNetworkService});
+ break;
+ case SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam::
+ kServiceWorkerServicification:
+ feature_list_.InitWithFeatures(
+ {blink::features::kServiceWorkerServicification},
+ {network::features::kNetworkService});
+ break;
+ case SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam::
+ kNetworkService:
+ feature_list_.InitAndEnableFeature(network::features::kNetworkService);
+ break;
+ }
+ SignedExchangeRequestHandlerBrowserTestBase::SetUp();
+ }
+
+ private:
+ base::test::ScopedFeatureList feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(
+ SignedExchangeRequestHandlerWithServiceWorkerBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerWithServiceWorkerBrowserTest,
+ LogicalUrlInServiceWorkerScope) {
+ // SW-scope: https://test.example.org/test/
+ // SXG physical URL: http://127.0.0.1:PORT/sxg/test.example.org_test.sxg
+ // SXG logical URL: https://test.example.org/test/
+ InstallUrlInterceptor(
+ GURL("https://cert.example.org/cert.msg"),
+ "content/test/data/sxg/test.example.org.public.pem.cbor");
+ InstallMockCert();
+
+ const GURL install_sw_url =
+ GURL("https://test.example.org/test/publisher-service-worker.html");
+
+ InstallUrlInterceptor(install_sw_url,
+ "content/test/data/sxg/publisher-service-worker.html");
+ InstallUrlInterceptor(
+ GURL("https://test.example.org/test/publisher-service-worker.js"),
+ "content/test/data/sxg/publisher-service-worker.js");
+ {
+ base::string16 title = base::ASCIIToUTF16("Done");
+ TitleWatcher title_watcher(shell()->web_contents(), title);
+ NavigateToURL(shell(), install_sw_url);
+ EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
+ }
+ embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");
+
+ base::string16 title = base::ASCIIToUTF16("https://test.example.org/test/");
+ TitleWatcher title_watcher(shell()->web_contents(), title);
+ title_watcher.AlsoWaitForTitle(base::ASCIIToUTF16("Generated"));
+ NavigateToURL(shell(), url);
+ // The page content shoud be served from the signed exchange.
+ EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerWithServiceWorkerBrowserTest,
+ NotControlledByDistributorsSW) {
+ // SW-scope: http://127.0.0.1:PORT/sxg/
+ // SXG physical URL: http://127.0.0.1:PORT/sxg/test.example.org_test.sxg
+ // SXG logical URL: https://test.example.org/test/
+ InstallUrlInterceptor(
+ GURL("https://cert.example.org/cert.msg"),
+ "content/test/data/sxg/test.example.org.public.pem.cbor");
+ InstallMockCert();
+ embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ const GURL install_sw_url = embedded_test_server()->GetURL(
+ "/sxg/no-respond-with-service-worker.html");
+
+ {
+ base::string16 title = base::ASCIIToUTF16("Done");
+ TitleWatcher title_watcher(shell()->web_contents(), title);
+ NavigateToURL(shell(), install_sw_url);
+ EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
+ }
+
+ base::string16 title = base::ASCIIToUTF16("https://test.example.org/test/");
+ TitleWatcher title_watcher(shell()->web_contents(), title);
+ NavigateToURL(shell(), embedded_test_server()->GetURL(
+ "/sxg/test.example.org_test.sxg"));
+ EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
+
+ // The page must not be controlled by the service worker of the physical URL.
+ EXPECT_EQ(false, EvalJs(shell(), "!!navigator.serviceWorker.controller"));
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerWithServiceWorkerBrowserTest,
+ NotControlledBySameOriginDistributorsSW) {
+ // SW-scope: https://test.example.org/scope/
+ // SXG physical URL: https://test.example.org/scope/test.example.org_test.sxg
+ // SXG logical URL: https://test.example.org/test/
+ InstallUrlInterceptor(
+ GURL("https://cert.example.org/cert.msg"),
+ "content/test/data/sxg/test.example.org.public.pem.cbor");
+ InstallMockCert();
+
+ InstallUrlInterceptor(GURL("https://test.example.org/scope/test.sxg"),
+ "content/test/data/sxg/test.example.org_test.sxg");
+
+ const GURL install_sw_url = GURL(
+ "https://test.example.org/scope/no-respond-with-service-worker.html");
+
+ InstallUrlInterceptor(
+ install_sw_url,
+ "content/test/data/sxg/no-respond-with-service-worker.html");
+ InstallUrlInterceptor(
+ GURL("https://test.example.org/scope/no-respond-with-service-worker.js"),
+ "content/test/data/sxg/no-respond-with-service-worker.js");
+
+ {
+ base::string16 title = base::ASCIIToUTF16("Done");
+ TitleWatcher title_watcher(shell()->web_contents(), title);
+ NavigateToURL(shell(), install_sw_url);
+ EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
+ }
+
+ base::string16 title = base::ASCIIToUTF16("https://test.example.org/test/");
+ TitleWatcher title_watcher(shell()->web_contents(), title);
+ NavigateToURL(shell(), GURL("https://test.example.org/scope/test.sxg"));
+ EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
+
+ // The page must not be controlled by the service worker of the physical URL.
+ EXPECT_EQ(false, EvalJs(shell(), "!!navigator.serviceWorker.controller"));
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeRequestHandlerWithServiceWorkerBrowserTest,
+ RegisterServiceWorkerFromSignedExchange) {
+ // SXG physical URL: http://127.0.0.1:PORT/sxg/test.example.org_test.sxg
+ // SXG logical URL: https://test.example.org/test/
+ InstallUrlInterceptor(
+ GURL("https://cert.example.org/cert.msg"),
+ "content/test/data/sxg/test.example.org.public.pem.cbor");
+ InstallMockCert();
+
+ InstallUrlInterceptor(
+ GURL("https://test.example.org/test/publisher-service-worker.js"),
+ "content/test/data/sxg/publisher-service-worker.js");
+
+ embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");
+
+ {
+ base::string16 title = base::ASCIIToUTF16("https://test.example.org/test/");
+ TitleWatcher title_watcher(shell()->web_contents(), title);
+ NavigateToURL(shell(), url);
+ EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
+ }
+
+ const std::string register_sw_script =
+ "(async function() {"
+ " try {"
+ " const registration = await navigator.serviceWorker.register("
+ " 'publisher-service-worker.js', {scope: './'});"
+ " window.domAutomationController.send(true);"
+ " } catch (e) {"
+ " window.domAutomationController.send(false);"
+ " }"
+ "})();";
+ bool result = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(shell()->web_contents(),
+ register_sw_script, &result));
+ // serviceWorker.register() fails because the document URL of
+ // ServiceWorkerProviderHost is empty.
+ EXPECT_FALSE(result);
+}
+
+INSTANTIATE_TEST_CASE_P(
+ SignedExchangeRequestHandlerWithServiceWorkerBrowserTest,
+ SignedExchangeRequestHandlerWithServiceWorkerBrowserTest,
+ testing::Values(
+ SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam::kLegacy,
+ SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam::
+ kServiceWorkerServicification,
+ SignedExchangeRequestHandlerWithServiceWorkerBrowserTestParam::
+ kNetworkService));
+
+struct SignedExchangeAcceptHeaderBrowserTestParam {
+ SignedExchangeAcceptHeaderBrowserTestParam(
+ bool sxg_enabled,
+ bool sxg_origin_trial_enabled,
+ bool sxg_accept_header_enabled,
+ bool service_worker_servicification_enabled)
+ : sxg_enabled(sxg_enabled),
+ sxg_origin_trial_enabled(sxg_origin_trial_enabled),
+ sxg_accept_header_enabled(sxg_accept_header_enabled),
+ service_worker_servicification_enabled(
+ service_worker_servicification_enabled) {}
+ const bool sxg_enabled;
+ const bool sxg_origin_trial_enabled;
+ const bool sxg_accept_header_enabled;
+ const bool service_worker_servicification_enabled;
+};
+
+class SignedExchangeAcceptHeaderBrowserTest
+ : public ContentBrowserTest,
+ public testing::WithParamInterface<
+ SignedExchangeAcceptHeaderBrowserTestParam> {
+ public:
+ using self = SignedExchangeAcceptHeaderBrowserTest;
+ SignedExchangeAcceptHeaderBrowserTest()
+ : enabled_https_server_(net::EmbeddedTestServer::TYPE_HTTPS),
+ disabled_https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
+ ~SignedExchangeAcceptHeaderBrowserTest() override = default;
+
+ protected:
+ void SetUp() override {
+ std::vector<base::Feature> enable_features;
+ std::vector<base::Feature> disable_features;
+ if (GetParam().sxg_enabled) {
+ enable_features.push_back(features::kSignedHTTPExchange);
+ } else {
+ disable_features.push_back(features::kSignedHTTPExchange);
+ }
+ if (GetParam().sxg_origin_trial_enabled) {
+ enable_features.push_back(features::kSignedHTTPExchangeOriginTrial);
+ } else {
+ disable_features.push_back(features::kSignedHTTPExchangeOriginTrial);
+ }
+ if (GetParam().service_worker_servicification_enabled) {
+ enable_features.push_back(blink::features::kServiceWorkerServicification);
+ } else {
+ disable_features.push_back(
+ blink::features::kServiceWorkerServicification);
+ }
+ feature_list_.InitWithFeatures(enable_features, disable_features);
+
+ enabled_https_server_.ServeFilesFromSourceDirectory("content/test/data");
+ enabled_https_server_.RegisterRequestHandler(
+ base::BindRepeating(&self::RedirectResponseHandler));
+ enabled_https_server_.RegisterRequestMonitor(
+ base::BindRepeating(&self::MonitorRequest, base::Unretained(this)));
+ ASSERT_TRUE(enabled_https_server_.Start());
+
+ disabled_https_server_.ServeFilesFromSourceDirectory("content/test/data");
+ disabled_https_server_.RegisterRequestHandler(
+ base::BindRepeating(&self::RedirectResponseHandler));
+ disabled_https_server_.RegisterRequestMonitor(
+ base::BindRepeating(&self::MonitorRequest, base::Unretained(this)));
+ ASSERT_TRUE(disabled_https_server_.Start());
+
+ if (GetParam().sxg_accept_header_enabled) {
+ std::map<std::string, std::string> feature_parameters;
+ feature_parameters["OriginsList"] =
+ base::StringPrintf("127.0.0.1:%u", enabled_https_server_.port());
+ feature_list_for_accept_header_.InitAndEnableFeatureWithParameters(
+ features::kSignedHTTPExchangeAcceptHeader, feature_parameters);
+ }
+ ContentBrowserTest::SetUp();
+ }
+
+ void NavigateAndWaitForTitle(const GURL& url, const std::string title) {
+ base::string16 expected_title = base::ASCIIToUTF16(title);
+ TitleWatcher title_watcher(shell()->web_contents(), expected_title);
+ NavigateToURL(shell(), url);
+ EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
+ }
+
+ bool ShouldHaveSXGAcceptHeaderInEnabledOrigin() const {
+ return GetParam().sxg_enabled || (GetParam().sxg_origin_trial_enabled &&
+ GetParam().sxg_accept_header_enabled);
+ }
+
+ bool ShouldHaveSXGAcceptHeaderInDisabledOrigin() const {
+ return GetParam().sxg_enabled;
+ }
+
+ void CheckAcceptHeader(const GURL& url, bool is_navigation) {
+ const bool is_enabled_origin =
+ url.IntPort() == enabled_https_server_.port();
+ const bool should_have_sxg =
+ is_enabled_origin ? ShouldHaveSXGAcceptHeaderInEnabledOrigin()
+ : ShouldHaveSXGAcceptHeaderInDisabledOrigin();
+ const auto accept_header = GetInterceptedAcceptHeader(url);
+ ASSERT_TRUE(accept_header);
+ EXPECT_EQ(
+ *accept_header,
+ should_have_sxg
+ ? (is_navigation
+ ? std::string(network::kFrameAcceptHeader) +
+ std::string(kAcceptHeaderSignedExchangeSuffix)
+ : std::string(kExpectedSXGEnabledAcceptHeaderForPrefetch))
+ : (is_navigation ? std::string(network::kFrameAcceptHeader)
+ : std::string(network::kDefaultAcceptHeader)));
+ }
+
+ void CheckNavigationAcceptHeader(const std::vector<GURL>& urls) {
+ for (const auto& url : urls) {
+ SCOPED_TRACE(url);
+ CheckAcceptHeader(url, true /* is_navigation */);
+ }
+ }
+
+ void CheckPrefetchAcceptHeader(const std::vector<GURL>& urls) {
+ for (const auto& url : urls) {
+ SCOPED_TRACE(url);
+ CheckAcceptHeader(url, false /* is_navigation */);
+ }
+ }
+
+ base::Optional<std::string> GetInterceptedAcceptHeader(
+ const GURL& url) const {
+ const auto it = url_accept_header_map_.find(url);
+ if (it == url_accept_header_map_.end())
+ return base::nullopt;
+ return it->second;
+ }
+
+ void ClearInterceptedAcceptHeaders() { url_accept_header_map_.clear(); }
+
+ net::EmbeddedTestServer enabled_https_server_;
+ net::EmbeddedTestServer disabled_https_server_;
+
+ private:
+ static std::unique_ptr<net::test_server::HttpResponse>
+ RedirectResponseHandler(const net::test_server::HttpRequest& request) {
+ if (!base::StartsWith(request.relative_url, "/r?",
+ base::CompareCase::SENSITIVE)) {
+ return std::unique_ptr<net::test_server::HttpResponse>();
+ }
+ std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
+ new net::test_server::BasicHttpResponse);
+ http_response->set_code(net::HTTP_MOVED_PERMANENTLY);
+ http_response->AddCustomHeader("Location", request.relative_url.substr(3));
+ http_response->AddCustomHeader("Cache-Control", "no-cache");
+ return std::move(http_response);
+ }
+
+ void MonitorRequest(const net::test_server::HttpRequest& request) {
+ const auto it = request.headers.find(std::string(network::kAcceptHeader));
+ if (it == request.headers.end())
+ return;
+ url_accept_header_map_[request.base_url.Resolve(request.relative_url)] =
+ it->second;
+ }
+
+ base::test::ScopedFeatureList feature_list_;
+ base::test::ScopedFeatureList feature_list_for_accept_header_;
+
+ std::map<GURL, std::string> url_accept_header_map_;
+};
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest, EnabledOrigin) {
+ const GURL enabled_test_url = enabled_https_server_.GetURL("/sxg/test.html");
+ EXPECT_EQ(ShouldHaveSXGAcceptHeaderInEnabledOrigin(),
+ signed_exchange_utils::ShouldAdvertiseAcceptHeader(
+ url::Origin::Create(enabled_test_url)));
+ NavigateAndWaitForTitle(enabled_test_url, enabled_test_url.spec());
+ CheckNavigationAcceptHeader({enabled_test_url});
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest, DisabledOrigin) {
+ const GURL disabled_test_url =
+ disabled_https_server_.GetURL("/sxg/test.html");
+ EXPECT_EQ(GetParam().sxg_enabled,
+ signed_exchange_utils::ShouldAdvertiseAcceptHeader(
+ url::Origin::Create(disabled_test_url)));
+
+ NavigateAndWaitForTitle(disabled_test_url, disabled_test_url.spec());
+ CheckNavigationAcceptHeader({disabled_test_url});
}
+IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest,
+ RedirectEnabledToDisabledToEnabled) {
+ const GURL enabled_test_url = enabled_https_server_.GetURL("/sxg/test.html");
+ const GURL redirect_disabled_to_enabled_url =
+ disabled_https_server_.GetURL("/r?" + enabled_test_url.spec());
+ const GURL redirect_enabled_to_disabled_to_enabled_url =
+ enabled_https_server_.GetURL("/r?" +
+ redirect_disabled_to_enabled_url.spec());
+ NavigateAndWaitForTitle(redirect_enabled_to_disabled_to_enabled_url,
+ enabled_test_url.spec());
+
+ CheckNavigationAcceptHeader({redirect_enabled_to_disabled_to_enabled_url,
+ redirect_disabled_to_enabled_url,
+ enabled_test_url});
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest,
+ RedirectDisabledToEnabledToDisabled) {
+ const GURL disabled_test_url =
+ disabled_https_server_.GetURL("/sxg/test.html");
+ const GURL redirect_enabled_to_disabled_url =
+ enabled_https_server_.GetURL("/r?" + disabled_test_url.spec());
+ const GURL redirect_disabled_to_enabled_to_disabled_url =
+ disabled_https_server_.GetURL("/r?" +
+ redirect_enabled_to_disabled_url.spec());
+ NavigateAndWaitForTitle(redirect_disabled_to_enabled_to_disabled_url,
+ disabled_test_url.spec());
+
+ CheckNavigationAcceptHeader({redirect_disabled_to_enabled_to_disabled_url,
+ redirect_enabled_to_disabled_url,
+ disabled_test_url});
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest,
+ PrefetchEnabledPageEnabledTarget) {
+ const GURL enabled_target = enabled_https_server_.GetURL("/sxg/hello.txt");
+ const GURL enabled_page_url = enabled_https_server_.GetURL(
+ std::string("/sxg/prefetch.html#") + enabled_target.spec());
+ NavigateAndWaitForTitle(enabled_page_url, "OK");
+ CheckPrefetchAcceptHeader({enabled_target});
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest,
+ PrefetchEnabledPageDisabledTarget) {
+ const GURL disabled_target = disabled_https_server_.GetURL("/sxg/hello.txt");
+ const GURL enabled_page_url = enabled_https_server_.GetURL(
+ std::string("/sxg/prefetch.html#") + disabled_target.spec());
+ NavigateAndWaitForTitle(enabled_page_url, "OK");
+ CheckPrefetchAcceptHeader({disabled_target});
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest,
+ PrefetchDisabledPageEnabledTarget) {
+ const GURL enabled_target = enabled_https_server_.GetURL("/sxg/hello.txt");
+ const GURL disabled_page_url = disabled_https_server_.GetURL(
+ std::string("/sxg/prefetch.html#") + enabled_target.spec());
+ NavigateAndWaitForTitle(disabled_page_url, "OK");
+ CheckPrefetchAcceptHeader({enabled_target});
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest,
+ PrefetchDisabledPageDisabledTarget) {
+ const GURL disabled_target = disabled_https_server_.GetURL("/sxg/hello.txt");
+ const GURL disabled_page_url = disabled_https_server_.GetURL(
+ std::string("/sxg/prefetch.html#") + disabled_target.spec());
+ NavigateAndWaitForTitle(disabled_page_url, "OK");
+ CheckPrefetchAcceptHeader({disabled_target});
+}
+
+IN_PROC_BROWSER_TEST_P(
+ SignedExchangeAcceptHeaderBrowserTest,
+ PrefetchEnabledPageRedirectFromDisabledToEnabledToDisabledTarget) {
+ const GURL disabled_target = disabled_https_server_.GetURL("/sxg/hello.txt");
+ const GURL redirect_enabled_to_disabled_url =
+ enabled_https_server_.GetURL("/r?" + disabled_target.spec());
+ const GURL redirect_disabled_to_enabled_to_disabled_url =
+ disabled_https_server_.GetURL("/r?" +
+ redirect_enabled_to_disabled_url.spec());
+
+ const GURL enabled_page_url = enabled_https_server_.GetURL(
+ std::string("/sxg/prefetch.html#") +
+ redirect_disabled_to_enabled_to_disabled_url.spec());
+
+ NavigateAndWaitForTitle(enabled_page_url, "OK");
+
+ CheckPrefetchAcceptHeader({redirect_disabled_to_enabled_to_disabled_url,
+ redirect_enabled_to_disabled_url,
+ disabled_target});
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest, ServiceWorker) {
+ NavigateAndWaitForTitle(
+ enabled_https_server_.GetURL("/sxg/service-worker.html"), "Done");
+ NavigateAndWaitForTitle(
+ disabled_https_server_.GetURL("/sxg/service-worker.html"), "Done");
+
+ const std::string frame_accept = std::string(network::kFrameAcceptHeader);
+ const std::string frame_accept_with_sxg =
+ frame_accept + std::string(kAcceptHeaderSignedExchangeSuffix);
+ const std::vector<std::string> scopes = {"/sxg/sw-scope-generated/",
+ "/sxg/sw-scope-navigation-preload/",
+ "/sxg/sw-scope-no-respond-with/"};
+ for (const auto& scope : scopes) {
+ SCOPED_TRACE(scope);
+ const bool is_generated_scope =
+ scope == std::string("/sxg/sw-scope-generated/");
+ const GURL enabled_target_url =
+ enabled_https_server_.GetURL(scope + "test.html");
+ const GURL disabled_target_url =
+ disabled_https_server_.GetURL(scope + "test.html");
+ const GURL redirect_disabled_to_enabled_target_url =
+ disabled_https_server_.GetURL("/r?" + enabled_target_url.spec());
+ const GURL redirect_enabled_to_disabled_to_enabled_target_url =
+ enabled_https_server_.GetURL(
+ "/r?" + redirect_disabled_to_enabled_target_url.spec());
+ const GURL redirect_enabled_to_disabled_target_url =
+ enabled_https_server_.GetURL("/r?" + disabled_target_url.spec());
+ const GURL redirect_disabled_to_enabled_to_disabled_target_url =
+ disabled_https_server_.GetURL(
+ "/r?" + redirect_enabled_to_disabled_target_url.spec());
+
+ const std::string expected_enabled_title =
+ is_generated_scope ? (ShouldHaveSXGAcceptHeaderInEnabledOrigin()
+ ? frame_accept_with_sxg
+ : frame_accept)
+ : "Done";
+ const std::string expected_disabled_title =
+ is_generated_scope ? (ShouldHaveSXGAcceptHeaderInDisabledOrigin()
+ ? frame_accept_with_sxg
+ : frame_accept)
+ : "Done";
+ const base::Optional<std::string> expected_enabled_target_accept_header =
+ is_generated_scope ? base::nullopt
+ : base::Optional<std::string>(
+ ShouldHaveSXGAcceptHeaderInEnabledOrigin()
+ ? frame_accept_with_sxg
+ : frame_accept);
+ const base::Optional<std::string> expected_disabled_target_accept_header =
+ is_generated_scope ? base::nullopt
+ : base::Optional<std::string>(
+ ShouldHaveSXGAcceptHeaderInDisabledOrigin()
+ ? frame_accept_with_sxg
+ : frame_accept);
+
+ NavigateAndWaitForTitle(enabled_target_url, expected_enabled_title);
+ EXPECT_EQ(expected_enabled_target_accept_header,
+ GetInterceptedAcceptHeader(enabled_target_url));
+ ClearInterceptedAcceptHeaders();
+
+ NavigateAndWaitForTitle(disabled_target_url, expected_disabled_title);
+ EXPECT_EQ(expected_disabled_target_accept_header,
+ GetInterceptedAcceptHeader(disabled_target_url));
+ ClearInterceptedAcceptHeaders();
+
+ NavigateAndWaitForTitle(redirect_disabled_to_enabled_target_url,
+ expected_enabled_title);
+ CheckNavigationAcceptHeader({redirect_disabled_to_enabled_target_url});
+ EXPECT_EQ(expected_enabled_target_accept_header,
+ GetInterceptedAcceptHeader(enabled_target_url));
+ ClearInterceptedAcceptHeaders();
+
+ NavigateAndWaitForTitle(redirect_enabled_to_disabled_target_url,
+ expected_disabled_title);
+ CheckNavigationAcceptHeader({redirect_enabled_to_disabled_target_url});
+ EXPECT_EQ(expected_disabled_target_accept_header,
+ GetInterceptedAcceptHeader(disabled_target_url));
+ ClearInterceptedAcceptHeaders();
+
+ NavigateAndWaitForTitle(redirect_enabled_to_disabled_to_enabled_target_url,
+ expected_enabled_title);
+ CheckNavigationAcceptHeader(
+ {redirect_enabled_to_disabled_to_enabled_target_url,
+ redirect_disabled_to_enabled_target_url});
+ EXPECT_EQ(expected_enabled_target_accept_header,
+ GetInterceptedAcceptHeader(enabled_target_url));
+ ClearInterceptedAcceptHeaders();
+
+ NavigateAndWaitForTitle(redirect_disabled_to_enabled_to_disabled_target_url,
+ expected_disabled_title);
+ CheckNavigationAcceptHeader(
+ {redirect_disabled_to_enabled_to_disabled_target_url,
+ redirect_enabled_to_disabled_target_url});
+ EXPECT_EQ(expected_disabled_target_accept_header,
+ GetInterceptedAcceptHeader(disabled_target_url));
+ }
+}
+
+IN_PROC_BROWSER_TEST_P(SignedExchangeAcceptHeaderBrowserTest,
+ ServiceWorkerPrefetch) {
+ NavigateAndWaitForTitle(
+ enabled_https_server_.GetURL("/sxg/service-worker-prefetch.html"),
+ "Done");
+ NavigateAndWaitForTitle(
+ disabled_https_server_.GetURL("/sxg/service-worker-prefetch.html"),
+ "Done");
+ const std::string scope = "/sxg/sw-prefetch-scope/";
+ const GURL enabled_target_url =
+ enabled_https_server_.GetURL(scope + "test.html");
+ const GURL disabled_target_url =
+ disabled_https_server_.GetURL(scope + "test.html");
+
+ const GURL enabled_prefetch_target =
+ enabled_https_server_.GetURL(std::string("/sxg/hello.txt"));
+ const GURL disabled_prefetch_target =
+ disabled_https_server_.GetURL(std::string("/sxg/hello.txt"));
+ const std::string load_prefetch_script = base::StringPrintf(
+ "(function loadPrefetch(urls) {"
+ " for (let url of urls) {"
+ " let link = document.createElement('link');"
+ " link.rel = 'prefetch';"
+ " link.href = url;"
+ " document.body.appendChild(link);"
+ " }"
+ " function check() {"
+ " const entries = performance.getEntriesByType('resource');"
+ " const url_set = new Set(urls);"
+ " for (let entry of entries) {"
+ " url_set.delete(entry.name);"
+ " }"
+ " if (!url_set.size) {"
+ " window.domAutomationController.send(true);"
+ " } else {"
+ " setTimeout(check, 100);"
+ " }"
+ " }"
+ " check();"
+ "})(['%s','%s'])",
+ enabled_prefetch_target.spec().c_str(),
+ disabled_prefetch_target.spec().c_str());
+ bool unused = false;
+
+ NavigateAndWaitForTitle(enabled_target_url, "Done");
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(shell()->web_contents(),
+ load_prefetch_script, &unused));
+ CheckPrefetchAcceptHeader(
+ {enabled_prefetch_target, disabled_prefetch_target});
+ ClearInterceptedAcceptHeaders();
+
+ NavigateAndWaitForTitle(disabled_target_url, "Done");
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(shell()->web_contents(),
+ load_prefetch_script, &unused));
+ CheckPrefetchAcceptHeader(
+ {enabled_prefetch_target, disabled_prefetch_target});
+}
+
+INSTANTIATE_TEST_CASE_P(
+ SignedExchangeAcceptHeaderBrowserTest,
+ SignedExchangeAcceptHeaderBrowserTest,
+ testing::Values(
+ SignedExchangeAcceptHeaderBrowserTestParam(false, false, false, false),
+ SignedExchangeAcceptHeaderBrowserTestParam(false, false, false, true),
+ SignedExchangeAcceptHeaderBrowserTestParam(false, false, true, false),
+ SignedExchangeAcceptHeaderBrowserTestParam(false, false, true, true),
+ SignedExchangeAcceptHeaderBrowserTestParam(false, true, false, false),
+ SignedExchangeAcceptHeaderBrowserTestParam(false, true, false, true),
+ SignedExchangeAcceptHeaderBrowserTestParam(false, true, true, false),
+ SignedExchangeAcceptHeaderBrowserTestParam(false, true, true, true),
+ SignedExchangeAcceptHeaderBrowserTestParam(true, false, false, false),
+ SignedExchangeAcceptHeaderBrowserTestParam(true, false, false, true),
+ SignedExchangeAcceptHeaderBrowserTestParam(true, false, true, false),
+ SignedExchangeAcceptHeaderBrowserTestParam(true, false, true, true),
+ SignedExchangeAcceptHeaderBrowserTestParam(true, true, false, false),
+ SignedExchangeAcceptHeaderBrowserTestParam(true, true, false, true),
+ SignedExchangeAcceptHeaderBrowserTestParam(true, true, true, false),
+ SignedExchangeAcceptHeaderBrowserTestParam(true, true, true, true)));
+
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_signature_header_field.cc b/chromium/content/browser/web_package/signed_exchange_signature_header_field.cc
index f6e3cfdeb81..907e09efa94 100644
--- a/chromium/content/browser/web_package/signed_exchange_signature_header_field.cc
+++ b/chromium/content/browser/web_package/signed_exchange_signature_header_field.cc
@@ -280,28 +280,6 @@ SignedExchangeSignatureHeaderField::ParseSignature(
return signatures;
}
-// static
-bool SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
- base::StringPiece content_type,
- base::Optional<SignedExchangeVersion>* version_param) {
- DCHECK(version_param);
- StructuredHeaderParser parser(content_type);
- ParameterisedIdentifier parameterised_identifier;
- parser.ParseParameterisedIdentifier(&parameterised_identifier);
- if (!parser.ParsedSuccessfully())
- return false;
- const auto it = parameterised_identifier.params.find("v");
- if (it == parameterised_identifier.params.end()) {
- *version_param = base::nullopt;
- } else {
- if (it->second == "b2")
- *version_param = SignedExchangeVersion::kB2;
- else
- return false;
- }
- return true;
-}
-
SignedExchangeSignatureHeaderField::Signature::Signature() = default;
SignedExchangeSignatureHeaderField::Signature::Signature(
const Signature& other) = default;
diff --git a/chromium/content/browser/web_package/signed_exchange_signature_header_field.h b/chromium/content/browser/web_package/signed_exchange_signature_header_field.h
index 166850ce21d..c2603c4d444 100644
--- a/chromium/content/browser/web_package/signed_exchange_signature_header_field.h
+++ b/chromium/content/browser/web_package/signed_exchange_signature_header_field.h
@@ -13,7 +13,6 @@
#include "base/macros.h"
#include "base/optional.h"
#include "base/strings/string_piece.h"
-#include "content/browser/web_package/signed_exchange_consts.h"
#include "content/common/content_export.h"
#include "net/base/hash_value.h"
#include "url/gurl.h"
@@ -22,7 +21,7 @@ namespace content {
class SignedExchangeDevToolsProxy;
-// SignedExchangeSignatureHeaderField provides parser for signed exchange's
+// SignedExchangeSignatureHeaderField provides a parser for signed exchange's
// `Signature` header field.
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html
class CONTENT_EXPORT SignedExchangeSignatureHeaderField {
@@ -49,14 +48,6 @@ class CONTENT_EXPORT SignedExchangeSignatureHeaderField {
static base::Optional<std::vector<Signature>> ParseSignature(
base::StringPiece signature_str,
SignedExchangeDevToolsProxy* devtools_proxy);
-
- // TODO(kouhei): Move this to another class.
- // Parses |content_type| to get the value of "v=" parameter of the signed
- // exchange, and converts to SignedExchangeVersion. Returns false if failed to
- // parse.
- static bool GetVersionParamFromContentType(
- base::StringPiece content_type,
- base::Optional<SignedExchangeVersion>* version_param);
};
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc b/chromium/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc
index e34fd133926..b6cacc14c51 100644
--- a/chromium/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc
+++ b/chromium/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc
@@ -274,60 +274,4 @@ TEST_F(SignedExchangeSignatureHeaderFieldTest, AsteriskInTheMiddleOfBinary) {
EXPECT_FALSE(signatures.has_value());
}
-TEST_F(SignedExchangeSignatureHeaderFieldTest, VersionParam_None) {
- const char content_type[] = "application/signed-exchange";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_TRUE(
- SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
- content_type, &version));
- EXPECT_FALSE(version);
-}
-
-TEST_F(SignedExchangeSignatureHeaderFieldTest, VersionParam_NoneWithSemicolon) {
- const char content_type[] = "application/signed-exchange;";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_FALSE(
- SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
- content_type, &version));
-}
-
-TEST_F(SignedExchangeSignatureHeaderFieldTest, VersionParam_EmptyString) {
- const char content_type[] = "application/signed-exchange;v=";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_FALSE(
- SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
- content_type, &version));
-}
-
-TEST_F(SignedExchangeSignatureHeaderFieldTest, VersionParam_Simple) {
- const char content_type[] = "application/signed-exchange;v=b2";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_TRUE(
- SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
- content_type, &version));
- ASSERT_TRUE(version);
- EXPECT_EQ(*version, SignedExchangeVersion::kB2);
-}
-
-TEST_F(SignedExchangeSignatureHeaderFieldTest, VersionParam_SimpleWithSpace) {
- const char content_type[] = "application/signed-exchange; v=b2";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_TRUE(
- SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
- content_type, &version));
- ASSERT_TRUE(version);
- EXPECT_EQ(*version, SignedExchangeVersion::kB2);
-}
-
-TEST_F(SignedExchangeSignatureHeaderFieldTest,
- VersionParam_SimpleWithDoublequotes) {
- const char content_type[] = "application/signed-exchange;v=\"b2\"";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_TRUE(
- SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
- content_type, &version));
- ASSERT_TRUE(version);
- EXPECT_EQ(*version, SignedExchangeVersion::kB2);
-}
-
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc b/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc
index f19306b6f9a..3e5960ef526 100644
--- a/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc
+++ b/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc
@@ -4,23 +4,31 @@
#include "content/browser/web_package/signed_exchange_signature_verifier.h"
+#include <string>
+#include <vector>
+
#include "base/big_endian.h"
+#include "base/command_line.h"
#include "base/containers/span.h"
#include "base/format_macros.h"
-#include "base/strings/string_number_conversions.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
-#include "components/cbor/cbor_writer.h"
#include "content/browser/web_package/signed_exchange_consts.h"
#include "content/browser/web_package/signed_exchange_envelope.h"
#include "content/browser/web_package/signed_exchange_signature_header_field.h"
#include "content/browser/web_package/signed_exchange_utils.h"
+#include "content/public/browser/content_browser_client.h"
+#include "crypto/sha2.h"
#include "crypto/signature_verifier.h"
#include "net/cert/asn1_util.h"
#include "net/cert/x509_util.h"
+#include "services/network/public/cpp/network_switches.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/ec.h"
#include "third_party/boringssl/src/include/openssl/ec_key.h"
@@ -46,54 +54,8 @@ constexpr uint8_t kMessageHeader[] =
// 5.3. "A single 0 byte which serves as a separator." [spec text]
"HTTP Exchange 1 b2";
-base::Optional<cbor::CBORValue> GenerateCanonicalRequestCBOR(
- const SignedExchangeEnvelope& envelope) {
- cbor::CBORValue::MapValue map;
- map.insert_or_assign(
- cbor::CBORValue(kMethodKey, cbor::CBORValue::Type::BYTE_STRING),
- cbor::CBORValue(envelope.request_method(),
- cbor::CBORValue::Type::BYTE_STRING));
- map.insert_or_assign(
- cbor::CBORValue(kUrlKey, cbor::CBORValue::Type::BYTE_STRING),
- cbor::CBORValue(envelope.request_url().spec(),
- cbor::CBORValue::Type::BYTE_STRING));
-
- return cbor::CBORValue(map);
-}
-
-base::Optional<cbor::CBORValue> GenerateCanonicalResponseCBOR(
- const SignedExchangeEnvelope& envelope) {
- const auto& headers = envelope.response_headers();
- cbor::CBORValue::MapValue map;
- std::string response_code_str =
- base::NumberToString(envelope.response_code());
- map.insert_or_assign(
- cbor::CBORValue(kStatusKey, cbor::CBORValue::Type::BYTE_STRING),
- cbor::CBORValue(response_code_str, cbor::CBORValue::Type::BYTE_STRING));
- for (const auto& pair : headers) {
- map.insert_or_assign(
- cbor::CBORValue(pair.first, cbor::CBORValue::Type::BYTE_STRING),
- cbor::CBORValue(pair.second, cbor::CBORValue::Type::BYTE_STRING));
- }
- return cbor::CBORValue(map);
-}
-
-// Generate CBORValue from |envelope| as specified in:
-// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#cbor-representation
-base::Optional<cbor::CBORValue> GenerateCanonicalExchangeHeadersCBOR(
- const SignedExchangeEnvelope& envelope) {
- auto req_val = GenerateCanonicalRequestCBOR(envelope);
- if (!req_val)
- return base::nullopt;
- auto res_val = GenerateCanonicalResponseCBOR(envelope);
- if (!res_val)
- return base::nullopt;
-
- cbor::CBORValue::ArrayValue array;
- array.push_back(std::move(*req_val));
- array.push_back(std::move(*res_val));
- return cbor::CBORValue(array);
-}
+constexpr int kFourWeeksInSeconds = base::TimeDelta::FromDays(28).InSeconds();
+constexpr int kOneWeekInSeconds = base::TimeDelta::FromDays(7).InSeconds();
base::Optional<crypto::SignatureVerifier::SignatureAlgorithm>
GetSignatureAlgorithm(scoped_refptr<net::X509Certificate> cert,
@@ -244,17 +206,43 @@ bool VerifyTimestamps(const SignedExchangeEnvelope& envelope,
// 3. "If expires is more than 7 days (604800 seconds) after date, return
// "invalid"." [spec text]
- if ((expires_time - creation_time).InSeconds() > 604800)
+ if ((expires_time - creation_time).InSeconds() > kOneWeekInSeconds)
return false;
// 4. "If the current time is before date or after expires, return
// "invalid"."
- if (verification_time < creation_time || expires_time < verification_time)
+ if (verification_time < creation_time) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "SignedExchange.SignatureVerificationError.NotYetValid",
+ (creation_time - verification_time).InSeconds(), 1, kFourWeeksInSeconds,
+ 50);
return false;
+ }
+ if (expires_time < verification_time) {
+ UMA_HISTOGRAM_CUSTOM_COUNTS(
+ "SignedExchange.SignatureVerificationError.Expired",
+ (verification_time - expires_time).InSeconds(), 1, kFourWeeksInSeconds,
+ 50);
+ return false;
+ }
+ UMA_HISTOGRAM_CUSTOM_COUNTS("SignedExchange.TimeUntilExpiration",
+ (expires_time - verification_time).InSeconds(), 1,
+ kOneWeekInSeconds, 50);
return true;
}
+// Returns true if SPKI hash of |certificate| is included in the
+// --ignore-certificate-errors-spki-list command line flag, and
+// ContentBrowserClient::CanIgnoreCertificateErrorIfNeeded() returns true.
+bool ShouldIgnoreTimestampError(
+ scoped_refptr<net::X509Certificate> certificate) {
+ static base::NoDestructor<
+ SignedExchangeSignatureVerifier::IgnoreErrorsSPKIList>
+ instance(*base::CommandLine::ForCurrentProcess());
+ return instance->ShouldIgnoreError(certificate);
+}
+
} // namespace
SignedExchangeSignatureVerifier::Result SignedExchangeSignatureVerifier::Verify(
@@ -262,10 +250,12 @@ SignedExchangeSignatureVerifier::Result SignedExchangeSignatureVerifier::Verify(
scoped_refptr<net::X509Certificate> certificate,
const base::Time& verification_time,
SignedExchangeDevToolsProxy* devtools_proxy) {
+ SCOPED_UMA_HISTOGRAM_TIMER("SignedExchange.Time.SignatureVerify");
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
"SignedExchangeSignatureVerifier::Verify");
- if (!VerifyTimestamps(envelope, verification_time)) {
+ if (!VerifyTimestamps(envelope, verification_time) &&
+ !ShouldIgnoreTimestampError(certificate)) {
signed_exchange_utils::ReportErrorAndTraceEvent(
devtools_proxy,
base::StringPrintf(
@@ -330,15 +320,43 @@ SignedExchangeSignatureVerifier::Result SignedExchangeSignatureVerifier::Verify(
return Result::kSuccess;
}
-base::Optional<std::vector<uint8_t>>
-SignedExchangeSignatureVerifier::EncodeCanonicalExchangeHeaders(
- const SignedExchangeEnvelope& envelope) {
- base::Optional<cbor::CBORValue> cbor_val =
- GenerateCanonicalExchangeHeadersCBOR(envelope);
- if (!cbor_val)
- return base::nullopt;
+SignedExchangeSignatureVerifier::IgnoreErrorsSPKIList::IgnoreErrorsSPKIList(
+ const std::string& spki_list) {
+ Parse(spki_list);
+}
+
+SignedExchangeSignatureVerifier::IgnoreErrorsSPKIList::IgnoreErrorsSPKIList(
+ const base::CommandLine& command_line) {
+ if (!GetContentClient()->browser()->CanIgnoreCertificateErrorIfNeeded())
+ return;
+ Parse(command_line.GetSwitchValueASCII(
+ network::switches::kIgnoreCertificateErrorsSPKIList));
+}
+
+void SignedExchangeSignatureVerifier::IgnoreErrorsSPKIList::Parse(
+ const std::string& spki_list) {
+ hash_set_ =
+ network::IgnoreErrorsCertVerifier::MakeWhitelist(base::SplitString(
+ spki_list, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL));
+}
- return cbor::CBORWriter::Write(*cbor_val);
+SignedExchangeSignatureVerifier::IgnoreErrorsSPKIList::~IgnoreErrorsSPKIList() =
+ default;
+
+bool SignedExchangeSignatureVerifier::IgnoreErrorsSPKIList::ShouldIgnoreError(
+ scoped_refptr<net::X509Certificate> certificate) {
+ if (hash_set_.empty())
+ return false;
+
+ base::StringPiece spki;
+ if (!net::asn1::ExtractSPKIFromDERCert(
+ net::x509_util::CryptoBufferAsStringPiece(certificate->cert_buffer()),
+ &spki)) {
+ return false;
+ }
+ net::SHA256HashValue hash;
+ crypto::SHA256HashString(spki, &hash, sizeof(net::SHA256HashValue));
+ return hash_set_.find(hash) != hash_set_.end();
}
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_signature_verifier.h b/chromium/content/browser/web_package/signed_exchange_signature_verifier.h
index cca2ea786f5..b34a54ae224 100644
--- a/chromium/content/browser/web_package/signed_exchange_signature_verifier.h
+++ b/chromium/content/browser/web_package/signed_exchange_signature_verifier.h
@@ -5,17 +5,14 @@
#ifndef CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_SIGNATURE_VERIFIER_H_
#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_SIGNATURE_VERIFIER_H_
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "content/common/content_export.h"
#include "net/cert/x509_certificate.h"
+#include "services/network/ignore_errors_cert_verifier.h"
namespace base {
+class CommandLine;
class Time;
} // namespace base
@@ -36,6 +33,7 @@ class SignedExchangeDevToolsProxy;
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#signature-validity
class CONTENT_EXPORT SignedExchangeSignatureVerifier final {
public:
+ // This enum is used for recording histograms. Treat as append-only.
enum class Result {
kSuccess,
kErrNoCertificate,
@@ -45,16 +43,35 @@ class CONTENT_EXPORT SignedExchangeSignatureVerifier final {
kErrSignatureVerificationFailed,
kErrInvalidSignatureIntegrity,
kErrInvalidTimestamp,
- kErrUnsupportedCertType
+ kErrUnsupportedCertType,
+ kMaxValue = kErrUnsupportedCertType
+ };
+
+ // An utility class which holds a set of certificates which errors should be
+ // ignored. It parses a comma-delimited list of base64-encoded SHA-256 SPKI
+ // fingerprints, and can query if a certificate is included in the set.
+ // CONTENT_EXPORT since it is used from the unit test.
+ class CONTENT_EXPORT IgnoreErrorsSPKIList {
+ public:
+ explicit IgnoreErrorsSPKIList(const base::CommandLine& command_line);
+ ~IgnoreErrorsSPKIList();
+ bool ShouldIgnoreError(scoped_refptr<net::X509Certificate> certificate);
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(SignedExchangeSignatureVerifierTest,
+ IgnoreErrorsSPKIList);
+
+ explicit IgnoreErrorsSPKIList(const std::string& spki_list);
+ void Parse(const std::string& spki_list);
+
+ network::IgnoreErrorsCertVerifier::SPKIHashSet hash_set_;
+ DISALLOW_COPY_AND_ASSIGN(IgnoreErrorsSPKIList);
};
static Result Verify(const SignedExchangeEnvelope& envelope,
scoped_refptr<net::X509Certificate> certificate,
const base::Time& verification_time,
SignedExchangeDevToolsProxy* devtools_proxy);
-
- static base::Optional<std::vector<uint8_t>> EncodeCanonicalExchangeHeaders(
- const SignedExchangeEnvelope& envelope);
};
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc b/chromium/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
index 25a6ab70296..41cfa75719f 100644
--- a/chromium/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
+++ b/chromium/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
@@ -4,62 +4,15 @@
#include "content/browser/web_package/signed_exchange_signature_verifier.h"
-#include "base/callback.h"
+#include "base/test/metrics/histogram_tester.h"
#include "content/browser/web_package/signed_exchange_envelope.h"
#include "content/browser/web_package/signed_exchange_signature_header_field.h"
#include "net/cert/x509_certificate.h"
-#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
-TEST(SignedExchangeSignatureVerifier, EncodeCanonicalExchangeHeaders) {
- SignedExchangeEnvelope envelope;
- envelope.set_request_method("GET");
- envelope.set_request_url(GURL("https://example.com/index.html"));
- envelope.set_response_code(net::HTTP_OK);
- envelope.AddResponseHeader("content-type", "text/html; charset=utf-8");
- envelope.AddResponseHeader("content-encoding", "mi-sha256-03");
-
- base::Optional<std::vector<uint8_t>> encoded =
- SignedExchangeSignatureVerifier::EncodeCanonicalExchangeHeaders(envelope);
- ASSERT_TRUE(encoded.has_value());
-
- static const uint8_t kExpected[] = {
- // clang-format off
- 0x82, // array(2)
- 0xa2, // map(2)
- 0x44, 0x3a, 0x75, 0x72, 0x6c, // bytes ":url"
- 0x58, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x65,
- 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
- 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c,
- // bytes "https://example.com/index.html"
-
- 0x47, 0x3a, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // bytes ":method"
- 0x43, 0x47, 0x45, 0x54, // bytes "GET"
-
- 0xa3, // map(3)
- 0x47, 0x3a, 0x73,0x74, 0x61, 0x74, 0x75, 0x73, // bytes ":status"
- 0x43, 0x32, 0x30, 0x30, // bytes "200"
-
- 0x4c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79,
- 0x70, 0x65, // bytes "content-type"
- 0x58, 0x18, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c,
- 0x3b, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75,
- 0x74, 0x66, 0x2d, 0x38, // bytes "text/html; charset=utf-8"
-
- 0x50, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e,
- 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, // bytes "content-encoding"
- 0x4c, 0x6d, 0x69, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2d,
- 0x30, 0x33
- // bytes "mi-sha256-03"
- // clang-format on
- };
- EXPECT_THAT(*encoded,
- testing::ElementsAreArray(kExpected, arraysize(kExpected)));
-}
-
const uint64_t kSignatureHeaderDate = 1517892341;
const uint64_t kSignatureHeaderExpires = 1517895941;
@@ -165,6 +118,13 @@ DGC2vA1lb2Uy9bgLCYYkZoESjb/JYRQjCmqlwYKOozU7ZbIe3zJPjRWYP1Tuany5
Xhe5DP7VATeQq3yGV3ps+rCTHDP6qSHDEWP7DqHQdSsxtI0E
-----END CERTIFICATE-----)";
+constexpr char kPEMECDSAP256SPKIHash[] =
+ "iwtEGagHhL9HbHI38aoFstFPEyB+lzZO5H2ZZAJlYOo=";
+constexpr char kPEMECDSAP384SPKIHash[] =
+ "aGcf7fF/2+mXuHjYen7FZ8HZPR0B6sK6zIsyrCoB6Y8=";
+
+} // namespace
+
class SignedExchangeSignatureVerifierTest : public ::testing::Test {
protected:
SignedExchangeSignatureVerifierTest() {}
@@ -177,34 +137,69 @@ class SignedExchangeSignatureVerifierTest : public ::testing::Test {
void TestVerifierGivenValidInput(
const SignedExchangeEnvelope& envelope,
scoped_refptr<net::X509Certificate> certificate) {
- EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kSuccess,
- SignedExchangeSignatureVerifier::Verify(
- envelope, certificate, VerificationTime(),
- nullptr /* devtools_proxy */));
-
- EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kErrInvalidTimestamp,
- SignedExchangeSignatureVerifier::Verify(
- envelope, certificate,
- base::Time::UnixEpoch() +
- base::TimeDelta::FromSeconds(kSignatureHeaderDate - 1),
- nullptr /* devtools_proxy */
- ));
-
- EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kSuccess,
- SignedExchangeSignatureVerifier::Verify(
- envelope, certificate,
- base::Time::UnixEpoch() +
- base::TimeDelta::FromSeconds(kSignatureHeaderExpires),
- nullptr /* devtools_proxy */
- ));
-
- EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kErrInvalidTimestamp,
- SignedExchangeSignatureVerifier::Verify(
- envelope, certificate,
- base::Time::UnixEpoch() +
- base::TimeDelta::FromSeconds(kSignatureHeaderExpires + 1),
- nullptr /* devtools_proxy */
- ));
+ {
+ base::HistogramTester histogram_tester;
+ EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kSuccess,
+ SignedExchangeSignatureVerifier::Verify(
+ envelope, certificate, VerificationTime(),
+ nullptr /* devtools_proxy */));
+ histogram_tester.ExpectUniqueSample(
+ "SignedExchange.TimeUntilExpiration",
+ kSignatureHeaderExpires - kSignatureHeaderDate, 1);
+ histogram_tester.ExpectTotalCount(
+ "SignedExchange.SignatureVerificationError.NotYetValid", 0);
+ histogram_tester.ExpectTotalCount(
+ "SignedExchange.SignatureVerificationError.Expired", 0);
+ }
+ {
+ base::HistogramTester histogram_tester;
+ EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kErrInvalidTimestamp,
+ SignedExchangeSignatureVerifier::Verify(
+ envelope, certificate,
+ base::Time::UnixEpoch() +
+ base::TimeDelta::FromSeconds(kSignatureHeaderDate - 1),
+ nullptr /* devtools_proxy */
+ ));
+ histogram_tester.ExpectTotalCount("SignedExchange.TimeUntilExpiration",
+ 0);
+ histogram_tester.ExpectUniqueSample(
+ "SignedExchange.SignatureVerificationError.NotYetValid", 1, 1);
+ histogram_tester.ExpectTotalCount(
+ "SignedExchange.SignatureVerificationError.Expired", 0);
+ }
+
+ {
+ base::HistogramTester histogram_tester;
+ EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kSuccess,
+ SignedExchangeSignatureVerifier::Verify(
+ envelope, certificate,
+ base::Time::UnixEpoch() +
+ base::TimeDelta::FromSeconds(kSignatureHeaderExpires),
+ nullptr /* devtools_proxy */
+ ));
+ histogram_tester.ExpectUniqueSample("SignedExchange.TimeUntilExpiration",
+ 0, 1);
+ histogram_tester.ExpectTotalCount(
+ "SignedExchange.SignatureVerificationError.NotYetValid", 0);
+ histogram_tester.ExpectTotalCount(
+ "SignedExchange.SignatureVerificationError.Expired", 0);
+ }
+ {
+ base::HistogramTester histogram_tester;
+ EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kErrInvalidTimestamp,
+ SignedExchangeSignatureVerifier::Verify(
+ envelope, certificate,
+ base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(
+ kSignatureHeaderExpires + 1),
+ nullptr /* devtools_proxy */
+ ));
+ histogram_tester.ExpectTotalCount("SignedExchange.TimeUntilExpiration",
+ 0);
+ histogram_tester.ExpectTotalCount(
+ "SignedExchange.SignatureVerificationError.NotYetValid", 0);
+ histogram_tester.ExpectUniqueSample(
+ "SignedExchange.SignatureVerificationError.Expired", 1, 1);
+ }
SignedExchangeEnvelope invalid_expires_envelope(envelope);
auto invalid_expires_signature =
@@ -338,5 +333,32 @@ TEST_F(SignedExchangeSignatureVerifierTest, VerifyECDSAP384) {
nullptr /* devtools_proxy */));
}
-} // namespace
+TEST_F(SignedExchangeSignatureVerifierTest, IgnoreErrorsSPKIList) {
+ SignedExchangeSignatureVerifier::IgnoreErrorsSPKIList ignore_nothing("");
+ SignedExchangeSignatureVerifier::IgnoreErrorsSPKIList ignore_ecdsap256(
+ kPEMECDSAP256SPKIHash);
+ SignedExchangeSignatureVerifier::IgnoreErrorsSPKIList ignore_ecdsap384(
+ kPEMECDSAP384SPKIHash);
+ SignedExchangeSignatureVerifier::IgnoreErrorsSPKIList ignore_both(
+ std::string(kPEMECDSAP256SPKIHash) + "," + kPEMECDSAP384SPKIHash);
+
+ scoped_refptr<net::X509Certificate> cert_ecdsap256 =
+ net::X509Certificate::CreateCertificateListFromBytes(
+ kCertPEMECDSAP256, base::size(kCertPEMECDSAP256),
+ net::X509Certificate::FORMAT_AUTO)[0];
+ scoped_refptr<net::X509Certificate> cert_ecdsap384 =
+ net::X509Certificate::CreateCertificateListFromBytes(
+ kCertPEMECDSAP384, base::size(kCertPEMECDSAP384),
+ net::X509Certificate::FORMAT_AUTO)[0];
+
+ EXPECT_FALSE(ignore_nothing.ShouldIgnoreError(cert_ecdsap256));
+ EXPECT_FALSE(ignore_nothing.ShouldIgnoreError(cert_ecdsap384));
+ EXPECT_TRUE(ignore_ecdsap256.ShouldIgnoreError(cert_ecdsap256));
+ EXPECT_FALSE(ignore_ecdsap256.ShouldIgnoreError(cert_ecdsap384));
+ EXPECT_FALSE(ignore_ecdsap384.ShouldIgnoreError(cert_ecdsap256));
+ EXPECT_TRUE(ignore_ecdsap384.ShouldIgnoreError(cert_ecdsap384));
+ EXPECT_TRUE(ignore_both.ShouldIgnoreError(cert_ecdsap256));
+ EXPECT_TRUE(ignore_both.ShouldIgnoreError(cert_ecdsap384));
+}
+
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_utils.cc b/chromium/content/browser/web_package/signed_exchange_utils.cc
index bc1a1af246a..d6f8c7232e5 100644
--- a/chromium/content/browser/web_package/signed_exchange_utils.cc
+++ b/chromium/content/browser/web_package/signed_exchange_utils.cc
@@ -5,12 +5,18 @@
#include "content/browser/web_package/signed_exchange_utils.h"
#include "base/feature_list.h"
+#include "base/metrics/field_trial_params.h"
+#include "base/no_destructor.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
+#include "content/browser/web_package/origins_list.h"
#include "content/browser/web_package/signed_exchange_devtools_proxy.h"
#include "content/browser/web_package/signed_exchange_error.h"
#include "content/browser/web_package/signed_exchange_request_handler.h"
#include "content/public/common/content_features.h"
+#include "net/http/http_util.h"
#include "services/network/public/cpp/resource_response.h"
#include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
@@ -28,6 +34,51 @@ void ReportErrorAndTraceEvent(
devtools_proxy->ReportError(error_message, std::move(error_field));
}
+namespace {
+
+OriginsList CreateAdvertiseAcceptHeaderOriginsList() {
+ std::string param = base::GetFieldTrialParamValueByFeature(
+ features::kSignedHTTPExchangeAcceptHeader,
+ features::kSignedHTTPExchangeAcceptHeaderFieldTrialParamName);
+ if (param.empty())
+ DLOG(ERROR) << "The Accept-SXG origins list param is empty.";
+
+ return OriginsList(param);
+}
+
+} // namespace
+
+bool NeedToCheckRedirectedURLForAcceptHeader() {
+ // When SignedHTTPExchange is enabled, the SignedExchange accept header must
+ // be sent to all origins. So we don't need to check the redirected URL.
+ return !base::FeatureList::IsEnabled(features::kSignedHTTPExchange) &&
+ base::FeatureList::IsEnabled(
+ features::kSignedHTTPExchangeOriginTrial) &&
+ base::FeatureList::IsEnabled(
+ features::kSignedHTTPExchangeAcceptHeader);
+}
+
+bool ShouldAdvertiseAcceptHeader(const url::Origin& origin) {
+ // When SignedHTTPExchange is enabled, we must send the SignedExchange accept
+ // header to all origins.
+ if (base::FeatureList::IsEnabled(features::kSignedHTTPExchange))
+ return true;
+ // When SignedHTTPExchangeOriginTrial is not enabled or
+ // SignedHTTPExchangeAcceptHeader is not enabled, we must not send the
+ // SignedExchange accept header.
+ if (!base::FeatureList::IsEnabled(features::kSignedHTTPExchangeOriginTrial) ||
+ !base::FeatureList::IsEnabled(
+ features::kSignedHTTPExchangeAcceptHeader)) {
+ return false;
+ }
+
+ // |origins_list| is initialized in a thread-safe manner.
+ // Querying OriginsList::Match() should be safe since it's read-only access.
+ static base::NoDestructor<OriginsList> origins_list(
+ CreateAdvertiseAcceptHeaderOriginsList());
+ return origins_list->Match(origin);
+}
+
bool IsSignedExchangeHandlingEnabled() {
return base::FeatureList::IsEnabled(features::kSignedHTTPExchange) ||
base::FeatureList::IsEnabled(features::kSignedHTTPExchangeOriginTrial);
@@ -49,9 +100,46 @@ bool ShouldHandleAsSignedHTTPExchange(
return false;
std::unique_ptr<blink::TrialTokenValidator> validator =
std::make_unique<blink::TrialTokenValidator>();
- return validator->RequestEnablesFeature(request_url, head.headers.get(),
- features::kSignedHTTPExchange.name,
- base::Time::Now());
+ return validator->RequestEnablesFeature(
+ request_url, head.headers.get(),
+ features::kSignedHTTPExchangeOriginTrial.name, base::Time::Now());
+}
+
+base::Optional<SignedExchangeVersion> GetSignedExchangeVersion(
+ const std::string& content_type) {
+ // https://wicg.github.io/webpackage/loading.html#signed-exchange-version
+ // Step 1. Let mimeType be the supplied MIME type of response. [spec text]
+ // |content_type| is the supplied MIME type.
+ // Step 2. If mimeType is undefined, return undefined. [spec text]
+ // Step 3. If mimeType's essence is not "application/signed-exchange", return
+ // undefined. [spec text]
+ const std::string::size_type semicolon = content_type.find(';');
+ const std::string essence = base::ToLowerASCII(base::TrimWhitespaceASCII(
+ content_type.substr(0, semicolon), base::TRIM_ALL));
+ if (essence != "application/signed-exchange")
+ return base::nullopt;
+
+ // Step 4.Let params be mimeType's parameters. [spec text]
+ std::map<std::string, std::string> params;
+ if (semicolon != base::StringPiece::npos) {
+ net::HttpUtil::NameValuePairsIterator parser(
+ content_type.begin() + semicolon + 1, content_type.end(), ';');
+ while (parser.GetNext()) {
+ const base::StringPiece name(parser.name_begin(), parser.name_end());
+ params[base::ToLowerASCII(name)] = parser.value();
+ }
+ if (!parser.valid())
+ return base::nullopt;
+ }
+ // Step 5. If params["v"] exists, return it. Otherwise, return undefined.
+ // [spec text]
+ auto iter = params.find("v");
+ if (iter != params.end()) {
+ if (iter->second == "b2")
+ return base::make_optional(SignedExchangeVersion::kB2);
+ return base::make_optional(SignedExchangeVersion::kUnknown);
+ }
+ return base::nullopt;
}
} // namespace signed_exchange_utils
diff --git a/chromium/content/browser/web_package/signed_exchange_utils.h b/chromium/content/browser/web_package/signed_exchange_utils.h
index 105cd892da7..bbcad0a2d08 100644
--- a/chromium/content/browser/web_package/signed_exchange_utils.h
+++ b/chromium/content/browser/web_package/signed_exchange_utils.h
@@ -8,10 +8,17 @@
#include <string>
#include "base/optional.h"
+#include "content/browser/web_package/origins_list.h"
+#include "content/browser/web_package/signed_exchange_consts.h"
#include "content/browser/web_package/signed_exchange_error.h"
+#include "content/common/content_export.h"
class GURL;
+namespace url {
+class Origin;
+} // namespace url
+
namespace network {
struct ResourceResponseHead;
} // namespace network
@@ -31,6 +38,15 @@ void ReportErrorAndTraceEvent(
base::Optional<SignedExchangeError::FieldIndexPair> error_field =
base::nullopt);
+// Returns true when SignedHTTPExchange feature is NOT enabled and
+// SignedHTTPExchangeOriginTrial and SignedHTTPExchangeAcceptHeader features are
+// enabled.
+bool NeedToCheckRedirectedURLForAcceptHeader();
+
+// Returns true if Accept headers should be sent with
+// "application/signed-exchange".
+CONTENT_EXPORT bool ShouldAdvertiseAcceptHeader(const url::Origin& origin);
+
// Returns true when SignedHTTPExchange feature or SignedHTTPExchangeOriginTrial
// feature is enabled.
bool IsSignedExchangeHandlingEnabled();
@@ -43,7 +59,15 @@ bool ShouldHandleAsSignedHTTPExchange(
const GURL& request_url,
const network::ResourceResponseHead& head);
-} // namespace signed_exchange_utils
+// Extracts the signed exchange version [1] from |content_type|, and converts it
+// to SignedExchanveVersion. Returns nullopt if the mime type is not a variant
+// of application/signed-exchange. Returns SignedExchangeVersion::kUnknown if an
+// unsupported signed exchange version is found.
+// [1] https://wicg.github.io/webpackage/loading.html#signed-exchange-version
+CONTENT_EXPORT base::Optional<SignedExchangeVersion> GetSignedExchangeVersion(
+ const std::string& content_type);
+
+} // namespace signed_exchange_utils
} // namespace content
#endif // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_UTILS_H_
diff --git a/chromium/content/browser/web_package/signed_exchange_utils_unittest.cc b/chromium/content/browser/web_package/signed_exchange_utils_unittest.cc
new file mode 100644
index 00000000000..95822755e9d
--- /dev/null
+++ b/chromium/content/browser/web_package/signed_exchange_utils_unittest.cc
@@ -0,0 +1,97 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_package/signed_exchange_utils.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace signed_exchange_utils {
+
+TEST(SignedExchangeUtilsTest, VersionParam_WrongEssence) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-foo");
+ EXPECT_FALSE(version.has_value());
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_None) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange");
+ EXPECT_FALSE(version.has_value());
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_NoneWithSemicolon) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange;");
+ EXPECT_FALSE(version.has_value());
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_Empty) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange;v=");
+ EXPECT_FALSE(version.has_value());
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_EmptyString) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange;v=\"\"");
+ EXPECT_EQ(version, SignedExchangeVersion::kUnknown);
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_UnknownVersion) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange;v=foobar");
+ EXPECT_EQ(version, SignedExchangeVersion::kUnknown);
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_Simple) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange;v=b2");
+ EXPECT_EQ(version, SignedExchangeVersion::kB2);
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_WithSpace) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange ; v=b2");
+ EXPECT_EQ(version, SignedExchangeVersion::kB2);
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_ExtraParam) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange;v=b2;foo=bar");
+ EXPECT_EQ(version, SignedExchangeVersion::kB2);
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_Quoted) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange;v=\"b2\"");
+ EXPECT_EQ(version, SignedExchangeVersion::kB2);
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_QuotesOpen) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange;v=\"b2");
+ EXPECT_EQ(version, SignedExchangeVersion::kB2);
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_QuotesOpenNonV) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange;v=\"b2;r=\"b2");
+ EXPECT_EQ(version, SignedExchangeVersion::kUnknown);
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_QuotesOpenNonV2) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("application/signed-exchange;v=\"b2\";r=\"b2");
+ EXPECT_EQ(version, SignedExchangeVersion::kB2);
+}
+
+TEST(SignedExchangeUtilsTest, VersionParam_UseCaseInsensitiveMatch) {
+ base::Optional<SignedExchangeVersion> version =
+ GetSignedExchangeVersion("Application/Signed-Exchange;V=b2");
+ EXPECT_EQ(version, SignedExchangeVersion::kB2);
+}
+
+} // namespace signed_exchange_utils
+} // namespace content
diff --git a/chromium/content/browser/webauth/authenticator_impl.cc b/chromium/content/browser/webauth/authenticator_impl.cc
index b2ffb181123..0bbb8c099e2 100644
--- a/chromium/content/browser/webauth/authenticator_impl.cc
+++ b/chromium/content/browser/webauth/authenticator_impl.cc
@@ -12,7 +12,9 @@
#include "base/base64url.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
+#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
+#include "base/strings/string_piece.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "content/browser/bad_message.h"
@@ -32,6 +34,7 @@
#include "crypto/sha2.h"
#include "device/base/features.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
+#include "device/fido/attestation_statement.h"
#include "device/fido/authenticator_selection_criteria.h"
#include "device/fido/ctap_get_assertion_request.h"
#include "device/fido/ctap_make_credential_request.h"
@@ -43,6 +46,10 @@
#include "device/fido/public_key_credential_descriptor.h"
#include "device/fido/public_key_credential_params.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "net/cert/asn1_util.h"
+#include "net/der/input.h"
+#include "net/der/parse_values.h"
+#include "net/der/parser.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "services/service_manager/public/cpp/connector.h"
@@ -62,12 +69,35 @@ const char kGetType[] = "webauthn.get";
namespace {
+// AttestationPromptResult enumerates events related to attestation prompts.
+// These values are recorded in an UMA histogram and so should not be
+// reassigned.
+enum class AttestationPromptResult {
+ // kQueried indicates that the embedder was queried in order to determine
+ // whether attestation information should be returned to the origin.
+ kQueried = 0,
+ // kTimeout indicates that a timeout occured while awaiting the result of an
+ // attestation query.
+ kTimeout = 1,
+ // kAllowed indicates that the query to the embedder was resolved positively.
+ // (E.g. the user clicked to allow, or the embedded allowed immediately by
+ // policy.)
+ kAllowed = 2,
+ // kBlocked indicates that the query to the embedder was resolved negatively.
+ // (E.g. the user clicked to block, or closed the dialog.)
+ kBlocked = 3,
+ // kAbandoned indications that the user closed the tab or navigated away while
+ // the attestation prompt was showing.
+ kAbandoned = 4,
+ kMaxValue = kAbandoned,
+};
+
// Ensure that the origin's effective domain is a valid domain.
// Only the domain format of host is valid.
// Reference https://url.spec.whatwg.org/#valid-domain-string and
// https://html.spec.whatwg.org/multipage/origin.html#concept-origin-effective-domain.
bool HasValidEffectiveDomain(url::Origin caller_origin) {
- return !caller_origin.unique() &&
+ return !caller_origin.opaque() &&
!url::HostIsIPAddress(caller_origin.host()) &&
content::IsOriginSecure(caller_origin.GetURL()) &&
// Additionally, the scheme is required to be HTTP(S). Other schemes
@@ -262,10 +292,63 @@ ProcessAppIdExtension(std::string appid, const url::Origin& caller_origin) {
return CreateApplicationParameter(appid);
}
+// Parses the FIDO transport types extension from the DER-encoded, X.509
+// certificate in |der_cert| and appends any unique transport types found to
+// |out_transports|.
+void AppendUniqueTransportsFromCertificate(
+ base::span<const uint8_t> der_cert,
+ std::vector<device::FidoTransportProtocol>* out_transports) {
+ // See
+ // https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-authenticator-transports-extension-v1.2-ps-20170411.html#fido-u2f-certificate-transports-extension
+ static constexpr uint8_t kTransportTypesOID[] = {
+ 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xe5, 0x1c, 0x02, 0x01, 0x01};
+ bool present, critical;
+ base::StringPiece contents;
+ if (!net::asn1::ExtractExtensionFromDERCert(
+ base::StringPiece(reinterpret_cast<const char*>(der_cert.data()),
+ der_cert.size()),
+ base::StringPiece(reinterpret_cast<const char*>(kTransportTypesOID),
+ sizeof(kTransportTypesOID)),
+ &present, &critical, &contents) ||
+ !present) {
+ return;
+ }
+
+ const net::der::Input contents_der(contents);
+ net::der::Parser contents_parser(contents_der);
+ net::der::BitString transport_bits;
+ if (!contents_parser.ReadBitString(&transport_bits)) {
+ return;
+ }
+
+ // The certificate extension contains a BIT STRING where different bits
+ // indicate support for different transports. The following array maps
+ // between these bit indexes and the FidoTransportProtocol enum.
+ static constexpr struct {
+ uint8_t bit_index;
+ device::FidoTransportProtocol transport;
+ } kTransportMapping[] = {
+ // Bit 0 is "Bluetooth Classic", not BLE. Since webauthn doesn't define a
+ // transport type for this we ignore it.
+ {1, device::FidoTransportProtocol::kBluetoothLowEnergy},
+ {2, device::FidoTransportProtocol::kUsbHumanInterfaceDevice},
+ {3, device::FidoTransportProtocol::kNearFieldCommunication},
+ {4, device::FidoTransportProtocol::kInternal},
+ };
+
+ for (const auto& mapping : kTransportMapping) {
+ if (transport_bits.AssertsBit(mapping.bit_index) &&
+ !base::ContainsValue(*out_transports, mapping.transport)) {
+ out_transports->push_back(mapping.transport);
+ }
+ }
+}
+
blink::mojom::MakeCredentialAuthenticatorResponsePtr
CreateMakeCredentialResponse(
const std::string& client_data_json,
- device::AuthenticatorMakeCredentialResponse response_data) {
+ device::AuthenticatorMakeCredentialResponse response_data,
+ bool preserve_attestation) {
auto response = blink::mojom::MakeCredentialAuthenticatorResponse::New();
auto common_info = blink::mojom::CommonCredentialInfo::New();
common_info->client_data_json.assign(client_data_json.begin(),
@@ -273,8 +356,32 @@ CreateMakeCredentialResponse(
common_info->raw_id = response_data.raw_credential_id();
common_info->id = response_data.GetId();
response->info = std::move(common_info);
+
+ // The transport list must not contain duplicates but the order doesn't matter
+ // because Blink will sort the resulting strings before returning them.
+ std::vector<device::FidoTransportProtocol> transports = {
+ response_data.transport_used()};
+ // If the attestation certificate specifies that the token supports any other
+ // transports, include them in the list.
+ base::Optional<base::span<const uint8_t>> leaf_cert =
+ response_data.attestation_object()
+ .attestation_statement()
+ .GetLeafCertificate();
+ if (leaf_cert) {
+ AppendUniqueTransportsFromCertificate(*leaf_cert, &transports);
+ }
+
+ for (auto transport : transports) {
+ response->transports.push_back(
+ mojo::ConvertTo<blink::mojom::AuthenticatorTransport>(transport));
+ }
+
+ if (!preserve_attestation) {
+ response_data.EraseAttestationStatement();
+ }
response->attestation_object =
response_data.GetCBOREncodedAttestationObject();
+
return response;
}
@@ -461,6 +568,16 @@ void AuthenticatorImpl::MakeCredential(
return;
}
+ if (options->authenticator_selection &&
+ options->authenticator_selection->require_resident_key) {
+ // Disallow the creation of resident credentials.
+ InvokeCallbackAndCleanup(
+ std::move(callback),
+ blink::mojom::AuthenticatorStatus::RESIDENT_CREDENTIALS_UNSUPPORTED,
+ nullptr, Focus::kDontCheck);
+ return;
+ }
+
DCHECK(make_credential_response_callback_.is_null());
make_credential_response_callback_ = std::move(callback);
@@ -506,7 +623,10 @@ void AuthenticatorImpl::MakeCredential(
request_->GetWeakPtr()) /* request_callback */,
base::BindRepeating(
&device::FidoRequestHandlerBase::PowerOnBluetoothAdapter,
- request_->GetWeakPtr()) /* bluetooth_adapter_power_on_callback */);
+ request_->GetWeakPtr()) /* bluetooth_adapter_power_on_callback */,
+ base::BindRepeating(
+ &device::FidoRequestHandlerBase::InitiatePairingWithDevice,
+ request_->GetWeakPtr()) /* ble_pairing_callback*/);
request_->set_observer(request_delegate_.get());
request_->SetPlatformAuthenticatorOrMarkUnavailable(
@@ -551,6 +671,15 @@ void AuthenticatorImpl::GetAssertion(
return;
}
+ if (options->allow_credentials.empty()) {
+ // Chrome currently does not support any resident keys.
+ InvokeCallbackAndCleanup(
+ std::move(callback),
+ blink::mojom::AuthenticatorStatus::RESIDENT_CREDENTIALS_UNSUPPORTED,
+ nullptr);
+ return;
+ }
+
if (options->appid) {
alternative_application_parameter_ =
ProcessAppIdExtension(*options->appid, caller_origin);
@@ -597,7 +726,10 @@ void AuthenticatorImpl::GetAssertion(
request_->GetWeakPtr()) /* request_callback */,
base::BindRepeating(
&device::FidoRequestHandlerBase::PowerOnBluetoothAdapter,
- request_->GetWeakPtr()) /* bluetooth_adapter_power_on_callback */);
+ request_->GetWeakPtr()) /* bluetooth_adapter_power_on_callback */,
+ base::BindRepeating(
+ &device::FidoRequestHandlerBase::InitiatePairingWithDevice,
+ request_->GetWeakPtr()) /* ble_pairing_callback*/);
request_->set_observer(request_delegate_.get());
request_->SetPlatformAuthenticatorOrMarkUnavailable(
@@ -695,6 +827,9 @@ void AuthenticatorImpl::OnRegisterResponse(
if (attestation_preference_ !=
blink::mojom::AttestationConveyancePreference::NONE) {
+ UMA_HISTOGRAM_ENUMERATION("WebAuthentication.AttestationPromptResult",
+ AttestationPromptResult::kQueried);
+ awaiting_attestation_response_ = true;
request_delegate_->ShouldReturnAttestation(
relying_party_id_,
base::BindOnce(
@@ -703,15 +838,13 @@ void AuthenticatorImpl::OnRegisterResponse(
return;
}
- if (!response_data->IsSelfAttestation()) {
- response_data->EraseAttestationStatement();
- }
-
+ const bool include_attestation = response_data->IsSelfAttestation();
InvokeCallbackAndCleanup(
std::move(make_credential_response_callback_),
blink::mojom::AuthenticatorStatus::SUCCESS,
CreateMakeCredentialResponse(std::move(client_data_json_),
- std::move(*response_data)),
+ std::move(*response_data),
+ include_attestation),
Focus::kDoCheck);
return;
}
@@ -721,6 +854,7 @@ void AuthenticatorImpl::OnRegisterResponse(
void AuthenticatorImpl::OnRegisterResponseAttestationDecided(
device::AuthenticatorMakeCredentialResponse response_data,
bool attestation_permitted) {
+ awaiting_attestation_response_ = false;
if (!request_) {
// The request has already been cleaned up, probably because a navigation
// occured while the permissions prompt was pending.
@@ -731,6 +865,8 @@ void AuthenticatorImpl::OnRegisterResponseAttestationDecided(
blink::mojom::AttestationConveyancePreference::NONE);
if (!attestation_permitted) {
+ UMA_HISTOGRAM_ENUMERATION("WebAuthentication.AttestationPromptResult",
+ AttestationPromptResult::kBlocked);
InvokeCallbackAndCleanup(
std::move(make_credential_response_callback_),
blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr,
@@ -738,6 +874,10 @@ void AuthenticatorImpl::OnRegisterResponseAttestationDecided(
return;
}
+ UMA_HISTOGRAM_ENUMERATION("WebAuthentication.AttestationPromptResult",
+ AttestationPromptResult::kAllowed);
+ bool include_attestation = true;
+
// The check for IsAttestationCertificateInappropriatelyIdentifying is
// performed after the permissions prompt, even though we know the answer
// before, because this still effectively discloses the make & model of the
@@ -755,15 +895,15 @@ void AuthenticatorImpl::OnRegisterResponseAttestationDecided(
// The only way to get the underlying attestation will be to list the RP ID
// in the enterprise policy, because that enables the individual attestation
// bit in the register request and permits individual attestation generally.
- response_data.EraseAttestationStatement();
+ include_attestation = false;
}
- InvokeCallbackAndCleanup(
- std::move(make_credential_response_callback_),
- blink::mojom::AuthenticatorStatus::SUCCESS,
- CreateMakeCredentialResponse(std::move(client_data_json_),
- std::move(response_data)),
- Focus::kDoCheck);
+ InvokeCallbackAndCleanup(std::move(make_credential_response_callback_),
+ blink::mojom::AuthenticatorStatus::SUCCESS,
+ CreateMakeCredentialResponse(
+ std::move(client_data_json_),
+ std::move(response_data), include_attestation),
+ Focus::kDoCheck);
}
void AuthenticatorImpl::OnSignResponse(
@@ -841,6 +981,12 @@ void AuthenticatorImpl::FailWithNotAllowedErrorAndCleanup() {
void AuthenticatorImpl::OnTimeout() {
DCHECK(request_delegate_);
+ if (awaiting_attestation_response_) {
+ UMA_HISTOGRAM_ENUMERATION("WebAuthentication.AttestationPromptResult",
+ AttestationPromptResult::kTimeout);
+ awaiting_attestation_response_ = false;
+ }
+
request_delegate_->DidFailWithInterestingReason(
AuthenticatorRequestClientDelegate::InterestingFailureReason::kTimeout);
@@ -881,6 +1027,12 @@ void AuthenticatorImpl::InvokeCallbackAndCleanup(
}
void AuthenticatorImpl::Cleanup() {
+ if (awaiting_attestation_response_) {
+ UMA_HISTOGRAM_ENUMERATION("WebAuthentication.AttestationPromptResult",
+ AttestationPromptResult::kAbandoned);
+ awaiting_attestation_response_ = false;
+ }
+
timer_->Stop();
request_.reset();
request_delegate_.reset();
@@ -948,4 +1100,4 @@ base::Optional<device::PlatformAuthenticatorInfo> AuthenticatorImpl::
#endif
}
-} // namespace content
+} // namespace content \ No newline at end of file
diff --git a/chromium/content/browser/webauth/authenticator_impl.h b/chromium/content/browser/webauth/authenticator_impl.h
index df8cdf26eb4..effdf9ccb26 100644
--- a/chromium/content/browser/webauth/authenticator_impl.h
+++ b/chromium/content/browser/webauth/authenticator_impl.h
@@ -186,6 +186,9 @@ class CONTENT_EXPORT AuthenticatorImpl : public blink::mojom::Authenticator,
// retried with this value.
base::Optional<std::array<uint8_t, crypto::kSHA256Length>>
alternative_application_parameter_;
+ // awaiting_attestation_response_ is true if the embedder has been queried
+ // about an attestsation decision and the response is still pending.
+ bool awaiting_attestation_response_ = false;
// Owns pipes to this Authenticator from |render_frame_host_|.
mojo::Binding<blink::mojom::Authenticator> binding_;
diff --git a/chromium/content/browser/webauth/authenticator_impl_unittest.cc b/chromium/content/browser/webauth/authenticator_impl_unittest.cc
index fdb9b181f0e..12568cb60d2 100644
--- a/chromium/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/chromium/content/browser/webauth/authenticator_impl_unittest.cc
@@ -399,6 +399,11 @@ class AuthenticatorImplTest : public content::RenderViewHostTestHarness {
scoped_feature_list_->InitAndEnableFeature(feature);
}
+ void DisableFeature(const base::Feature& feature) {
+ scoped_feature_list_.emplace();
+ scoped_feature_list_->InitAndDisableFeature(feature);
+ }
+
protected:
std::unique_ptr<AuthenticatorImpl> authenticator_impl_;
service_manager::mojom::ConnectorRequest request_;
@@ -526,8 +531,8 @@ TEST_F(AuthenticatorImplTest, MakeCredentialUserVerification) {
EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
}
-// Test that MakeCredential request times out with NOT_ALLOWED_ERROR if resident
-// key is requested for U2F devices on create().
+// Test that MakeCredential request returns if resident
+// key is requested on create().
TEST_F(AuthenticatorImplTest, MakeCredentialResidentKey) {
SimulateNavigation(GURL(kTestOrigin1));
device::test::ScopedVirtualFidoDevice scoped_virtual_device;
@@ -546,7 +551,10 @@ TEST_F(AuthenticatorImplTest, MakeCredentialResidentKey) {
base::RunLoop().RunUntilIdle();
task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
+ EXPECT_EQ(AuthenticatorStatus::RESIDENT_CREDENTIALS_UNSUPPORTED,
+ callback_receiver.status());
+
+ // TODO add CTAP device
}
// Test that MakeCredential request times out with NOT_ALLOWED_ERROR if a
@@ -830,22 +838,16 @@ TEST_F(AuthenticatorImplTest, OversizedCredentialId) {
TEST_F(AuthenticatorImplTest, TestCableDiscoveryByDefault) {
auto authenticator = ConnectToAuthenticator();
-// On Windows caBLE should be disabled by default regardless of version.
-#if defined(OS_WIN)
- EXPECT_FALSE(SupportsTransportProtocol(
- device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy));
-// Otherwise, it should be enabled by default if BLE is supported.
-#else
+
+ // caBLE should be enabled by default if BLE is supported.
EXPECT_EQ(
device::BluetoothAdapterFactory::Get().IsLowEnergySupported(),
SupportsTransportProtocol(
device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy));
-#endif
}
TEST_F(AuthenticatorImplTest, TestCableDiscoveryDisabledWithFlag) {
- scoped_feature_list_.emplace();
- scoped_feature_list_->InitAndDisableFeature(features::kWebAuthCable);
+ DisableFeature(features::kWebAuthCable);
auto authenticator = ConnectToAuthenticator();
EXPECT_FALSE(SupportsTransportProtocol(
@@ -931,7 +933,7 @@ TEST_F(AuthenticatorImplTest, GetAssertionWithEmptyAllowCredentials) {
base::RunLoop().RunUntilIdle();
task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::CREDENTIAL_NOT_RECOGNIZED,
+ EXPECT_EQ(AuthenticatorStatus::RESIDENT_CREDENTIALS_UNSUPPORTED,
callback_receiver.status());
}
@@ -1124,7 +1126,9 @@ class TestAuthenticatorRequestDelegate
void RegisterActionCallbacks(
base::OnceClosure cancel_callback,
device::FidoRequestHandlerBase::RequestCallback request_callback,
- base::RepeatingClosure bluetooth_adapter_power_on_callback) override {
+ base::RepeatingClosure bluetooth_adapter_power_on_callback,
+ device::FidoRequestHandlerBase::BlePairingCallback ble_pairing_callback)
+ override {
ASSERT_TRUE(action_callbacks_registered_callback_)
<< "RegisterActionCallbacks called twice.";
std::move(action_callbacks_registered_callback_).Run();
@@ -1704,6 +1708,7 @@ TEST_F(AuthenticatorContentBrowserClientTest,
TEST_F(AuthenticatorContentBrowserClientTest, IsUVPAAFalseIfFeatureFlagOff) {
if (__builtin_available(macOS 10.12.2, *)) {
// Touch ID is hardware-supported and embedder-enabled, but the flag is off.
+ DisableFeature(device::kWebAuthTouchId);
device::fido::mac::ScopedTouchIdTestEnvironment touch_id_test_environment;
touch_id_test_environment.SetTouchIdAvailable(true);
test_client_.supports_touch_id = true;
@@ -2009,4 +2014,34 @@ TEST_F(AuthenticatorImplRequestDelegateTest,
std::get<0>(*failure_reason_receiver.result()));
}
+TEST_F(AuthenticatorImplTest, Transports) {
+ TestServiceManagerContext smc;
+ NavigateAndCommit(GURL(kTestOrigin1));
+
+ for (auto protocol :
+ {device::ProtocolVersion::kU2f, device::ProtocolVersion::kCtap}) {
+ SCOPED_TRACE(static_cast<int>(protocol));
+
+ device::test::ScopedVirtualFidoDevice scoped_virtual_device;
+ scoped_virtual_device.SetSupportedProtocol(protocol);
+
+ AuthenticatorPtr authenticator = ConnectToAuthenticator();
+ PublicKeyCredentialCreationOptionsPtr options =
+ GetTestPublicKeyCredentialCreationOptions();
+ TestMakeCredentialCallback callback_receiver;
+ authenticator->MakeCredential(std::move(options),
+ callback_receiver.callback());
+ callback_receiver.WaitForCallback();
+ EXPECT_EQ(AuthenticatorStatus::SUCCESS, callback_receiver.status());
+
+ const std::vector<blink::mojom::AuthenticatorTransport>& transports(
+ callback_receiver.value()->transports);
+ ASSERT_EQ(2u, transports.size());
+ EXPECT_EQ(blink::mojom::AuthenticatorTransport::USB, transports[0]);
+ // VirtualFidoDevice generates an attestation certificate that asserts NFC
+ // support via an extension.
+ EXPECT_EQ(blink::mojom::AuthenticatorTransport::NFC, transports[1]);
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/webauth/authenticator_type_converters.cc b/chromium/content/browser/webauth/authenticator_type_converters.cc
index b916b86a15c..68b7878a755 100644
--- a/chromium/content/browser/webauth/authenticator_type_converters.cc
+++ b/chromium/content/browser/webauth/authenticator_type_converters.cc
@@ -44,6 +44,25 @@ TypeConverter<::device::FidoTransportProtocol, AuthenticatorTransport>::Convert(
return ::device::FidoTransportProtocol::kUsbHumanInterfaceDevice;
}
+AuthenticatorTransport
+TypeConverter<AuthenticatorTransport, ::device::FidoTransportProtocol>::Convert(
+ const ::device::FidoTransportProtocol& input) {
+ switch (input) {
+ case ::device::FidoTransportProtocol::kUsbHumanInterfaceDevice:
+ return AuthenticatorTransport::USB;
+ case ::device::FidoTransportProtocol::kNearFieldCommunication:
+ return AuthenticatorTransport::NFC;
+ case ::device::FidoTransportProtocol::kBluetoothLowEnergy:
+ return AuthenticatorTransport::BLE;
+ case ::device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy:
+ return AuthenticatorTransport::CABLE;
+ case ::device::FidoTransportProtocol::kInternal:
+ return AuthenticatorTransport::INTERNAL;
+ }
+ NOTREACHED();
+ return AuthenticatorTransport::USB;
+}
+
// static
::device::CredentialType
TypeConverter<::device::CredentialType, PublicKeyCredentialType>::Convert(
diff --git a/chromium/content/browser/webauth/authenticator_type_converters.h b/chromium/content/browser/webauth/authenticator_type_converters.h
index 90fd80fb7c6..5c5e7136a4a 100644
--- a/chromium/content/browser/webauth/authenticator_type_converters.h
+++ b/chromium/content/browser/webauth/authenticator_type_converters.h
@@ -30,6 +30,13 @@ struct TypeConverter<::device::FidoTransportProtocol,
};
template <>
+struct TypeConverter<::blink::mojom::AuthenticatorTransport,
+ ::device::FidoTransportProtocol> {
+ static ::blink::mojom::AuthenticatorTransport Convert(
+ const ::device::FidoTransportProtocol& input);
+};
+
+template <>
struct TypeConverter<::device::CredentialType,
::blink::mojom::PublicKeyCredentialType> {
static ::device::CredentialType Convert(
diff --git a/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.cc b/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.cc
index 3f3d4a2df33..482b3f01ba2 100644
--- a/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.cc
+++ b/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.cc
@@ -96,7 +96,7 @@ void ScopedVirtualAuthenticatorEnvironment::ClearAuthenticators(
std::move(callback).Run();
}
-std::unique_ptr<::device::FidoDiscovery>
+std::unique_ptr<::device::FidoDeviceDiscovery>
ScopedVirtualAuthenticatorEnvironment::CreateFidoDiscovery(
device::FidoTransportProtocol transport,
::service_manager::Connector* connector) {
diff --git a/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.h b/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.h
index 0c0bf6f47b9..663738c7cc9 100644
--- a/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.h
+++ b/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.h
@@ -13,7 +13,7 @@
#include "base/macros.h"
#include "base/no_destructor.h"
#include "content/common/content_export.h"
-#include "device/fido/fido_discovery.h"
+#include "device/fido/fido_device_discovery.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "third_party/blink/public/platform/modules/webauthn/virtual_authenticator.mojom.h"
@@ -53,7 +53,7 @@ class CONTENT_EXPORT ScopedVirtualAuthenticatorEnvironment
void ClearAuthenticators(ClearAuthenticatorsCallback callback) override;
// ScopedFidoDiscoveryFactory:
- std::unique_ptr<::device::FidoDiscovery> CreateFidoDiscovery(
+ std::unique_ptr<::device::FidoDeviceDiscovery> CreateFidoDiscovery(
device::FidoTransportProtocol transport,
::service_manager::Connector* connector) override;
diff --git a/chromium/content/browser/webauth/virtual_discovery.cc b/chromium/content/browser/webauth/virtual_discovery.cc
index 1f37ee855ba..82e022b48ed 100644
--- a/chromium/content/browser/webauth/virtual_discovery.cc
+++ b/chromium/content/browser/webauth/virtual_discovery.cc
@@ -17,7 +17,7 @@ namespace content {
VirtualFidoDiscovery::VirtualFidoDiscovery(
ScopedVirtualAuthenticatorEnvironment* environment,
::device::FidoTransportProtocol transport)
- : FidoDiscovery(transport), environment_(environment) {}
+ : FidoDeviceDiscovery(transport), environment_(environment) {}
VirtualFidoDiscovery::~VirtualFidoDiscovery() {
environment_->OnDiscoveryDestroyed(this);
@@ -28,7 +28,7 @@ void VirtualFidoDiscovery::AddVirtualDevice(
// The real implementation would never notify the client's observer about
// devices before the client calls Start(), mimic the same behavior.
if (is_start_requested()) {
- FidoDiscovery::AddDevice(std::move(device));
+ FidoDeviceDiscovery::AddDevice(std::move(device));
} else {
devices_pending_discovery_start_.push_back(std::move(device));
}
@@ -36,12 +36,12 @@ void VirtualFidoDiscovery::AddVirtualDevice(
bool VirtualFidoDiscovery::RemoveVirtualDevice(base::StringPiece device_id) {
DCHECK(is_start_requested());
- return ::device::FidoDiscovery::RemoveDevice(device_id);
+ return ::device::FidoDeviceDiscovery::RemoveDevice(device_id);
}
void VirtualFidoDiscovery::StartInternal() {
for (auto& device : devices_pending_discovery_start_)
- FidoDiscovery::AddDevice(std::move(device));
+ FidoDeviceDiscovery::AddDevice(std::move(device));
devices_pending_discovery_start_.clear();
base::ThreadTaskRunnerHandle::Get()->PostTask(
diff --git a/chromium/content/browser/webauth/virtual_discovery.h b/chromium/content/browser/webauth/virtual_discovery.h
index 7c57b042ff9..b4c14fc205a 100644
--- a/chromium/content/browser/webauth/virtual_discovery.h
+++ b/chromium/content/browser/webauth/virtual_discovery.h
@@ -11,7 +11,7 @@
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "content/common/content_export.h"
-#include "device/fido/fido_discovery.h"
+#include "device/fido/fido_device_discovery.h"
namespace device {
class FidoDevice;
@@ -21,9 +21,10 @@ namespace content {
class ScopedVirtualAuthenticatorEnvironment;
-// A fully automated FidoDiscovery implementation, which is disconnected from
-// the real world, and discovers VirtualFidoDevice instances.
-class CONTENT_EXPORT VirtualFidoDiscovery : public ::device::FidoDiscovery {
+// A fully automated FidoDeviceDiscovery implementation, which is disconnected
+// from the real world, and discovers VirtualFidoDevice instances.
+class CONTENT_EXPORT VirtualFidoDiscovery
+ : public ::device::FidoDeviceDiscovery {
public:
// The |environment| must outlive this instance.
VirtualFidoDiscovery(ScopedVirtualAuthenticatorEnvironment* environment,
@@ -36,7 +37,7 @@ class CONTENT_EXPORT VirtualFidoDiscovery : public ::device::FidoDiscovery {
bool RemoveVirtualDevice(base::StringPiece device_id);
protected:
- // FidoDiscovery:
+ // FidoDeviceDiscovery:
void StartInternal() override;
private:
diff --git a/chromium/content/browser/webauth/webauth_browsertest.cc b/chromium/content/browser/webauth/webauth_browsertest.cc
index 57bc30c924b..b78d7129899 100644
--- a/chromium/content/browser/webauth/webauth_browsertest.cc
+++ b/chromium/content/browser/webauth/webauth_browsertest.cc
@@ -67,9 +67,9 @@ constexpr char kTimeoutErrorMessage[] =
"webauth: NotAllowedError: The operation either timed out or was not "
"allowed. See: https://w3c.github.io/webauthn/#sec-assertion-privacy.";
-constexpr char kInvalidStateErrorMessage[] =
- "webauth: InvalidStateError: The user attempted to use an authenticator "
- "that recognized none of the provided credentials.";
+constexpr char kResidentCredentialsErrorMessage[] =
+ "webauth: NotSupportedError: Resident credentials or empty "
+ "'allowCredentials' lists are not supported at this time.";
constexpr char kRelyingPartySecurityErrorMessage[] =
"webauth: SecurityError: The relying party ID 'localhost' is not a "
@@ -590,7 +590,7 @@ IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
// factory as one of the first steps. Here, the request should not have been
// serviced at all, so the fake request should still be pending on the fake
// factory.
- auto hid_discovery = ::device::FidoDiscovery::Create(
+ auto hid_discovery = ::device::FidoDeviceDiscovery::Create(
::device::FidoTransportProtocol::kUsbHumanInterfaceDevice, nullptr);
ASSERT_TRUE(!!hid_discovery);
@@ -735,7 +735,7 @@ IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
shell()->web_contents()->GetMainFrame(),
BuildCreateCallWithParameters(parameters), &result));
- ASSERT_EQ(kTimeoutErrorMessage, result);
+ ASSERT_EQ(kResidentCredentialsErrorMessage, result);
}
}
@@ -806,7 +806,7 @@ IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
ASSERT_TRUE(content::ExecuteScriptAndExtractString(
shell()->web_contents()->GetMainFrame(),
BuildGetCallWithParameters(parameters), &result));
- ASSERT_EQ(kInvalidStateErrorMessage, result);
+ ASSERT_EQ(kResidentCredentialsErrorMessage, result);
}
// WebAuthBrowserBleDisabledTest
diff --git a/chromium/content/browser/webrtc/webrtc_audio_browsertest.cc b/chromium/content/browser/webrtc/webrtc_audio_browsertest.cc
index 308f749f75d..538577a8ba9 100644
--- a/chromium/content/browser/webrtc/webrtc_audio_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_audio_browsertest.cc
@@ -18,73 +18,25 @@
#include "media/base/media_switches.h"
#include "media/webrtc/webrtc_switches.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
-#include "services/service_manager/sandbox/features.h"
#include "testing/gtest/include/gtest/gtest-param-test.h"
namespace content {
-namespace {
-
-// Temporary enum, used for running the tests with different combination of
-// flags while audio service is under experiment.
-// TODO(https://crbug.com/850878) Remove after enabling sandboxing on all
-// platforms.
-enum class AudioServiceFeatures {
- kDisabled,
- kOutOfProcess,
-#if defined(OS_WIN)
- kSandboxed,
-#endif
-#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
- kSandboxedWithAudioServiceAPM
-#endif
-};
-} // namespace
-
// This class tests the scenario when permission to access mic or camera is
// granted.
-class WebRtcAudioBrowserTest
- : public WebRtcContentBrowserTestBase,
- public testing::WithParamInterface<AudioServiceFeatures> {
+class WebRtcAudioBrowserTest : public WebRtcContentBrowserTestBase,
+ public testing::WithParamInterface<bool> {
public:
WebRtcAudioBrowserTest() {
std::vector<base::Feature> audio_service_oop_features = {
features::kAudioServiceAudioStreams,
features::kAudioServiceOutOfProcess};
- switch (GetParam()) {
- case AudioServiceFeatures::kDisabled:
- // Force audio service out of process to disabled.
- audio_service_features_.InitWithFeatures({},
- audio_service_oop_features);
- break;
- case AudioServiceFeatures::kOutOfProcess:
- // Force audio service out of process to enabled.
- audio_service_features_.InitWithFeatures(
- audio_service_oop_features,
-#if defined(OS_WIN)
- // Force audio service sandboxing (available only on Windows) to
- // disabled.
- {service_manager::features::kAudioServiceSandbox});
-#else
- {});
-#endif
- break;
-#if defined(OS_WIN)
- case AudioServiceFeatures::kSandboxed:
- // Force audio service out of process and sandboxing to enabled.
- audio_service_oop_features.push_back(
- service_manager::features::kAudioServiceSandbox);
- audio_service_features_.InitWithFeatures(audio_service_oop_features,
- {});
- break;
-#endif
-#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
- case AudioServiceFeatures::kSandboxedWithAudioServiceAPM:
- audio_service_oop_features.push_back(
- service_manager::features::kAudioServiceSandbox);
- audio_service_oop_features.push_back(
- features::kWebRtcApmInAudioService);
-#endif
+ if (GetParam()) {
+ // Force audio service out of process to enabled.
+ audio_service_features_.InitWithFeatures(audio_service_oop_features, {});
+ } else {
+ // Force audio service out of process to disabled.
+ audio_service_features_.InitWithFeatures({}, audio_service_oop_features);
}
}
~WebRtcAudioBrowserTest() override {}
@@ -178,30 +130,14 @@ IN_PROC_BROWSER_TEST_P(WebRtcAudioBrowserTest,
// We run these tests with the audio service both in and out of the the browser
// process to have waterfall coverage while the feature rolls out. It should be
// removed after launch.
-#if defined(OS_LINUX) || defined(OS_MACOSX)
+#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
// Supported platforms.
-INSTANTIATE_TEST_CASE_P(
- ,
- WebRtcAudioBrowserTest,
- ::testing::Values(AudioServiceFeatures::kDisabled,
- AudioServiceFeatures::kOutOfProcess,
- AudioServiceFeatures::kSandboxedWithAudioServiceAPM));
-#elif defined(OS_WIN)
-// On Windows, also run in sandboxed mode.
-INSTANTIATE_TEST_CASE_P(
- ,
- WebRtcAudioBrowserTest,
- ::testing::Values(AudioServiceFeatures::kDisabled,
- AudioServiceFeatures::kOutOfProcess,
- AudioServiceFeatures::kSandboxed,
- AudioServiceFeatures::kSandboxedWithAudioServiceAPM));
+INSTANTIATE_TEST_CASE_P(, WebRtcAudioBrowserTest, ::testing::Bool());
#elif defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
// Renderer crashes under Android ASAN: https://crbug.com/408496.
#else
// Platforms where the out of process audio service isn't supported
-INSTANTIATE_TEST_CASE_P(,
- WebRtcAudioBrowserTest,
- ::testing::Values(AudioServiceFeatures::kDisabled));
+INSTANTIATE_TEST_CASE_P(, WebRtcAudioBrowserTest, ::testing::Values(false));
#endif
} // namespace content
diff --git a/chromium/content/browser/webrtc/webrtc_browsertest.cc b/chromium/content/browser/webrtc/webrtc_browsertest.cc
index cbbb5ee815c..74c2b7d8c58 100644
--- a/chromium/content/browser/webrtc/webrtc_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_browsertest.cc
@@ -17,6 +17,7 @@
#include "media/base/media_switches.h"
#include "media/media_buildflags.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "services/network/public/cpp/features.h"
namespace content {
@@ -58,6 +59,14 @@ IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, CanSetupAudioAndVideoCall) {
MakeTypicalPeerConnectionCall("call({video: true, audio: true});");
}
+IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, NetworkProcessCrashRecovery) {
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
+ return;
+ MakeTypicalPeerConnectionCall("call({video: true, audio: true});");
+ SimulateNetworkServiceCrash();
+ MakeTypicalPeerConnectionCall("call({video: true, audio: true});");
+}
+
IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest,
CanSetupDefaultVideoCallWithOldGetUserMedia) {
MakeTypicalPeerConnectionCall("oldStyleCall();");
diff --git a/chromium/content/browser/webrtc/webrtc_content_browsertest_base.cc b/chromium/content/browser/webrtc/webrtc_content_browsertest_base.cc
index 6c1cd8c7d72..d79ccc7549b 100644
--- a/chromium/content/browser/webrtc/webrtc_content_browsertest_base.cc
+++ b/chromium/content/browser/webrtc/webrtc_content_browsertest_base.cc
@@ -76,7 +76,8 @@ std::string WebRtcContentBrowserTestBase::ExecuteJavascriptAndReturnResult(
void WebRtcContentBrowserTestBase::MakeTypicalCall(
const std::string& javascript,
const std::string& html_file) {
- ASSERT_TRUE(embedded_test_server()->Start());
+ if (!embedded_test_server()->Started())
+ ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL(html_file));
NavigateToURL(shell(), url);
diff --git a/chromium/content/browser/webrtc/webrtc_depth_capture_browsertest.cc b/chromium/content/browser/webrtc/webrtc_depth_capture_browsertest.cc
index f2936a8bcc0..6ac469bdde7 100644
--- a/chromium/content/browser/webrtc/webrtc_depth_capture_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_depth_capture_browsertest.cc
@@ -5,6 +5,7 @@
#include <stddef.h>
#include "base/command_line.h"
+#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/webrtc/webrtc_content_browsertest_base.h"
@@ -34,12 +35,10 @@ void RemoveSwitchFromCommandLine(base::CommandLine* command_line,
#else
switch_value;
#endif
- argv.erase(std::remove_if(
- argv.begin(), argv.end(),
- [switch_string](const base::CommandLine::StringType& value) {
- return value.find(switch_string) != std::string::npos;
- }),
- argv.end());
+ base::EraseIf(argv,
+ [switch_string](const base::CommandLine::StringType& value) {
+ return value.find(switch_string) != std::string::npos;
+ });
command_line->InitFromArgv(argv);
}
diff --git a/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc b/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
index 5a997c3dcd8..c9dc8a33c09 100644
--- a/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
@@ -34,7 +34,6 @@
#if defined(OS_WIN)
#include "base/win/windows_version.h"
-#include "services/service_manager/sandbox/features.h"
#endif
namespace {
@@ -58,18 +57,6 @@ static const char kRenderDuplicatedMediastreamAndStop[] =
// Results returned by JS.
static const char kOK[] = "OK";
-// Temporary enum, used for running the tests with different combination of
-// flags while audio service is under experiment.
-// TODO(https://crbug.com/850878) Remove after enabling sandboxing on all
-// platforms.
-enum class AudioServiceFeatures {
- kDisabled,
- kOutOfProcess,
-#if defined(OS_WIN)
- kSandboxed,
-#endif
-};
-
std::string GenerateGetUserMediaWithMandatorySourceID(
const std::string& function_name,
const std::string& audio_source_id,
@@ -115,9 +102,8 @@ bool VerifyDisableLocalEcho(bool expect_value,
namespace content {
-class WebRtcGetUserMediaBrowserTest
- : public WebRtcContentBrowserTestBase,
- public testing::WithParamInterface<AudioServiceFeatures> {
+class WebRtcGetUserMediaBrowserTest : public WebRtcContentBrowserTestBase,
+ public testing::WithParamInterface<bool> {
public:
WebRtcGetUserMediaBrowserTest() {
// Automatically grant device permission.
@@ -125,33 +111,12 @@ class WebRtcGetUserMediaBrowserTest
std::vector<base::Feature> audio_service_oop_features = {
features::kAudioServiceAudioStreams,
features::kAudioServiceOutOfProcess};
- switch (GetParam()) {
- case AudioServiceFeatures::kDisabled:
- // Force audio service out of process to disabled.
- audio_service_features_.InitWithFeatures({},
- audio_service_oop_features);
- break;
- case AudioServiceFeatures::kOutOfProcess:
- // Force audio service out of process to enabled.
- audio_service_features_.InitWithFeatures(
- audio_service_oop_features,
-#if defined(OS_WIN)
- // Force audio service sandboxing (available only on Windows) to
- // disabled.
- {service_manager::features::kAudioServiceSandbox});
-#else
- {});
-#endif
- break;
-#if defined(OS_WIN)
- case AudioServiceFeatures::kSandboxed:
- // Force audio service out of process and sandboxing to enabled.
- audio_service_oop_features.push_back(
- service_manager::features::kAudioServiceSandbox);
- audio_service_features_.InitWithFeatures(audio_service_oop_features,
- {});
- break;
-#endif
+ if (GetParam()) {
+ // Force audio service out of process to enabled.
+ audio_service_features_.InitWithFeatures(audio_service_oop_features, {});
+ } else {
+ // Force audio service out of process to disabled.
+ audio_service_features_.InitWithFeatures({}, audio_service_oop_features);
}
}
~WebRtcGetUserMediaBrowserTest() override {}
@@ -193,8 +158,7 @@ class WebRtcGetUserMediaBrowserTest
base::ListValue* values;
ASSERT_TRUE(value->GetAsList(&values));
- for (base::ListValue::iterator it = values->begin();
- it != values->end(); ++it) {
+ for (auto it = values->begin(); it != values->end(); ++it) {
const base::DictionaryValue* dict;
std::string kind;
std::string device_id;
@@ -729,7 +693,7 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest, SrcObjectAddVideoTrack) {
// TODO(crbug.com/848330) Flaky on all platforms
IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
- DISABLE_SrcObjectReplaceInactiveTracks) {
+ DISABLED_SrcObjectReplaceInactiveTracks) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -825,7 +789,7 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
GetAudioStreamAndCheckMutingInitiallyUnmuted) {
// Muting tests do not work with the out-of-process audio service.
// https://crbug.com/843490.
- if (GetParam() != AudioServiceFeatures::kDisabled)
+ if (GetParam())
return;
ASSERT_TRUE(embedded_test_server()->Start());
@@ -854,7 +818,7 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
GetAudioStreamAndCheckMutingInitiallyMuted) {
// Muting tests do not work with the out-of-process audio service.
// https://crbug.com/843490.
- if (GetParam() != AudioServiceFeatures::kDisabled)
+ if (GetParam())
return;
ASSERT_TRUE(embedded_test_server()->Start());
@@ -884,7 +848,7 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
RecoverFromCrashInAudioService) {
// This test only makes sense with the audio service running out of process,
// with or without sandbox.
- if (GetParam() == AudioServiceFeatures::kDisabled)
+ if (!GetParam())
return;
ASSERT_TRUE(embedded_test_server()->Start());
@@ -907,24 +871,15 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
// We run these tests with the audio service both in and out of the the browser
// process to have waterfall coverage while the feature rolls out. It should be
// removed after launch.
-#if (defined(OS_LINUX) && !defined(CHROME_OS)) || defined(OS_MACOSX)
+#if (defined(OS_LINUX) && !defined(CHROME_OS)) || defined(OS_MACOSX) || \
+ defined(OS_WIN)
// Supported platforms.
-INSTANTIATE_TEST_CASE_P(,
- WebRtcGetUserMediaBrowserTest,
- ::testing::Values(AudioServiceFeatures::kDisabled,
- AudioServiceFeatures::kOutOfProcess));
-#elif defined(OS_WIN)
-// On Windows, also run in sandboxed mode.
-INSTANTIATE_TEST_CASE_P(,
- WebRtcGetUserMediaBrowserTest,
- ::testing::Values(AudioServiceFeatures::kDisabled,
- AudioServiceFeatures::kOutOfProcess,
- AudioServiceFeatures::kSandboxed));
+INSTANTIATE_TEST_CASE_P(, WebRtcGetUserMediaBrowserTest, ::testing::Bool());
#else
// Platforms where the out of process audio service is not supported
INSTANTIATE_TEST_CASE_P(,
WebRtcGetUserMediaBrowserTest,
- ::testing::Values(AudioServiceFeatures::kDisabled));
+ ::testing::Values(false));
#endif
} // namespace content
diff --git a/chromium/content/browser/webrtc/webrtc_internals.cc b/chromium/content/browser/webrtc/webrtc_internals.cc
index 89f968cb9a9..71666e4a6e7 100644
--- a/chromium/content/browser/webrtc/webrtc_internals.cc
+++ b/chromium/content/browser/webrtc/webrtc_internals.cc
@@ -11,10 +11,12 @@
#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/web_contents/web_contents_view.h"
#include "content/browser/webrtc/webrtc_internals_ui_observer.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/web_contents.h"
@@ -421,8 +423,8 @@ void WebRTCInternals::SendUpdate(const char* command,
pending_updates_.push(PendingUpdate(command, std::move(value)));
if (queue_was_empty) {
- BrowserThread::PostDelayedTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostDelayedTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&WebRTCInternals::ProcessPendingUpdates,
weak_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(aggregate_updates_ms_));
diff --git a/chromium/content/browser/webrtc/webrtc_internals_unittest.cc b/chromium/content/browser/webrtc/webrtc_internals_unittest.cc
index 8e4dd0a0687..bad42e39fda 100644
--- a/chromium/content/browser/webrtc/webrtc_internals_unittest.cc
+++ b/chromium/content/browser/webrtc/webrtc_internals_unittest.cc
@@ -8,8 +8,10 @@
#include <string>
#include "base/run_loop.h"
+#include "base/task/post_task.h"
#include "base/values.h"
#include "content/browser/webrtc/webrtc_internals_ui_observer.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -144,7 +146,7 @@ TEST_F(WebRtcInternalsTest, AddRemoveObserver) {
webrtc_internals.OnAddPeerConnection(0, 3, 4, kUrl, kRtcConfiguration,
kContraints);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, loop.QuitClosure());
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, loop.QuitClosure());
loop.Run();
EXPECT_EQ("", observer.command());
@@ -160,7 +162,7 @@ TEST_F(WebRtcInternalsTest, EnsureNoLogWhenNoObserver) {
webrtc_internals.OnAddPeerConnection(0, 3, 4, kUrl, kRtcConfiguration,
kContraints);
webrtc_internals.OnUpdatePeerConnection(3, 4, "update_type", "update_value");
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, loop.QuitClosure());
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, loop.QuitClosure());
loop.Run();
// Make sure we don't have a log entry since there was no observer.
@@ -189,7 +191,7 @@ TEST_F(WebRtcInternalsTest, EnsureLogIsRemovedWhenObserverIsRemoved) {
webrtc_internals.OnAddPeerConnection(0, 3, 4, kUrl, kRtcConfiguration,
kContraints);
webrtc_internals.OnUpdatePeerConnection(3, 4, "update_type", "update_value");
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, loop.QuitClosure());
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, loop.QuitClosure());
loop.Run();
// Make sure we have a log entry since there was an observer.
diff --git a/chromium/content/browser/webrtc/webrtc_video_capture_browsertest.cc b/chromium/content/browser/webrtc/webrtc_video_capture_browsertest.cc
index 75ceb0e923c..9e38210316a 100644
--- a/chromium/content/browser/webrtc/webrtc_video_capture_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_video_capture_browsertest.cc
@@ -36,7 +36,7 @@ namespace {
static const char kVideoCaptureHtmlFile[] = "/media/video_capture_test.html";
static const char kStartVideoCaptureAndVerifySize[] =
- "startVideoCaptureAndVerifySize()";
+ "startVideoCaptureAndVerifySize(320, 200)";
static const char kWaitForVideoToTurnBlack[] = "waitForVideoToTurnBlack()";
static const char kVerifyHasReceivedTrackEndedEvent[] =
"verifyHasReceivedTrackEndedEvent()";
diff --git a/chromium/content/browser/webrtc/webrtc_video_capture_service_browsertest.cc b/chromium/content/browser/webrtc/webrtc_video_capture_service_browsertest.cc
index 032f909449b..337c91dd2d0 100644
--- a/chromium/content/browser/webrtc/webrtc_video_capture_service_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_video_capture_service_browsertest.cc
@@ -6,6 +6,7 @@
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
+#include "cc/base/math_util.h"
#include "components/viz/common/gpu/context_provider.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
@@ -55,13 +56,15 @@ class InvokeClosureOnDelete
};
static const char kVideoCaptureHtmlFile[] = "/media/video_capture_test.html";
-static const char kStartVideoCaptureAndVerifySize[] =
- "startVideoCaptureFromDeviceNamedVirtualDeviceAndVerifySize()";
+static const char kStartVideoCaptureAndVerify[] =
+ "startVideoCaptureFromVirtualDeviceAndVerifyUniformColorVideoWithSize(%d, "
+ "%d)";
static const char kVirtualDeviceId[] = "/virtual/device";
static const char kVirtualDeviceName[] = "Virtual Device";
-static const gfx::Size kDummyFrameDimensions(320, 200);
+static const gfx::Size kDummyFrameCodedSize(320, 200);
+static const gfx::Rect kDummyFrameVisibleRect(94, 36, 178, 150);
static const int kDummyFrameRate = 5;
} // namespace
@@ -76,6 +79,7 @@ class VirtualDeviceExerciser {
virtual void RegisterVirtualDeviceAtFactory(
video_capture::mojom::DeviceFactoryPtr* factory,
const media::VideoCaptureDeviceInfo& info) = 0;
+ virtual gfx::Size GetVideoSize() = 0;
virtual void PushNextFrame(base::TimeDelta timestamp) = 0;
virtual void ShutDown() = 0;
};
@@ -123,6 +127,8 @@ class TextureDeviceExerciser : public VirtualDeviceExerciser {
frame_being_consumed_[1] = false;
}
+ gfx::Size GetVideoSize() override { return kDummyFrameCodedSize; }
+
void PushNextFrame(base::TimeDelta timestamp) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (frame_being_consumed_[dummy_frame_index_]) {
@@ -145,9 +151,8 @@ class TextureDeviceExerciser : public VirtualDeviceExerciser {
media::mojom::VideoFrameInfoPtr info = media::mojom::VideoFrameInfo::New();
info->timestamp = timestamp;
info->pixel_format = media::PIXEL_FORMAT_ARGB;
- info->coded_size = kDummyFrameDimensions;
- info->visible_rect = gfx::Rect(kDummyFrameDimensions.width(),
- kDummyFrameDimensions.height());
+ info->coded_size = kDummyFrameCodedSize;
+ info->visible_rect = gfx::Rect(kDummyFrameCodedSize);
info->metadata = metadata.GetInternalValues().Clone();
frame_being_consumed_[dummy_frame_index_] = true;
@@ -169,8 +174,8 @@ class TextureDeviceExerciser : public VirtualDeviceExerciser {
uint8_t value_for_all_rgb_bytes,
std::vector<gpu::MailboxHolder>* target) {
const int32_t kBytesPerRGBPixel = 3;
- int32_t frame_size_in_bytes = kDummyFrameDimensions.width() *
- kDummyFrameDimensions.height() *
+ int32_t frame_size_in_bytes = kDummyFrameCodedSize.width() *
+ kDummyFrameCodedSize.height() *
kBytesPerRGBPixel;
std::unique_ptr<uint8_t[]> dummy_frame_data(
new uint8_t[frame_size_in_bytes]);
@@ -191,9 +196,9 @@ class TextureDeviceExerciser : public VirtualDeviceExerciser {
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kDummyFrameDimensions.width(),
- kDummyFrameDimensions.height(), 0, GL_RGB,
- GL_UNSIGNED_BYTE, dummy_frame_data.get());
+ gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kDummyFrameCodedSize.width(),
+ kDummyFrameCodedSize.height(), 0, GL_RGB, GL_UNSIGNED_BYTE,
+ dummy_frame_data.get());
gl->BindTexture(GL_TEXTURE_2D, 0);
gpu::Mailbox mailbox;
@@ -225,12 +230,15 @@ class TextureDeviceExerciser : public VirtualDeviceExerciser {
// A VirtualDeviceExerciser for exercising
// DeviceFactory.AddSharedMemoryVirtualDevice().
// It generates (dummy) I420 frame data by setting all bytes equal to the
-// current frame count.
+// current frame count. Padding bytes are set to 0.
class SharedMemoryDeviceExerciser : public VirtualDeviceExerciser,
public video_capture::mojom::Producer {
public:
- SharedMemoryDeviceExerciser()
- : producer_binding_(this), weak_factory_(this) {}
+ explicit SharedMemoryDeviceExerciser(
+ media::mojom::PlaneStridesPtr strides = nullptr)
+ : strides_(std::move(strides)),
+ producer_binding_(this),
+ weak_factory_(this) {}
// VirtualDeviceExerciser implementation.
void Initialize() override {}
@@ -245,9 +253,14 @@ class SharedMemoryDeviceExerciser : public VirtualDeviceExerciser,
kSendBufferHandlesToProducerAsRawFileDescriptors,
mojo::MakeRequest(&virtual_device_));
}
+ gfx::Size GetVideoSize() override {
+ return gfx::Size(kDummyFrameVisibleRect.width(),
+ kDummyFrameVisibleRect.height());
+ }
void PushNextFrame(base::TimeDelta timestamp) override {
virtual_device_->RequestFrameBuffer(
- kDummyFrameDimensions, media::VideoPixelFormat::PIXEL_FORMAT_I420,
+ kDummyFrameCodedSize, media::VideoPixelFormat::PIXEL_FORMAT_I420,
+ strides_.Clone(),
base::BindOnce(&SharedMemoryDeviceExerciser::OnFrameBufferReceived,
weak_factory_.GetWeakPtr(), timestamp));
}
@@ -287,22 +300,91 @@ class SharedMemoryDeviceExerciser : public VirtualDeviceExerciser,
media::mojom::VideoFrameInfoPtr info = media::mojom::VideoFrameInfo::New();
info->timestamp = timestamp;
info->pixel_format = media::PIXEL_FORMAT_I420;
- info->coded_size = kDummyFrameDimensions;
- info->visible_rect = gfx::Rect(kDummyFrameDimensions.width(),
- kDummyFrameDimensions.height());
+ info->coded_size = kDummyFrameCodedSize;
+ info->visible_rect = kDummyFrameVisibleRect;
info->metadata = metadata.GetInternalValues().Clone();
+ info->strides = strides_.Clone();
auto outgoing_buffer = outgoing_buffer_id_to_buffer_map_.at(buffer_id)
->GetHandleForInProcessAccess();
static int frame_count = 0;
frame_count++;
- memset(outgoing_buffer->data(), frame_count % 256,
- outgoing_buffer->mapped_size());
+ const uint8_t dummy_value = frame_count % 256;
+
+ // Reset the whole buffer to 0
+ memset(outgoing_buffer->data(), 0, outgoing_buffer->mapped_size());
+
+ // Set all bytes affecting |info->visible_rect| to |dummy_value|.
+ const int kYStride = info->strides ? info->strides->stride_by_plane[0]
+ : info->coded_size.width();
+ const int kYColsToSkipAtStart = info->visible_rect.x();
+ const int kYVisibleColCount = info->visible_rect.width();
+ const int kYCodedRowCount = info->coded_size.height();
+ const int kYRowsToSkipAtStart = info->visible_rect.y();
+ const int kYVisibleRowCount = info->visible_rect.height();
+
+ const int kUStride = info->strides ? info->strides->stride_by_plane[1]
+ : info->coded_size.width() / 2;
+ const int kUColsToSkipAtStart =
+ cc::MathUtil::UncheckedRoundDown(info->visible_rect.x(), 2) / 2;
+ const int kUVisibleColCount =
+ (cc::MathUtil::UncheckedRoundUp(info->visible_rect.right(), 2) / 2) -
+ kUColsToSkipAtStart;
+ const int kUCodedRowCount = info->coded_size.height() / 2;
+ const int kURowsToSkipAtStart =
+ cc::MathUtil::UncheckedRoundDown(info->visible_rect.y(), 2) / 2;
+ const int kUVisibleRowCount =
+ (cc::MathUtil::UncheckedRoundUp(info->visible_rect.bottom(), 2) / 2) -
+ kURowsToSkipAtStart;
+
+ const int kVStride = info->strides ? info->strides->stride_by_plane[2]
+ : info->coded_size.width() / 2;
+
+ uint8_t* write_ptr = outgoing_buffer->data();
+ FillVisiblePortionOfPlane(&write_ptr, dummy_value, kYCodedRowCount,
+ kYRowsToSkipAtStart, kYVisibleRowCount, kYStride,
+ kYColsToSkipAtStart, kYVisibleColCount);
+ FillVisiblePortionOfPlane(&write_ptr, dummy_value, kUCodedRowCount,
+ kURowsToSkipAtStart, kUVisibleRowCount, kUStride,
+ kUColsToSkipAtStart, kUVisibleColCount);
+ FillVisiblePortionOfPlane(&write_ptr, dummy_value, kUCodedRowCount,
+ kURowsToSkipAtStart, kUVisibleRowCount, kVStride,
+ kUColsToSkipAtStart, kUVisibleColCount);
virtual_device_->OnFrameReadyInBuffer(buffer_id, std::move(info));
}
+ void FillVisiblePortionOfPlane(uint8_t** write_ptr,
+ uint8_t fill_value,
+ int row_count,
+ int rows_to_skip_at_start,
+ int visible_row_count,
+ int col_count,
+ int cols_to_skip_at_start,
+ int visible_col_count) {
+ const int kColsToSkipAtEnd =
+ col_count - visible_col_count - cols_to_skip_at_start;
+ const int kRowsToSkipAtEnd =
+ row_count - visible_row_count - rows_to_skip_at_start;
+
+ // Skip rows at start
+ (*write_ptr) += col_count * rows_to_skip_at_start;
+ // Fill rows
+ for (int i = 0; i < visible_row_count; i++) {
+ // Skip cols at start
+ (*write_ptr) += cols_to_skip_at_start;
+ // Fill visible bytes
+ memset(*write_ptr, fill_value, visible_col_count);
+ (*write_ptr) += visible_col_count;
+ // Skip cols at end
+ (*write_ptr) += kColsToSkipAtEnd;
+ }
+ // Skip rows at end
+ (*write_ptr) += col_count * kRowsToSkipAtEnd;
+ }
+
+ media::mojom::PlaneStridesPtr strides_;
mojo::Binding<video_capture::mojom::Producer> producer_binding_;
video_capture::mojom::SharedMemoryVirtualDevicePtr virtual_device_;
std::map<int32_t /*buffer_id*/,
@@ -337,6 +419,7 @@ class WebRtcVideoCaptureServiceBrowserTest : public ContentBrowserTest {
info.descriptor.set_display_name(kVirtualDeviceName);
info.descriptor.capture_api = media::VideoCaptureApi::VIRTUAL_DEVICE;
+ video_size_ = device_exerciser->GetVideoSize();
device_exerciser->RegisterVirtualDeviceAtFactory(&factory_, info);
main_task_runner_->PostTask(
@@ -384,10 +467,12 @@ class WebRtcVideoCaptureServiceBrowserTest : public ContentBrowserTest {
GURL url(embedded_test_server()->GetURL(kVideoCaptureHtmlFile));
NavigateToURL(shell(), url);
+ std::string javascript_to_execute = base::StringPrintf(
+ kStartVideoCaptureAndVerify, video_size_.width(), video_size_.height());
std::string result;
// Start video capture and wait until it started rendering
- ASSERT_TRUE(ExecuteScriptAndExtractString(
- shell(), kStartVideoCaptureAndVerifySize, &result));
+ ASSERT_TRUE(
+ ExecuteScriptAndExtractString(shell(), javascript_to_execute, &result));
ASSERT_EQ("OK", result);
std::move(finish_test_cb).Run();
@@ -433,6 +518,7 @@ class WebRtcVideoCaptureServiceBrowserTest : public ContentBrowserTest {
base::test::ScopedFeatureList scoped_feature_list_;
video_capture::mojom::DeviceFactoryProviderPtr provider_;
video_capture::mojom::DeviceFactoryPtr factory_;
+ gfx::Size video_size_;
base::TimeTicks first_frame_time_;
base::WeakPtrFactory<WebRtcVideoCaptureServiceBrowserTest> weak_factory_;
@@ -473,6 +559,25 @@ IN_PROC_BROWSER_TEST_F(
run_loop.Run();
}
+IN_PROC_BROWSER_TEST_F(
+ WebRtcVideoCaptureServiceBrowserTest,
+ PaddedI420FramesSentThroughSharedMemoryVirtualDeviceGetDisplayedOnPage) {
+ Initialize();
+ auto device_exerciser = std::make_unique<SharedMemoryDeviceExerciser>(
+ media::mojom::PlaneStrides::New(
+ std::vector<uint32_t>({1024u, 512u, 1024u, 0u})));
+ device_exerciser->Initialize();
+
+ base::RunLoop run_loop;
+ virtual_device_thread_.task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&WebRtcVideoCaptureServiceBrowserTest::
+ AddVirtualDeviceAndStartCapture,
+ base::Unretained(this), device_exerciser.get(),
+ media::BindToCurrentLoop(run_loop.QuitClosure())));
+ run_loop.Run();
+}
+
} // namespace content
#endif // defined(CAN_USE_IMAGE_TRANSPORT_FACTORY)
diff --git a/chromium/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc b/chromium/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc
new file mode 100644
index 00000000000..c3957b2a9f8
--- /dev/null
+++ b/chromium/content/browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc
@@ -0,0 +1,160 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "base/test/scoped_feature_list.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/service_manager_connection.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "media/base/media_switches.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/video_capture/public/mojom/constants.mojom.h"
+#include "services/video_capture/public/mojom/device_factory_provider.mojom.h"
+
+namespace content {
+
+namespace {
+
+static const char kVideoCaptureHtmlFile[] = "/media/video_capture_test.html";
+static const std::string kEnumerateVideoCaptureDevicesAndVerify =
+ "enumerateVideoCaptureDevicesAndVerifyCount";
+
+} // anonymous namespace
+
+// Integration test that obtains a connection to the video capture service via
+// the Browser process' service manager. It then registers and unregisters
+// virtual devices at the service and checks in JavaScript that the list of
+// enumerated devices changes correspondingly.
+class WebRtcVideoCaptureServiceEnumerationBrowserTest
+ : public ContentBrowserTest {
+ public:
+ WebRtcVideoCaptureServiceEnumerationBrowserTest() {
+ scoped_feature_list_.InitAndEnableFeature(features::kMojoVideoCapture);
+ }
+
+ ~WebRtcVideoCaptureServiceEnumerationBrowserTest() override {}
+
+ void ConnectToService() {
+ connector_->BindInterface(video_capture::mojom::kServiceName, &provider_);
+ provider_->ConnectToDeviceFactory(mojo::MakeRequest(&factory_));
+ }
+
+ void AddVirtualDevice(const std::string& device_id) {
+ media::VideoCaptureDeviceInfo info;
+ info.descriptor.device_id = device_id;
+ info.descriptor.set_display_name(device_id);
+ info.descriptor.capture_api = media::VideoCaptureApi::VIRTUAL_DEVICE;
+
+ video_capture::mojom::TextureVirtualDevicePtr virtual_device;
+ factory_->AddTextureVirtualDevice(info, mojo::MakeRequest(&virtual_device));
+ virtual_devices_by_id_.insert(
+ std::make_pair(device_id, std::move(virtual_device)));
+ }
+
+ void RemoveVirtualDevice(const std::string& device_id) {
+ virtual_devices_by_id_.erase(device_id);
+ }
+
+ void DisconnectFromService() {
+ factory_ = nullptr;
+ provider_ = nullptr;
+ }
+
+ void EnumerateDevicesInRendererAndVerifyDeviceCount(
+ int expected_device_count) {
+ NavigateToURL(shell(),
+ GURL(embedded_test_server()->GetURL(kVideoCaptureHtmlFile)));
+
+ const std::string javascript_to_execute = base::StringPrintf(
+ (kEnumerateVideoCaptureDevicesAndVerify + "(%d)").c_str(),
+ expected_device_count);
+ std::string result;
+ ASSERT_TRUE(
+ ExecuteScriptAndExtractString(shell(), javascript_to_execute, &result));
+ ASSERT_EQ("OK", result);
+ }
+
+ protected:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ // Note: We are not planning to actually use any fake device, but we want
+ // to avoid enumerating or otherwise calling into real capture devices.
+ command_line->AppendSwitchASCII(switches::kUseFakeDeviceForMediaStream,
+ "device-count=0");
+ command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
+ }
+
+ void Initialize() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
+ embedded_test_server()->StartAcceptingConnections();
+
+ auto* connection = content::ServiceManagerConnection::GetForProcess();
+ ASSERT_TRUE(connection);
+ auto* connector = connection->GetConnector();
+ ASSERT_TRUE(connector);
+ connector_ = connector->Clone();
+ }
+
+ std::unique_ptr<service_manager::Connector> connector_;
+ std::map<std::string, video_capture::mojom::TextureVirtualDevicePtr>
+ virtual_devices_by_id_;
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+ video_capture::mojom::DeviceFactoryProviderPtr provider_;
+ video_capture::mojom::DeviceFactoryPtr factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcVideoCaptureServiceEnumerationBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(WebRtcVideoCaptureServiceEnumerationBrowserTest,
+ SingleAddedVirtualDeviceGetsEnumerated) {
+ Initialize();
+ ConnectToService();
+
+ // Exercise
+ // TODO(chfremer): It is probably not guaranteed that the Mojo IPC call to
+ // AddVirtualDevice arrives at the service before the request to enumerate
+ // devices triggered by JavaScript. To guarantee this, we would have to add
+ // a done-callback to AddVirtualDevice() and wait for that to arrive before
+ // doing the enumeration.
+ AddVirtualDevice("test");
+ EnumerateDevicesInRendererAndVerifyDeviceCount(1);
+
+ // Tear down
+ RemoveVirtualDevice("test");
+ DisconnectFromService();
+}
+
+IN_PROC_BROWSER_TEST_F(WebRtcVideoCaptureServiceEnumerationBrowserTest,
+ RemoveVirtualDeviceAfterItHasBeenEnumerated) {
+ // TODO(chfremer): Remove this when https://crbug.com/876892 is resolved.
+ if (base::FeatureList::IsEnabled(features::kMediaDevicesSystemMonitorCache)) {
+ LOG(WARNING) << "Skipping test, because feature not yet supported when "
+ "device monitoring is enabled.";
+ return;
+ }
+ Initialize();
+ ConnectToService();
+
+ AddVirtualDevice("test_1");
+ AddVirtualDevice("test_2");
+ EnumerateDevicesInRendererAndVerifyDeviceCount(2);
+ RemoveVirtualDevice("test_1");
+ EnumerateDevicesInRendererAndVerifyDeviceCount(1);
+ RemoveVirtualDevice("test_2");
+ EnumerateDevicesInRendererAndVerifyDeviceCount(0);
+
+ // Tear down
+ DisconnectFromService();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/webrtc/webrtc_webcam_browsertest.cc b/chromium/content/browser/webrtc/webrtc_webcam_browsertest.cc
index 867d6dd33cb..353cc98189d 100644
--- a/chromium/content/browser/webrtc/webrtc_webcam_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_webcam_browsertest.cc
@@ -5,6 +5,7 @@
#include "content/browser/webrtc/webrtc_webcam_browsertest.h"
#include "base/command_line.h"
+#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -32,9 +33,7 @@ bool IsUseFakeDeviceForMediaStream(const base::CommandLine::StringType& arg) {
void RemoveFakeDeviceFromCommandLine(base::CommandLine* command_line) {
base::CommandLine::StringVector argv = command_line->argv();
- argv.erase(std::remove_if(argv.begin(), argv.end(),
- IsUseFakeDeviceForMediaStream),
- argv.end());
+ base::EraseIf(argv, IsUseFakeDeviceForMediaStream);
command_line->InitFromArgv(argv);
}
diff --git a/chromium/content/browser/websockets/websocket_manager.cc b/chromium/content/browser/websockets/websocket_manager.cc
index 13db9a3a2df..3f51142864c 100644
--- a/chromium/content/browser/websockets/websocket_manager.cc
+++ b/chromium/content/browser/websockets/websocket_manager.cc
@@ -14,11 +14,13 @@
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/numerics/safe_conversions.h"
+#include "base/task/post_task.h"
#include "content/browser/bad_message.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/ssl/ssl_error_handler.h"
#include "content/browser/ssl/ssl_manager.h"
#include "content/browser/websockets/websocket_handshake_request_info_impl.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@@ -194,8 +196,8 @@ void WebSocketManager::CreateWebSocket(
DCHECK(handle->manager());
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&WebSocketManager::DoCreateWebSocket,
base::Unretained(handle->manager()), frame_id,
std::move(origin), std::move(request)));
@@ -210,8 +212,8 @@ WebSocketManager::WebSocketManager(int process_id,
// This unretained pointer is safe because we destruct a WebSocketManager
// only via WebSocketManager::Handle::RenderProcessHostDestroyed which
// posts a deletion task to the IO thread.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&WebSocketManager::ObserveURLRequestContextGetter,
base::Unretained(this)));
}
diff --git a/chromium/content/browser/webui/shared_resources_data_source.cc b/chromium/content/browser/webui/shared_resources_data_source.cc
index b00558bd012..0e81e4c6244 100644
--- a/chromium/content/browser/webui/shared_resources_data_source.cc
+++ b/chromium/content/browser/webui/shared_resources_data_source.cc
@@ -13,7 +13,9 @@
#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
+#include "base/task/post_task.h"
#include "build/build_config.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
@@ -25,6 +27,11 @@
#include "ui/resources/grit/webui_resources.h"
#include "ui/resources/grit/webui_resources_map.h"
+#if defined(OS_CHROMEOS)
+#include "chromeos/grit/chromeos_resources.h"
+#include "chromeos/grit/chromeos_resources_map.h"
+#endif
+
#if defined(OS_WIN)
#include "base/strings/utf_string_conversions.h"
#endif
@@ -39,7 +46,7 @@ struct IdrGzipped {
};
using ResourcesMap = base::hash_map<std::string, IdrGzipped>;
-const std::map<std::string, std::string> CreateAliasesMap() {
+const std::map<std::string, std::string> CreatePathPrefixAliasesMap() {
// TODO(rkc): Once we have a separate source for apps, remove '*/apps/'
// aliases.
std::map<std::string, std::string> aliases = {
@@ -62,6 +69,28 @@ const std::map<std::string, std::string> CreateAliasesMap() {
return aliases;
}
+const std::map<int, std::string> CreateMojoResourceIdToAliasMap() {
+ return std::map<int, std::string> {
+ {IDR_MOJO_MOJO_BINDINGS_JS, "js/mojo_bindings.js"},
+#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
+ {IDR_MOJO_TIME_MOJOM_JS, "js/time.mojom.js"},
+#endif // defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
+ };
+}
+
+#if defined(OS_CHROMEOS)
+const std::map<int, std::string> CreateChromeosMojoResourceIdToAliasMap() {
+ return std::map<int, std::string>{
+ {IDR_MULTIDEVICE_DEVICE_SYNC_MOJOM_JS,
+ "js/chromeos/device_sync.mojom.js"},
+ {IDR_MULTIDEVICE_MULTIDEVICE_SETUP_MOJOM_JS,
+ "js/chromeos/multidevice_setup.mojom.js"},
+ {IDR_MULTIDEVICE_MULTIDEVICE_SETUP_CONSTANTS_MOJOM_JS,
+ "js/chromeos/multidevice_setup_constants.mojom.js"},
+ };
+}
+#endif // !defined(OS_CHROMEOS)
+
#if !defined(OS_ANDROID)
bool ShouldIgnore(std::string resource) {
if (base::FeatureList::IsEnabled(features::kWebUIPolymer2) &&
@@ -93,10 +122,10 @@ void AddResource(const std::string& path,
NOTREACHED() << "Redefinition of '" << path << "'";
}
-const ResourcesMap* CreateResourcesMap() {
- std::map<std::string, std::string> aliases = CreateAliasesMap();
+void AddResourcesToMap(ResourcesMap* resources_map) {
+ const std::map<std::string, std::string> aliases =
+ CreatePathPrefixAliasesMap();
- ResourcesMap* result = new ResourcesMap();
for (size_t i = 0; i < kWebuiResourcesSize; ++i) {
const auto& resource = kWebuiResources[i];
@@ -105,25 +134,48 @@ const ResourcesMap* CreateResourcesMap() {
continue;
#endif // !defined(OS_ANDROID)
- AddResource(resource.name, resource.value, resource.gzipped, result);
+ AddResource(resource.name, resource.value, resource.gzipped, resources_map);
for (auto it = aliases.begin(); it != aliases.end(); ++it) {
if (base::StartsWith(resource.name, it->first,
base::CompareCase::SENSITIVE)) {
std::string resource_name(resource.name);
AddResource(it->second + resource_name.substr(it->first.length()),
- resource.value, resource.gzipped, result);
+ resource.value, resource.gzipped, resources_map);
}
}
}
- for (size_t i = 0; i < kMojoBindingsResourcesSize; ++i) {
- const auto& resource = kMojoBindingsResources[i];
- if (resource.value == IDR_MOJO_BINDINGS_JS) {
- AddResource("js/mojo_bindings.js", resource.value, resource.gzipped,
- result);
- break;
- }
+}
+
+// Adds |resources| to |resources_map|, but renames each resource according to
+// the scheme in |resource_aliases|, which maps from resource ID to resource
+// alias. Note that resources which do not have an alias will not be added.
+void AddAliasedResourcesToMap(
+ const std::map<int, std::string>& resource_aliases,
+ const GzippedGritResourceMap resources[],
+ size_t resources_size,
+ ResourcesMap* resources_map) {
+ for (size_t i = 0; i < resources_size; ++i) {
+ const auto& resource = resources[i];
+
+ const auto it = resource_aliases.find(resource.value);
+ if (it == resource_aliases.end())
+ continue;
+
+ AddResource(it->second, resource.value, resource.gzipped, resources_map);
}
+}
+
+const ResourcesMap* CreateResourcesMap() {
+ ResourcesMap* result = new ResourcesMap();
+ AddResourcesToMap(result);
+ AddAliasedResourcesToMap(CreateMojoResourceIdToAliasMap(),
+ kMojoBindingsResources, kMojoBindingsResourcesSize,
+ result);
+#if defined(OS_CHROMEOS)
+ AddAliasedResourcesToMap(CreateChromeosMojoResourceIdToAliasMap(),
+ kChromeosResources, kChromeosResourcesSize, result);
+#endif // !defined(OS_CHROMEOS)
return result;
}
@@ -227,7 +279,7 @@ SharedResourcesDataSource::TaskRunnerForRequestPath(
idr == IDR_WEBUI_CSS_TEXT_DEFAULTS_MD) {
// Use UI thread to load CSS since its construction touches non-thread-safe
// gfx::Font names in ui::ResourceBundle.
- return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
+ return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
}
return nullptr;
diff --git a/chromium/content/browser/webui/url_data_manager.cc b/chromium/content/browser/webui/url_data_manager.cc
index fca1d4aa616..a9f5cfc95d4 100644
--- a/chromium/content/browser/webui/url_data_manager.cc
+++ b/chromium/content/browser/webui/url_data_manager.cc
@@ -15,11 +15,14 @@
#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_util.h"
#include "base/synchronization/lock.h"
+#include "base/task/post_task.h"
+#include "base/thread_annotations.h"
#include "content/browser/resource_context_impl.h"
#include "content/browser/webui/url_data_manager_backend.h"
#include "content/browser/webui/url_data_source_impl.h"
#include "content/browser/webui/web_ui_data_source_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/url_data_source.h"
@@ -59,7 +62,8 @@ static void UpdateWebUIDataSourceOnIOThread(
} // namespace
// static
-URLDataManager::URLDataSources* URLDataManager::data_sources_ = nullptr;
+URLDataManager::URLDataSources* URLDataManager::data_sources_ PT_GUARDED_BY(
+ g_delete_lock.Get()) = nullptr;
URLDataManager::URLDataManager(BrowserContext* browser_context)
: browser_context_(browser_context) {
@@ -70,18 +74,19 @@ URLDataManager::~URLDataManager() {
void URLDataManager::AddDataSource(URLDataSourceImpl* source) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&AddDataSourceOnIOThread,
- browser_context_->GetResourceContext(),
- base::WrapRefCounted(source)));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
+ base::BindOnce(&AddDataSourceOnIOThread,
+ browser_context_->GetResourceContext(),
+ base::WrapRefCounted(source)));
}
void URLDataManager::UpdateWebUIDataSource(
const std::string& source_name,
std::unique_ptr<base::DictionaryValue> update) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&UpdateWebUIDataSourceOnIOThread,
browser_context_->GetResourceContext(), source_name,
base::Owned(update.release())));
@@ -122,8 +127,9 @@ void URLDataManager::DeleteDataSource(const URLDataSourceImpl* data_source) {
}
if (schedule_delete) {
// Schedule a task to delete the DataSource back on the UI thread.
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&URLDataManager::DeleteDataSources));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(&URLDataManager::DeleteDataSources));
}
}
diff --git a/chromium/content/browser/webui/url_data_manager_backend.cc b/chromium/content/browser/webui/url_data_manager_backend.cc
index 9a2cb49cf5a..9df29806e05 100644
--- a/chromium/content/browser/webui/url_data_manager_backend.cc
+++ b/chromium/content/browser/webui/url_data_manager_backend.cc
@@ -28,6 +28,7 @@
#include "content/browser/webui/url_data_source_impl.h"
#include "content/browser/webui/web_ui_data_source_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_process_host.h"
@@ -195,8 +196,8 @@ void URLRequestChromeJob::Start() {
// TODO(caseq): Fix the race condition and remove this thread hop in
// https://crbug.com/616641.
if (url.SchemeIs(kChromeDevToolsScheme)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
base::BindOnce(&URLRequestChromeJob::DelayStartForDevTools,
weak_factory_.GetWeakPtr()));
return;
@@ -338,8 +339,8 @@ int URLRequestChromeJob::PostReadTask(scoped_refptr<net::IOBuffer> buf,
void URLRequestChromeJob::DelayStartForDevTools(
const base::WeakPtr<URLRequestChromeJob>& job) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&URLRequestChromeJob::StartAsync, job));
}
@@ -444,7 +445,7 @@ void URLDataManagerBackend::AddDataSource(
URLDataSourceImpl* source) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!source->source()->ShouldReplaceExistingSource()) {
- DataSourceMap::iterator i = data_sources_.find(source->source_name());
+ auto i = data_sources_.find(source->source_name());
if (i != data_sources_.end())
return;
}
@@ -455,7 +456,7 @@ void URLDataManagerBackend::AddDataSource(
void URLDataManagerBackend::UpdateWebUIDataSource(
const std::string& source_name,
const base::DictionaryValue& update) {
- DataSourceMap::iterator it = data_sources_.find(source_name);
+ auto it = data_sources_.find(source_name);
if (it == data_sources_.end() || !it->second->IsWebUIDataSourceImpl()) {
NOTREACHED();
return;
@@ -466,8 +467,7 @@ void URLDataManagerBackend::UpdateWebUIDataSource(
bool URLDataManagerBackend::HasPendingJob(
URLRequestChromeJob* job) const {
- for (PendingRequestMap::const_iterator i = pending_requests_.begin();
- i != pending_requests_.end(); ++i) {
+ for (auto i = pending_requests_.begin(); i != pending_requests_.end(); ++i) {
if (i->second == job)
return true;
}
@@ -539,7 +539,7 @@ URLDataSourceImpl* URLDataManagerBackend::GetDataSourceFromURL(
const GURL& url) {
// The input usually looks like: chrome://source_name/extra_bits?foo
// so do a lookup using the host of the URL.
- DataSourceMap::iterator i = data_sources_.find(url.host());
+ auto i = data_sources_.find(url.host());
if (i != data_sources_.end())
return i->second.get();
@@ -568,8 +568,7 @@ void URLDataManagerBackend::RemoveRequest(URLRequestChromeJob* job) {
// Remove the request from our list of pending requests.
// If/when the source sends the data that was requested, the data will just
// be thrown away.
- for (PendingRequestMap::iterator i = pending_requests_.begin();
- i != pending_requests_.end(); ++i) {
+ for (auto i = pending_requests_.begin(); i != pending_requests_.end(); ++i) {
if (i->second == job) {
pending_requests_.erase(i);
return;
@@ -580,7 +579,7 @@ void URLDataManagerBackend::RemoveRequest(URLRequestChromeJob* job) {
void URLDataManagerBackend::DataAvailable(RequestID request_id,
base::RefCountedMemory* bytes) {
// Forward this data on to the pending net::URLRequest, if it exists.
- PendingRequestMap::iterator i = pending_requests_.find(request_id);
+ auto i = pending_requests_.find(request_id);
if (i != pending_requests_.end()) {
URLRequestChromeJob* job = i->second;
pending_requests_.erase(i);
diff --git a/chromium/content/browser/webui/url_data_source_impl.cc b/chromium/content/browser/webui/url_data_source_impl.cc
index 1a38e0b9c1d..13953766bf6 100644
--- a/chromium/content/browser/webui/url_data_source_impl.cc
+++ b/chromium/content/browser/webui/url_data_source_impl.cc
@@ -9,7 +9,9 @@
#include "base/bind.h"
#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_util.h"
+#include "base/task/post_task.h"
#include "content/browser/webui/url_data_manager_backend.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/url_data_source.h"
@@ -39,8 +41,8 @@ void URLDataSourceImpl::SendResponse(
// when the object is deleted.
return;
}
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&URLDataSourceImpl::SendResponseOnIOThread, this,
request_id, std::move(bytes)));
}
diff --git a/chromium/content/browser/webui/web_ui_message_handler_unittest.cc b/chromium/content/browser/webui/web_ui_message_handler_unittest.cc
index e940e5c9395..ba1bb02755b 100644
--- a/chromium/content/browser/webui/web_ui_message_handler_unittest.cc
+++ b/chromium/content/browser/webui/web_ui_message_handler_unittest.cc
@@ -14,10 +14,13 @@ namespace content {
TEST(WebUIMessageHandlerTest, ExtractIntegerValue) {
base::ListValue list;
- int value, zero_value = 0, neg_value = -1234, pos_value = 1234;
- base::string16 zero_string(base::UTF8ToUTF16("0"));
- base::string16 neg_string(base::UTF8ToUTF16("-1234"));
- base::string16 pos_string(base::UTF8ToUTF16("1234"));
+ int value;
+ constexpr int zero_value = 0;
+ constexpr int neg_value = -1234;
+ constexpr int pos_value = 1234;
+ static const char zero_string[] = "0";
+ static const char neg_string[] = "-1234";
+ static const char pos_string[] = "1234";
list.AppendInteger(zero_value);
EXPECT_TRUE(WebUIMessageHandler::ExtractIntegerValue(&list, &value));
@@ -51,10 +54,13 @@ TEST(WebUIMessageHandlerTest, ExtractIntegerValue) {
TEST(WebUIMessageHandlerTest, ExtractDoubleValue) {
base::ListValue list;
- double value, zero_value = 0.0, neg_value = -1234.5, pos_value = 1234.5;
- base::string16 zero_string(base::UTF8ToUTF16("0"));
- base::string16 neg_string(base::UTF8ToUTF16("-1234.5"));
- base::string16 pos_string(base::UTF8ToUTF16("1234.5"));
+ double value;
+ constexpr double zero_value = 0.0;
+ constexpr double neg_value = -1234.5;
+ constexpr double pos_value = 1234.5;
+ static const char zero_string[] = "0";
+ static const char neg_string[] = "-1234.5";
+ static const char pos_string[] = "1234.5";
list.AppendDouble(zero_value);
EXPECT_TRUE(WebUIMessageHandler::ExtractDoubleValue(&list, &value));
@@ -88,19 +94,16 @@ TEST(WebUIMessageHandlerTest, ExtractDoubleValue) {
TEST(WebUIMessageHandlerTest, ExtractStringValue) {
base::ListValue list;
- base::string16 in_string(base::UTF8ToUTF16(
- "The facts, though interesting, are irrelevant."));
+ static const char in_string[] =
+ "The facts, though interesting, are irrelevant.";
list.AppendString(in_string);
base::string16 out_string = WebUIMessageHandler::ExtractStringValue(&list);
- EXPECT_EQ(in_string, out_string);
+ EXPECT_EQ(base::ASCIIToUTF16(in_string), out_string);
}
class TestWebUIMessageHandler : public WebUIMessageHandler {
public:
- TestWebUIMessageHandler()
- : on_javascript_allowed_calls_(0), on_javascript_disallowed_calls_(0) {
- set_web_ui(&test_web_ui_);
- }
+ TestWebUIMessageHandler() { set_web_ui(&test_web_ui_); }
~TestWebUIMessageHandler() override {
// The test handler unusually owns its own TestWebUI, so we make sure to
@@ -121,8 +124,8 @@ class TestWebUIMessageHandler : public WebUIMessageHandler {
void OnJavascriptAllowed() override { ++on_javascript_allowed_calls_; }
void OnJavascriptDisallowed() override { ++on_javascript_disallowed_calls_; }
- int on_javascript_allowed_calls_;
- int on_javascript_disallowed_calls_;
+ int on_javascript_allowed_calls_ = 0;
+ int on_javascript_disallowed_calls_ = 0;
};
TEST(WebUIMessageHandlerTest, AllowAndDisallowJavascript) {
diff --git a/chromium/content/browser/webui/web_ui_mojo_browsertest.cc b/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
index 3f4031598fa..0425adabad2 100644
--- a/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
+++ b/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -110,10 +110,23 @@ class TestWebUIController : public WebUIController {
int bindings = BINDINGS_POLICY_MOJO_WEB_UI)
: WebUIController(web_ui), run_loop_(run_loop) {
web_ui->SetBindings(bindings);
- WebUIDataSource* data_source = WebUIDataSource::Create("mojo-web-ui");
- data_source->SetRequestFilter(base::Bind(&GetResource));
- WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
- data_source);
+ {
+ WebUIDataSource* data_source = WebUIDataSource::Create("mojo-web-ui");
+ data_source->SetRequestFilter(base::BindRepeating(&GetResource));
+ WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
+ data_source);
+ }
+ {
+ WebUIDataSource* data_source = WebUIDataSource::Create("dummy-web-ui");
+ data_source->SetRequestFilter(base::BindRepeating(
+ [](const std::string& id,
+ const WebUIDataSource::GotDataCallback& callback) {
+ callback.Run(new base::RefCountedString);
+ return true;
+ }));
+ WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
+ data_source);
+ }
}
protected:
@@ -246,9 +259,9 @@ class WebUIMojoTest : public ContentBrowserTest {
TestWebUIControllerFactory* factory() { return &factory_; }
void NavigateWithNewWebUI(const std::string& path) {
- // Load an invalid URL first so that a new WebUI is set up when we load
+ // Load a dummy WebUI URL first so that a new WebUI is set up when we load
// the URL we're actually interested in.
- EXPECT_FALSE(NavigateToURL(shell(), GURL()));
+ EXPECT_TRUE(NavigateToURL(shell(), GURL("chrome://dummy-web-ui")));
constexpr char kChromeUIMojoWebUIOrigin[] = "chrome://mojo-web-ui/";
EXPECT_TRUE(NavigateToURL(shell(), GURL(kChromeUIMojoWebUIOrigin + path)));
diff --git a/chromium/content/browser/webui/web_ui_url_loader_factory.cc b/chromium/content/browser/webui/web_ui_url_loader_factory.cc
index a0e39809838..63fe0125ca1 100644
--- a/chromium/content/browser/webui/web_ui_url_loader_factory.cc
+++ b/chromium/content/browser/webui/web_ui_url_loader_factory.cc
@@ -24,6 +24,7 @@
#include "content/browser/webui/url_data_manager_backend.h"
#include "content/browser/webui/url_data_source_impl.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
@@ -270,8 +271,8 @@ class WebUIURLLoaderFactory : public network::mojom::URLLoaderFactory,
}
if (request.url.host_piece() == kChromeUIBlobInternalsHost) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&StartBlobInternalsURLLoader, request,
client.PassInterface(),
base::Unretained(ChromeBlobStorageContext::GetFor(
@@ -289,8 +290,8 @@ class WebUIURLLoaderFactory : public network::mojom::URLLoaderFactory,
// from frames can happen while the RFH is changed for a cross-process
// navigation. The URLDataSources just need the WebContents; the specific
// frame doesn't matter.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(
&StartURLLoader, request, render_frame_host_->GetFrameTreeNodeId(),
client.PassInterface(),
diff --git a/chromium/content/child/BUILD.gn b/chromium/content/child/BUILD.gn
index 018a0053ef9..ac7667c09cf 100644
--- a/chromium/content/child/BUILD.gn
+++ b/chromium/content/child/BUILD.gn
@@ -110,7 +110,7 @@ target(link_target_type, "child") {
"//services/device/public/cpp:device_features",
"//services/device/public/cpp/power_monitor",
"//services/device/public/mojom:constants",
- "//services/resource_coordinator/public/cpp:resource_coordinator_cpp",
+ "//services/resource_coordinator/public/cpp/memory_instrumentation",
"//services/service_manager/public/cpp",
"//services/service_manager/public/mojom",
"//services/service_manager/runner/common",
@@ -126,6 +126,7 @@ target(link_target_type, "child") {
"//third_party/ced",
"//third_party/zlib/google:compression_utils",
"//ui/base",
+ "//ui/events/blink",
"//ui/events/gestures/blink",
"//ui/gfx",
"//ui/gfx/geometry",
diff --git a/chromium/content/child/blink_platform_impl.cc b/chromium/content/child/blink_platform_impl.cc
index 50fedfa4c46..1f0bfd3cc8f 100644
--- a/chromium/content/child/blink_platform_impl.cc
+++ b/chromium/content/child/blink_platform_impl.cc
@@ -23,10 +23,7 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
-#include "base/synchronization/waitable_event.h"
#include "base/sys_info.h"
-#include "base/threading/platform_thread.h"
-#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/memory_allocator_dump_guid.h"
@@ -129,40 +126,16 @@ static int ToMessageID(WebLocalizedString::Name name) {
return IDS_AX_MEDIA_AUDIO_ELEMENT_HELP;
case WebLocalizedString::kAXMediaVideoElementHelp:
return IDS_AX_MEDIA_VIDEO_ELEMENT_HELP;
- case WebLocalizedString::kAXMediaMuteButtonHelp:
- return IDS_AX_MEDIA_MUTE_BUTTON_HELP;
- case WebLocalizedString::kAXMediaUnMuteButtonHelp:
- return IDS_AX_MEDIA_UNMUTE_BUTTON_HELP;
- case WebLocalizedString::kAXMediaPlayButtonHelp:
- return IDS_AX_MEDIA_PLAY_BUTTON_HELP;
- case WebLocalizedString::kAXMediaPauseButtonHelp:
- return IDS_AX_MEDIA_PAUSE_BUTTON_HELP;
case WebLocalizedString::kAXMediaAudioSliderHelp:
return IDS_AX_MEDIA_AUDIO_SLIDER_HELP;
case WebLocalizedString::kAXMediaVideoSliderHelp:
return IDS_AX_MEDIA_VIDEO_SLIDER_HELP;
+ case WebLocalizedString::kAXMediaVolumeSliderHelp:
+ return IDS_AX_MEDIA_VOLUME_SLIDER_HELP;
case WebLocalizedString::kAXMediaCurrentTimeDisplayHelp:
return IDS_AX_MEDIA_CURRENT_TIME_DISPLAY_HELP;
case WebLocalizedString::kAXMediaTimeRemainingDisplayHelp:
return IDS_AX_MEDIA_TIME_REMAINING_DISPLAY_HELP;
- case WebLocalizedString::kAXMediaEnterFullscreenButtonHelp:
- return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON_HELP;
- case WebLocalizedString::kAXMediaExitFullscreenButtonHelp:
- return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON_HELP;
- case WebLocalizedString::kAXMediaDisplayCutoutFullscreenButtonHelp:
- return IDS_AX_MEDIA_DISPLAY_CUT_OUT_FULL_SCREEN_BUTTON_HELP;
- case WebLocalizedString::kAXMediaEnterPictureInPictureButtonHelp:
- return IDS_AX_MEDIA_ENTER_PICTURE_IN_PICTURE_BUTTON_HELP;
- case WebLocalizedString::kAXMediaExitPictureInPictureButtonHelp:
- return IDS_AX_MEDIA_EXIT_PICTURE_IN_PICTURE_BUTTON_HELP;
- case WebLocalizedString::kAXMediaShowClosedCaptionsButtonHelp:
- return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP;
- case WebLocalizedString::kAXMediaHideClosedCaptionsButtonHelp:
- return IDS_AX_MEDIA_HIDE_CLOSED_CAPTIONS_BUTTON_HELP;
- case WebLocalizedString::kAXMediaCastOffButtonHelp:
- return IDS_AX_MEDIA_CAST_OFF_BUTTON_HELP;
- case WebLocalizedString::kAXMediaCastOnButtonHelp:
- return IDS_AX_MEDIA_CAST_ON_BUTTON_HELP;
case WebLocalizedString::kAXMediaOverflowButtonHelp:
return IDS_AX_MEDIA_OVERFLOW_BUTTON_HELP;
case WebLocalizedString::kAXMillisecondFieldText:
@@ -359,55 +332,9 @@ BlinkPlatformImpl::BlinkPlatformImpl(
: main_thread_task_runner_(std::move(main_thread_task_runner)),
io_thread_task_runner_(std::move(io_thread_task_runner)) {}
-void BlinkPlatformImpl::WaitUntilWebThreadTLSUpdate(
- blink::scheduler::WebThreadBase* thread) {
- base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- thread->GetTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&BlinkPlatformImpl::UpdateWebThreadTLS,
- base::Unretained(this), base::Unretained(thread),
- base::Unretained(&event)));
- event.Wait();
-}
-
-void BlinkPlatformImpl::UpdateWebThreadTLS(blink::WebThread* thread,
- base::WaitableEvent* event) {
- DCHECK(!current_thread_slot_.Get());
- current_thread_slot_.Set(thread);
- event->Signal();
-}
-
BlinkPlatformImpl::~BlinkPlatformImpl() {
}
-std::unique_ptr<blink::WebThread> BlinkPlatformImpl::CreateThread(
- const blink::WebThreadCreationParams& params) {
- std::unique_ptr<blink::scheduler::WebThreadBase> thread =
- blink::scheduler::WebThreadBase::CreateWorkerThread(params);
- thread->Init();
- WaitUntilWebThreadTLSUpdate(thread.get());
- return std::move(thread);
-}
-
-std::unique_ptr<blink::WebThread> BlinkPlatformImpl::CreateWebAudioThread() {
- blink::WebThreadCreationParams params(blink::WebThreadType::kWebAudioThread);
- // WebAudio uses a thread with |DISPLAY| priority to avoid glitch when the
- // system is under the high pressure. Note that the main browser thread also
- // runs with same priority. (see: crbug.com/734539)
- params.thread_options.priority = base::ThreadPriority::DISPLAY;
-
- std::unique_ptr<blink::scheduler::WebThreadBase> thread =
- blink::scheduler::WebThreadBase::CreateWorkerThread(params);
- thread->Init();
- WaitUntilWebThreadTLSUpdate(thread.get());
- return std::move(thread);
-}
-
-blink::WebThread* BlinkPlatformImpl::CurrentThread() {
- return static_cast<blink::WebThread*>(current_thread_slot_.Get());
-}
-
void BlinkPlatformImpl::RecordAction(const blink::UserMetricsAction& name) {
if (ChildThread* child_thread = ChildThread::Get())
child_thread->RecordComputedAction(name.Action());
@@ -625,12 +552,6 @@ WebString BlinkPlatformImpl::QueryLocalizedString(
GetContentClient()->GetLocalizedString(message_id));
}
-WebString BlinkPlatformImpl::queryLocalizedString(
- WebLocalizedString::Name name, int numeric_value) {
- return QueryLocalizedString(
- name, WebString::FromUTF16(base::IntToString16(numeric_value)));
-}
-
WebString BlinkPlatformImpl::QueryLocalizedString(WebLocalizedString::Name name,
const WebString& value) {
int message_id = ToMessageID(name);
@@ -761,11 +682,6 @@ bool BlinkPlatformImpl::IsLowEndDevice() {
return base::SysInfo::IsLowEndDevice();
}
-bool BlinkPlatformImpl::IsMainThread() const {
- return main_thread_task_runner_.get() &&
- main_thread_task_runner_->BelongsToCurrentThread();
-}
-
WebString BlinkPlatformImpl::DomCodeStringFromEnum(int dom_code) {
return WebString::FromUTF8(ui::KeycodeConverter::DomCodeToCodeString(
static_cast<ui::DomCode>(dom_code)));
diff --git a/chromium/content/child/blink_platform_impl.h b/chromium/content/child/blink_platform_impl.h
index 67329003283..000a65ca3d4 100644
--- a/chromium/content/child/blink_platform_impl.h
+++ b/chromium/content/child/blink_platform_impl.h
@@ -10,7 +10,6 @@
#include "base/compiler_specific.h"
#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_local_storage.h"
#include "base/timer/timer.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
@@ -33,16 +32,6 @@
#include "content/child/webthemeengine_impl_android.h"
#endif
-namespace base {
-class WaitableEvent;
-}
-
-namespace blink {
-namespace scheduler {
-class WebThreadBase;
-}
-}
-
namespace content {
class WebCryptoImpl;
@@ -72,18 +61,11 @@ class CONTENT_EXPORT BlinkPlatformImpl : public blink::Platform {
size_t MaxDecodedImageBytes() override;
bool IsLowEndDevice() override;
- std::unique_ptr<blink::WebThread> CreateThread(
- const blink::WebThreadCreationParams& params) override;
- std::unique_ptr<blink::WebThread> CreateWebAudioThread() override;
- blink::WebThread* CurrentThread() override;
void RecordAction(const blink::UserMetricsAction&) override;
blink::WebData GetDataResource(const char* name) override;
blink::WebString QueryLocalizedString(
blink::WebLocalizedString::Name name) override;
- virtual blink::WebString queryLocalizedString(
- blink::WebLocalizedString::Name name,
- int numeric_value);
blink::WebString QueryLocalizedString(blink::WebLocalizedString::Name name,
const blink::WebString& value) override;
blink::WebString QueryLocalizedString(
@@ -103,21 +85,14 @@ class CONTENT_EXPORT BlinkPlatformImpl : public blink::Platform {
int DomKeyEnumFromString(const blink::WebString& key_string) override;
bool IsDomKeyForModifier(int dom_key) override;
- void WaitUntilWebThreadTLSUpdate(blink::scheduler::WebThreadBase* thread);
-
scoped_refptr<base::SingleThreadTaskRunner> GetIOTaskRunner() const override;
std::unique_ptr<NestedMessageLoopRunner> CreateNestedMessageLoopRunner()
const override;
private:
- void UpdateWebThreadTLS(blink::WebThread* thread, base::WaitableEvent* event);
-
- bool IsMainThread() const;
-
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_;
WebThemeEngineImpl native_theme_engine_;
- base::ThreadLocalStorage::Slot current_thread_slot_;
webcrypto::WebCryptoImpl web_crypto_;
media::WebMediaCapabilitiesClientImpl media_capabilities_client_;
};
diff --git a/chromium/content/child/blink_platform_impl_unittest.cc b/chromium/content/child/blink_platform_impl_unittest.cc
index 6cb1152a775..50e3c8627ea 100644
--- a/chromium/content/child/blink_platform_impl_unittest.cc
+++ b/chromium/content/child/blink_platform_impl_unittest.cc
@@ -17,15 +17,16 @@ namespace content {
void CheckCastedOriginsAlreadyNormalized(
const blink::WebSecurityOrigin& origin) {
- url::Origin checked_origin =
- url::Origin::UnsafelyCreateOriginWithoutNormalization(
+ if (origin.IsOpaque())
+ return;
+
+ base::Optional<url::Origin> checked_origin =
+ url::Origin::UnsafelyCreateTupleOriginWithoutNormalization(
origin.Protocol().Utf8(), origin.Host().Utf8(),
origin.EffectivePort());
url::Origin non_checked_origin = url::Origin::CreateFromNormalizedTuple(
origin.Protocol().Utf8(), origin.Host().Utf8(), origin.EffectivePort());
- EXPECT_EQ(checked_origin.scheme(), non_checked_origin.scheme());
- EXPECT_EQ(checked_origin.host(), non_checked_origin.host());
- EXPECT_EQ(checked_origin.port(), non_checked_origin.port());
+ EXPECT_EQ(checked_origin, non_checked_origin);
}
TEST(BlinkPlatformTest, CastWebSecurityOrigin) {
@@ -116,7 +117,7 @@ TEST(BlinkPlatformTest, CastWebSecurityOrigin) {
EXPECT_TRUE(web_origin.IsUnique());
url::Origin url_origin = web_origin;
- EXPECT_TRUE(url_origin.unique());
+ EXPECT_TRUE(url_origin.opaque());
web_origin = url::Origin::Create(GURL(""));
EXPECT_TRUE(web_origin.IsUnique());
diff --git a/chromium/content/child/child_process.cc b/chromium/content/child/child_process.cc
index 7b55e6f2a25..43134211220 100644
--- a/chromium/content/child/child_process.cc
+++ b/chromium/content/child/child_process.cc
@@ -21,7 +21,7 @@ namespace content {
namespace {
base::LazyInstance<base::ThreadLocalPointer<ChildProcess>>::DestructorAtExit
- g_lazy_tls = LAZY_INSTANCE_INITIALIZER;
+ g_lazy_child_process_tls = LAZY_INSTANCE_INITIALIZER;
}
ChildProcess::ChildProcess(
@@ -32,8 +32,8 @@ ChildProcess::ChildProcess(
shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED),
io_thread_("Chrome_ChildIOThread") {
- DCHECK(!g_lazy_tls.Pointer()->Get());
- g_lazy_tls.Pointer()->Set(this);
+ DCHECK(!g_lazy_child_process_tls.Pointer()->Get());
+ g_lazy_child_process_tls.Pointer()->Set(this);
// Initialize TaskScheduler if not already done. A TaskScheduler may already
// exist when ChildProcess is instantiated in the browser process or in a
@@ -63,7 +63,7 @@ ChildProcess::ChildProcess(
}
ChildProcess::~ChildProcess() {
- DCHECK(g_lazy_tls.Pointer()->Get() == this);
+ DCHECK(g_lazy_child_process_tls.Pointer()->Get() == this);
// Signal this event before destroying the child process. That way all
// background threads can cleanup.
@@ -82,7 +82,7 @@ ChildProcess::~ChildProcess() {
}
}
- g_lazy_tls.Pointer()->Set(nullptr);
+ g_lazy_child_process_tls.Pointer()->Set(nullptr);
io_thread_.Stop();
if (initialized_task_scheduler_) {
@@ -117,7 +117,7 @@ void ChildProcess::ReleaseProcess() {
}
ChildProcess* ChildProcess::current() {
- return g_lazy_tls.Pointer()->Get();
+ return g_lazy_child_process_tls.Pointer()->Get();
}
base::WaitableEvent* ChildProcess::GetShutDownEvent() {
diff --git a/chromium/content/child/child_process.h b/chromium/content/child/child_process.h
index 0721f11a460..11c5e200aaf 100644
--- a/chromium/content/child/child_process.h
+++ b/chromium/content/child/child_process.h
@@ -72,13 +72,13 @@ class CONTENT_EXPORT ChildProcess {
// These are used for ref-counting the child process. The process shuts
// itself down when the ref count reaches 0.
- // For example, in the renderer process, generally each tab managed by this
- // process will hold a reference to the process, and release when closed.
- // However for renderer processes specifically, there is also fast shutdown
- // code path initiated by the browser process. The process refcount does
- // not influence fast shutdown. See blink::Platform::suddenTerminationChanged.
- void AddRefProcess();
- void ReleaseProcess();
+ //
+ // This is not used for renderer processes. The browser process is the only
+ // one responsible for shutting them down. See mojo::KeepAliveHandle and more
+ // generally the RenderProcessHostImpl class if you want to keep the renderer
+ // process alive longer.
+ virtual void AddRefProcess();
+ virtual void ReleaseProcess();
// Getter for the one ChildProcess object for this process. Can only be called
// on the main thread.
diff --git a/chromium/content/child/child_process_sandbox_support_impl_linux.cc b/chromium/content/child/child_process_sandbox_support_impl_linux.cc
index 9dd008c8417..5122a63a58b 100644
--- a/chromium/content/child/child_process_sandbox_support_impl_linux.cc
+++ b/chromium/content/child/child_process_sandbox_support_impl_linux.cc
@@ -21,7 +21,7 @@
#include "content/public/common/common_sandbox_support_linux.h"
#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#include "services/service_manager/zygote/common/common_sandbox_support_linux.h"
-#include "third_party/blink/public/platform/linux/web_fallback_font.h"
+#include "third_party/blink/public/platform/linux/out_of_process_font.h"
#include "third_party/blink/public/platform/web_font_render_style.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
@@ -31,7 +31,7 @@ namespace content {
void GetFallbackFontForCharacter(sk_sp<font_service::FontLoader> font_loader,
int32_t character,
const char* preferred_locale,
- blink::WebFallbackFont* fallback_font) {
+ blink::OutOfProcessFont* fallback_font) {
DCHECK(font_loader.get());
font_service::mojom::FontIdentityPtr font_identity;
bool is_bold = false;
@@ -44,7 +44,7 @@ void GetFallbackFontForCharacter(sk_sp<font_service::FontLoader> font_loader,
return;
}
- // TODO(drott): Perhaps take WebFallbackFont out of the picture here and pass
+ // TODO(drott): Perhaps take OutOfProcessFont out of the picture here and pass
// mojo FontIdentityPtr directly?
fallback_font->name =
blink::WebString::FromUTF8(family_name.c_str(), family_name.length());
@@ -94,4 +94,23 @@ void GetRenderStyleForStrike(sk_sp<font_service::FontLoader> font_loader,
static_cast<char>(font_render_style->use_subpixel_positioning);
}
+void MatchFontByPostscriptNameOrFullFontName(
+ sk_sp<font_service::FontLoader> font_loader,
+ const char* font_unique_name,
+ blink::OutOfProcessFont* fallback_font) {
+ font_service::mojom::FontIdentityPtr font_identity;
+ std::string family_name;
+ if (!font_loader->MatchFontByPostscriptNameOrFullFontName(font_unique_name,
+ &font_identity)) {
+ LOG(ERROR) << "FontService unique font name matching request did not "
+ "receive a response.";
+ return;
+ }
+
+ fallback_font->fontconfig_interface_id = font_identity->id;
+ fallback_font->filename.Assign(font_identity->str_representation.c_str(),
+ font_identity->str_representation.length());
+ fallback_font->ttc_index = font_identity->ttc_index;
+}
+
} // namespace content
diff --git a/chromium/content/child/child_process_sandbox_support_impl_linux.h b/chromium/content/child/child_process_sandbox_support_impl_linux.h
index 140060cbf14..4c01a623db8 100644
--- a/chromium/content/child/child_process_sandbox_support_impl_linux.h
+++ b/chromium/content/child/child_process_sandbox_support_impl_linux.h
@@ -11,7 +11,7 @@
#include "third_party/skia/include/core/SkRefCnt.h"
namespace blink {
-struct WebFallbackFont;
+struct OutOfProcessFont;
struct WebFontRenderStyle;
}
@@ -24,7 +24,7 @@ namespace content {
void GetFallbackFontForCharacter(sk_sp<font_service::FontLoader> font_loader,
const int32_t character,
const char* preferred_locale,
- blink::WebFallbackFont* family);
+ blink::OutOfProcessFont* family);
// Returns rendering settings for a provided font family, size, and style.
// |size_and_style| stores the bold setting in its least-significant bit, the
@@ -38,6 +38,16 @@ void GetRenderStyleForStrike(sk_sp<font_service::FontLoader> font_loader,
float device_scale_factor,
blink::WebFontRenderStyle* out);
+// Matches a font uniquely by postscript name or full font name. Used in Blink
+// for @font-face { src: local(arg) } matching. Provide full font name or
+// postscript name as argument font_unique_name in UTF-8. fallback_font contains
+// a filename and fontconfig interface id if a match was found. The filename is
+// empty and the interface id is zero if no match is found.
+void MatchFontByPostscriptNameOrFullFontName(
+ sk_sp<font_service::FontLoader> font_loader,
+ const char* font_unique_name,
+ blink::OutOfProcessFont* uniquely_matched_font);
+
}; // namespace content
#endif // CONTENT_CHILD_CHILD_PROCESS_SANDBOX_SUPPORT_IMPL_LINUX_H_
diff --git a/chromium/content/child/child_thread_impl.cc b/chromium/content/child/child_thread_impl.cc
index f797ee88a23..85a0d8f9710 100644
--- a/chromium/content/child/child_thread_impl.cc
+++ b/chromium/content/child/child_thread_impl.cc
@@ -84,7 +84,7 @@ namespace {
const int kConnectionTimeoutS = 15;
base::LazyInstance<base::ThreadLocalPointer<ChildThreadImpl>>::DestructorAtExit
- g_lazy_tls = LAZY_INSTANCE_INITIALIZER;
+ g_lazy_child_thread_impl_tls = LAZY_INSTANCE_INITIALIZER;
// This isn't needed on Windows because there the sandbox's job object
// terminates child processes automatically. For unsandboxed processes (i.e.
@@ -179,44 +179,27 @@ class SuicideOnChannelErrorFilter : public IPC::MessageFilter {
class QuitClosure {
public:
QuitClosure();
- ~QuitClosure();
+ ~QuitClosure() = default;
- void BindToMainThread();
- void PostQuitFromNonMainThread();
+ void BindToMainThread(base::RepeatingClosure quit_closure);
+ void QuitFromNonMainThread();
private:
- static void PostClosure(
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- base::Closure closure);
-
base::Lock lock_;
base::ConditionVariable cond_var_;
- base::Closure closure_;
+ base::RepeatingClosure closure_;
};
QuitClosure::QuitClosure() : cond_var_(&lock_) {
}
-QuitClosure::~QuitClosure() {
-}
-
-void QuitClosure::PostClosure(
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- base::Closure closure) {
- task_runner->PostTask(FROM_HERE, closure);
-}
-
-void QuitClosure::BindToMainThread() {
+void QuitClosure::BindToMainThread(base::RepeatingClosure quit_closure) {
base::AutoLock lock(lock_);
- scoped_refptr<base::SingleThreadTaskRunner> task_runner(
- base::ThreadTaskRunnerHandle::Get());
- base::Closure quit_closure =
- base::RunLoop::QuitCurrentWhenIdleClosureDeprecated();
- closure_ = base::Bind(&QuitClosure::PostClosure, task_runner, quit_closure);
+ closure_ = std::move(quit_closure);
cond_var_.Signal();
}
-void QuitClosure::PostQuitFromNonMainThread() {
+void QuitClosure::QuitFromNonMainThread() {
base::AutoLock lock(lock_);
while (closure_.is_null())
cond_var_.Wait();
@@ -364,18 +347,14 @@ bool ChildThreadImpl::ChildThreadMessageRouter::RouteMessage(
return handled;
}
-ChildThreadImpl::ChildThreadImpl()
- : route_provider_binding_(this),
- router_(this),
- channel_connected_factory_(
- new base::WeakPtrFactory<ChildThreadImpl>(this)),
- weak_factory_(this) {
- Init(Options::Builder().Build());
-}
+ChildThreadImpl::ChildThreadImpl(base::RepeatingClosure quit_closure)
+ : ChildThreadImpl(std::move(quit_closure), Options::Builder().Build()) {}
-ChildThreadImpl::ChildThreadImpl(const Options& options)
+ChildThreadImpl::ChildThreadImpl(base::RepeatingClosure quit_closure,
+ const Options& options)
: route_provider_binding_(this),
router_(this),
+ quit_closure_(std::move(quit_closure)),
browser_process_io_runner_(options.browser_process_io_runner),
channel_connected_factory_(
new base::WeakPtrFactory<ChildThreadImpl>(this)),
@@ -423,7 +402,7 @@ void ChildThreadImpl::ConnectChannel() {
void ChildThreadImpl::Init(const Options& options) {
TRACE_EVENT0("startup", "ChildThreadImpl::Init");
- g_lazy_tls.Pointer()->Set(this);
+ g_lazy_child_thread_impl_tls.Pointer()->Set(this);
on_channel_error_called_ = false;
main_thread_runner_ = base::ThreadTaskRunnerHandle::Get();
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
@@ -561,7 +540,7 @@ void ChildThreadImpl::Init(const Options& options) {
base::TimeDelta::FromSeconds(connection_timeout));
#if defined(OS_ANDROID)
- g_quit_closure.Get().BindToMainThread();
+ g_quit_closure.Get().BindToMainThread(quit_closure_);
#endif
// In single-process mode, there is no need to synchronize trials to the
@@ -626,7 +605,7 @@ ChildThreadImpl::~ChildThreadImpl() {
// automatically. We used to watch the object handle on Windows to do this,
// but it wasn't possible to do so on POSIX.
channel_->ClearIPCTaskRunner();
- g_lazy_tls.Pointer()->Set(nullptr);
+ g_lazy_child_thread_impl_tls.Pointer()->Set(nullptr);
}
void ChildThreadImpl::Shutdown() {}
@@ -644,7 +623,7 @@ void ChildThreadImpl::OnChannelError() {
// If this thread runs in the browser process, only Thread::Stop should
// stop its message loop. Otherwise, QuitWhenIdle could race Thread::Stop.
if (!IsInBrowserProcess())
- base::RunLoop::QuitCurrentWhenIdleDeprecated();
+ quit_closure_.Run();
}
bool ChildThreadImpl::Send(IPC::Message* msg) {
@@ -774,7 +753,7 @@ bool ChildThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
}
void ChildThreadImpl::ProcessShutdown() {
- base::RunLoop::QuitCurrentWhenIdleDeprecated();
+ quit_closure_.Run();
}
#if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
@@ -792,7 +771,7 @@ void ChildThreadImpl::OnChildControlRequest(
}
ChildThreadImpl* ChildThreadImpl::current() {
- return g_lazy_tls.Pointer()->Get();
+ return g_lazy_child_thread_impl_tls.Pointer()->Get();
}
#if defined(OS_ANDROID)
@@ -801,7 +780,7 @@ ChildThreadImpl* ChildThreadImpl::current() {
void ChildThreadImpl::ShutdownThread() {
DCHECK(!ChildThreadImpl::current()) <<
"this method should NOT be called from child thread itself";
- g_quit_closure.Get().PostQuitFromNonMainThread();
+ g_quit_closure.Get().QuitFromNonMainThread();
}
#endif
diff --git a/chromium/content/child/child_thread_impl.h b/chromium/content/child/child_thread_impl.h
index 3155e449790..71c3eb0a81b 100644
--- a/chromium/content/child/child_thread_impl.h
+++ b/chromium/content/child/child_thread_impl.h
@@ -70,10 +70,10 @@ class CONTENT_EXPORT ChildThreadImpl
struct CONTENT_EXPORT Options;
// Creates the thread.
- ChildThreadImpl();
+ explicit ChildThreadImpl(base::RepeatingClosure quit_closure);
// Allow to be used for single-process mode and for in process gpu mode via
// options.
- explicit ChildThreadImpl(const Options& options);
+ ChildThreadImpl(base::RepeatingClosure quit_closure, const Options& options);
// ChildProcess::main_thread() is reset after Shutdown(), and before the
// destructor, so any subsystem that relies on ChildProcess::main_thread()
// must be terminated before Shutdown returns. In particular, if a subsystem
@@ -255,6 +255,9 @@ class CONTENT_EXPORT ChildThreadImpl
// TaskRunner to post tasks to the main thread.
scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner_;
+ // Used to quit the main thread.
+ base::RepeatingClosure quit_closure_;
+
std::unique_ptr<base::PowerMonitor> power_monitor_;
scoped_refptr<base::SingleThreadTaskRunner> browser_process_io_runner_;
diff --git a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc
index a6cd064c079..808946168ed 100644
--- a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc
+++ b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc
@@ -26,8 +26,10 @@ namespace content {
namespace {
-mswr::ComPtr<DWriteFontCollectionProxy> g_font_collection;
-mswr::ComPtr<FontFallback> g_font_fallback;
+// Created on demand and then kept around until process exit.
+DWriteFontCollectionProxy* g_font_collection = nullptr;
+FontFallback* g_font_fallback = nullptr;
+
base::RepeatingCallback<mojom::DWriteFontProxyPtrInfo(void)>*
g_connection_callback_override = nullptr;
@@ -67,11 +69,13 @@ void InitializeDWriteFontProxy(service_manager::Connector* connector) {
mswr::ComPtr<IDWriteFactory2> factory2;
if (SUCCEEDED(factory.As(&factory2)) && factory2.Get()) {
- FontFallback::Create(&g_font_fallback, g_font_collection.Get());
+ if (g_font_fallback)
+ g_font_fallback->Release();
+ FontFallback::Create(&g_font_fallback, g_font_collection);
}
sk_sp<SkFontMgr> skia_font_manager = SkFontMgr_New_DirectWrite(
- factory.Get(), g_font_collection.Get(), g_font_fallback.Get());
+ factory.Get(), g_font_collection, g_font_fallback);
blink::WebFontRendering::SetSkiaFontManager(skia_font_manager);
SetDefaultSkiaFactory(std::move(skia_font_manager));
@@ -83,7 +87,7 @@ void InitializeDWriteFontProxy(service_manager::Connector* connector) {
// instead fall back on WebKit's fallback logic, we don't use Skia's font
// fallback if IDWriteFontFallback is not available.
// This flag can be removed when Win8.0 and earlier are no longer supported.
- bool fallback_available = g_font_fallback.Get() != nullptr;
+ bool fallback_available = g_font_fallback != nullptr;
DCHECK_EQ(fallback_available,
base::win::GetVersion() > base::win::VERSION_WIN8);
blink::WebFontRendering::SetUseSkiaFontFallback(fallback_available);
diff --git a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
index 6387f299273..66c1b21c154 100644
--- a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
+++ b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc
@@ -13,6 +13,7 @@
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "content/child/dwrite_font_proxy/dwrite_localized_strings_win.h"
@@ -381,9 +382,10 @@ FontProxyScopeWrapper DWriteFontCollectionProxy::GetFontProxyScopeWrapper() {
}
SetProxy(std::move(dwrite_font_proxy));
}
- static base::ThreadLocalBoolean font_proxy_method_in_flight;
-
- return FontProxyScopeWrapper(font_proxy_.get(), &font_proxy_method_in_flight);
+ static base::NoDestructor<base::ThreadLocalBoolean>
+ font_proxy_method_in_flight;
+ return FontProxyScopeWrapper(font_proxy_.get(),
+ font_proxy_method_in_flight.get());
}
DWriteFontFamilyProxy::DWriteFontFamilyProxy() = default;
@@ -647,8 +649,7 @@ HRESULT FontFileStream::RuntimeClassInitialize(HANDLE handle) {
return E_FAIL;
}
- data_.Initialize(base::File(duplicate_handle));
- if (!data_.IsValid()) {
+ if (!data_.Initialize(base::File(duplicate_handle))) {
LogFontProxyError(MAPPED_FILE_FAILED);
return E_FAIL;
}
diff --git a/chromium/content/child/font_warmup_win.cc b/chromium/content/child/font_warmup_win.cc
index be505c8e79d..93b698c3073 100644
--- a/chromium/content/child/font_warmup_win.cc
+++ b/chromium/content/child/font_warmup_win.cc
@@ -14,6 +14,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/no_destructor.h"
#include "base/numerics/safe_conversions.h"
#include "base/numerics/safe_math.h"
#include "base/strings/utf_string_conversions.h"
@@ -40,12 +41,6 @@ namespace {
// The Skia font manager, used for the life of the process (leaked at the end).
SkFontMgr* g_warmup_fontmgr = nullptr;
-base::win::IATPatchFunction g_iat_patch_open_sc_manager;
-base::win::IATPatchFunction g_iat_patch_close_service_handle;
-base::win::IATPatchFunction g_iat_patch_open_service;
-base::win::IATPatchFunction g_iat_patch_start_service;
-base::win::IATPatchFunction g_iat_patch_nt_connect_port;
-
// These are from ntddk.h
#if !defined(STATUS_ACCESS_DENIED)
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
@@ -400,27 +395,33 @@ void PatchServiceManagerCalls() {
is_patched = true;
- DWORD patched = g_iat_patch_open_sc_manager.Patch(
+ static base::NoDestructor<base::win::IATPatchFunction> patch_open_sc_manager;
+ DWORD patched = patch_open_sc_manager->Patch(
L"dwrite.dll", service_provider_dll, "OpenSCManagerW",
reinterpret_cast<void*>(OpenSCManagerWPatch));
DCHECK(patched == 0);
- patched = g_iat_patch_close_service_handle.Patch(
+ static base::NoDestructor<base::win::IATPatchFunction>
+ patch_close_service_handle;
+ patched = patch_close_service_handle->Patch(
L"dwrite.dll", service_provider_dll, "CloseServiceHandle",
reinterpret_cast<void*>(CloseServiceHandlePatch));
DCHECK(patched == 0);
- patched = g_iat_patch_open_service.Patch(
+ static base::NoDestructor<base::win::IATPatchFunction> patch_open_service;
+ patched = patch_open_service->Patch(
L"dwrite.dll", service_provider_dll, "OpenServiceW",
reinterpret_cast<void*>(OpenServiceWPatch));
DCHECK(patched == 0);
- patched = g_iat_patch_start_service.Patch(
+ static base::NoDestructor<base::win::IATPatchFunction> patch_start_service;
+ patched = patch_start_service->Patch(
L"dwrite.dll", service_provider_dll, "StartServiceW",
reinterpret_cast<void*>(StartServiceWPatch));
DCHECK(patched == 0);
- patched = g_iat_patch_nt_connect_port.Patch(
+ static base::NoDestructor<base::win::IATPatchFunction> patch_nt_connect_port;
+ patched = patch_nt_connect_port->Patch(
L"dwrite.dll", "ntdll.dll", "NtAlpcConnectPort",
reinterpret_cast<void*>(NtALpcConnectPortPatch));
DCHECK(patched == 0);
diff --git a/chromium/content/child/memory/child_memory_coordinator_impl_unittest.cc b/chromium/content/child/memory/child_memory_coordinator_impl_unittest.cc
index 976b67cbe67..842ac14d5e8 100644
--- a/chromium/content/child/memory/child_memory_coordinator_impl_unittest.cc
+++ b/chromium/content/child/memory/child_memory_coordinator_impl_unittest.cc
@@ -11,8 +11,8 @@
#include <memory>
#include "base/memory/memory_coordinator_client_registry.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -44,7 +44,7 @@ class ChildMemoryCoordinatorImplTest : public testing::Test,
public ChildMemoryCoordinatorDelegate {
public:
ChildMemoryCoordinatorImplTest()
- : message_loop_(new base::MessageLoop) {
+ : task_environment_(new base::test::ScopedTaskEnvironment) {
auto parent = coordinator_handle_.Bind();
coordinator_impl_ = CreateChildMemoryCoordinator(std::move(parent), this);
// Needs to run loop to initalize mojo pointers including |child_| in
@@ -84,7 +84,7 @@ class ChildMemoryCoordinatorImplTest : public testing::Test,
bool on_trim_memory_called_ = false;
private:
- std::unique_ptr<base::MessageLoop> message_loop_;
+ std::unique_ptr<base::test::ScopedTaskEnvironment> task_environment_;
MockMemoryCoordinatorHandle coordinator_handle_;
std::unique_ptr<ChildMemoryCoordinatorImpl> coordinator_impl_;
diff --git a/chromium/content/child/runtime_features.cc b/chromium/content/child/runtime_features.cc
index 1221dc2adfc..7eecb0391ee 100644
--- a/chromium/content/child/runtime_features.cc
+++ b/chromium/content/child/runtime_features.cc
@@ -17,10 +17,12 @@
#include "content/public/common/content_switches.h"
#include "gpu/config/gpu_switches.h"
#include "media/base/media_switches.h"
+#include "net/base/features.h"
#include "services/device/public/cpp/device_features.h"
#include "services/network/public/cpp/features.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
+#include "ui/events/blink/blink_features.h"
#include "ui/gfx/switches.h"
#include "ui/gl/gl_switches.h"
#include "ui/native_theme/native_theme_features.h"
@@ -134,9 +136,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
if (!base::FeatureList::IsEnabled(features::kNotificationContentImage))
WebRuntimeFeatures::EnableNotificationContentImage(false);
- WebRuntimeFeatures::EnableWebAssemblyStreaming(
- base::FeatureList::IsEnabled(features::kWebAssemblyStreaming));
-
WebRuntimeFeatures::EnableSharedArrayBuffer(
base::FeatureList::IsEnabled(features::kSharedArrayBuffer) ||
base::FeatureList::IsEnabled(features::kWebAssemblyThreads));
@@ -174,11 +173,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
!command_line.HasSwitch(switches::kDisable2dCanvasImageChromium) &&
!command_line.HasSwitch(switches::kDisableGpu) &&
base::FeatureList::IsEnabled(features::kCanvas2DImageChromium);
-#elif defined(OS_CHROMEOS)
- const bool enable_canvas_2d_image_chromium =
- !command_line.HasSwitch(switches::kDisable2dCanvasImageChromium) &&
- !command_line.HasSwitch(switches::kDisableGpu) &&
- base::FeatureList::IsEnabled(features::kCanvas2DImageChromium);
#else
constexpr bool enable_canvas_2d_image_chromium = false;
#endif
@@ -186,17 +180,14 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
enable_canvas_2d_image_chromium);
#if defined(OS_MACOSX)
- bool enable_web_gl_image_chromium = command_line.HasSwitch(
- switches::kEnableGpuMemoryBufferCompositorResources) &&
+ const bool enable_web_gl_image_chromium =
+ command_line.HasSwitch(
+ switches::kEnableGpuMemoryBufferCompositorResources) &&
!command_line.HasSwitch(switches::kDisableWebGLImageChromium) &&
- !command_line.HasSwitch(switches::kDisableGpu);
-
- if (enable_web_gl_image_chromium) {
- enable_web_gl_image_chromium =
- base::FeatureList::IsEnabled(features::kWebGLImageChromium);
- }
+ !command_line.HasSwitch(switches::kDisableGpu) &&
+ base::FeatureList::IsEnabled(features::kWebGLImageChromium);
#else
- bool enable_web_gl_image_chromium =
+ const bool enable_web_gl_image_chromium =
command_line.HasSwitch(switches::kEnableWebGLImageChromium);
#endif
WebRuntimeFeatures::EnableWebGLImageChromium(enable_web_gl_image_chromium);
@@ -267,9 +258,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
if (command_line.HasSwitch(switches::kEnableSlimmingPaintV2))
WebRuntimeFeatures::EnableSlimmingPaintV2(true);
- if (base::FeatureList::IsEnabled(features::kLazyParseCSS))
- WebRuntimeFeatures::EnableLazyParseCSS(true);
-
WebRuntimeFeatures::EnablePassiveDocumentEventListeners(
base::FeatureList::IsEnabled(features::kPassiveDocumentEventListeners));
@@ -380,6 +368,10 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnableWebAuth(
base::FeatureList::IsEnabled(features::kWebAuth));
+ WebRuntimeFeatures::EnableWebAuthGetTransports(
+ base::FeatureList::IsEnabled(features::kWebAuthGetTransports) ||
+ enableExperimentalWebPlatformFeatures);
+
WebRuntimeFeatures::EnableClientPlaceholdersForServerLoFi(
base::GetFieldTrialParamValue("PreviewsClientLoFi",
"replace_server_placeholders") != "false");
@@ -400,12 +392,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
base::FeatureList::IsEnabled(
media::kMediaEngagementBypassAutoplayPolicies));
- WebRuntimeFeatures::EnableModuleScriptsDynamicImport(
- base::FeatureList::IsEnabled(features::kModuleScriptsDynamicImport));
-
- WebRuntimeFeatures::EnableModuleScriptsImportMetaUrl(
- base::FeatureList::IsEnabled(features::kModuleScriptsImportMetaUrl));
-
WebRuntimeFeatures::EnableOverflowIconsForMediaControls(
base::FeatureList::IsEnabled(media::kOverflowIconsForMediaControls));
@@ -446,7 +432,7 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
base::FeatureList::IsEnabled(features::kCacheInlineScriptCode));
WebRuntimeFeatures::EnableIsolatedCodeCache(
- base::FeatureList::IsEnabled(features::kIsolatedCodeCache));
+ base::FeatureList::IsEnabled(net::features::kIsolatedCodeCache));
if (base::FeatureList::IsEnabled(features::kSignedHTTPExchange)) {
WebRuntimeFeatures::EnableSignedHTTPExchange(true);
@@ -476,6 +462,9 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
if (command_line.HasSwitch(switches::kEnableAccessibilityObjectModel))
WebRuntimeFeatures::EnableAccessibilityObjectModel(true);
+ if (base::FeatureList::IsEnabled(blink::features::kWritableFilesAPI))
+ WebRuntimeFeatures::EnableFeatureFromString("WritableFiles", true);
+
// End individual features.
// Do not add individual features below this line.
@@ -492,10 +481,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
base::FeatureList::IsEnabled(media::kMediaControlsExpandGesture));
#endif
- WebRuntimeFeatures::EnableFeatureFromString(
- "WritableFiles",
- base::FeatureList::IsEnabled(blink::features::kWritableFilesAPI));
-
// Enable explicitly enabled features, and then disable explicitly disabled
// ones.
for (const std::string& feature :
@@ -509,6 +494,19 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnablePortals(
base::FeatureList::IsEnabled(blink::features::kPortals));
-};
+
+ if (!base::FeatureList::IsEnabled(features::kBackgroundFetch))
+ WebRuntimeFeatures::EnableBackgroundFetch(false);
+
+ WebRuntimeFeatures::EnableNoHoverAfterLayoutChange(
+ base::FeatureList::IsEnabled(features::kNoHoverAfterLayoutChange));
+
+ WebRuntimeFeatures::EnableJankTracking(
+ base::FeatureList::IsEnabled(blink::features::kJankTracking) ||
+ enableExperimentalWebPlatformFeatures);
+
+ WebRuntimeFeatures::EnableNoHoverDuringScroll(
+ base::FeatureList::IsEnabled(features::kNoHoverDuringScroll));
+}
} // namespace content
diff --git a/chromium/content/common/BUILD.gn b/chromium/content/common/BUILD.gn
index 1940f0d9774..53e2a5420b0 100644
--- a/chromium/content/common/BUILD.gn
+++ b/chromium/content/common/BUILD.gn
@@ -100,8 +100,6 @@ source_set("common") {
"dom_storage/dom_storage_map.cc",
"dom_storage/dom_storage_map.h",
"dom_storage/dom_storage_messages.h",
- "dom_storage/dom_storage_namespace_ids.cc",
- "dom_storage/dom_storage_namespace_ids.h",
"dom_storage/dom_storage_types.h",
"download/mhtml_save_status.cc",
"download/mhtml_save_status.h",
@@ -133,6 +131,8 @@ source_set("common") {
"gin_java_bridge_messages.h",
"in_process_child_thread_params.cc",
"in_process_child_thread_params.h",
+ "input/actions_parser.cc",
+ "input/actions_parser.h",
"input/event_with_latency_info.h",
"input/gesture_event_stream_validator.cc",
"input/gesture_event_stream_validator.h",
@@ -172,6 +172,8 @@ source_set("common") {
"input/touch_action_optional_struct_traits.h",
"input/touch_event_stream_validator.cc",
"input/touch_event_stream_validator.h",
+ "input/web_mouse_wheel_event_traits.cc",
+ "input/web_mouse_wheel_event_traits.h",
"input/web_touch_event_traits.cc",
"input/web_touch_event_traits.h",
"input_messages.h",
@@ -189,8 +191,6 @@ source_set("common") {
"media/media_player_messages_android.h",
"media/media_stream_controls.cc",
"media/media_stream_controls.h",
- "media/media_stream_param_traits.cc",
- "media/media_stream_param_traits.h",
"media/midi_messages.h",
"media/peer_connection_tracker_messages.h",
"media/video_capture.h",
@@ -209,8 +209,6 @@ source_set("common") {
"net/url_request_service_worker_data.h",
"net/url_request_user_data.cc",
"net/url_request_user_data.h",
- "notifications/notification_struct_traits.cc",
- "notifications/notification_struct_traits.h",
"origin_util.cc",
"page_messages.h",
"page_state_serialization.cc",
@@ -267,10 +265,10 @@ source_set("common") {
"url_schemes.cc",
"url_schemes.h",
"user_agent.cc",
- "view_message_enums.h",
"view_messages.h",
"visual_properties.cc",
"visual_properties.h",
+ "widget_messages.h",
]
configs += [
@@ -319,7 +317,6 @@ source_set("common") {
"//media:shared_memory_support",
"//media/base/ipc",
"//media/capture",
- "//media/capture/ipc",
"//media/gpu:buildflags",
"//media/gpu/ipc/client",
"//media/gpu/ipc/common",
@@ -332,7 +329,7 @@ source_set("common") {
"//sandbox:sandbox_buildflags",
"//services/network/public/cpp",
"//services/network/public/mojom",
- "//services/resource_coordinator/public/cpp:resource_coordinator_cpp",
+ "//services/resource_coordinator/public/cpp/memory_instrumentation",
"//services/service_manager",
"//services/service_manager/embedder",
"//services/service_manager/public/cpp",
@@ -353,6 +350,7 @@ source_set("common") {
"//ui/events/blink",
"//ui/gfx",
"//ui/gfx/geometry",
+ "//ui/gfx/geometry/mojo:struct_traits",
"//ui/gfx/ipc",
"//ui/gfx/ipc/color",
"//ui/gfx/ipc/geometry",
@@ -469,8 +467,8 @@ source_set("common") {
deps += [
"//third_party/fuchsia-sdk:fdio",
- "//third_party/fuchsia-sdk:fonts",
- "//third_party/fuchsia-sdk:scenic",
+ "//third_party/fuchsia-sdk/sdk:fonts",
+ "//third_party/fuchsia-sdk/sdk:scenic",
]
}
}
@@ -578,6 +576,7 @@ mojom("mojo_bindings") {
"//content/public/common:interfaces",
"//content/public/common:resource_type_bindings",
"//ipc:mojom_constants",
+ "//media/capture/mojom:video_capture",
"//media/mojo/interfaces",
"//mojo/public/mojom/base",
"//services/audio/public/mojom",
diff --git a/chromium/content/common/DEPS b/chromium/content/common/DEPS
index 96e605eeb23..ba5997defc0 100644
--- a/chromium/content/common/DEPS
+++ b/chromium/content/common/DEPS
@@ -67,14 +67,12 @@ include_rules = [
"+third_party/blink/public/web/web_ax_enums.h",
"+third_party/blink/public/web/web_device_emulation_params.h",
"+third_party/blink/public/web/web_drag_status.h",
- "+third_party/blink/public/web/web_find_options.h",
"+third_party/blink/public/web/web_frame_owner_properties.h",
"+third_party/blink/public/web/web_frame_serializer_cache_control_policy.h",
"+third_party/blink/public/web/web_fullscreen_options.h",
"+third_party/blink/public/web/web_ime_text_span.h",
"+third_party/blink/public/web/web_media_player_action.h",
"+third_party/blink/public/web/web_plugin_action.h",
- "+third_party/blink/public/web/web_popup_type.h",
"+third_party/blink/public/web/WebSharedWorkerCreationContextType.h",
"+third_party/blink/public/web/WebSharedWorkerCreationErrors.h",
"+third_party/blink/public/web/web_text_direction.h",
diff --git a/chromium/content/common/OWNERS b/chromium/content/common/OWNERS
index c3390635291..a0ebcffeae2 100644
--- a/chromium/content/common/OWNERS
+++ b/chromium/content/common/OWNERS
@@ -16,9 +16,6 @@ per-file sandbox_mac*=file://sandbox/mac/OWNERS
per-file *.sb=set noparent
per-file *.sb=file://sandbox/mac/OWNERS
-per-file pepper*=bauerb@chromium.org
-per-file plugin*=bauerb@chromium.org
-
per-file *_messages*.h=set noparent
per-file *_messages*.h=file://ipc/SECURITY_OWNERS
diff --git a/chromium/content/common/accessibility_messages.h b/chromium/content/common/accessibility_messages.h
index 827dd7a21df..39257438e09 100644
--- a/chromium/content/common/accessibility_messages.h
+++ b/chromium/content/common/accessibility_messages.h
@@ -10,7 +10,6 @@
#include "content/common/ax_content_node_data.h"
#include "content/common/content_export.h"
#include "content/common/content_param_traits.h"
-#include "content/common/view_message_enums.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_message_utils.h"
#include "ipc/ipc_param_traits.h"
diff --git a/chromium/content/common/background_fetch/background_fetch_struct_traits.cc b/chromium/content/common/background_fetch/background_fetch_struct_traits.cc
index dd5321bedc3..fd3f88ba2eb 100644
--- a/chromium/content/common/background_fetch/background_fetch_struct_traits.cc
+++ b/chromium/content/common/background_fetch/background_fetch_struct_traits.cc
@@ -38,7 +38,7 @@ bool StructTraits<blink::mojom::BackgroundFetchRegistrationDataView,
registration->uploaded = data.uploaded();
registration->download_total = data.download_total();
registration->downloaded = data.downloaded();
- registration->state = data.state();
+ registration->result = data.result();
registration->failure_reason = data.failure_reason();
return true;
}
diff --git a/chromium/content/common/background_fetch/background_fetch_struct_traits.h b/chromium/content/common/background_fetch/background_fetch_struct_traits.h
index 30dfc0efd95..2fc02abf101 100644
--- a/chromium/content/common/background_fetch/background_fetch_struct_traits.h
+++ b/chromium/content/common/background_fetch/background_fetch_struct_traits.h
@@ -64,9 +64,9 @@ struct CONTENT_EXPORT
const content::BackgroundFetchRegistration& registration) {
return registration.downloaded;
}
- static blink::mojom::BackgroundFetchState state(
+ static blink::mojom::BackgroundFetchResult result(
const content::BackgroundFetchRegistration& registration) {
- return registration.state;
+ return registration.result;
}
static blink::mojom::BackgroundFetchFailureReason failure_reason(
const content::BackgroundFetchRegistration& registration) {
diff --git a/chromium/content/common/background_fetch/background_fetch_struct_traits_unittest.cc b/chromium/content/common/background_fetch/background_fetch_struct_traits_unittest.cc
index 98ffea5c591..90d2ac37209 100644
--- a/chromium/content/common/background_fetch/background_fetch_struct_traits_unittest.cc
+++ b/chromium/content/common/background_fetch/background_fetch_struct_traits_unittest.cc
@@ -59,7 +59,7 @@ TEST(BackgroundFetchStructTraitsTest, BackgroundFetchRegistrationRoundTrip) {
registration.developer_id = "my_id";
registration.unique_id = "7e57ab1e-c0de-a150-ca75-1e75f005ba11";
registration.download_total = 9001;
- registration.state = blink::mojom::BackgroundFetchState::FAILURE;
+ registration.result = blink::mojom::BackgroundFetchResult::FAILURE;
registration.failure_reason =
blink::mojom::BackgroundFetchFailureReason::CANCELLED_FROM_UI;
@@ -72,7 +72,7 @@ TEST(BackgroundFetchStructTraitsTest, BackgroundFetchRegistrationRoundTrip) {
EXPECT_EQ(roundtrip_registration.unique_id, registration.unique_id);
EXPECT_EQ(roundtrip_registration.download_total, registration.download_total);
- EXPECT_EQ(roundtrip_registration.state, registration.state);
+ EXPECT_EQ(roundtrip_registration.result, registration.result);
EXPECT_EQ(roundtrip_registration.failure_reason, registration.failure_reason);
}
diff --git a/chromium/content/common/background_fetch/background_fetch_types.cc b/chromium/content/common/background_fetch/background_fetch_types.cc
index 7db59cf5190..5ff3ae79dbd 100644
--- a/chromium/content/common/background_fetch/background_fetch_types.cc
+++ b/chromium/content/common/background_fetch/background_fetch_types.cc
@@ -29,7 +29,7 @@ BackgroundFetchOptions::BackgroundFetchOptions(
BackgroundFetchOptions::~BackgroundFetchOptions() = default;
BackgroundFetchRegistration::BackgroundFetchRegistration()
- : state(blink::mojom::BackgroundFetchState::PENDING),
+ : result(blink::mojom::BackgroundFetchResult::UNSET),
failure_reason(blink::mojom::BackgroundFetchFailureReason::NONE) {}
BackgroundFetchRegistration::BackgroundFetchRegistration(
@@ -39,7 +39,7 @@ BackgroundFetchRegistration::BackgroundFetchRegistration(
uint64_t uploaded,
uint64_t download_total,
uint64_t downloaded,
- blink::mojom::BackgroundFetchState state,
+ blink::mojom::BackgroundFetchResult result,
blink::mojom::BackgroundFetchFailureReason failure_reason)
: developer_id(developer_id),
unique_id(unique_id),
@@ -47,7 +47,7 @@ BackgroundFetchRegistration::BackgroundFetchRegistration(
uploaded(uploaded),
download_total(download_total),
downloaded(downloaded),
- state(state),
+ result(result),
failure_reason(failure_reason) {}
BackgroundFetchRegistration::BackgroundFetchRegistration(
diff --git a/chromium/content/common/background_fetch/background_fetch_types.h b/chromium/content/common/background_fetch/background_fetch_types.h
index 73685818e47..c20ad3a8bd7 100644
--- a/chromium/content/common/background_fetch/background_fetch_types.h
+++ b/chromium/content/common/background_fetch/background_fetch_types.h
@@ -17,7 +17,7 @@
namespace blink {
namespace mojom {
enum class BackgroundFetchFailureReason;
-enum class BackgroundFetchState;
+enum class BackgroundFetchResult;
} // namespace mojom
} // namespace blink
@@ -48,7 +48,7 @@ struct CONTENT_EXPORT BackgroundFetchRegistration {
uint64_t uploaded,
uint64_t download_total,
uint64_t downloaded,
- blink::mojom::BackgroundFetchState state,
+ blink::mojom::BackgroundFetchResult result,
blink::mojom::BackgroundFetchFailureReason failure_reason);
BackgroundFetchRegistration(const BackgroundFetchRegistration& other);
~BackgroundFetchRegistration();
@@ -65,7 +65,7 @@ struct CONTENT_EXPORT BackgroundFetchRegistration {
uint64_t uploaded = 0;
uint64_t download_total = 0;
uint64_t downloaded = 0;
- blink::mojom::BackgroundFetchState state;
+ blink::mojom::BackgroundFetchResult result;
blink::mojom::BackgroundFetchFailureReason failure_reason;
};
diff --git a/chromium/content/common/browser_plugin/browser_plugin_messages.h b/chromium/content/common/browser_plugin/browser_plugin_messages.h
index f511cb5049f..a34f05ba4fa 100644
--- a/chromium/content/common/browser_plugin/browser_plugin_messages.h
+++ b/chromium/content/common/browser_plugin/browser_plugin_messages.h
@@ -215,10 +215,6 @@ IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetCursor,
int /* browser_plugin_instance_id */,
content::WebCursor /* cursor */)
-IPC_MESSAGE_CONTROL2(BrowserPluginMsg_FirstSurfaceActivation,
- int /* browser_plugin_instance_id */,
- viz::SurfaceInfo /* surface_info */)
-
// Forwards a PointerLock Unlock request to the BrowserPlugin.
IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetMouseLock,
int /* browser_plugin_instance_id */,
diff --git a/chromium/content/common/common_param_traits_unittest.cc b/chromium/content/common/common_param_traits_unittest.cc
index 4d4ee04d13b..cb95c23f7f4 100644
--- a/chromium/content/common/common_param_traits_unittest.cc
+++ b/chromium/content/common/common_param_traits_unittest.cc
@@ -173,8 +173,6 @@ TEST(IPCMessageTest, SSLInfo) {
in.pkp_bypassed = true;
in.client_cert_sent = true;
in.channel_id_sent = true;
- in.token_binding_negotiated = true;
- in.token_binding_key_param = net::TB_PARAM_ECDSAP256;
in.handshake_type = net::SSLInfo::HANDSHAKE_FULL;
const net::SHA256HashValue kCertPublicKeyHashValue = {{0x01, 0x02}};
in.public_key_hashes.push_back(net::HashValue(kCertPublicKeyHashValue));
@@ -218,8 +216,6 @@ TEST(IPCMessageTest, SSLInfo) {
ASSERT_EQ(in.pkp_bypassed, out.pkp_bypassed);
ASSERT_EQ(in.client_cert_sent, out.client_cert_sent);
ASSERT_EQ(in.channel_id_sent, out.channel_id_sent);
- ASSERT_EQ(in.token_binding_negotiated, out.token_binding_negotiated);
- ASSERT_EQ(in.token_binding_key_param, out.token_binding_key_param);
ASSERT_EQ(in.handshake_type, out.handshake_type);
ASSERT_EQ(in.public_key_hashes, out.public_key_hashes);
ASSERT_EQ(in.pinning_failure_log, out.pinning_failure_log);
@@ -256,9 +252,9 @@ TEST(IPCMessageTest, RenderWidgetSurfaceProperties) {
content::RenderWidgetSurfaceProperties input;
input.size = gfx::Size(23, 45);
input.device_scale_factor = 0.8;
-#ifdef OS_ANDROID
input.top_controls_height = 16.5;
input.top_controls_shown_ratio = 0.4;
+#ifdef OS_ANDROID
input.bottom_controls_height = 23.4;
input.bottom_controls_shown_ratio = 0.8;
input.selection.start.set_type(gfx::SelectionBound::Type::CENTER);
@@ -275,9 +271,9 @@ TEST(IPCMessageTest, RenderWidgetSurfaceProperties) {
EXPECT_EQ(input.size, output.size);
EXPECT_EQ(input.device_scale_factor, output.device_scale_factor);
-#ifdef OS_ANDROID
EXPECT_EQ(input.top_controls_height, output.top_controls_height);
EXPECT_EQ(input.top_controls_shown_ratio, output.top_controls_shown_ratio);
+#ifdef OS_ANDROID
EXPECT_EQ(input.bottom_controls_height, output.bottom_controls_height);
EXPECT_EQ(input.bottom_controls_shown_ratio,
output.bottom_controls_shown_ratio);
diff --git a/chromium/content/common/content_message_generator.h b/chromium/content/common/content_message_generator.h
index c604ee0e5ba..3635f791e3c 100644
--- a/chromium/content/common/content_message_generator.h
+++ b/chromium/content/common/content_message_generator.h
@@ -83,6 +83,11 @@
#ifndef CONTENT_COMMON_VIEW_MESSAGES_H_
#error "Failed to include content/common/view_messages.h"
#endif
+#undef CONTENT_COMMON_WIDGET_MESSAGES_H_
+#include "content/common/widget_messages.h"
+#ifndef CONTENT_COMMON_WIDGET_MESSAGES_H_
+#error "Failed to include content/common/widget_messages.h"
+#endif
#include "media/media_buildflags.h"
#undef CONTENT_COMMON_SYNC_COMPOSITOR_MESSAGES_H_
diff --git a/chromium/content/common/content_param_traits.cc b/chromium/content/common/content_param_traits.cc
index cac6c159e5b..e1f1476c938 100644
--- a/chromium/content/common/content_param_traits.cc
+++ b/chromium/content/common/content_param_traits.cc
@@ -16,12 +16,13 @@
#include "ipc/ipc_mojo_message_helper.h"
#include "ipc/ipc_mojo_param_traits.h"
#include "net/base/ip_endpoint.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
-#include "third_party/blink/public/common/message_port/transferable_message.h"
-#include "third_party/blink/public/mojom/message_port/message_port.mojom.h"
-#include "ui/accessibility/ax_modes.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/transferable_message.h"
+#include "third_party/blink/public/mojom/messaging/transferable_message.mojom.h"
+#include "ui/accessibility/ax_mode.h"
#include "ui/base/ui_base_features.h"
#include "ui/events/blink/web_input_event_traits.h"
+#include "url/ipc/url_param_traits.h"
// #include "ui/gfx/ipc/geometry/gfx_param_traits.h"
namespace IPC {
@@ -148,7 +149,7 @@ void ParamTraits<scoped_refptr<storage::BlobHandle>>::Log(const param_type& p,
void ParamTraits<content::FrameMsg_ViewChanged_Params>::Write(
base::Pickle* m,
const param_type& p) {
- DCHECK(features::IsUsingWindowService() ||
+ DCHECK(features::IsMultiProcessMash() ||
(p.frame_sink_id.has_value() && p.frame_sink_id->is_valid()));
WriteParam(m, p.frame_sink_id);
}
@@ -159,7 +160,7 @@ bool ParamTraits<content::FrameMsg_ViewChanged_Params>::Read(
param_type* r) {
if (!ReadParam(m, iter, &(r->frame_sink_id)))
return false;
- if (!features::IsUsingWindowService() &&
+ if (!features::IsMultiProcessMash() &&
(!r->frame_sink_id || !r->frame_sink_id->is_valid())) {
NOTREACHED();
return false;
@@ -397,6 +398,78 @@ void ParamTraits<viz::SurfaceInfo>::Log(const param_type& p, std::string* l) {
l->append(")");
}
+void ParamTraits<blink::mojom::FileChooserFileInfoPtr>::Write(
+ base::Pickle* m,
+ const param_type& p) {
+ WriteParam(m, p->is_native_file());
+ if (p->is_native_file()) {
+ WriteParam(m, p->get_native_file()->file_path);
+ WriteParam(m, p->get_native_file()->display_name);
+ } else {
+ WriteParam(m, p->get_file_system()->url);
+ WriteParam(m, p->get_file_system()->modification_time);
+ WriteParam(m, p->get_file_system()->length);
+ }
+}
+
+bool ParamTraits<blink::mojom::FileChooserFileInfoPtr>::Read(
+ const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* p) {
+ bool is_native;
+ if (!ReadParam(m, iter, &is_native))
+ return false;
+
+ if (is_native) {
+ base::FilePath file_path;
+ if (!ReadParam(m, iter, &file_path))
+ return false;
+
+ base::string16 display_name;
+ if (!ReadParam(m, iter, &display_name))
+ return false;
+
+ *p = blink::mojom::FileChooserFileInfo::NewNativeFile(
+ blink::mojom::NativeFileInfo::New(file_path, display_name));
+ } else {
+ GURL file_system_url;
+ if (!ReadParam(m, iter, &file_system_url))
+ return false;
+
+ base::Time modification_time;
+ if (!ReadParam(m, iter, &modification_time))
+ return false;
+
+ int64_t length;
+ if (!ReadParam(m, iter, &length))
+ return false;
+
+ *p = blink::mojom::FileChooserFileInfo::NewFileSystem(
+ blink::mojom::FileSystemFileInfo::New(file_system_url,
+ modification_time, length));
+ }
+ return true;
+}
+
+void ParamTraits<blink::mojom::FileChooserFileInfoPtr>::Log(const param_type& p,
+ std::string* l) {
+ l->append("blink::mojom::FileChooserFileInfo(");
+ if (p->is_native_file()) {
+ l->append("NativeFileInfo(");
+ LogParam(p->get_native_file()->file_path, l);
+ l->append(", ");
+ LogParam(p->get_native_file()->display_name, l);
+ } else {
+ l->append("FileSystemFileInfo(");
+ LogParam(p->get_file_system()->url, l);
+ l->append(", ");
+ LogParam(p->get_file_system()->modification_time, l);
+ l->append(", ");
+ LogParam(p->get_file_system()->length, l);
+ }
+ l->append("))");
+}
+
} // namespace IPC
// Generate param traits write methods.
diff --git a/chromium/content/common/content_param_traits.h b/chromium/content/common/content_param_traits.h
index e9a29ff4075..d5f57bca4ad 100644
--- a/chromium/content/common/content_param_traits.h
+++ b/chromium/content/common/content_param_traits.h
@@ -18,8 +18,9 @@
#include "content/common/cursors/webcursor.h"
#include "ipc/ipc_mojo_param_traits.h"
#include "storage/common/blob_storage/blob_handle.h"
+#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
#include "third_party/blink/public/platform/web_input_event.h"
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
namespace blink {
class MessagePortChannel;
@@ -156,6 +157,17 @@ struct CONTENT_EXPORT ParamTraits<viz::SurfaceInfo> {
static void Log(const param_type& p, std::string* l);
};
+// TODO(tkent): Remove this when we switch to mojo. crbug.com/869257
+template <>
+struct CONTENT_EXPORT ParamTraits<blink::mojom::FileChooserFileInfoPtr> {
+ using param_type = blink::mojom::FileChooserFileInfoPtr;
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
} // namespace IPC
#endif // CONTENT_COMMON_CONTENT_PARAM_TRAITS_H_
diff --git a/chromium/content/common/content_param_traits_macros.h b/chromium/content/common/content_param_traits_macros.h
index aaddd3ed6d3..a2c4c7a1b0e 100644
--- a/chromium/content/common/content_param_traits_macros.h
+++ b/chromium/content/common/content_param_traits_macros.h
@@ -14,10 +14,10 @@
#include "content/common/download/mhtml_save_status.h"
#include "content/common/render_widget_surface_properties.h"
#include "content/public/common/input_event_ack_state.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "ipc/ipc_message_macros.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/web_content_security_policy.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/public/web/web_ime_text_span.h"
@@ -30,8 +30,8 @@
IPC_ENUM_TRAITS_MAX_VALUE(content::InputEventAckState,
content::INPUT_EVENT_ACK_STATE_MAX)
-IPC_ENUM_TRAITS_MAX_VALUE(content::RequestContextType,
- content::REQUEST_CONTEXT_TYPE_LAST)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::RequestContextType,
+ blink::mojom::RequestContextType::kMaxValue)
IPC_ENUM_TRAITS_MAX_VALUE(content::ResourceType,
content::RESOURCE_TYPE_LAST_TYPE - 1)
IPC_ENUM_TRAITS_MAX_VALUE(content::MhtmlSaveStatus,
@@ -69,9 +69,9 @@ IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::RenderWidgetSurfaceProperties)
IPC_STRUCT_TRAITS_MEMBER(size)
IPC_STRUCT_TRAITS_MEMBER(device_scale_factor)
-#ifdef OS_ANDROID
IPC_STRUCT_TRAITS_MEMBER(top_controls_height)
IPC_STRUCT_TRAITS_MEMBER(top_controls_shown_ratio)
+#ifdef OS_ANDROID
IPC_STRUCT_TRAITS_MEMBER(bottom_controls_height)
IPC_STRUCT_TRAITS_MEMBER(bottom_controls_shown_ratio)
IPC_STRUCT_TRAITS_MEMBER(selection)
diff --git a/chromium/content/common/content_security_policy/content_security_policy.cc b/chromium/content/common/content_security_policy/content_security_policy.cc
index 0a5565c573c..d024d304959 100644
--- a/chromium/content/common/content_security_policy/content_security_policy.cc
+++ b/chromium/content/common/content_security_policy/content_security_policy.cc
@@ -57,7 +57,7 @@ void ReportViolation(CSPContext* context,
const CSPDirective& directive,
const CSPDirective::Name directive_name,
const GURL& url,
- bool is_redirect,
+ bool has_followed_redirect,
const SourceLocation& source_location) {
// We should never have a violation against `child-src` or `default-src`
// directly; the effective directive should always be one of the explicit
@@ -71,8 +71,8 @@ void ReportViolation(CSPContext* context,
// renderers.
GURL safe_url = url;
SourceLocation safe_source_location = source_location;
- context->SanitizeDataForUseInCspViolation(is_redirect, directive_name,
- &safe_url, &safe_source_location);
+ context->SanitizeDataForUseInCspViolation(
+ has_followed_redirect, directive_name, &safe_url, &safe_source_location);
std::stringstream message;
@@ -103,7 +103,7 @@ void ReportViolation(CSPContext* context,
CSPDirective::NameToString(directive.name),
CSPDirective::NameToString(directive_name), message.str(), safe_url,
policy.report_endpoints, policy.use_reporting_api,
- policy.header.header_value, policy.header.type, is_redirect,
+ policy.header.header_value, policy.header.type, has_followed_redirect,
safe_source_location));
}
@@ -112,16 +112,16 @@ bool AllowDirective(CSPContext* context,
const CSPDirective& directive,
CSPDirective::Name directive_name,
const GURL& url,
- bool is_redirect,
+ bool has_followed_redirect,
bool is_response_check,
const SourceLocation& source_location) {
- if (CSPSourceList::Allow(directive.source_list, url, context, is_redirect,
- is_response_check)) {
+ if (CSPSourceList::Allow(directive.source_list, url, context,
+ has_followed_redirect, is_response_check)) {
return true;
}
- ReportViolation(context, policy, directive, directive_name, url, is_redirect,
- source_location);
+ ReportViolation(context, policy, directive, directive_name, url,
+ has_followed_redirect, source_location);
return false;
}
@@ -164,7 +164,7 @@ ContentSecurityPolicy::~ContentSecurityPolicy() = default;
bool ContentSecurityPolicy::Allow(const ContentSecurityPolicy& policy,
CSPDirective::Name directive_name,
const GURL& url,
- bool is_redirect,
+ bool has_followed_redirect,
bool is_response_check,
CSPContext* context,
const SourceLocation& source_location,
@@ -184,9 +184,9 @@ bool ContentSecurityPolicy::Allow(const ContentSecurityPolicy& policy,
const CSPDirective* current_directive =
FindDirective(current_directive_name, policy.directives);
if (current_directive) {
- bool allowed =
- AllowDirective(context, policy, *current_directive, directive_name,
- url, is_redirect, is_response_check, source_location);
+ bool allowed = AllowDirective(context, policy, *current_directive,
+ directive_name, url, has_followed_redirect,
+ is_response_check, source_location);
return allowed ||
policy.header.type == blink::kWebContentSecurityPolicyTypeReport;
}
diff --git a/chromium/content/common/content_security_policy/content_security_policy.h b/chromium/content/common/content_security_policy/content_security_policy.h
index abac1dead71..70113daae39 100644
--- a/chromium/content/common/content_security_policy/content_security_policy.h
+++ b/chromium/content/common/content_security_policy/content_security_policy.h
@@ -44,7 +44,7 @@ struct CONTENT_EXPORT ContentSecurityPolicy {
static bool Allow(const ContentSecurityPolicy& policy,
CSPDirective::Name directive,
const GURL& url,
- bool is_redirect,
+ bool has_followed_redirect,
bool is_response_check,
CSPContext* context,
const SourceLocation& source_location,
diff --git a/chromium/content/common/content_security_policy/content_security_policy_unittest.cc b/chromium/content/common/content_security_policy/content_security_policy_unittest.cc
index a7e57115ffc..a8b5be93ab8 100644
--- a/chromium/content/common/content_security_policy/content_security_policy_unittest.cc
+++ b/chromium/content/common/content_security_policy/content_security_policy_unittest.cc
@@ -269,7 +269,6 @@ TEST(ContentSecurityPolicy, NavigateToChecks) {
struct TestCase {
const CSPSourceList& navigate_to_list;
const GURL& url;
- bool is_redirect;
bool is_response_check;
bool expected;
bool is_form_submission;
@@ -277,48 +276,45 @@ TEST(ContentSecurityPolicy, NavigateToChecks) {
} cases[] = {
// Basic source matching.
{none_source_list, GURL("https://example.test"), false, false, false,
- false, nullptr},
- {example_source_list, GURL("https://example.test"), false, false, true,
- false, nullptr},
+ nullptr},
+ {example_source_list, GURL("https://example.test"), false, true, false,
+ nullptr},
{example_source_list, GURL("https://not-example.test"), false, false,
- false, false, nullptr},
- {self_source_list, GURL("https://example.test"), false, false, true,
false, nullptr},
+ {self_source_list, GURL("https://example.test"), false, true, false,
+ nullptr},
// Checking allow_redirect flag interactions.
- {redirects_source_list, GURL("https://example.test"), false, false, true,
- false, nullptr},
- {redirects_source_list, GURL("https://example.test"), true, false, true,
- false, nullptr},
- {redirects_source_list, GURL("https://example.test"), true, true, true,
- false, nullptr},
{redirects_source_list, GURL("https://example.test"), false, true, false,
- false, nullptr},
+ nullptr},
+ {redirects_source_list, GURL("https://example.test"), true, false, false,
+ nullptr},
{redirects_example_source_list, GURL("https://example.test"), false, true,
- true, false, nullptr},
+ false, nullptr},
+ {redirects_example_source_list, GURL("https://example.test"), true, true,
+ false, nullptr},
// Interaction with form-action
// Form submission without form-action present
- {none_source_list, GURL("https://example.test"), false, false, false,
- true, nullptr},
- {example_source_list, GURL("https://example.test"), false, false, true,
- true, nullptr},
+ {none_source_list, GURL("https://example.test"), false, false, true,
+ nullptr},
+ {example_source_list, GURL("https://example.test"), false, true, true,
+ nullptr},
{example_source_list, GURL("https://not-example.test"), false, false,
- false, true, nullptr},
- {self_source_list, GURL("https://example.test"), false, false, true, true,
+ true, nullptr},
+ {self_source_list, GURL("https://example.test"), false, true, true,
nullptr},
// Form submission with form-action present
- {none_source_list, GURL("https://example.test"), false, false, true, true,
+ {none_source_list, GURL("https://example.test"), false, true, true,
&example_source_list},
- {example_source_list, GURL("https://example.test"), false, false, true,
- true, &example_source_list},
- {example_source_list, GURL("https://not-example.test"), false, false,
- true, true, &example_source_list},
- {self_source_list, GURL("https://example.test"), false, false, true, true,
+ {example_source_list, GURL("https://example.test"), false, true, true,
+ &example_source_list},
+ {example_source_list, GURL("https://not-example.test"), false, true, true,
+ &example_source_list},
+ {self_source_list, GURL("https://example.test"), false, true, true,
&example_source_list},
-
};
for (const auto& test : cases) {
@@ -333,11 +329,14 @@ TEST(ContentSecurityPolicy, NavigateToChecks) {
ContentSecurityPolicy policy(EmptyCspHeader(), directives,
report_end_points, false);
- EXPECT_EQ(test.expected,
- ContentSecurityPolicy::Allow(
- policy, CSPDirective::NavigateTo, test.url, test.is_redirect,
- test.is_response_check, &context, SourceLocation(),
- test.is_form_submission));
+ EXPECT_EQ(test.expected, ContentSecurityPolicy::Allow(
+ policy, CSPDirective::NavigateTo, test.url,
+ true, test.is_response_check, &context,
+ SourceLocation(), test.is_form_submission));
+ EXPECT_EQ(test.expected, ContentSecurityPolicy::Allow(
+ policy, CSPDirective::NavigateTo, test.url,
+ false, test.is_response_check, &context,
+ SourceLocation(), test.is_form_submission));
}
}
diff --git a/chromium/content/common/content_security_policy/csp_context.cc b/chromium/content/common/content_security_policy/csp_context.cc
index 94b0a96ce6e..f83e3166ba5 100644
--- a/chromium/content/common/content_security_policy/csp_context.cc
+++ b/chromium/content/common/content_security_policy/csp_context.cc
@@ -32,7 +32,7 @@ CSPContext::~CSPContext() {}
bool CSPContext::IsAllowedByCsp(CSPDirective::Name directive_name,
const GURL& url,
- bool is_redirect,
+ bool has_followed_redirect,
bool is_response_check,
const SourceLocation& source_location,
CheckCSPDisposition check_csp_disposition,
@@ -44,8 +44,8 @@ bool CSPContext::IsAllowedByCsp(CSPDirective::Name directive_name,
for (const auto& policy : policies_) {
if (ShouldCheckPolicy(policy, check_csp_disposition)) {
allow &= ContentSecurityPolicy::Allow(
- policy, directive_name, url, is_redirect, is_response_check, this,
- source_location, is_form_submission);
+ policy, directive_name, url, has_followed_redirect, is_response_check,
+ this, source_location, is_form_submission);
}
}
@@ -80,7 +80,7 @@ void CSPContext::SetSelf(const url::Origin origin) {
// When the origin is unique, no URL should match with 'self'. That's why
// |self_source_| stays undefined here.
- if (origin.unique())
+ if (origin.opaque())
return;
if (origin.scheme() == url::kFileScheme) {
@@ -105,7 +105,7 @@ bool CSPContext::SchemeShouldBypassCSP(const base::StringPiece& scheme) {
}
void CSPContext::SanitizeDataForUseInCspViolation(
- bool is_redirect,
+ bool has_followed_redirect,
CSPDirective::Name directive,
GURL* blocked_url,
SourceLocation* source_location) const {
diff --git a/chromium/content/common/content_security_policy/csp_context.h b/chromium/content/common/content_security_policy/csp_context.h
index e7f1ceedbe9..fb86c02fc4c 100644
--- a/chromium/content/common/content_security_policy/csp_context.h
+++ b/chromium/content/common/content_security_policy/csp_context.h
@@ -48,7 +48,7 @@ class CONTENT_EXPORT CSPContext {
// Returns true when the request can proceed, false otherwise.
bool IsAllowedByCsp(CSPDirective::Name directive_name,
const GURL& url,
- bool is_redirect,
+ bool has_followed_redirect,
bool is_response_check,
const SourceLocation& source_location,
CheckCSPDisposition check_csp_disposition,
@@ -92,7 +92,7 @@ class CONTENT_EXPORT CSPContext {
// without the round trip in the renderer process.
// See https://crbug.com/721329
virtual void SanitizeDataForUseInCspViolation(
- bool is_redirect,
+ bool has_followed_redirect,
CSPDirective::Name directive,
GURL* blocked_url,
SourceLocation* source_location) const;
diff --git a/chromium/content/common/content_security_policy/csp_source.cc b/chromium/content/common/content_security_policy/csp_source.cc
index 69b7db2ca28..9ada01e8dbb 100644
--- a/chromium/content/common/content_security_policy/csp_source.cc
+++ b/chromium/content/common/content_security_policy/csp_source.cc
@@ -103,8 +103,8 @@ PortMatchingResult SourceAllowPort(const CSPSource& source, const GURL& url) {
bool SourceAllowPath(const CSPSource& source,
const GURL& url,
- bool is_redirect) {
- if (is_redirect)
+ bool has_followed_redirect) {
+ if (has_followed_redirect)
return true;
if (source.path.empty() || url.path().empty())
@@ -174,7 +174,7 @@ CSPSource::~CSPSource() = default;
bool CSPSource::Allow(const CSPSource& source,
const GURL& url,
CSPContext* context,
- bool is_redirect) {
+ bool has_followed_redirect) {
if (source.IsSchemeOnly())
return SourceAllowScheme(source, url, context) !=
SchemeMatchingResult::NotMatching;
@@ -190,7 +190,7 @@ bool CSPSource::Allow(const CSPSource& source,
return schemeResult != SchemeMatchingResult::NotMatching &&
SourceAllowHost(source, url) &&
portResult != PortMatchingResult::NotMatching &&
- SourceAllowPath(source, url, is_redirect);
+ SourceAllowPath(source, url, has_followed_redirect);
}
std::string CSPSource::ToString() const {
diff --git a/chromium/content/common/content_security_policy/csp_source.h b/chromium/content/common/content_security_policy/csp_source.h
index 62670ed77f8..de2c051945c 100644
--- a/chromium/content/common/content_security_policy/csp_source.h
+++ b/chromium/content/common/content_security_policy/csp_source.h
@@ -59,7 +59,7 @@ struct CONTENT_EXPORT CSPSource {
static bool Allow(const CSPSource& source,
const GURL& url,
CSPContext* context,
- bool is_redirect = false);
+ bool has_followed_redirect = false);
};
} // namespace content
diff --git a/chromium/content/common/content_security_policy/csp_source_list.cc b/chromium/content/common/content_security_policy/csp_source_list.cc
index 4bf358daa1d..343c4c1bb07 100644
--- a/chromium/content/common/content_security_policy/csp_source_list.cc
+++ b/chromium/content/common/content_security_policy/csp_source_list.cc
@@ -11,9 +11,9 @@ namespace {
bool AllowFromSources(const GURL& url,
const std::vector<CSPSource>& sources,
CSPContext* context,
- bool is_redirect) {
+ bool has_followed_redirect) {
for (const CSPSource& source : sources) {
- if (CSPSource::Allow(source, url, context, is_redirect))
+ if (CSPSource::Allow(source, url, context, has_followed_redirect))
return true;
}
return false;
@@ -22,15 +22,18 @@ bool AllowFromSources(const GURL& url,
}; // namespace
CSPSourceList::CSPSourceList()
- : allow_self(false), allow_star(false), allow_redirects(false), sources() {}
+ : allow_self(false),
+ allow_star(false),
+ allow_response_redirects(false),
+ sources() {}
CSPSourceList::CSPSourceList(bool allow_self,
bool allow_star,
- bool allow_redirects,
+ bool allow_response_redirects,
std::vector<CSPSource> sources)
: allow_self(allow_self),
allow_star(allow_star),
- allow_redirects(allow_redirects),
+ allow_response_redirects(allow_response_redirects),
sources(sources) {}
CSPSourceList::CSPSourceList(const CSPSourceList&) = default;
@@ -40,21 +43,16 @@ CSPSourceList::~CSPSourceList() = default;
bool CSPSourceList::Allow(const CSPSourceList& source_list,
const GURL& url,
CSPContext* context,
- bool is_redirect,
+ bool has_followed_redirect,
bool is_response_check) {
// If the source list allows all redirects, the decision can't be made until
// the response is received.
- if (source_list.allow_redirects && !is_response_check)
+ if (source_list.allow_response_redirects && !is_response_check)
return true;
// If the source list does not allow all redirects, the decision has already
// been made when checking the request.
- if (!source_list.allow_redirects && is_response_check)
- return true;
-
- // If the source list allows all redirects, all responses that are a redirect
- // are allowed.
- if (source_list.allow_redirects && is_response_check && is_redirect)
+ if (!source_list.allow_response_redirects && is_response_check)
return true;
// Wildcards match network schemes ('http', 'https', 'ftp', 'ws', 'wss'), and
@@ -73,11 +71,12 @@ bool CSPSourceList::Allow(const CSPSourceList& source_list,
if (source_list.allow_self && context->self_source() &&
CSPSource::Allow(context->self_source().value(), url, context,
- is_redirect)) {
+ has_followed_redirect)) {
return true;
}
- return AllowFromSources(url, source_list.sources, context, is_redirect);
+ return AllowFromSources(url, source_list.sources, context,
+ has_followed_redirect);
}
std::string CSPSourceList::ToString() const {
diff --git a/chromium/content/common/content_security_policy/csp_source_list.h b/chromium/content/common/content_security_policy/csp_source_list.h
index 94af77554dd..a1ce31f83c0 100644
--- a/chromium/content/common/content_security_policy/csp_source_list.h
+++ b/chromium/content/common/content_security_policy/csp_source_list.h
@@ -18,7 +18,7 @@ struct CONTENT_EXPORT CSPSourceList {
CSPSourceList();
CSPSourceList(bool allow_self,
bool allow_star,
- bool allow_redirects,
+ bool allow_response_redirects,
std::vector<CSPSource> source_list);
CSPSourceList(const CSPSourceList&);
~CSPSourceList();
@@ -27,7 +27,7 @@ struct CONTENT_EXPORT CSPSourceList {
// on the source list itself.
bool allow_self;
bool allow_star;
- bool allow_redirects;
+ bool allow_response_redirects;
std::vector<CSPSource> sources;
std::string ToString() const;
@@ -39,7 +39,7 @@ struct CONTENT_EXPORT CSPSourceList {
static bool Allow(const CSPSourceList& source_list,
const GURL& url,
CSPContext* context,
- bool is_redirect = false,
+ bool has_followed_redirect = false,
bool is_response_check = false);
};
diff --git a/chromium/content/common/dom_storage/dom_storage_namespace_ids.cc b/chromium/content/common/dom_storage/dom_storage_namespace_ids.cc
deleted file mode 100644
index dec86ea9549..00000000000
--- a/chromium/content/common/dom_storage/dom_storage_namespace_ids.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/dom_storage/dom_storage_namespace_ids.h"
-
-#include <algorithm>
-
-#include "base/guid.h"
-
-namespace content {
-
-std::string AllocateSessionStorageNamespaceId() {
- std::string guid = base::GenerateGUID();
- std::replace(guid.begin(), guid.end(), '-', '_');
- // The database deserialization code makes assumptions based on this length.
- DCHECK_EQ(guid.size(), kSessionStorageNamespaceIdLength);
- return guid;
-}
-
-} // namespace content
diff --git a/chromium/content/common/dom_storage/dom_storage_namespace_ids.h b/chromium/content/common/dom_storage/dom_storage_namespace_ids.h
deleted file mode 100644
index 331f729e9aa..00000000000
--- a/chromium/content/common/dom_storage/dom_storage_namespace_ids.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#ifndef CONTENT_COMMON_DOM_STORAGE_DOM_STORAGE_NAMESPACE_IDS_H_
-#define CONTENT_COMMON_DOM_STORAGE_DOM_STORAGE_NAMESPACE_IDS_H_
-
-#include <string>
-
-namespace content {
-
-// The length of session storage namespace ids.
-constexpr const size_t kSessionStorageNamespaceIdLength = 36;
-
-// Allocates a unique session storage namespace id.
-std::string AllocateSessionStorageNamespaceId();
-
-} // namespace content
-
-#endif // CONTENT_COMMON_DOM_STORAGE_DOM_STORAGE_NAMESPACE_IDS_H_
diff --git a/chromium/content/common/font_cache_dispatcher_win.cc b/chromium/content/common/font_cache_dispatcher_win.cc
index 9337781bfdd..680062dee42 100644
--- a/chromium/content/common/font_cache_dispatcher_win.cc
+++ b/chromium/content/common/font_cache_dispatcher_win.cc
@@ -12,6 +12,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string16.h"
+#include "base/thread_annotations.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/service_manager/public/cpp/bind_source_info.h"
@@ -125,8 +126,8 @@ class FontCache {
FontCache() {
}
- std::map<base::string16, CacheElement> cache_;
- DispatcherToFontNames dispatcher_font_map_;
+ std::map<base::string16, CacheElement> cache_ GUARDED_BY(mutex_);
+ DispatcherToFontNames dispatcher_font_map_ GUARDED_BY(mutex_);
base::Lock mutex_;
DISALLOW_COPY_AND_ASSIGN(FontCache);
diff --git a/chromium/content/common/frame.mojom b/chromium/content/common/frame.mojom
index c2ce967c17a..25346dc852e 100644
--- a/chromium/content/common/frame.mojom
+++ b/chromium/content/common/frame.mojom
@@ -20,8 +20,10 @@ import "services/service_manager/public/mojom/interface_provider.mojom";
import "services/viz/public/interfaces/compositing/surface_id.mojom";
import "third_party/blink/public/mojom/blob/blob_url_store.mojom";
import "third_party/blink/public/mojom/feature_policy/feature_policy.mojom";
+import "third_party/blink/public/mojom/frame/navigation_initiator.mojom";
import "third_party/blink/public/platform/referrer.mojom";
import "third_party/blink/public/web/commit_result.mojom";
+import "third_party/blink/public/web/devtools_agent.mojom";
import "third_party/blink/public/web/window_features.mojom";
import "ui/base/mojo/window_open_disposition.mojom";
import "url/mojom/url.mojom";
@@ -150,6 +152,14 @@ interface FrameNavigationControl {
// receiver's existing bundle.
UpdateSubresourceLoaderFactories(
URLLoaderFactoryBundle subresource_loader_factories);
+
+ // Returns a DevToolsAgent interface for this frame, used for
+ // remote debugging. See DevToolsAgent for details.
+ // Returned DevToolsAgent must be associated with navigation control,
+ // due to various ordering dependencies between DevTools protocol and
+ // navigation.
+ BindDevToolsAgent(associated blink.mojom.DevToolsAgentHost agent_host,
+ associated blink.mojom.DevToolsAgent& agent);
};
// Implemented by the frame (e.g. renderer processes).
@@ -306,7 +316,8 @@ interface FrameHost {
CommonNavigationParams common_params,
BeginNavigationParams begin_params,
blink.mojom.BlobURLToken? blob_url_token,
- associated NavigationClient? navigation_client);
+ associated NavigationClient? navigation_client,
+ blink.mojom.NavigationInitiator? navigation_initiator);
// Sent when a subresource response has started.
// |cert_status| is the bitmask of status info of the SSL certificate. (see
@@ -358,4 +369,11 @@ interface FrameHost {
// Notifies the browser that the current frame has either become or is no
// longer fullscreen.
FullscreenStateChanged(bool is_fullscreen);
+
+ // Updates information to determine whether a user gesture should carryover to
+ // future navigations. This is needed so navigations within a certain
+ // timeframe of a request initiated by a gesture will be treated as if they
+ // were initiated by a gesture too, otherwise the navigation may be blocked.
+ [EnableIf=is_android]
+ UpdateUserGestureCarryoverInfo();
};
diff --git a/chromium/content/common/frame_message_enums.h b/chromium/content/common/frame_message_enums.h
index c2b16621fde..85943bf1ad2 100644
--- a/chromium/content/common/frame_message_enums.h
+++ b/chromium/content/common/frame_message_enums.h
@@ -5,7 +5,7 @@
#ifndef CONTENT_COMMON_FRAME_MESSAGE_ENUMS_H_
#define CONTENT_COMMON_FRAME_MESSAGE_ENUMS_H_
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
struct FrameMsg_Navigate_Type {
public:
diff --git a/chromium/content/common/frame_messages.h b/chromium/content/common/frame_messages.h
index c42a88101a4..eee8d28ea50 100644
--- a/chromium/content/common/frame_messages.h
+++ b/chromium/content/common/frame_messages.h
@@ -40,18 +40,16 @@
#include "content/public/common/console_message_level.h"
#include "content/public/common/context_menu_params.h"
#include "content/public/common/favicon_url.h"
-#include "content/public/common/file_chooser_file_info.h"
-#include "content/public/common/file_chooser_params.h"
#include "content/public/common/frame_navigate_params.h"
#include "content/public/common/javascript_dialog_type.h"
#include "content/public/common/page_importance_signals.h"
#include "content/public/common/page_state.h"
#include "content/public/common/previews_state.h"
#include "content/public/common/referrer.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/screen_info.h"
#include "content/public/common/stop_find_action.h"
#include "content/public/common/three_d_api_types.h"
+#include "content/public/common/was_activated_option.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_platform_file.h"
#include "mojo/public/cpp/system/message_pipe.h"
@@ -59,15 +57,16 @@
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/common/frame/frame_policy.h"
#include "third_party/blink/public/common/frame/user_activation_update_type.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
-#include "third_party/blink/public/common/message_port/transferable_message.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/transferable_message.h"
+#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/web_focus_type.h"
#include "third_party/blink/public/platform/web_insecure_request_policy.h"
#include "third_party/blink/public/platform/web_intrinsic_sizing_info.h"
#include "third_party/blink/public/platform/web_scroll_into_view_params.h"
#include "third_party/blink/public/platform/web_scroll_types.h"
#include "third_party/blink/public/platform/web_sudden_termination_disabler_type.h"
-#include "third_party/blink/public/web/web_find_options.h"
#include "third_party/blink/public/web/web_frame_owner_properties.h"
#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h"
#include "third_party/blink/public/web/web_fullscreen_options.h"
@@ -128,8 +127,8 @@ IPC_ENUM_TRAITS(blink::WebSandboxFlags) // Bitmask.
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebTreeScopeType,
blink::WebTreeScopeType::kLast)
IPC_ENUM_TRAITS_MAX_VALUE(ui::MenuSourceType, ui::MENU_SOURCE_TYPE_LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(content::FileChooserParams::Mode,
- content::FileChooserParams::Save)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::FileChooserParams::Mode,
+ blink::mojom::FileChooserParams::Mode::kMaxValue)
IPC_ENUM_TRAITS_MAX_VALUE(content::CSPDirective::Name,
content::CSPDirective::NameLast)
IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::FeaturePolicyFeature,
@@ -142,6 +141,8 @@ IPC_ENUM_TRAITS_MAX_VALUE(blink::UserActivationUpdateType,
blink::UserActivationUpdateType::kMaxValue)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebMediaPlayerAction::Type,
blink::WebMediaPlayerAction::Type::kTypeLast)
+IPC_ENUM_TRAITS_MAX_VALUE(content::WasActivatedOption,
+ content::WasActivatedOption::kMaxValue)
IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::WebScrollDirection,
blink::kFirstScrollDirection,
blink::kLastScrollDirection)
@@ -426,12 +427,6 @@ IPC_STRUCT_BEGIN_WITH_PARENT(FrameHostMsg_DidCommitProvisionalLoad_Params,
// considered potentially trustworthy.
IPC_STRUCT_MEMBER(bool, has_potentially_trustworthy_unique_origin)
- // See WebSearchableFormData for a description of these.
- // Not used by PlzNavigate: in that case these fields are sent to the browser
- // in mojom::BeginNavigationParams.
- IPC_STRUCT_MEMBER(GURL, searchable_form_url)
- IPC_STRUCT_MEMBER(std::string, searchable_form_encoding)
-
// This is a non-decreasing value that the browser process can use to
// identify and discard compositor frames that correspond to now-unloaded
// web content.
@@ -465,6 +460,12 @@ IPC_STRUCT_TRAITS_BEGIN(content::SourceLocation)
IPC_STRUCT_TRAITS_MEMBER(column_number)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(content::InitiatorCSPInfo)
+ IPC_STRUCT_TRAITS_MEMBER(should_check_main_world_csp)
+ IPC_STRUCT_TRAITS_MEMBER(initiator_csp)
+ IPC_STRUCT_TRAITS_MEMBER(initiator_self_source)
+IPC_STRUCT_TRAITS_END()
+
IPC_STRUCT_TRAITS_BEGIN(content::CommonNavigationParams)
IPC_STRUCT_TRAITS_MEMBER(url)
IPC_STRUCT_TRAITS_MEMBER(referrer)
@@ -479,11 +480,9 @@ IPC_STRUCT_TRAITS_BEGIN(content::CommonNavigationParams)
IPC_STRUCT_TRAITS_MEMBER(method)
IPC_STRUCT_TRAITS_MEMBER(post_data)
IPC_STRUCT_TRAITS_MEMBER(source_location)
- IPC_STRUCT_TRAITS_MEMBER(should_check_main_world_csp)
IPC_STRUCT_TRAITS_MEMBER(has_user_gesture)
IPC_STRUCT_TRAITS_MEMBER(started_from_context_menu)
- IPC_STRUCT_TRAITS_MEMBER(initiator_csp)
- IPC_STRUCT_TRAITS_MEMBER(initiator_self_source)
+ IPC_STRUCT_TRAITS_MEMBER(initiator_csp_info)
IPC_STRUCT_TRAITS_MEMBER(origin_policy)
IPC_STRUCT_TRAITS_MEMBER(input_start)
IPC_STRUCT_TRAITS_END()
@@ -677,6 +676,7 @@ IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::CSPSourceList)
IPC_STRUCT_TRAITS_MEMBER(allow_self)
IPC_STRUCT_TRAITS_MEMBER(allow_star)
+ IPC_STRUCT_TRAITS_MEMBER(allow_response_redirects)
IPC_STRUCT_TRAITS_MEMBER(sources)
IPC_STRUCT_TRAITS_END()
@@ -711,31 +711,20 @@ IPC_STRUCT_TRAITS_BEGIN(content::CSPViolationParams)
IPC_STRUCT_TRAITS_MEMBER(source_location)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(content::FileChooserFileInfo)
- IPC_STRUCT_TRAITS_MEMBER(file_path)
- IPC_STRUCT_TRAITS_MEMBER(display_name)
- IPC_STRUCT_TRAITS_MEMBER(file_system_url)
- IPC_STRUCT_TRAITS_MEMBER(modification_time)
- IPC_STRUCT_TRAITS_MEMBER(length)
- IPC_STRUCT_TRAITS_MEMBER(is_directory)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(content::FileChooserParams)
+IPC_STRUCT_TRAITS_BEGIN(blink::mojom::FileChooserParams)
IPC_STRUCT_TRAITS_MEMBER(mode)
IPC_STRUCT_TRAITS_MEMBER(title)
IPC_STRUCT_TRAITS_MEMBER(default_file_name)
IPC_STRUCT_TRAITS_MEMBER(accept_types)
IPC_STRUCT_TRAITS_MEMBER(need_local_path)
-#if defined(OS_ANDROID)
- IPC_STRUCT_TRAITS_MEMBER(capture)
-#endif
+ IPC_STRUCT_TRAITS_MEMBER(use_media_capture)
IPC_STRUCT_TRAITS_MEMBER(requestor)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_BEGIN(FrameMsg_MixedContentFound_Params)
IPC_STRUCT_MEMBER(GURL, main_resource_url)
IPC_STRUCT_MEMBER(GURL, mixed_content_url)
- IPC_STRUCT_MEMBER(content::RequestContextType, request_context_type)
+ IPC_STRUCT_MEMBER(blink::mojom::RequestContextType, request_context_type)
IPC_STRUCT_MEMBER(bool, was_allowed)
IPC_STRUCT_MEMBER(bool, had_redirect)
IPC_STRUCT_MEMBER(content::SourceLocation, source_location)
@@ -797,7 +786,8 @@ IPC_STRUCT_TRAITS_END()
// Messages sent from the browser to the renderer.
// Notifies the embedding frame that the intrinsic sizing info parameters
-// of a child frame have changed.
+// of a child frame have changed. Generated when the browser receives a
+// WidgetHostMsg_IntrinsicSizingInfoChanged.
IPC_MESSAGE_ROUTED1(FrameMsg_IntrinsicSizingInfoOfChildChanged,
blink::WebIntrinsicSizingInfo)
@@ -1124,7 +1114,7 @@ IPC_MESSAGE_ROUTED1(FrameMsg_SetHasReceivedUserGestureBeforeNavigation,
bool /* value */)
IPC_MESSAGE_ROUTED1(FrameMsg_RunFileChooserResponse,
- std::vector<content::FileChooserFileInfo>)
+ std::vector<blink::mojom::FileChooserFileInfoPtr>)
// Updates the renderer with a list of unique blink::UseCounter::Feature values
// representing Blink features used, performed or encountered by the browser
@@ -1193,12 +1183,6 @@ IPC_MESSAGE_ROUTED2(FrameHostMsg_RenderProcessGone,
// Sent by the renderer when the frame becomes focused.
IPC_MESSAGE_ROUTED0(FrameHostMsg_FrameFocused)
-// Sent when the renderer starts a provisional load for a frame.
-IPC_MESSAGE_ROUTED3(FrameHostMsg_DidStartProvisionalLoad,
- GURL /* url */,
- std::vector<GURL> /* redirect_chain */,
- base::TimeTicks /* navigation_start */)
-
// Sent when the renderer fails a provisional load with an error.
IPC_MESSAGE_ROUTED1(FrameHostMsg_DidFailProvisionalLoadWithError,
FrameHostMsg_DidFailProvisionalLoadWithError_Params)
@@ -1211,12 +1195,6 @@ IPC_MESSAGE_ROUTED3(FrameHostMsg_DidFailLoadWithError,
int /* error_code */,
base::string16 /* error_description */)
-// Sent when the renderer starts loading the page. |to_different_document| will
-// be true unless the load is a fragment navigation, or triggered by
-// history.pushState/replaceState.
-IPC_MESSAGE_ROUTED1(FrameHostMsg_DidStartLoading,
- bool /* to_different_document */)
-
// Sent when the renderer is done loading a page.
IPC_MESSAGE_ROUTED0(FrameHostMsg_DidStopLoading)
@@ -1483,7 +1461,11 @@ IPC_MESSAGE_ROUTED3(FrameHostMsg_UpdateViewportIntersection,
// Informs the child that the frame has changed visibility.
IPC_MESSAGE_ROUTED1(FrameHostMsg_VisibilityChanged, bool /* visible */)
-// Sets or unsets the inert bit on a remote frame.
+// Sent by a RenderFrameProxy to the browser signaling that the renderer
+// has determined the DOM subtree it represents is inert and should no
+// longer process input events. Also see WidgetMsg_SetIsInert.
+//
+// https://html.spec.whatwg.org/multipage/interaction.html#inert
IPC_MESSAGE_ROUTED1(FrameHostMsg_SetIsInert, bool /* inert */)
// Sets the inherited effective touch action on a remote frame.
@@ -1694,7 +1676,8 @@ IPC_MESSAGE_ROUTED0(FrameHostMsg_RequestOverlayRoutingToken)
// Asks the browser to display the file chooser. The result is returned in a
// FrameMsg_RunFileChooserResponse message.
-IPC_MESSAGE_ROUTED1(FrameHostMsg_RunFileChooser, content::FileChooserParams)
+IPC_MESSAGE_ROUTED1(FrameHostMsg_RunFileChooser,
+ blink::mojom::FileChooserParams)
// Notification that the urls for the favicon of a site has been determined.
IPC_MESSAGE_ROUTED1(FrameHostMsg_UpdateFaviconURL,
diff --git a/chromium/content/renderer/gpu/actions_parser.cc b/chromium/content/common/input/actions_parser.cc
index d65cfa3e748..785031843f1 100644
--- a/chromium/content/renderer/gpu/actions_parser.cc
+++ b/chromium/content/common/input/actions_parser.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/gpu/actions_parser.h"
+#include "content/common/input/actions_parser.h"
#include "base/format_macros.h"
#include "base/strings/stringprintf.h"
@@ -69,8 +69,7 @@ bool ActionsParser::ParsePointerActionSequence() {
const base::ListValue* pointer_list;
if (!pointer_actions_value_ ||
!pointer_actions_value_->GetAsList(&pointer_list)) {
- error_message_ =
- base::StringPrintf("pointer_list is missing or not a list");
+ error_message_ = std::string("pointer_list is missing or not a list");
return false;
}
@@ -78,7 +77,7 @@ bool ActionsParser::ParsePointerActionSequence() {
const base::DictionaryValue* pointer_actions;
if (!pointer_value.GetAsDictionary(&pointer_actions)) {
error_message_ =
- base::StringPrintf("pointer actions is missing or not a dictionary");
+ std::string("pointer actions is missing or not a dictionary");
return false;
} else if (!ParsePointerActions(*pointer_actions)) {
return false;
@@ -107,13 +106,11 @@ bool ActionsParser::ParsePointerActionSequence() {
bool ActionsParser::ParsePointerActions(const base::DictionaryValue& pointer) {
std::string source_type;
if (!pointer.GetString("source", &source_type)) {
- error_message_ =
- base::StringPrintf("source type is missing or not a string");
+ error_message_ = std::string("source type is missing or not a string");
return false;
} else if (source_type != "touch" && source_type != "mouse" &&
source_type != "pen") {
- error_message_ =
- base::StringPrintf("source type is an unsupported input source");
+ error_message_ = std::string("source type is an unsupported input source");
return false;
}
@@ -122,18 +119,50 @@ bool ActionsParser::ParsePointerActions(const base::DictionaryValue& pointer) {
}
if (source_type_ != source_type) {
- error_message_ = base::StringPrintf(
- "currently multiple input sources are not not supported");
+ error_message_ =
+ std::string("currently multiple input sources are not not supported");
return false;
}
if (source_type != "touch" && action_index_ > 0) {
- error_message_ = base::StringPrintf(
+ error_message_ = std::string(
"for input source type of mouse and pen, we only support one device in "
"one sequence");
return false;
}
+ int pointer_id = -1;
+ if (pointer.HasKey("id")) {
+ if (!pointer.GetInteger("id", &pointer_id)) {
+ error_message_ = std::string("pointer id is not an integer");
+ return false;
+ }
+
+ if (pointer_id < 0) {
+ error_message_ = std::string("pointer id can not be negative");
+ return false;
+ }
+ }
+
+ if (pointer_id != -1) {
+ if (pointer_id_set_.find(pointer_id) != pointer_id_set_.end()) {
+ error_message_ = std::string("pointer id already exists");
+ return false;
+ }
+
+ if (action_index_ != static_cast<int>(pointer_id_set_.size())) {
+ error_message_ = std::string("some pointers do not have a pointer id");
+ return false;
+ }
+
+ pointer_id_set_.insert(pointer_id);
+ } else {
+ if (pointer_id_set_.size() > 0) {
+ error_message_ = std::string("this pointer does not have a pointer id");
+ return false;
+ }
+ }
+
const base::ListValue* actions;
if (!pointer.GetList("actions", &actions)) {
error_message_ = base::StringPrintf(
@@ -141,13 +170,14 @@ bool ActionsParser::ParsePointerActions(const base::DictionaryValue& pointer) {
return false;
}
- if (!ParseActions(*actions))
+ if (!ParseActions(*actions, pointer_id))
return false;
return true;
}
-bool ActionsParser::ParseActions(const base::ListValue& actions) {
+bool ActionsParser::ParseActions(const base::ListValue& actions,
+ int pointer_id) {
SyntheticPointerActionListParams::ParamList param_list;
for (const auto& action_value : actions) {
const base::DictionaryValue* action;
@@ -155,7 +185,7 @@ bool ActionsParser::ParseActions(const base::ListValue& actions) {
error_message_ = base::StringPrintf(
"actions[%d].actions is missing or not a dictionary", action_index_);
return false;
- } else if (!ParseAction(*action, param_list)) {
+ } else if (!ParseAction(*action, param_list, pointer_id)) {
return false;
}
}
@@ -169,7 +199,8 @@ bool ActionsParser::ParseActions(const base::ListValue& actions) {
bool ActionsParser::ParseAction(
const base::DictionaryValue& action,
- SyntheticPointerActionListParams::ParamList& param_list) {
+ SyntheticPointerActionListParams::ParamList& param_list,
+ int pointer_id) {
SyntheticPointerActionParams::PointerActionType pointer_action_type =
SyntheticPointerActionParams::PointerActionType::NOT_INITIALIZED;
std::string name;
@@ -235,7 +266,10 @@ bool ActionsParser::ParseAction(
}
SyntheticPointerActionParams action_param(pointer_action_type);
- action_param.set_index(action_index_);
+ if (pointer_id == -1)
+ action_param.set_pointer_id(action_index_);
+ else
+ action_param.set_pointer_id(pointer_id);
switch (pointer_action_type) {
case SyntheticPointerActionParams::PointerActionType::PRESS:
action_param.set_position(gfx::PointF(position_x, position_y));
diff --git a/chromium/content/renderer/gpu/actions_parser.h b/chromium/content/common/input/actions_parser.h
index 5939685f259..c5d0ca83c41 100644
--- a/chromium/content/renderer/gpu/actions_parser.h
+++ b/chromium/content/common/input/actions_parser.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_GPU_ACTION_PARSER_H_
-#define CONTENT_RENDERER_GPU_ACTION_PARSER_H_
+#ifndef CONTENT_COMMON_INPUT_ACTIONS_PARSER_H_
+#define CONTENT_COMMON_INPUT_ACTIONS_PARSER_H_
#include <cstddef>
#include <set>
@@ -21,7 +21,7 @@ namespace content {
// This class takes the arugment of json format from
// GpuBenchmarking::PointerActionSequence, parses it and warps
// it into a SyntheticPointerActionListParams object.
-class ActionsParser {
+class CONTENT_EXPORT ActionsParser {
public:
explicit ActionsParser(base::Value* value);
~ActionsParser();
@@ -33,9 +33,10 @@ class ActionsParser {
private:
bool ParsePointerActions(const base::DictionaryValue& pointer_actions);
- bool ParseActions(const base::ListValue& actions);
+ bool ParseActions(const base::ListValue& actions, int pointer_id);
bool ParseAction(const base::DictionaryValue& action,
- SyntheticPointerActionListParams::ParamList& param_list);
+ SyntheticPointerActionListParams::ParamList& param_list,
+ int pointer_id);
SyntheticPointerActionListParams gesture_params_;
std::vector<SyntheticPointerActionListParams::ParamList>
@@ -46,10 +47,11 @@ class ActionsParser {
base::Value* pointer_actions_value_;
int action_index_;
+ std::set<int> pointer_id_set_;
DISALLOW_COPY_AND_ASSIGN(ActionsParser);
};
} // namespace content
-#endif // CONTENT_RENDERER_GPU_ACTION_PARSER_H_
+#endif // CONTENT_COMMON_INPUT_ACTIONS_PARSER_H_
diff --git a/chromium/content/common/input/actions_parser_unittest.cc b/chromium/content/common/input/actions_parser_unittest.cc
new file mode 100644
index 00000000000..8a5b21fcde3
--- /dev/null
+++ b/chromium/content/common/input/actions_parser_unittest.cc
@@ -0,0 +1,250 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/input/actions_parser.h"
+
+#include "base/json/json_reader.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+TEST(ActionsParserTest, ParseMousePointerActionSequence) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "mouse", "id": 0,
+ "actions": [{"name": "pointerDown", "x": 2, "y": 3,
+ "button": "left"},
+ {"name": "pointerUp", "x": 2, "y": 3,
+ "button": "left"}]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_TRUE(actions_parser.ParsePointerActionSequence());
+ SyntheticPointerActionListParams action_list_params =
+ actions_parser.gesture_params();
+ EXPECT_EQ(SyntheticGestureParams::MOUSE_INPUT,
+ action_list_params.gesture_source_type);
+ EXPECT_EQ(2U, action_list_params.params.size());
+ EXPECT_EQ(1U, action_list_params.params[0].size());
+ EXPECT_EQ(SyntheticPointerActionParams::PointerActionType::PRESS,
+ action_list_params.params[0][0].pointer_action_type());
+ EXPECT_EQ(gfx::PointF(2, 3), action_list_params.params[0][0].position());
+ EXPECT_EQ(SyntheticPointerActionParams::Button::LEFT,
+ action_list_params.params[0][0].button());
+ EXPECT_EQ(SyntheticPointerActionParams::PointerActionType::RELEASE,
+ action_list_params.params[1][0].pointer_action_type());
+}
+
+TEST(ActionsParserTest, ParseTouchPointerActionSequence) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "touch", "id": 1,
+ "actions": [{"name": "pointerDown", "x": 3, "y": 5},
+ {"name": "pointerMove", "x": 30, "y": 30},
+ {"name": "pointerUp" } ]},
+ {"source": "touch", "id": 2,
+ "actions": [{"name": "pointerDown", "x": 10, "y": 10},
+ {"name": "pointerMove", "x": 50, "y": 50},
+ {"name": "pointerUp" } ]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_TRUE(actions_parser.ParsePointerActionSequence());
+ SyntheticPointerActionListParams action_list_params =
+ actions_parser.gesture_params();
+ EXPECT_EQ(SyntheticGestureParams::TOUCH_INPUT,
+ action_list_params.gesture_source_type);
+ EXPECT_EQ(3U, action_list_params.params.size());
+ EXPECT_EQ(2U, action_list_params.params[0].size());
+ EXPECT_EQ(SyntheticPointerActionParams::PointerActionType::PRESS,
+ action_list_params.params[0][0].pointer_action_type());
+ EXPECT_EQ(gfx::PointF(3, 5), action_list_params.params[0][0].position());
+ EXPECT_EQ(1U, action_list_params.params[0][0].pointer_id());
+ EXPECT_EQ(SyntheticPointerActionParams::PointerActionType::PRESS,
+ action_list_params.params[0][1].pointer_action_type());
+ EXPECT_EQ(gfx::PointF(10, 10), action_list_params.params[0][1].position());
+ EXPECT_EQ(2U, action_list_params.params[0][1].pointer_id());
+}
+
+TEST(ActionsParserTest, ParseTouchPointerActionSequenceWithoutId) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "touch", "id": 0,
+ "actions": [{"name": "pointerDown", "x": 3, "y": 5},
+ {"name": "pointerMove", "x": 30, "y": 30},
+ {"name": "pointerUp" } ]},
+ {"source": "touch", "id": 1,
+ "actions": [{"name": "pointerDown", "x": 10, "y": 10},
+ {"name": "pointerMove", "x": 50, "y": 50},
+ {"name": "pointerUp" } ]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_TRUE(actions_parser.ParsePointerActionSequence());
+ SyntheticPointerActionListParams action_list_params =
+ actions_parser.gesture_params();
+ EXPECT_EQ(SyntheticGestureParams::TOUCH_INPUT,
+ action_list_params.gesture_source_type);
+ EXPECT_EQ(3U, action_list_params.params.size());
+ EXPECT_EQ(2U, action_list_params.params[0].size());
+ EXPECT_EQ(SyntheticPointerActionParams::PointerActionType::PRESS,
+ action_list_params.params[0][0].pointer_action_type());
+ EXPECT_EQ(gfx::PointF(3, 5), action_list_params.params[0][0].position());
+ EXPECT_EQ(0U, action_list_params.params[0][0].pointer_id());
+ EXPECT_EQ(SyntheticPointerActionParams::PointerActionType::PRESS,
+ action_list_params.params[0][1].pointer_action_type());
+ EXPECT_EQ(gfx::PointF(10, 10), action_list_params.params[0][1].position());
+ EXPECT_EQ(1U, action_list_params.params[0][1].pointer_id());
+}
+
+TEST(ActionsParserTest, ParseTouchPointerActionSequenceIdNotInt) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "touch", "id": "0",
+ "actions": [{"name": "pointerDown", "x": 0, "y": 0},
+ {"name": "pointerMove", "x": 30, "y": 30},
+ {"name": "pointerUp" } ]},
+ {"source": "touch", "id": "1",
+ "actions": [{"name": "pointerDown", "x": 10, "y": 10},
+ {"name": "pointerMove", "x": 50, "y": 50},
+ {"name": "pointerUp" } ]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_FALSE(actions_parser.ParsePointerActionSequence());
+ EXPECT_EQ("pointer id is not an integer", actions_parser.error_message());
+}
+
+TEST(ActionsParserTest, ParseTouchPointerActionSequenceIdNegative) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "touch", "id": -1,
+ "actions": [{"name": "pointerDown", "x": 0, "y": 0},
+ {"name": "pointerMove", "x": 30, "y": 30},
+ {"name": "pointerUp" } ]},
+ {"source": "touch", "id": -2,
+ "actions": [{"name": "pointerDown", "x": 10, "y": 10},
+ {"name": "pointerMove", "x": 50, "y": 50},
+ {"name": "pointerUp" } ]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_FALSE(actions_parser.ParsePointerActionSequence());
+ EXPECT_EQ("pointer id can not be negative", actions_parser.error_message());
+}
+
+TEST(ActionsParserTest, ParseTouchPointerActionSequenceDuplicateId) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "touch", "id": 0,
+ "actions": [{"name": "pointerDown", "x": 0, "y": 0},
+ {"name": "pointerMove", "x": 30, "y": 30},
+ {"name": "pointerUp" } ]},
+ {"source": "touch", "id": 0,
+ "actions": [{"name": "pointerDown", "x": 10, "y": 10},
+ {"name": "pointerMove", "x": 50, "y": 50},
+ {"name": "pointerUp" } ]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_FALSE(actions_parser.ParsePointerActionSequence());
+ EXPECT_EQ("pointer id already exists", actions_parser.error_message());
+}
+
+TEST(ActionsParserTest, ParseTouchPointerActionSequenceNoId) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "touch", "id": 0,
+ "actions": [{"name": "pointerDown", "x": 0, "y": 0},
+ {"name": "pointerMove", "x": 30, "y": 30},
+ {"name": "pointerUp" } ]},
+ {"source": "touch",
+ "actions": [{"name": "pointerDown", "x": 10, "y": 10},
+ {"name": "pointerMove", "x": 50, "y": 50},
+ {"name": "pointerUp" } ]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_FALSE(actions_parser.ParsePointerActionSequence());
+ EXPECT_EQ("this pointer does not have a pointer id",
+ actions_parser.error_message());
+}
+
+TEST(ActionsParserTest, ParseTouchPointerActionSequenceMissingId) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "touch",
+ "actions": [{"name": "pointerDown", "x": 0, "y": 0},
+ {"name": "pointerMove", "x": 30, "y": 30},
+ {"name": "pointerUp" } ]},
+ {"source": "touch", "id": 0,
+ "actions": [{"name": "pointerDown", "x": 10, "y": 10},
+ {"name": "pointerMove", "x": 50, "y": 50},
+ {"name": "pointerUp" } ]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_FALSE(actions_parser.ParsePointerActionSequence());
+ EXPECT_EQ("some pointers do not have a pointer id",
+ actions_parser.error_message());
+}
+
+TEST(ActionsParserTest, ParseMousePointerActionSequenceNoSource) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"id": 0, "actions": [{"name": "pointerDown", "x": 2, "y": 3,
+ "button": "left"},
+ {"name": "pointerUp", "x": 2, "y": 3,
+ "button": "left"}]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_FALSE(actions_parser.ParsePointerActionSequence());
+ EXPECT_EQ("source type is missing or not a string",
+ actions_parser.error_message());
+}
+
+TEST(ActionsParserTest, ParseMousePointerActionSequenceNoAction) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "mouse", "id": 0}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_FALSE(actions_parser.ParsePointerActionSequence());
+ EXPECT_EQ("pointer[0].actions is missing or not a list",
+ actions_parser.error_message());
+}
+
+TEST(ActionsParserTest, ParseMousePointerActionSequenceUnsupportedButton) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "mouse", "id": 0,
+ "actions": [{"name": "pointerDown", "x": 2, "y": 3,
+ "button": "l"},
+ {"name": "pointerUp", "x": 2, "y": 3,
+ "button": "left"}]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_FALSE(actions_parser.ParsePointerActionSequence());
+ EXPECT_EQ("actions[0].actions.button is an unsupported button",
+ actions_parser.error_message());
+}
+
+TEST(ActionsParserTest, ParseTouchPointerActionSequenceMultiSource) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "touch", "id": 1,
+ "actions": [{"name": "pointerDown", "x": 3, "y": 5},
+ {"name": "pointerMove", "x": 30, "y": 30},
+ {"name": "pointerUp" } ]},
+ {"source": "mouse", "id": 2,
+ "actions": [{"name": "pointerDown", "x": 10, "y": 10},
+ {"name": "pointerMove", "x": 50, "y": 50},
+ {"name": "pointerUp" } ]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_FALSE(actions_parser.ParsePointerActionSequence());
+ EXPECT_EQ("currently multiple input sources are not not supported",
+ actions_parser.error_message());
+}
+
+TEST(ActionsParserTest, ParseTouchPointerActionSequenceMultiMouse) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(
+ R"( [{"source": "mouse", "id": 1,
+ "actions": [{"name": "pointerDown", "x": 3, "y": 5},
+ {"name": "pointerMove", "x": 30, "y": 30},
+ {"name": "pointerUp" } ]},
+ {"source": "mouse", "id": 2,
+ "actions": [{"name": "pointerDown", "x": 10, "y": 10},
+ {"name": "pointerMove", "x": 50, "y": 50},
+ {"name": "pointerUp" } ]}] )");
+
+ ActionsParser actions_parser(value.get());
+ EXPECT_FALSE(actions_parser.ParsePointerActionSequence());
+ EXPECT_EQ(
+ "for input source type of mouse and pen, we only support one device in "
+ "one sequence",
+ actions_parser.error_message());
+}
+
+} // namespace content
diff --git a/chromium/content/common/input/input_event_struct_traits.cc b/chromium/content/common/input/input_event_struct_traits.cc
index c67a68488d4..c88261fb1ef 100644
--- a/chromium/content/common/input/input_event_struct_traits.cc
+++ b/chromium/content/common/input/input_event_struct_traits.cc
@@ -8,6 +8,7 @@
#include "content/common/input_messages.h"
#include "mojo/public/cpp/base/time_mojom_traits.h"
#include "third_party/blink/public/platform/web_keyboard_event.h"
+#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
#include "ui/latency/mojo/latency_info_struct_traits.h"
namespace mojo {
@@ -134,8 +135,6 @@ bool StructTraits<content::mojom::EventDataView, InputEventUniquePtr>::Read(
default:
break;
case blink::WebInputEvent::Type::kGestureTapDown:
- case blink::WebInputEvent::Type::kGestureTapUnconfirmed:
- case blink::WebInputEvent::Type::kGestureDoubleTap:
gesture_event->data.tap_down.width =
gesture_data->contact_size->width();
gesture_event->data.tap_down.height =
@@ -148,10 +147,13 @@ bool StructTraits<content::mojom::EventDataView, InputEventUniquePtr>::Read(
gesture_data->contact_size->height();
break;
case blink::WebInputEvent::Type::kGestureTap:
+ case blink::WebInputEvent::Type::kGestureTapUnconfirmed:
+ case blink::WebInputEvent::Type::kGestureDoubleTap:
gesture_event->data.tap.width = gesture_data->contact_size->width();
gesture_event->data.tap.height = gesture_data->contact_size->height();
break;
case blink::WebInputEvent::Type::kGestureLongPress:
+ case blink::WebInputEvent::Type::kGestureLongTap:
gesture_event->data.long_press.width =
gesture_data->contact_size->width();
gesture_event->data.long_press.height =
@@ -330,6 +332,9 @@ bool StructTraits<content::mojom::EventDataView, InputEventUniquePtr>::Read(
wheel_event->has_precise_scrolling_deltas =
wheel_data->has_precise_scrolling_deltas;
wheel_event->dispatch_type = wheel_data->cancelable;
+ wheel_event->event_action =
+ static_cast<blink::WebMouseWheelEvent::EventAction>(
+ wheel_data->event_action);
}
}
@@ -381,7 +386,8 @@ StructTraits<content::mojom::EventDataView, InputEventUniquePtr>::pointer_data(
wheel_event->acceleration_ratio_y, wheel_event->resending_plugin_id,
wheel_event->phase, wheel_event->momentum_phase,
wheel_event->scroll_by_page, wheel_event->has_precise_scrolling_deltas,
- wheel_event->dispatch_type);
+ wheel_event->dispatch_type,
+ static_cast<uint8_t>(wheel_event->event_action));
}
return PointerDataFromPointerProperties(
@@ -429,6 +435,7 @@ StructTraits<content::mojom::EventDataView, InputEventUniquePtr>::gesture_data(
content::mojom::TapData::New(gesture_event->data.tap.tap_count);
break;
case blink::WebInputEvent::Type::kGestureLongPress:
+ case blink::WebInputEvent::Type::kGestureLongTap:
gesture_data->contact_size =
gfx::Size(gesture_event->data.long_press.width,
gesture_event->data.long_press.height);
diff --git a/chromium/content/common/input/input_handler.mojom b/chromium/content/common/input/input_handler.mojom
index 1dd238373a5..eb63d1ae8e0 100644
--- a/chromium/content/common/input/input_handler.mojom
+++ b/chromium/content/common/input/input_handler.mojom
@@ -65,6 +65,7 @@ struct WheelData {
bool scroll_by_page;
bool has_precise_scrolling_deltas;
Cancelability cancelable;
+ uint8 event_action;
};
struct MouseData {
@@ -333,6 +334,14 @@ interface FrameInputHandler {
AdjustSelectionByCharacterOffset(
int32 start, int32 end, blink.mojom.SelectionMenuBehavior behavior);
+ // Requests the renderer to select word around caret.
+ // Expects ack with new selection information when finished. |start_adjust|
+ // and |end_adjust| are the start and end offset difference between the
+ // current selection and the previous selection (which is a caret).
+ [EnableIf=is_android]
+ SelectWordAroundCaret()
+ => (bool did_select, int32 start_adjust, int32 end_adjust);
+
// Requests the renderer to move the selection extent point to a new position.
// Expects a MoveRangeSelectionExtent_ACK message when finished.
MoveRangeSelectionExtent(gfx.mojom.Point extent);
diff --git a/chromium/content/common/input/synthetic_pointer_action_params.cc b/chromium/content/common/input/synthetic_pointer_action_params.cc
index a54e974b247..0f93e358e7a 100644
--- a/chromium/content/common/input/synthetic_pointer_action_params.cc
+++ b/chromium/content/common/input/synthetic_pointer_action_params.cc
@@ -8,12 +8,14 @@ namespace content {
SyntheticPointerActionParams::SyntheticPointerActionParams()
: pointer_action_type_(PointerActionType::NOT_INITIALIZED),
- index_(0),
+ pointer_id_(0),
button_(Button::LEFT) {}
SyntheticPointerActionParams::SyntheticPointerActionParams(
PointerActionType action_type)
- : pointer_action_type_(action_type), index_(0), button_(Button::LEFT) {}
+ : pointer_action_type_(action_type),
+ pointer_id_(0),
+ button_(Button::LEFT) {}
SyntheticPointerActionParams::~SyntheticPointerActionParams() {}
@@ -31,6 +33,8 @@ unsigned SyntheticPointerActionParams::GetWebMouseEventModifier(
return blink::WebMouseEvent::kBackButtonDown;
case SyntheticPointerActionParams::Button::FORWARD:
return blink::WebMouseEvent::kForwardButtonDown;
+ case SyntheticPointerActionParams::Button::NO_BUTTON:
+ return blink::WebMouseEvent::kNoModifiers;
}
NOTREACHED();
return blink::WebMouseEvent::kNoModifiers;
@@ -51,9 +55,25 @@ SyntheticPointerActionParams::GetWebMouseEventButton(
return blink::WebMouseEvent::Button::kBack;
case SyntheticPointerActionParams::Button::FORWARD:
return blink::WebMouseEvent::Button::kForward;
+ case SyntheticPointerActionParams::Button::NO_BUTTON:
+ return blink::WebMouseEvent::Button::kNoButton;
}
NOTREACHED();
return blink::WebMouseEvent::Button::kNoButton;
}
+// static
+blink::WebMouseEvent::Button
+SyntheticPointerActionParams::GetWebMouseEventButtonFromModifier(
+ unsigned modifiers) {
+ blink::WebMouseEvent::Button button = blink::WebMouseEvent::Button::kNoButton;
+ if (modifiers & blink::WebMouseEvent::kLeftButtonDown)
+ button = blink::WebMouseEvent::Button::kLeft;
+ if (modifiers & blink::WebMouseEvent::kMiddleButtonDown)
+ button = blink::WebMouseEvent::Button::kMiddle;
+ if (modifiers & blink::WebMouseEvent::kRightButtonDown)
+ button = blink::WebMouseEvent::Button::kRight;
+ return button;
+}
+
} // namespace content
diff --git a/chromium/content/common/input/synthetic_pointer_action_params.h b/chromium/content/common/input/synthetic_pointer_action_params.h
index 534a01365c7..7a8ec223427 100644
--- a/chromium/content/common/input/synthetic_pointer_action_params.h
+++ b/chromium/content/common/input/synthetic_pointer_action_params.h
@@ -35,6 +35,7 @@ struct CONTENT_EXPORT SyntheticPointerActionParams {
};
enum class Button {
+ NO_BUTTON,
LEFT,
MIDDLE,
RIGHT,
@@ -51,11 +52,7 @@ struct CONTENT_EXPORT SyntheticPointerActionParams {
pointer_action_type_ = pointer_action_type;
}
- void set_index(int index) {
- DCHECK_GE(index, 0);
- DCHECK_LT(index, blink::WebTouchEvent::kTouchesLengthCap);
- index_ = index;
- }
+ void set_pointer_id(uint32_t pointer_id) { pointer_id_ = pointer_id; }
void set_position(const gfx::PointF& position) {
DCHECK(pointer_action_type_ == PointerActionType::PRESS ||
@@ -71,11 +68,7 @@ struct CONTENT_EXPORT SyntheticPointerActionParams {
PointerActionType pointer_action_type() const { return pointer_action_type_; }
- int index() const {
- DCHECK_GE(index_, 0);
- DCHECK_LT(index_, blink::WebTouchEvent::kTouchesLengthCap);
- return index_;
- }
+ uint32_t pointer_id() const { return pointer_id_; }
gfx::PointF position() const {
DCHECK(pointer_action_type_ == PointerActionType::PRESS ||
@@ -93,6 +86,8 @@ struct CONTENT_EXPORT SyntheticPointerActionParams {
SyntheticPointerActionParams::Button button);
static blink::WebMouseEvent::Button GetWebMouseEventButton(
SyntheticPointerActionParams::Button button);
+ static blink::WebMouseEvent::Button GetWebMouseEventButtonFromModifier(
+ unsigned modifiers);
private:
friend struct IPC::ParamTraits<content::SyntheticPointerActionParams>;
@@ -101,9 +96,8 @@ struct CONTENT_EXPORT SyntheticPointerActionParams {
PointerActionType pointer_action_type_;
// The position of the pointer, where it presses or moves to.
gfx::PointF position_;
- // The index of the pointer in the pointer action sequence passed from the
- // user API.
- int index_;
+ // The id of the pointer given by the users.
+ uint32_t pointer_id_;
Button button_;
};
diff --git a/chromium/content/common/input/synthetic_web_input_event_builders.cc b/chromium/content/common/input/synthetic_web_input_event_builders.cc
index e4b9aad042d..49611607eb2 100644
--- a/chromium/content/common/input/synthetic_web_input_event_builders.cc
+++ b/chromium/content/common/input/synthetic_web_input_event_builders.cc
@@ -5,6 +5,7 @@
#include "content/common/input/synthetic_web_input_event_builders.h"
#include "base/logging.h"
+#include "content/common/input/web_mouse_wheel_event_traits.h"
#include "content/common/input/web_touch_event_traits.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/event.h"
@@ -47,6 +48,7 @@ WebMouseWheelEvent SyntheticWebMouseWheelEventBuilder::Build(
WebMouseWheelEvent result(WebInputEvent::kMouseWheel,
WebInputEvent::kNoModifiers, ui::EventTimeForNow());
result.phase = phase;
+ result.event_action = WebMouseWheelEventTraits::GetEventAction(result);
return result;
}
@@ -83,6 +85,7 @@ WebMouseWheelEvent SyntheticWebMouseWheelEventBuilder::Build(
result.wheel_ticks_y = dy > 0.0f ? 1.0f : -1.0f;
result.has_precise_scrolling_deltas = precise;
result.scroll_by_page = scroll_by_page;
+ result.event_action = WebMouseWheelEventTraits::GetEventAction(result);
return result;
}
diff --git a/chromium/content/common/input/synthetic_web_input_event_builders_unittest.cc b/chromium/content/common/input/synthetic_web_input_event_builders_unittest.cc
index e93d32c89db..1c225e7aa9b 100644
--- a/chromium/content/common/input/synthetic_web_input_event_builders_unittest.cc
+++ b/chromium/content/common/input/synthetic_web_input_event_builders_unittest.cc
@@ -2,10 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/common/input/touch_event_stream_validator.h"
-
-#include <stddef.h>
-
#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/common/input/web_touch_event_traits.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/content/common/input/web_mouse_wheel_event_traits.cc b/chromium/content/common/input/web_mouse_wheel_event_traits.cc
new file mode 100644
index 00000000000..372ae755785
--- /dev/null
+++ b/chromium/content/common/input/web_mouse_wheel_event_traits.cc
@@ -0,0 +1,40 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/input/web_mouse_wheel_event_traits.h"
+
+#include "third_party/blink/public/platform/web_input_event.h"
+
+namespace content {
+
+using blink::WebInputEvent;
+
+// static
+blink::WebMouseWheelEvent::EventAction WebMouseWheelEventTraits::GetEventAction(
+ const blink::WebMouseWheelEvent& event) {
+#if defined(USE_AURA)
+ // Scroll events generated from the mouse wheel when the control key is held
+ // don't trigger scrolling. Instead, they may cause zooming.
+ if (!event.has_precise_scrolling_deltas &&
+ (event.GetModifiers() & WebInputEvent::kControlKey)) {
+ return blink::WebMouseWheelEvent::EventAction::kPageZoom;
+ }
+
+ if (event.delta_x == 0 && (event.GetModifiers() & WebInputEvent::kShiftKey))
+ return blink::WebMouseWheelEvent::EventAction::kScrollHorizontal;
+#endif
+ if (event.rails_mode == WebInputEvent::kRailsModeHorizontal ||
+ (event.delta_x != 0 && event.delta_y == 0)) {
+ return blink::WebMouseWheelEvent::EventAction::kScrollHorizontal;
+ }
+
+ if (event.rails_mode == WebInputEvent::kRailsModeVertical ||
+ (event.delta_x == 0 && event.delta_y != 0)) {
+ return blink::WebMouseWheelEvent::EventAction::kScrollVertical;
+ }
+
+ return blink::WebMouseWheelEvent::EventAction::kScroll;
+}
+
+} // namespace content
diff --git a/chromium/content/common/input/web_mouse_wheel_event_traits.h b/chromium/content/common/input/web_mouse_wheel_event_traits.h
new file mode 100644
index 00000000000..171ea244fcf
--- /dev/null
+++ b/chromium/content/common/input/web_mouse_wheel_event_traits.h
@@ -0,0 +1,28 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_INPUT_WEB_MOUSE_WHEEL_EVENT_TRAITS_H_
+#define CONTENT_COMMON_INPUT_WEB_MOUSE_WHEEL_EVENT_TRAITS_H_
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
+
+namespace content {
+
+// Utility class for performing operations on and with WebMouseWheelEvent.
+class CONTENT_EXPORT WebMouseWheelEventTraits {
+ public:
+ // Returns the *platform specific* event action corresponding with the wheel
+ // event.
+ static blink::WebMouseWheelEvent::EventAction GetEventAction(
+ const blink::WebMouseWheelEvent& event);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(WebMouseWheelEventTraits);
+};
+
+} // namespace content
+
+#endif // CONTENT_COMMON_INPUT_WEB_MOUSE_WHEEL_EVENT_TRAITS_H_
diff --git a/chromium/content/common/input_messages.h b/chromium/content/common/input_messages.h
index 7d5b879a20b..299e214b9da 100644
--- a/chromium/content/common/input_messages.h
+++ b/chromium/content/common/input_messages.h
@@ -141,7 +141,7 @@ IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::SyntheticPointerActionParams)
IPC_STRUCT_TRAITS_MEMBER(pointer_action_type_)
- IPC_STRUCT_TRAITS_MEMBER(index_)
+ IPC_STRUCT_TRAITS_MEMBER(pointer_id_)
IPC_STRUCT_TRAITS_MEMBER(position_)
IPC_STRUCT_TRAITS_MEMBER(button_)
IPC_STRUCT_TRAITS_END()
diff --git a/chromium/content/common/media/media_player_delegate_messages.h b/chromium/content/common/media/media_player_delegate_messages.h
index e352c277348..b482679efdf 100644
--- a/chromium/content/common/media/media_player_delegate_messages.h
+++ b/chromium/content/common/media/media_player_delegate_messages.h
@@ -124,20 +124,22 @@ IPC_MESSAGE_ROUTED2(MediaPlayerDelegateHostMsg_OnMediaSizeChanged,
int /* delegate_id, distinguishes instances */,
gfx::Size /* new size of video */)
-IPC_MESSAGE_ROUTED4(MediaPlayerDelegateHostMsg_OnPictureInPictureModeStarted,
+IPC_MESSAGE_ROUTED5(MediaPlayerDelegateHostMsg_OnPictureInPictureModeStarted,
int /* delegate id */,
viz::SurfaceId /* surface_id */,
gfx::Size /* natural_size */,
- int /* request_id */)
+ int /* request_id */,
+ bool /* show_play_pause_button */)
IPC_MESSAGE_ROUTED2(MediaPlayerDelegateHostMsg_OnPictureInPictureModeEnded,
int /* delegate id */,
int /* request_id */)
-IPC_MESSAGE_ROUTED3(MediaPlayerDelegateHostMsg_OnPictureInPictureSurfaceChanged,
+IPC_MESSAGE_ROUTED4(MediaPlayerDelegateHostMsg_OnPictureInPictureSurfaceChanged,
int /* delegate id */,
viz::SurfaceId /* surface_id */,
- gfx::Size /* natural_size */)
+ gfx::Size /* natural_size */,
+ bool /* show_play_pause_button */)
IPC_MESSAGE_ROUTED2(
MediaPlayerDelegateHostMsg_OnSetPictureInPictureCustomControls,
diff --git a/chromium/content/common/media/media_stream.mojom b/chromium/content/common/media/media_stream.mojom
index 99faa657e2d..665fafe4b23 100644
--- a/chromium/content/common/media/media_stream.mojom
+++ b/chromium/content/common/media/media_stream.mojom
@@ -4,12 +4,9 @@
module content.mojom;
-// TODO(c.padhi): Add typemapping for MediaStreamDevice,
-// see https://crbug.com/742682.
-// Native struct content::MediaStreamDevice.
-// (see content/public/common/media_stream_request.h)
-[Native]
-struct MediaStreamDevice;
+import "media/capture/mojom/video_capture_types.mojom";
+import "media/mojo/interfaces/audio_parameters.mojom";
+import "media/mojo/interfaces/display_media_information.mojom";
// Types of media streams (see content/public/common/media_stream_request.h).
enum MediaStreamType {
@@ -43,6 +40,20 @@ enum MediaStreamRequestResult {
KILL_SWITCH_ON
};
+// See content/public/common/media_stream_request.h.
+struct MediaStreamDevice {
+ MediaStreamType type;
+ string id;
+ media.mojom.VideoFacingMode video_facing;
+ string? group_id;
+ string? matched_output_device_id;
+ string name;
+ media.mojom.AudioParameters input;
+ int32 session_id;
+ media.mojom.VideoCaptureDeviceDescriptorCameraCalibration? camera_calibration;
+ media.mojom.DisplayMediaInformation? display_media_info;
+};
+
// See content/common/media/media_stream_controls.h.
struct TrackControls {
bool requested;
diff --git a/chromium/content/common/media/media_stream.typemap b/chromium/content/common/media/media_stream.typemap
index eacf4d619a8..f6df0252f48 100644
--- a/chromium/content/common/media/media_stream.typemap
+++ b/chromium/content/common/media/media_stream.typemap
@@ -9,10 +9,7 @@ public_headers = [
"//content/public/common/media_stream_request.h",
]
-traits_headers = [
- "//content/common/media/media_stream_param_traits.h",
- "//content/common/media/media_stream_mojom_traits.h",
-]
+traits_headers = [ "//content/common/media/media_stream_mojom_traits.h" ]
sources = [
"//content/common/media/media_stream_mojom_traits.cc",
diff --git a/chromium/content/common/media/media_stream_mojom_traits.cc b/chromium/content/common/media/media_stream_mojom_traits.cc
index d88a188c3b4..324923e690e 100644
--- a/chromium/content/common/media/media_stream_mojom_traits.cc
+++ b/chromium/content/common/media/media_stream_mojom_traits.cc
@@ -5,6 +5,9 @@
#include "content/common/media/media_stream_mojom_traits.h"
#include "base/logging.h"
+#include "media/base/ipc/media_param_traits.h"
+#include "media/capture/mojom/video_capture_types_mojom_traits.h"
+#include "media/mojo/interfaces/display_media_information.mojom.h"
namespace mojo {
@@ -187,6 +190,33 @@ bool EnumTraits<content::mojom::MediaStreamRequestResult,
}
// static
+bool StructTraits<content::mojom::MediaStreamDeviceDataView,
+ content::MediaStreamDevice>::
+ Read(content::mojom::MediaStreamDeviceDataView input,
+ content::MediaStreamDevice* out) {
+ if (!input.ReadType(&out->type))
+ return false;
+ if (!input.ReadId(&out->id))
+ return false;
+ if (!input.ReadVideoFacing(&out->video_facing))
+ return false;
+ if (!input.ReadGroupId(&out->group_id))
+ return false;
+ if (!input.ReadMatchedOutputDeviceId(&out->matched_output_device_id))
+ return false;
+ if (!input.ReadName(&out->name))
+ return false;
+ if (!input.ReadInput(&out->input))
+ return false;
+ out->session_id = input.session_id();
+ if (!input.ReadCameraCalibration(&out->camera_calibration))
+ return false;
+ if (!input.ReadDisplayMediaInfo(&out->display_media_info))
+ return false;
+ return true;
+}
+
+// static
bool StructTraits<
content::mojom::TrackControlsDataView,
content::TrackControls>::Read(content::mojom::TrackControlsDataView input,
diff --git a/chromium/content/common/media/media_stream_mojom_traits.h b/chromium/content/common/media/media_stream_mojom_traits.h
index 69abea71225..bd5ff321f23 100644
--- a/chromium/content/common/media/media_stream_mojom_traits.h
+++ b/chromium/content/common/media/media_stream_mojom_traits.h
@@ -30,6 +30,61 @@ struct EnumTraits<content::mojom::MediaStreamRequestResult,
};
template <>
+struct StructTraits<content::mojom::MediaStreamDeviceDataView,
+ content::MediaStreamDevice> {
+ static const content::MediaStreamType& type(
+ const content::MediaStreamDevice& device) {
+ return device.type;
+ }
+
+ static const std::string& id(const content::MediaStreamDevice& device) {
+ return device.id;
+ }
+
+ static const media::VideoFacingMode& video_facing(
+ const content::MediaStreamDevice& device) {
+ return device.video_facing;
+ }
+
+ static const base::Optional<std::string>& group_id(
+ const content::MediaStreamDevice& device) {
+ return device.group_id;
+ }
+
+ static const base::Optional<std::string>& matched_output_device_id(
+ const content::MediaStreamDevice& device) {
+ return device.matched_output_device_id;
+ }
+
+ static const std::string& name(const content::MediaStreamDevice& device) {
+ return device.name;
+ }
+
+ static const media::AudioParameters& input(
+ const content::MediaStreamDevice& device) {
+ return device.input;
+ }
+
+ static int session_id(const content::MediaStreamDevice& device) {
+ return device.session_id;
+ }
+
+ static const base::Optional<
+ media::VideoCaptureDeviceDescriptor::CameraCalibration>&
+ camera_calibration(const content::MediaStreamDevice& device) {
+ return device.camera_calibration;
+ }
+
+ static const base::Optional<media::mojom::DisplayMediaInformationPtr>&
+ display_media_info(const content::MediaStreamDevice& device) {
+ return device.display_media_info;
+ }
+
+ static bool Read(content::mojom::MediaStreamDeviceDataView input,
+ content::MediaStreamDevice* out);
+};
+
+template <>
struct StructTraits<content::mojom::TrackControlsDataView,
content::TrackControls> {
static bool requested(const content::TrackControls& controls) {
diff --git a/chromium/content/common/media/media_stream_param_traits.cc b/chromium/content/common/media/media_stream_param_traits.cc
deleted file mode 100644
index f515d969175..00000000000
--- a/chromium/content/common/media/media_stream_param_traits.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Get basic type definitions.
-#define IPC_MESSAGE_IMPL
-#include "content/common/media/media_stream_param_traits.h"
-
-// Generate constructors.
-#include "ipc/struct_constructor_macros.h"
-#include "content/common/media/media_stream_param_traits.h"
-
-// Generate destructors.
-#include "ipc/struct_destructor_macros.h"
-#include "content/common/media/media_stream_param_traits.h"
-
-// Generate param traits write methods.
-#include "ipc/param_traits_write_macros.h"
-namespace IPC {
-#include "content/common/media/media_stream_param_traits.h"
-} // namespace IPC
-
-// Generate param traits read methods.
-#include "ipc/param_traits_read_macros.h"
-namespace IPC {
-#include "content/common/media/media_stream_param_traits.h"
-} // namespace IPC
-
-// Generate param traits log methods.
-#include "ipc/param_traits_log_macros.h"
-namespace IPC {
-#include "content/common/media/media_stream_param_traits.h"
-} // namespace IPC
diff --git a/chromium/content/common/media/media_stream_param_traits.h b/chromium/content/common/media/media_stream_param_traits.h
deleted file mode 100644
index 3b58a31792e..00000000000
--- a/chromium/content/common/media/media_stream_param_traits.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// IPC messages for the media streaming.
-// no-include-guard-because-multiply-included
-
-#include "content/common/content_export.h"
-#include "content/public/common/media_stream_request.h"
-#include "ipc/ipc_message_macros.h"
-#include "media/base/ipc/media_param_traits.h"
-#include "media/capture/ipc/capture_param_traits.h"
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
-
-IPC_ENUM_TRAITS_MAX_VALUE(content::MediaStreamType,
- content::NUM_MEDIA_TYPES - 1)
-
-IPC_ENUM_TRAITS_MAX_VALUE(media::VideoFacingMode,
- media::NUM_MEDIA_VIDEO_FACING_MODES - 1)
-
-IPC_STRUCT_TRAITS_BEGIN(content::MediaStreamDevice)
- IPC_STRUCT_TRAITS_MEMBER(type)
- IPC_STRUCT_TRAITS_MEMBER(id)
- IPC_STRUCT_TRAITS_MEMBER(group_id)
- IPC_STRUCT_TRAITS_MEMBER(video_facing)
- IPC_STRUCT_TRAITS_MEMBER(matched_output_device_id)
- IPC_STRUCT_TRAITS_MEMBER(name)
- IPC_STRUCT_TRAITS_MEMBER(input)
- IPC_STRUCT_TRAITS_MEMBER(session_id)
- IPC_STRUCT_TRAITS_MEMBER(camera_calibration)
-IPC_STRUCT_TRAITS_END()
diff --git a/chromium/content/common/native_types.mojom b/chromium/content/common/native_types.mojom
index 7754ec1dc0f..f87b8aa50e0 100644
--- a/chromium/content/common/native_types.mojom
+++ b/chromium/content/common/native_types.mojom
@@ -44,9 +44,6 @@ enum NetworkConnectionType;
struct WebCursor;
[Native]
-enum WebPopupType;
-
-[Native]
enum Button;
[Native]
diff --git a/chromium/content/common/native_types.typemap b/chromium/content/common/native_types.typemap
index 3caf59a4c87..da10e5b11db 100644
--- a/chromium/content/common/native_types.typemap
+++ b/chromium/content/common/native_types.typemap
@@ -26,7 +26,6 @@ public_headers = [
"//third_party/blink/public/platform/web_mouse_wheel_event.h",
"//third_party/blink/public/platform/web_pointer_properties.h",
"//third_party/blink/public/platform/web_touch_point.h",
- "//third_party/blink/public/web/web_popup_type.h",
"//ui/events/blink/did_overscroll_params.h",
"//ui/events/blink/web_input_event_traits.h",
"//ui/latency/ipc/latency_info_param_traits.h",
@@ -37,6 +36,7 @@ traits_headers = [
"//content/common/input/input_event_struct_traits.h",
"//content/common/input/touch_action_optional_struct_traits.h",
"//content/common/view_messages.h",
+ "//content/common/widget_messages.h",
"//content/public/common/common_param_traits.h",
"//services/network/public/cpp/p2p_param_traits.h",
]
diff --git a/chromium/content/common/navigation_gesture.h b/chromium/content/common/navigation_gesture.h
index 380cd51fff7..f38031b0ab6 100644
--- a/chromium/content/common/navigation_gesture.h
+++ b/chromium/content/common/navigation_gesture.h
@@ -14,9 +14,7 @@ enum NavigationGesture {
// setTimeout-triggered document.location changes and form.submits. See
// http://b/1046841 for some cases that should be treated this way but aren't.
NavigationGestureAuto,
- // Initial state.
- NavigationGestureUnknown,
- NavigationGestureLast = NavigationGestureUnknown
+ NavigationGestureLast = NavigationGestureAuto
};
} // namespace content
diff --git a/chromium/content/common/navigation_params.cc b/chromium/content/common/navigation_params.cc
index 04cf967022a..e3d07f56b6c 100644
--- a/chromium/content/common/navigation_params.cc
+++ b/chromium/content/common/navigation_params.cc
@@ -24,6 +24,18 @@ SourceLocation::SourceLocation(const std::string& url,
SourceLocation::~SourceLocation() = default;
+InitiatorCSPInfo::InitiatorCSPInfo() = default;
+InitiatorCSPInfo::InitiatorCSPInfo(
+ CSPDisposition should_check_main_world_csp,
+ const std::vector<ContentSecurityPolicy>& initiator_csp,
+ const base::Optional<CSPSource>& initiator_self_source)
+ : should_check_main_world_csp(should_check_main_world_csp),
+ initiator_csp(initiator_csp),
+ initiator_self_source(initiator_self_source) {}
+InitiatorCSPInfo::InitiatorCSPInfo(const InitiatorCSPInfo& other) = default;
+
+InitiatorCSPInfo::~InitiatorCSPInfo() = default;
+
CommonNavigationParams::CommonNavigationParams() = default;
CommonNavigationParams::CommonNavigationParams(
@@ -40,11 +52,9 @@ CommonNavigationParams::CommonNavigationParams(
std::string method,
const scoped_refptr<network::ResourceRequestBody>& post_data,
base::Optional<SourceLocation> source_location,
- CSPDisposition should_check_main_world_csp,
bool started_from_context_menu,
bool has_user_gesture,
- const std::vector<ContentSecurityPolicy>& initiator_csp,
- const base::Optional<CSPSource>& initiator_self_source,
+ const InitiatorCSPInfo& initiator_csp_info,
base::TimeTicks input_start)
: url(url),
referrer(referrer),
@@ -59,11 +69,9 @@ CommonNavigationParams::CommonNavigationParams(
method(method),
post_data(post_data),
source_location(source_location),
- should_check_main_world_csp(should_check_main_world_csp),
started_from_context_menu(started_from_context_menu),
has_user_gesture(has_user_gesture),
- initiator_csp(initiator_csp),
- initiator_self_source(initiator_self_source),
+ initiator_csp_info(initiator_csp_info),
input_start(input_start) {
// |method != "POST"| should imply absence of |post_data|.
if (method != "POST" && post_data) {
diff --git a/chromium/content/common/navigation_params.h b/chromium/content/common/navigation_params.h
index 748f4c20324..08655e4eba9 100644
--- a/chromium/content/common/navigation_params.h
+++ b/chromium/content/common/navigation_params.h
@@ -23,11 +23,12 @@
#include "content/public/common/page_state.h"
#include "content/public/common/previews_state.h"
#include "content/public/common/referrer.h"
-#include "content/public/common/request_context_type.h"
+#include "content/public/common/was_activated_option.h"
#include "net/url_request/redirect_info.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/resource_response_info.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/web_mixed_content_context_type.h"
#include "ui/base/page_transition_types.h"
#include "url/gurl.h"
@@ -56,6 +57,28 @@ struct CONTENT_EXPORT SourceLocation {
// Provided by the browser or the renderer -------------------------------------
+// Represents the Content Security Policy of the initator of the navigation.
+struct CONTENT_EXPORT InitiatorCSPInfo {
+ InitiatorCSPInfo();
+ InitiatorCSPInfo(CSPDisposition should_check_main_world_csp,
+ const std::vector<ContentSecurityPolicy>& initiator_csp,
+ const base::Optional<CSPSource>& initiator_self_source);
+ InitiatorCSPInfo(const InitiatorCSPInfo& other);
+ ~InitiatorCSPInfo();
+
+ // Whether or not the CSP of the main world should apply. When the navigation
+ // is initiated from a content script in an isolated world, the CSP defined
+ // in the main world should not apply.
+ // TODO(arthursonzogni): Instead of this boolean, the origin of the isolated
+ // world which has initiated the navigation should be passed.
+ // See https://crbug.com/702540
+ CSPDisposition should_check_main_world_csp = CSPDisposition::CHECK;
+
+ // The relevant CSP policies and the initiator 'self' source to be used.
+ std::vector<ContentSecurityPolicy> initiator_csp;
+ base::Optional<CSPSource> initiator_self_source;
+};
+
// Used by all navigation IPCs.
struct CONTENT_EXPORT CommonNavigationParams {
CommonNavigationParams();
@@ -73,11 +96,9 @@ struct CONTENT_EXPORT CommonNavigationParams {
std::string method,
const scoped_refptr<network::ResourceRequestBody>& post_data,
base::Optional<SourceLocation> source_location,
- CSPDisposition should_check_main_world_csp,
bool started_from_context_menu,
bool has_user_gesture,
- const std::vector<ContentSecurityPolicy>& initiator_csp,
- const base::Optional<CSPSource>& initiator_self_source,
+ const InitiatorCSPInfo& initiator_csp_info,
base::TimeTicks input_start = base::TimeTicks());
CommonNavigationParams(const CommonNavigationParams& other);
~CommonNavigationParams();
@@ -140,14 +161,6 @@ struct CONTENT_EXPORT CommonNavigationParams {
// not be set.
base::Optional<SourceLocation> source_location;
- // Whether or not the CSP of the main world should apply. When the navigation
- // is initiated from a content script in an isolated world, the CSP defined
- // in the main world should not apply.
- // TODO(arthursonzogni): Instead of this boolean, the origin of the isolated
- // world which has initiated the navigation should be passed.
- // See https://crbug.com/702540
- CSPDisposition should_check_main_world_csp = CSPDisposition::CHECK;
-
// Whether or not this navigation was started from a context menu.
bool started_from_context_menu = false;
@@ -155,8 +168,7 @@ struct CONTENT_EXPORT CommonNavigationParams {
bool has_user_gesture = false;
// We require a copy of the relevant CSP to perform navigation checks.
- std::vector<ContentSecurityPolicy> initiator_csp;
- base::Optional<CSPSource> initiator_self_source;
+ InitiatorCSPInfo initiator_csp_info;
// The current origin policy for this request's origin.
// (Empty if none applies.)
@@ -300,15 +312,15 @@ struct CONTENT_EXPORT RequestNavigationParams {
// The AppCache host id to be used to identify this navigation.
int appcache_host_id = kAppCacheNoHostId;
- // True if a navigation is following the rules of user activation propagation.
- // This is different from |has_user_gesture| (in CommonNavigationParams) as
- // the activation may have happened before the navigation was triggered, for
- // example.
+ // Set to |kYes| if a navigation is following the rules of user activation
+ // propagation. This is different from |has_user_gesture|
+ // (in CommonNavigationParams) as the activation may have happened before
+ // the navigation was triggered, for example.
// In other words, the distinction isn't regarding user activation and user
// gesture but whether there was an activation prior to the navigation or to
// start it. `was_activated` will answer the former question while
// `user_gesture` will answer the latter.
- bool was_activated = false;
+ WasActivatedOption was_activated = WasActivatedOption::kUnknown;
#if defined(OS_ANDROID)
// The real content of the data: URL. Only used in Android WebView for
diff --git a/chromium/content/common/notifications/DEPS b/chromium/content/common/notifications/DEPS
deleted file mode 100644
index 3855191b858..00000000000
--- a/chromium/content/common/notifications/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
- "+third_party/blink/public/platform/modules/notifications/notification.mojom.h",
-]
diff --git a/chromium/content/common/notifications/OWNERS b/chromium/content/common/notifications/OWNERS
deleted file mode 100644
index cb33c42852f..00000000000
--- a/chromium/content/common/notifications/OWNERS
+++ /dev/null
@@ -1,10 +0,0 @@
-file://content/browser/notifications/OWNERS
-
-per-file *_struct_traits*.*=set noparent
-per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
-
-per-file *.typemap=set noparent
-per-file *.typemap=file://ipc/SECURITY_OWNERS
-
-# TEAM: platform-capabilities@chromium.org
-# COMPONENT: UI>Notifications
diff --git a/chromium/content/common/notifications/notification_struct_traits.cc b/chromium/content/common/notifications/notification_struct_traits.cc
deleted file mode 100644
index f51f378610c..00000000000
--- a/chromium/content/common/notifications/notification_struct_traits.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/notifications/notification_struct_traits.h"
-
-#include "base/feature_list.h"
-#include "content/public/common/content_features.h"
-
-namespace {
-
-// Maximum number of entries in a vibration pattern.
-constexpr int kMaximumVibrationPatternLength = 99;
-
-// Maximum duration of each vibration in a pattern.
-constexpr int kMaximumVibrationDurationMs = 10000; // 10 seconds.
-
-// Maximum number of developer-provided actions on a notification.
-constexpr size_t kMaximumActions = 2;
-
-bool ValidateVibrationPattern(const std::vector<int>& vibration_pattern) {
- if (vibration_pattern.size() > kMaximumVibrationPatternLength)
- return false;
- for (const int duration : vibration_pattern) {
- if (duration < 0 || duration > kMaximumVibrationDurationMs)
- return false;
- }
- return true;
-}
-
-bool ValidateActions(
- const std::vector<content::PlatformNotificationAction>& actions) {
- return actions.size() <= kMaximumActions;
-}
-
-bool ValidateData(const std::vector<char>& data) {
- return data.size() <=
- blink::mojom::NotificationData::kMaximumDeveloperDataSize;
-}
-
-bool ValidateImage(const SkBitmap& image) {
- return image.drawsNothing() ||
- base::FeatureList::IsEnabled(features::kNotificationContentImage);
-}
-
-} // namespace
-
-namespace mojo {
-
-using blink::mojom::NotificationDirection;
-using blink::mojom::NotificationActionType;
-
-// static
-NotificationDirection EnumTraits<NotificationDirection,
- content::PlatformNotificationData::Direction>::
- ToMojom(content::PlatformNotificationData::Direction input) {
- switch (input) {
- case content::PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT:
- return NotificationDirection::LEFT_TO_RIGHT;
- case content::PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT:
- return NotificationDirection::RIGHT_TO_LEFT;
- case content::PlatformNotificationData::DIRECTION_AUTO:
- return NotificationDirection::AUTO;
- }
-
- NOTREACHED();
- return NotificationDirection::AUTO;
-}
-
-// static
-bool EnumTraits<NotificationDirection,
- content::PlatformNotificationData::Direction>::
- FromMojom(NotificationDirection input,
- content::PlatformNotificationData::Direction* out) {
- switch (input) {
- case NotificationDirection::LEFT_TO_RIGHT:
- *out = content::PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT;
- return true;
- case NotificationDirection::RIGHT_TO_LEFT:
- *out = content::PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT;
- return true;
- case NotificationDirection::AUTO:
- *out = content::PlatformNotificationData::DIRECTION_AUTO;
- return true;
- }
-
- return false;
-}
-
-// static
-NotificationActionType
-EnumTraits<NotificationActionType, content::PlatformNotificationActionType>::
- ToMojom(content::PlatformNotificationActionType input) {
- switch (input) {
- case content::PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON:
- return NotificationActionType::BUTTON;
- case content::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT:
- return NotificationActionType::TEXT;
- }
-
- NOTREACHED();
- return NotificationActionType::BUTTON;
-}
-
-// static
-bool EnumTraits<NotificationActionType,
- content::PlatformNotificationActionType>::
- FromMojom(NotificationActionType input,
- content::PlatformNotificationActionType* out) {
- switch (input) {
- case NotificationActionType::BUTTON:
- *out = content::PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON;
- return true;
- case NotificationActionType::TEXT:
- *out = content::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT;
- return true;
- }
-
- return false;
-}
-
-// static
-bool StructTraits<blink::mojom::NotificationActionDataView,
- content::PlatformNotificationAction>::
- Read(blink::mojom::NotificationActionDataView notification_action,
- content::PlatformNotificationAction* out) {
- base::Optional<base::string16> placeholder;
- if (!notification_action.ReadType(&out->type) ||
- !notification_action.ReadTitle(&out->title) ||
- !notification_action.ReadAction(&out->action) ||
- !notification_action.ReadIcon(&out->icon) ||
- !notification_action.ReadPlaceholder(&placeholder)) {
- return false;
- }
- out->placeholder = base::NullableString16(placeholder);
- return true;
-}
-
-// static
-bool StructTraits<blink::mojom::NotificationDataDataView,
- content::PlatformNotificationData>::
- Read(blink::mojom::NotificationDataDataView notification_data,
- content::PlatformNotificationData* platform_notification_data) {
- // TODO(https://crbug.com/798466): Read the data directly into
- // platform_notification_data.data once it stores a vector of ints not chars.
- std::vector<uint8_t> data;
-
- if (!notification_data.ReadTitle(&platform_notification_data->title) ||
- !notification_data.ReadDirection(
- &platform_notification_data->direction) ||
- !notification_data.ReadLang(&platform_notification_data->lang) ||
- !notification_data.ReadBody(&platform_notification_data->body) ||
- !notification_data.ReadTag(&platform_notification_data->tag) ||
- !notification_data.ReadImage(&platform_notification_data->image) ||
- !notification_data.ReadIcon(&platform_notification_data->icon) ||
- !notification_data.ReadBadge(&platform_notification_data->badge) ||
- !notification_data.ReadVibrationPattern(
- &platform_notification_data->vibration_pattern) ||
- !notification_data.ReadActions(&platform_notification_data->actions) ||
- !notification_data.ReadData(&data)) {
- return false;
- }
-
- platform_notification_data->data.assign(data.begin(), data.end());
-
- platform_notification_data->timestamp =
- base::Time::FromJsTime(notification_data.timestamp());
-
- platform_notification_data->renotify = notification_data.renotify();
-
- platform_notification_data->silent = notification_data.silent();
-
- platform_notification_data->require_interaction =
- notification_data.require_interaction();
-
- return ValidateVibrationPattern(
- platform_notification_data->vibration_pattern) &&
- ValidateActions(platform_notification_data->actions) &&
- ValidateData(platform_notification_data->data);
-}
-
-// static
-bool StructTraits<blink::mojom::NotificationResourcesDataView,
- content::NotificationResources>::
- Read(blink::mojom::NotificationResourcesDataView in,
- content::NotificationResources* out) {
- if (!in.ReadImage(&out->image) || !in.ReadIcon(&out->notification_icon) ||
- !in.ReadBadge(&out->badge) || !in.ReadActionIcons(&out->action_icons)) {
- return false;
- }
- return ValidateImage(out->image);
-}
-
-} // namespace mojo
diff --git a/chromium/content/common/notifications/notification_struct_traits.h b/chromium/content/common/notifications/notification_struct_traits.h
deleted file mode 100644
index bf2fccb4d5d..00000000000
--- a/chromium/content/common/notifications/notification_struct_traits.h
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_COMMON_NOTIFICATIONS_NOTIFICATION_STRUCT_TRAITS_H_
-#define CONTENT_COMMON_NOTIFICATIONS_NOTIFICATION_STRUCT_TRAITS_H_
-
-#include "base/containers/span.h"
-#include "base/strings/string16.h"
-#include "content/common/content_export.h"
-#include "content/public/common/platform_notification_data.h"
-#include "mojo/public/cpp/base/string16_mojom_traits.h"
-#include "mojo/public/cpp/bindings/struct_traits.h"
-#include "skia/public/interfaces/bitmap_skbitmap_struct_traits.h"
-#include "third_party/blink/public/platform/modules/notifications/notification.mojom.h"
-#include "url/gurl.h"
-#include "url/mojom/url_gurl_mojom_traits.h"
-
-namespace mojo {
-
-template <>
-struct CONTENT_EXPORT EnumTraits<blink::mojom::NotificationDirection,
- content::PlatformNotificationData::Direction> {
- static blink::mojom::NotificationDirection ToMojom(
- content::PlatformNotificationData::Direction input);
-
- static bool FromMojom(blink::mojom::NotificationDirection input,
- content::PlatformNotificationData::Direction* out);
-};
-
-template <>
-struct CONTENT_EXPORT EnumTraits<blink::mojom::NotificationActionType,
- content::PlatformNotificationActionType> {
- static blink::mojom::NotificationActionType ToMojom(
- content::PlatformNotificationActionType input);
-
- static bool FromMojom(blink::mojom::NotificationActionType input,
- content::PlatformNotificationActionType* out);
-};
-
-template <>
-struct CONTENT_EXPORT StructTraits<blink::mojom::NotificationActionDataView,
- content::PlatformNotificationAction> {
- static content::PlatformNotificationActionType type(
- const content::PlatformNotificationAction& action) {
- return action.type;
- }
-
- static const std::string& action(
- const content::PlatformNotificationAction& action) {
- return action.action;
- }
-
- static const base::string16& title(
- const content::PlatformNotificationAction& action) {
- return action.title;
- }
-
- static const GURL& icon(const content::PlatformNotificationAction& action) {
- return action.icon;
- }
-
- static const base::Optional<base::string16>& placeholder(
- const content::PlatformNotificationAction& action) {
- return action.placeholder.as_optional_string16();
- }
-
- static bool Read(
- blink::mojom::NotificationActionDataView notification_action,
- content::PlatformNotificationAction* platform_notification_action);
-};
-
-template <>
-struct CONTENT_EXPORT StructTraits<blink::mojom::NotificationDataDataView,
- content::PlatformNotificationData> {
- static const base::string16& title(
- const content::PlatformNotificationData& data) {
- return data.title;
- }
-
- static content::PlatformNotificationData::Direction direction(
- const content::PlatformNotificationData& data) {
- return data.direction;
- }
-
- static const std::string& lang(
- const content::PlatformNotificationData& data) {
- return data.lang;
- }
-
- static const base::string16& body(
- const content::PlatformNotificationData& data) {
- return data.body;
- }
-
- static const std::string& tag(const content::PlatformNotificationData& data) {
- return data.tag;
- }
-
- static const GURL& image(const content::PlatformNotificationData& data) {
- return data.image;
- }
-
- static const GURL& icon(const content::PlatformNotificationData& data) {
- return data.icon;
- }
-
- static const GURL& badge(const content::PlatformNotificationData& data) {
- return data.badge;
- }
-
- static const base::span<const int32_t> vibration_pattern(
- const content::PlatformNotificationData& data) {
- // TODO(https://crbug.com/798466): Store as int32s to avoid this cast.
- return base::make_span(
- reinterpret_cast<const int32_t*>(data.vibration_pattern.data()),
- data.vibration_pattern.size());
- }
-
- static double timestamp(const content::PlatformNotificationData& data) {
- return data.timestamp.ToJsTime();
- }
-
- static bool renotify(const content::PlatformNotificationData& data) {
- return data.renotify;
- }
-
- static bool silent(const content::PlatformNotificationData& data) {
- return data.silent;
- }
-
- static bool require_interaction(
- const content::PlatformNotificationData& data) {
- return data.require_interaction;
- }
-
- static const base::span<const uint8_t> data(
- const content::PlatformNotificationData& data) {
- // TODO(https://crbug.com/798466): Align data types to avoid this cast.
- return base::make_span(reinterpret_cast<const uint8_t*>(data.data.data()),
- data.data.size());
- }
-
- static const std::vector<content::PlatformNotificationAction>& actions(
- const content::PlatformNotificationData& data) {
- return data.actions;
- }
-
- static bool Read(
- blink::mojom::NotificationDataDataView notification_data,
- content::PlatformNotificationData* platform_notification_data);
-};
-
-template <>
-struct CONTENT_EXPORT StructTraits<blink::mojom::NotificationResourcesDataView,
- content::NotificationResources> {
- static const SkBitmap& image(
- const content::NotificationResources& resources) {
- return resources.image;
- }
-
- static const SkBitmap& icon(const content::NotificationResources& resources) {
- return resources.notification_icon;
- }
-
- static const SkBitmap& badge(
- const content::NotificationResources& resources) {
- return resources.badge;
- }
-
- static const std::vector<SkBitmap>& action_icons(
- const content::NotificationResources& resources) {
- return resources.action_icons;
- }
-
- static bool Read(blink::mojom::NotificationResourcesDataView in,
- content::NotificationResources* out);
-};
-
-} // namespace mojo
-
-#endif // CONTENT_BROWSER_NOTIFICATIONS_NOTIFICATION_STRUCT_TRAITS_H_
diff --git a/chromium/content/common/notifications/notification_struct_traits_unittest.cc b/chromium/content/common/notifications/notification_struct_traits_unittest.cc
deleted file mode 100644
index 1ecf6106af8..00000000000
--- a/chromium/content/common/notifications/notification_struct_traits_unittest.cc
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/common/notifications/notification_struct_traits.h"
-
-#include "base/macros.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/time/time.h"
-#include "content/public/common/content_features.h"
-#include "content/public/common/platform_notification_data.h"
-#include "mojo/public/cpp/test_support/test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/notifications/notification.mojom.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "url/gurl.h"
-
-namespace content {
-
-namespace {
-
-SkBitmap CreateBitmap(int width, int height, SkColor color) {
- SkBitmap bitmap;
- bitmap.allocN32Pixels(width, height);
- bitmap.eraseColor(color);
- return bitmap;
-}
-
-// Returns true if |lhs| and |rhs| have the same width and height and the
-// pixel at position (0, 0) is the same color in both.
-bool ImagesShareDimensionsAndColor(const SkBitmap& lhs, const SkBitmap& rhs) {
- return lhs.width() == rhs.width() && lhs.height() == rhs.height() &&
- lhs.getColor(0, 0) == rhs.getColor(0, 0);
-}
-
-} // namespace
-
-TEST(NotificationStructTraitsTest, NotificationDataRoundtrip) {
- PlatformNotificationData notification_data;
- notification_data.title = base::ASCIIToUTF16("Title of my notification");
- notification_data.direction =
- PlatformNotificationData::Direction::DIRECTION_AUTO;
- notification_data.lang = "test-lang";
- notification_data.body = base::ASCIIToUTF16("Notification body.");
- notification_data.tag = "notification-tag";
- notification_data.image = GURL("https://example.com/image.png");
- notification_data.icon = GURL("https://example.com/icon.png");
- notification_data.badge = GURL("https://example.com/badge.png");
-
- const int vibration_pattern[] = {500, 100, 30};
- notification_data.vibration_pattern.assign(
- vibration_pattern, vibration_pattern + arraysize(vibration_pattern));
-
- notification_data.timestamp = base::Time::FromJsTime(1513966159000.);
- notification_data.renotify = true;
- notification_data.silent = true;
- notification_data.require_interaction = true;
-
- const char data[] = "mock binary notification data";
- notification_data.data.assign(data, data + arraysize(data));
-
- notification_data.actions.resize(2);
- notification_data.actions[0].type = PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON;
- notification_data.actions[0].action = "buttonAction";
- notification_data.actions[0].title = base::ASCIIToUTF16("Button Title!");
- notification_data.actions[0].icon = GURL("https://example.com/aButton.png");
- notification_data.actions[0].placeholder = base::NullableString16();
-
- notification_data.actions[1].type = PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT;
- notification_data.actions[1].action = "textAction";
- notification_data.actions[1].title = base::ASCIIToUTF16("Reply Button Title");
- notification_data.actions[1].icon = GURL("https://example.com/reply.png");
- notification_data.actions[1].placeholder =
- base::NullableString16(base::ASCIIToUTF16("Placeholder Text"), false);
-
- PlatformNotificationData roundtrip_notification_data;
-
- ASSERT_TRUE(
- mojo::test::SerializeAndDeserialize<blink::mojom::NotificationData>(
- &notification_data, &roundtrip_notification_data));
-
- EXPECT_EQ(roundtrip_notification_data.title, notification_data.title);
- EXPECT_EQ(roundtrip_notification_data.direction, notification_data.direction);
- EXPECT_EQ(roundtrip_notification_data.lang, notification_data.lang);
- EXPECT_EQ(roundtrip_notification_data.body, notification_data.body);
- EXPECT_EQ(roundtrip_notification_data.tag, notification_data.tag);
- EXPECT_EQ(roundtrip_notification_data.image, notification_data.image);
- EXPECT_EQ(roundtrip_notification_data.icon, notification_data.icon);
- EXPECT_EQ(roundtrip_notification_data.badge, notification_data.badge);
- EXPECT_EQ(roundtrip_notification_data.vibration_pattern,
- notification_data.vibration_pattern);
- EXPECT_EQ(roundtrip_notification_data.timestamp, notification_data.timestamp);
- EXPECT_EQ(roundtrip_notification_data.renotify, notification_data.renotify);
- EXPECT_EQ(roundtrip_notification_data.silent, notification_data.silent);
- EXPECT_EQ(roundtrip_notification_data.require_interaction,
- notification_data.require_interaction);
- EXPECT_EQ(roundtrip_notification_data.data, notification_data.data);
- ASSERT_EQ(notification_data.actions.size(),
- roundtrip_notification_data.actions.size());
- for (size_t i = 0; i < notification_data.actions.size(); ++i) {
- SCOPED_TRACE(base::StringPrintf("Action index: %zd", i));
- EXPECT_EQ(notification_data.actions[i].type,
- roundtrip_notification_data.actions[i].type);
- EXPECT_EQ(notification_data.actions[i].action,
- roundtrip_notification_data.actions[i].action);
- EXPECT_EQ(notification_data.actions[i].title,
- roundtrip_notification_data.actions[i].title);
- EXPECT_EQ(notification_data.actions[i].icon,
- roundtrip_notification_data.actions[i].icon);
- EXPECT_EQ(notification_data.actions[i].placeholder,
- roundtrip_notification_data.actions[i].placeholder);
- }
-}
-
-// Check upper bound on vibration entries (99).
-TEST(NotificationStructTraitsTest, ValidVibrationPattern) {
- constexpr int kEntries = 99; // valid
- constexpr int kDurationMs = 999; // valid
-
- PlatformNotificationData notification_data;
- notification_data.title =
- base::ASCIIToUTF16("Notification with 99 x 999ms entries (valid)");
-
- for (size_t i = 0; i < kEntries; ++i)
- notification_data.vibration_pattern.push_back(kDurationMs);
-
- PlatformNotificationData platform_notification_data;
-
- ASSERT_TRUE(
- mojo::test::SerializeAndDeserialize<blink::mojom::NotificationData>(
- &notification_data, &platform_notification_data));
-}
-
-// Check round-trip fails when there are too many entries in the vibration
-// pattern.
-TEST(NotificationStructTraitsTest, TooManyVibrations) {
- constexpr int kEntries = 100; // invalid
- constexpr int kDurationMs = 1; // valid
-
- PlatformNotificationData notification_data;
- notification_data.title =
- base::ASCIIToUTF16("Notification with 100 x 1ms entries (invalid)");
-
- for (size_t i = 0; i < kEntries; ++i)
- notification_data.vibration_pattern.push_back(kDurationMs);
-
- PlatformNotificationData platform_notification_data;
-
- ASSERT_FALSE(
- mojo::test::SerializeAndDeserialize<blink::mojom::NotificationData>(
- &notification_data, &platform_notification_data));
-}
-
-// Check round-trip fails when there is a too-long vibration duration.
-TEST(NotificationStructTraitsTest, TooLongVibrationDuration) {
- constexpr int kEntries = 1; // valid
- constexpr int kDurationMs = 10001; // invalid (>10 seconds)
-
- PlatformNotificationData notification_data;
- notification_data.title =
- base::ASCIIToUTF16("Notification with 1 x 10001ms entries (invalid)");
-
- for (size_t i = 0; i < kEntries; ++i)
- notification_data.vibration_pattern.push_back(kDurationMs);
-
- PlatformNotificationData platform_notification_data;
-
- ASSERT_FALSE(
- mojo::test::SerializeAndDeserialize<blink::mojom::NotificationData>(
- &notification_data, &platform_notification_data));
-}
-
-// Check round-trip fails when there are too many actions provided.
-TEST(NotificationStructTraitsTest, TooManyActions) {
- constexpr int kActions = 3; // invalid (max is 2)
-
- PlatformNotificationData notification_data;
- notification_data.title =
- base::ASCIIToUTF16("Notification with 3 actions provided (invalid)");
-
- notification_data.actions.resize(kActions);
- for (size_t i = 0; i < kActions; ++i) {
- notification_data.actions[i].title = base::ASCIIToUTF16("action title");
- }
-
- PlatformNotificationData platform_notification_data;
-
- ASSERT_FALSE(
- mojo::test::SerializeAndDeserialize<blink::mojom::NotificationData>(
- &notification_data, &platform_notification_data));
-}
-
-// Check round-trip fails when the data size is too big.
-TEST(NotificationStructTraitsTest, DataExceedsMaximumSize) {
- constexpr size_t kDataSize = 1024 * 1024 + 1; // 1 more than max data size.
-
- PlatformNotificationData notification_data;
- notification_data.title =
- base::ASCIIToUTF16("Notification with too much data");
-
- notification_data.data.resize(kDataSize);
-
- PlatformNotificationData platform_notification_data;
-
- ASSERT_FALSE(
- mojo::test::SerializeAndDeserialize<blink::mojom::NotificationData>(
- &notification_data, &platform_notification_data));
-}
-
-// Check round-trip fails if image supplied when kill-switch is active.
-TEST(NotificationStructTraitsTest, ContentImageKillSwitch) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(
- features::kNotificationContentImage);
-
- NotificationResources resources;
- resources.image = CreateBitmap(200, 100, SK_ColorMAGENTA);
-
- NotificationResources roundtrip_resources;
- ASSERT_FALSE(
- mojo::test::SerializeAndDeserialize<blink::mojom::NotificationResources>(
- &resources, &roundtrip_resources));
-}
-
-TEST(NotificationStructTraitsTest, NotificationResourcesRoundtrip) {
- NotificationResources resources;
-
- resources.image = CreateBitmap(200, 100, SK_ColorMAGENTA);
- resources.notification_icon = CreateBitmap(100, 50, SK_ColorGREEN);
- resources.badge = CreateBitmap(20, 10, SK_ColorBLUE);
-
- resources.action_icons.resize(2);
- resources.action_icons[0] = CreateBitmap(10, 10, SK_ColorLTGRAY);
- resources.action_icons[1] = CreateBitmap(11, 11, SK_ColorDKGRAY);
-
- NotificationResources roundtrip_resources;
-
- ASSERT_TRUE(
- mojo::test::SerializeAndDeserialize<blink::mojom::NotificationResources>(
- &resources, &roundtrip_resources));
-
- ASSERT_FALSE(roundtrip_resources.image.empty());
- EXPECT_TRUE(ImagesShareDimensionsAndColor(resources.image,
- roundtrip_resources.image));
-
- ASSERT_FALSE(roundtrip_resources.notification_icon.empty());
- EXPECT_TRUE(ImagesShareDimensionsAndColor(
- resources.notification_icon, roundtrip_resources.notification_icon));
-
- ASSERT_FALSE(roundtrip_resources.badge.empty());
- EXPECT_TRUE(ImagesShareDimensionsAndColor(resources.badge,
- roundtrip_resources.badge));
-
- ASSERT_EQ(resources.action_icons.size(),
- roundtrip_resources.action_icons.size());
-
- for (size_t i = 0; i < roundtrip_resources.action_icons.size(); ++i) {
- SCOPED_TRACE(base::StringPrintf("Action icon index: %zd", i));
- ASSERT_FALSE(roundtrip_resources.action_icons[i].empty());
- EXPECT_TRUE(ImagesShareDimensionsAndColor(
- resources.action_icons[i], roundtrip_resources.action_icons[i]));
- }
-}
-
-} // namespace content
diff --git a/chromium/content/common/notifications/notification_types.typemap b/chromium/content/common/notifications/notification_types.typemap
deleted file mode 100644
index f96161612fc..00000000000
--- a/chromium/content/common/notifications/notification_types.typemap
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//third_party/blink/public/platform/modules/notifications/notification.mojom"
-public_headers = [
- "//content/public/common/notification_resources.h",
- "//content/public/common/platform_notification_data.h",
-]
-traits_headers =
- [ "//content/common/notifications/notification_struct_traits.h" ]
-deps = [
- "//mojo/public/cpp/bindings",
- "//third_party/blink/public:blink_headers",
-]
-type_mappings = [
- "blink.mojom.NotificationData=content::PlatformNotificationData",
- "blink.mojom.NotificationDirection=content::PlatformNotificationData::Direction",
- "blink.mojom.NotificationResources=content::NotificationResources",
-]
diff --git a/chromium/content/common/origin_util.cc b/chromium/content/common/origin_util.cc
index 6cac476bd4b..2b15f617775 100644
--- a/chromium/content/common/origin_util.cc
+++ b/chromium/content/common/origin_util.cc
@@ -20,7 +20,7 @@ namespace {
// SecurityOrigin::create might return unique origins for URLs whose schemes are
// included in SchemeRegistry::shouldTreatURLSchemeAsNoAccess.
bool IsOriginUnique(const url::Origin& origin) {
- return origin.unique() ||
+ return origin.opaque() ||
base::ContainsValue(url::GetNoAccessSchemes(), origin.scheme());
}
diff --git a/chromium/content/common/page_state_serialization.cc b/chromium/content/common/page_state_serialization.cc
index 4231b01474a..ae640735bde 100644
--- a/chromium/content/common/page_state_serialization.cc
+++ b/chromium/content/common/page_state_serialization.cc
@@ -25,17 +25,15 @@
#include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
#include "url/mojom/url_gurl_mojom_traits.h"
-namespace mojom = content::history::mojom;
-
namespace content {
#define STATIC_ASSERT_ENUM(a, b) \
static_assert(static_cast<int>(a) == static_cast<int>(b), \
"mismatching enums: " #a)
-STATIC_ASSERT_ENUM(mojom::ScrollRestorationType::kAuto,
+STATIC_ASSERT_ENUM(history::mojom::ScrollRestorationType::kAuto,
blink::kWebHistoryScrollRestorationAuto);
-STATIC_ASSERT_ENUM(mojom::ScrollRestorationType::kManual,
+STATIC_ASSERT_ENUM(history::mojom::ScrollRestorationType::kManual,
blink::kWebHistoryScrollRestorationManual);
namespace {
@@ -686,9 +684,9 @@ void WritePageState(const ExplodedPageState& state, SerializeObject* obj) {
// "Modern" read/write functions start here. These are probably what you want.
void WriteResourceRequestBody(const network::ResourceRequestBody& request_body,
- mojom::RequestBody* mojo_body) {
+ history::mojom::RequestBody* mojo_body) {
for (const auto& element : *request_body.elements()) {
- mojom::ElementPtr data_element = mojom::Element::New();
+ history::mojom::ElementPtr data_element = history::mojom::Element::New();
switch (element.type()) {
case network::DataElement::TYPE_BYTES: {
data_element->set_bytes(std::vector<unsigned char>(
@@ -697,7 +695,7 @@ void WriteResourceRequestBody(const network::ResourceRequestBody& request_body,
break;
}
case network::DataElement::TYPE_FILE: {
- mojom::FilePtr file = mojom::File::New(
+ history::mojom::FilePtr file = history::mojom::File::New(
element.path().AsUTF16Unsafe(), element.offset(), element.length(),
element.expected_modification_time());
data_element->set_file(std::move(file));
@@ -721,27 +719,27 @@ void WriteResourceRequestBody(const network::ResourceRequestBody& request_body,
}
void ReadResourceRequestBody(
- mojom::RequestBody* mojo_body,
+ history::mojom::RequestBody* mojo_body,
const scoped_refptr<network::ResourceRequestBody>& request_body) {
for (const auto& element : mojo_body->elements) {
- mojom::Element::Tag tag = element->which();
+ history::mojom::Element::Tag tag = element->which();
switch (tag) {
- case mojom::Element::Tag::BYTES:
+ case history::mojom::Element::Tag::BYTES:
AppendDataToRequestBody(
request_body,
reinterpret_cast<const char*>(element->get_bytes().data()),
element->get_bytes().size());
break;
- case mojom::Element::Tag::FILE: {
- mojom::File* file = element->get_file().get();
+ case history::mojom::Element::Tag::FILE: {
+ history::mojom::File* file = element->get_file().get();
AppendFileRangeToRequestBody(request_body, file->path, file->offset,
file->length, file->modification_time);
break;
}
- case mojom::Element::Tag::BLOB_UUID:
+ case history::mojom::Element::Tag::BLOB_UUID:
AppendBlobToRequestBody(request_body, element->get_blob_uuid());
break;
- case mojom::Element::Tag::DEPRECATED_FILE_SYSTEM_FILE:
+ case history::mojom::Element::Tag::DEPRECATED_FILE_SYSTEM_FILE:
// No longer supported.
break;
}
@@ -750,9 +748,9 @@ void ReadResourceRequestBody(
}
void WriteHttpBody(const ExplodedHttpBody& http_body,
- mojom::HttpBody* mojo_body) {
+ history::mojom::HttpBody* mojo_body) {
if (http_body.request_body != nullptr) {
- mojo_body->request_body = mojom::RequestBody::New();
+ mojo_body->request_body = history::mojom::RequestBody::New();
mojo_body->contains_passwords = http_body.contains_passwords;
mojo_body->http_content_type = http_body.http_content_type;
WriteResourceRequestBody(*http_body.request_body,
@@ -760,7 +758,8 @@ void WriteHttpBody(const ExplodedHttpBody& http_body,
}
}
-void ReadHttpBody(mojom::HttpBody* mojo_body, ExplodedHttpBody* http_body) {
+void ReadHttpBody(history::mojom::HttpBody* mojo_body,
+ ExplodedHttpBody* http_body) {
http_body->contains_passwords = mojo_body->contains_passwords;
http_body->http_content_type = mojo_body->http_content_type;
if (mojo_body->request_body) {
@@ -772,7 +771,7 @@ void ReadHttpBody(mojom::HttpBody* mojo_body, ExplodedHttpBody* http_body) {
}
void WriteFrameState(const ExplodedFrameState& state,
- mojom::FrameState* frame) {
+ history::mojom::FrameState* frame) {
frame->url_string = state.url_string;
frame->referrer = state.referrer;
frame->target = state.target;
@@ -783,10 +782,11 @@ void WriteFrameState(const ExplodedFrameState& state,
}
frame->scroll_restoration_type =
- static_cast<mojom::ScrollRestorationType>(state.scroll_restoration_type);
+ static_cast<history::mojom::ScrollRestorationType>(
+ state.scroll_restoration_type);
if (state.did_save_scroll_or_scale_state) {
- frame->view_state = mojom::ViewState::New();
+ frame->view_state = history::mojom::ViewState::New();
frame->view_state->scroll_offset = state.scroll_offset;
frame->view_state->visual_viewport_scroll_offset =
state.visual_viewport_scroll_offset;
@@ -807,19 +807,21 @@ void WriteFrameState(const ExplodedFrameState& state,
frame->referrer_policy = state.referrer_policy;
- frame->http_body = mojom::HttpBody::New();
+ frame->http_body = history::mojom::HttpBody::New();
WriteHttpBody(state.http_body, frame->http_body.get());
// Subitems
const std::vector<ExplodedFrameState>& children = state.children;
for (const auto& child : children) {
- mojom::FrameStatePtr child_frame = mojom::FrameState::New();
+ history::mojom::FrameStatePtr child_frame =
+ history::mojom::FrameState::New();
WriteFrameState(child, child_frame.get());
frame->children.push_back(std::move(child_frame));
}
}
-void ReadFrameState(mojom::FrameState* frame, ExplodedFrameState* state) {
+void ReadFrameState(history::mojom::FrameState* frame,
+ ExplodedFrameState* state) {
state->url_string = frame->url_string;
state->referrer = frame->referrer;
state->target = frame->target;
@@ -872,8 +874,9 @@ void ReadMojoPageState(SerializeObject* obj, ExplodedPageState* state) {
if (obj->parse_error)
return;
- mojom::PageStatePtr page;
- obj->parse_error = !(mojom::PageState::Deserialize(tmp, length, &page));
+ history::mojom::PageStatePtr page;
+ obj->parse_error =
+ !(history::mojom::PageState::Deserialize(tmp, length, &page));
if (obj->parse_error)
return;
@@ -891,15 +894,15 @@ void ReadMojoPageState(SerializeObject* obj, ExplodedPageState* state) {
void WriteMojoPageState(const ExplodedPageState& state, SerializeObject* obj) {
WriteInteger(obj->version, obj);
- mojom::PageStatePtr page = mojom::PageState::New();
+ history::mojom::PageStatePtr page = history::mojom::PageState::New();
for (const auto& referenced_file : state.referenced_files) {
page->referenced_files.push_back(referenced_file.value());
}
- page->top = mojom::FrameState::New();
+ page->top = history::mojom::FrameState::New();
WriteFrameState(state.top, page->top.get());
- std::vector<uint8_t> page_bytes = mojom::PageState::Serialize(&page);
+ std::vector<uint8_t> page_bytes = history::mojom::PageState::Serialize(&page);
obj->pickle.WriteData(reinterpret_cast<char*>(page_bytes.data()),
page_bytes.size());
}
diff --git a/chromium/content/common/plugin_list.h b/chromium/content/common/plugin_list.h
index 35ff2d0b735..a76f0a61a5d 100644
--- a/chromium/content/common/plugin_list.h
+++ b/chromium/content/common/plugin_list.h
@@ -15,6 +15,7 @@
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/synchronization/lock.h"
+#include "base/thread_annotations.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/common/webplugininfo.h"
@@ -122,7 +123,8 @@ class CONTENT_EXPORT PluginList {
// Removes |plugin_path| from the list of extra plugin paths. Should only be
// called while holding |lock_|.
- void RemoveExtraPluginPathLocked(const base::FilePath& plugin_path);
+ void RemoveExtraPluginPathLocked(const base::FilePath& plugin_path)
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Creates a WebPluginInfo structure given a plugin's path. On success
// returns true, with the information being put into "info".
@@ -142,19 +144,19 @@ class CONTENT_EXPORT PluginList {
// States whether we will load the plugin list the next time we try to access
// it, whether we are currently in the process of loading it, or whether we
// consider it up to date.
- LoadingState loading_state_;
+ LoadingState loading_state_ GUARDED_BY(lock_);
// Extra plugin paths that we want to search when loading.
- std::vector<base::FilePath> extra_plugin_paths_;
+ std::vector<base::FilePath> extra_plugin_paths_ GUARDED_BY(lock_);
// Holds information about internal plugins.
- std::vector<WebPluginInfo> internal_plugins_;
+ std::vector<WebPluginInfo> internal_plugins_ GUARDED_BY(lock_);
// A list holding all plugins.
- std::vector<WebPluginInfo> plugins_list_;
+ std::vector<WebPluginInfo> plugins_list_ GUARDED_BY(lock_);
// Callback that is invoked whenever the PluginList will reload the plugins.
- base::Closure will_load_plugins_callback_;
+ base::Closure will_load_plugins_callback_ GUARDED_BY(lock_);
// Need synchronization for the above members since this object can be
// accessed on multiple threads.
diff --git a/chromium/content/common/render_frame_metadata.mojom b/chromium/content/common/render_frame_metadata.mojom
index 1470abb5978..8af7f1a0751 100644
--- a/chromium/content/common/render_frame_metadata.mojom
+++ b/chromium/content/common/render_frame_metadata.mojom
@@ -48,10 +48,8 @@ struct RenderFrameMetadata {
// Used to position the Android location top bar and page content, whose
// precise position is computed by the renderer compositor.
- [EnableIf=is_android]
float top_controls_height;
- [EnableIf=is_android]
float top_controls_shown_ratio;
// Used to position Android bottom bar, whose position is computed by the
diff --git a/chromium/content/common/render_frame_metadata.typemap b/chromium/content/common/render_frame_metadata.typemap
index 3d7a39e3a4c..da6d30010c1 100644
--- a/chromium/content/common/render_frame_metadata.typemap
+++ b/chromium/content/common/render_frame_metadata.typemap
@@ -7,6 +7,7 @@ public_headers = [ "//cc/trees/render_frame_metadata.h" ]
traits_headers = [ "//content/common/render_frame_metadata_struct_traits.h" ]
deps = [
"//cc",
+ "//ui/gfx/geometry/mojo:struct_traits",
]
sources = [
"//content/common/render_frame_metadata_struct_traits.cc",
diff --git a/chromium/content/common/render_frame_metadata_struct_traits.cc b/chromium/content/common/render_frame_metadata_struct_traits.cc
index 302e4cd3bfa..68340d3283b 100644
--- a/chromium/content/common/render_frame_metadata_struct_traits.cc
+++ b/chromium/content/common/render_frame_metadata_struct_traits.cc
@@ -21,9 +21,9 @@ bool StructTraits<content::mojom::RenderFrameMetadataDataView,
out->is_mobile_optimized = data.is_mobile_optimized();
out->device_scale_factor = data.device_scale_factor();
out->page_scale_factor = data.page_scale_factor();
-#if defined(OS_ANDROID)
out->top_controls_height = data.top_controls_height();
out->top_controls_shown_ratio = data.top_controls_shown_ratio();
+#if defined(OS_ANDROID)
out->bottom_controls_height = data.bottom_controls_height();
out->bottom_controls_shown_ratio = data.bottom_controls_shown_ratio();
out->min_page_scale_factor = data.min_page_scale_factor();
diff --git a/chromium/content/common/render_frame_metadata_struct_traits.h b/chromium/content/common/render_frame_metadata_struct_traits.h
index 5f76e36fd52..cd317a3640c 100644
--- a/chromium/content/common/render_frame_metadata_struct_traits.h
+++ b/chromium/content/common/render_frame_metadata_struct_traits.h
@@ -57,7 +57,6 @@ struct StructTraits<content::mojom::RenderFrameMetadataDataView,
return metadata.page_scale_factor;
}
-#if defined(OS_ANDROID)
static float top_controls_height(const cc::RenderFrameMetadata& metadata) {
return metadata.top_controls_height;
}
@@ -67,6 +66,7 @@ struct StructTraits<content::mojom::RenderFrameMetadataDataView,
return metadata.top_controls_shown_ratio;
}
+#if defined(OS_ANDROID)
static float bottom_controls_height(const cc::RenderFrameMetadata& metadata) {
return metadata.bottom_controls_height;
}
diff --git a/chromium/content/common/render_message_filter.mojom b/chromium/content/common/render_message_filter.mojom
index e78a32d98ae..c83c5d0688f 100644
--- a/chromium/content/common/render_message_filter.mojom
+++ b/chromium/content/common/render_message_filter.mojom
@@ -5,7 +5,6 @@
module content.mojom;
import "content/common/input/input_handler.mojom";
-import "content/common/native_types.mojom";
import "content/common/widget.mojom";
import "content/public/common/renderer_preferences.mojom";
import "mojo/public/mojom/base/thread_priority.mojom";
@@ -19,32 +18,13 @@ interface RenderMessageFilter {
// Similar to CreateWindow, except used for sub-widgets, like <select>
// dropdowns.
- [Sync] CreateNewWidget(int32 opener_id, content.mojom.WebPopupType popup_type, Widget widget)
+ [Sync] CreateNewWidget(int32 opener_id, Widget widget)
=> (int32 route_id);
// Similar to CreateWidget except the widget is a full screen window.
[Sync] CreateFullscreenWidget(int32 opener_id, Widget widget)
=> (int32 route_id);
- // Requests that the browser cache |data| associated with |url| and |expected_response_time|.
- // TODO(https://crbug.com/779444): Verify or remove |url| and |cache_storage_origin|.
- DidGenerateCacheableMetadata(url.mojom.Url url,
- mojo_base.mojom.Time expected_response_time,
- array<uint8> data);
-
- // TODO(crbug.com/867848) Pass the data as mojo data_pipe instead of
- // array<unit8>.
- FetchCachedCode(url.mojom.Url url) => (mojo_base.mojom.Time response_time,
- array<uint8> data);
-
- ClearCodeCacheEntry(url.mojom.Url url);
-
- // Requests that the browser cache |data| for the specified CacheStorage entry.
- DidGenerateCacheableMetadataInCacheStorage(
- url.mojom.Url url, mojo_base.mojom.Time expected_response_time,
- array<uint8> data, url.mojom.Origin cache_storage_origin,
- string cache_storage_cache_name);
-
// A renderer sends this when it wants to know whether a gpu process exists.
[Sync] HasGpuProcess() => (bool has_gpu_process);
diff --git a/chromium/content/common/render_widget_host_ns_view.mojom b/chromium/content/common/render_widget_host_ns_view.mojom
index 4d435ea86b0..ba73fbe67a3 100644
--- a/chromium/content/common/render_widget_host_ns_view.mojom
+++ b/chromium/content/common/render_widget_host_ns_view.mojom
@@ -22,8 +22,11 @@ import "ui/platform_window/mojo/text_input_state.mojom";
interface RenderWidgetHostNSViewBridge {
// Specify that the NSView will a popup (e.g, date/time picker) that will
// create its own NSWindow.
- InitAsPopup(gfx.mojom.Rect content_rect,
- content.mojom.WebPopupType popup_type);
+ InitAsPopup(gfx.mojom.Rect content_rect);
+
+ // Set this to be a child NSView of the NSView mapped to by
+ // |parent_ns_view_id|.
+ SetParentWebContentsNSView(uint64 parent_ns_view_id);
// Disable displaying any content (including the background color). This is
// to be called on views that are to be displayed via a parent ui::Compositor.
diff --git a/chromium/content/common/render_widget_surface_properties.cc b/chromium/content/common/render_widget_surface_properties.cc
index 2848b01eb5d..09a9a0d600a 100644
--- a/chromium/content/common/render_widget_surface_properties.cc
+++ b/chromium/content/common/render_widget_surface_properties.cc
@@ -13,9 +13,9 @@ RenderWidgetSurfaceProperties::FromCompositorFrame(
RenderWidgetSurfaceProperties properties;
properties.size = frame.size_in_pixels();
properties.device_scale_factor = frame.device_scale_factor();
-#ifdef OS_ANDROID
properties.top_controls_height = frame.metadata.top_controls_height;
properties.top_controls_shown_ratio = frame.metadata.top_controls_shown_ratio;
+#ifdef OS_ANDROID
properties.bottom_controls_height = frame.metadata.bottom_controls_height;
properties.bottom_controls_shown_ratio =
frame.metadata.bottom_controls_shown_ratio;
@@ -39,9 +39,9 @@ RenderWidgetSurfaceProperties& RenderWidgetSurfaceProperties::operator=(
bool RenderWidgetSurfaceProperties::operator==(
const RenderWidgetSurfaceProperties& other) const {
return other.device_scale_factor == device_scale_factor &&
-#ifdef OS_ANDROID
other.top_controls_height == top_controls_height &&
other.top_controls_shown_ratio == top_controls_shown_ratio &&
+#ifdef OS_ANDROID
other.bottom_controls_height == bottom_controls_height &&
other.bottom_controls_shown_ratio == bottom_controls_shown_ratio &&
other.selection == selection &&
@@ -77,7 +77,6 @@ std::string RenderWidgetSurfaceProperties::ToDiffString(
++changed_properties;
}
-#ifdef OS_ANDROID
if (top_controls_height != other.top_controls_height) {
if (changed_properties > 0)
stream << ", ";
@@ -94,6 +93,8 @@ std::string RenderWidgetSurfaceProperties::ToDiffString(
++changed_properties;
}
+#ifdef OS_ANDROID
+
if (bottom_controls_height != other.bottom_controls_height) {
if (changed_properties > 0)
stream << ", ";
diff --git a/chromium/content/common/render_widget_surface_properties.h b/chromium/content/common/render_widget_surface_properties.h
index da357db8178..c30cf77eb8c 100644
--- a/chromium/content/common/render_widget_surface_properties.h
+++ b/chromium/content/common/render_widget_surface_properties.h
@@ -30,9 +30,9 @@ struct CONTENT_EXPORT RenderWidgetSurfaceProperties {
gfx::Size size;
float device_scale_factor = 0;
-#ifdef OS_ANDROID
float top_controls_height = 0;
float top_controls_shown_ratio = 0;
+#ifdef OS_ANDROID
float bottom_controls_height = 0;
float bottom_controls_shown_ratio = 0;
viz::Selection<gfx::SelectionBound> selection;
diff --git a/chromium/content/common/sandbox_policy_fuchsia.cc b/chromium/content/common/sandbox_policy_fuchsia.cc
index 723586c97a4..26e3278091d 100644
--- a/chromium/content/common/sandbox_policy_fuchsia.cc
+++ b/chromium/content/common/sandbox_policy_fuchsia.cc
@@ -19,6 +19,7 @@
#include "base/files/file_util.h"
#include "base/fuchsia/component_context.h"
#include "base/fuchsia/filtered_service_directory.h"
+#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -29,7 +30,7 @@ namespace content {
namespace {
constexpr const char* const kRendererServices[] = {
- fuchsia::fonts::FontProvider::Name_};
+ fuchsia::fonts::Provider::Name_};
constexpr const char* const kGpuServices[] = {
fuchsia::ui::scenic::Scenic::Name_};
@@ -103,7 +104,9 @@ void SandboxPolicyFuchsia::UpdateLaunchOptionsForSandbox(
// Map /pkg (read-only files deployed from the package) into the child's
// namespace.
- options->paths_to_clone.push_back(base::GetPackageRoot());
+ base::FilePath package_root;
+ base::PathService::Get(base::DIR_SOURCE_ROOT, &package_root);
+ options->paths_to_clone.push_back(package_root);
// Clear environmental variables to better isolate the child from
// this process.
diff --git a/chromium/content/common/service_manager/service_manager_connection_impl.cc b/chromium/content/common/service_manager/service_manager_connection_impl.cc
index dac316d7662..5c5eca51022 100644
--- a/chromium/content/common/service_manager/service_manager_connection_impl.cc
+++ b/chromium/content/common/service_manager/service_manager_connection_impl.cc
@@ -14,6 +14,7 @@
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/message_loop/message_loop_current.h"
+#include "base/thread_annotations.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
@@ -339,14 +340,15 @@ class ServiceManagerConnectionImpl::IOThreadContext
std::unique_ptr<service_manager::ServiceContext> service_context_;
mojo::BindingSet<service_manager::mojom::ServiceFactory> factory_bindings_;
- int next_filter_id_ = kInvalidConnectionFilterId;
// Not owned.
MessageLoopObserver* message_loop_observer_ = nullptr;
- // Guards |connection_filters_|.
+ // Guards |connection_filters_| and |next_filter_id_|.
base::Lock lock_;
- std::map<int, std::unique_ptr<ConnectionFilter>> connection_filters_;
+ std::map<int, std::unique_ptr<ConnectionFilter>> connection_filters_
+ GUARDED_BY(lock_);
+ int next_filter_id_ GUARDED_BY(lock_) = kInvalidConnectionFilterId;
std::map<std::string, std::unique_ptr<service_manager::EmbeddedServiceRunner>>
embedded_services_;
diff --git a/chromium/content/common/service_manager/service_manager_connection_impl_unittest.cc b/chromium/content/common/service_manager/service_manager_connection_impl_unittest.cc
index ee5c8da44a0..64065b2f5bc 100644
--- a/chromium/content/common/service_manager/service_manager_connection_impl_unittest.cc
+++ b/chromium/content/common/service_manager/service_manager_connection_impl_unittest.cc
@@ -4,8 +4,8 @@
#include "content/common/service_manager/service_manager_connection_impl.h"
-#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "services/service_manager/public/cpp/identity.h"
#include "services/service_manager/public/cpp/service.h"
@@ -27,7 +27,7 @@ std::unique_ptr<service_manager::Service> LaunchService(
} // namespace
TEST(ServiceManagerConnectionImplTest, ServiceLaunchThreading) {
- base::MessageLoop message_loop;
+ base::test::ScopedTaskEnvironment task_environment;
base::Thread io_thread("ServiceManagerConnectionImplTest IO Thread");
io_thread.Start();
service_manager::mojom::ServicePtr service;
diff --git a/chromium/content/common/service_worker/controller_service_worker.mojom b/chromium/content/common/service_worker/controller_service_worker.mojom
index 901ffcb7c85..36aea20480e 100644
--- a/chromium/content/common/service_worker/controller_service_worker.mojom
+++ b/chromium/content/common/service_worker/controller_service_worker.mojom
@@ -6,6 +6,7 @@ module content.mojom;
import "content/common/service_worker/service_worker.mojom";
import "mojo/public/mojom/base/time.mojom";
+import "mojo/public/mojom/base/unguessable_token.mojom";
import "services/network/public/mojom/url_loader.mojom";
import "third_party/blink/public/mojom/service_worker/dispatch_fetch_event_params.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom";
@@ -41,7 +42,7 @@ interface ControllerServiceWorker {
blink.mojom.DispatchFetchEventParams params,
blink.mojom.ServiceWorkerFetchResponseCallback response_callback)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
// TODO(kinuko): Add DispatchExtendableMessageEvent() as well.
@@ -70,6 +71,11 @@ struct ControllerServiceWorkerInfo {
// information, as this isn't really a part of controller info.
string client_id;
+ // This also identifies the client. Used to set |fetch_window_id| on
+ // network::ResourceRequests originating from the client's context. Null if
+ // this client is not a window.
+ mojo_base.mojom.UnguessableToken? fetch_request_window_id;
+
// Represents ServiceWorkerContainer#controller.
// Null if there is no controller.
blink.mojom.ServiceWorkerObjectInfo? object_info;
diff --git a/chromium/content/common/service_worker/embedded_worker.mojom b/chromium/content/common/service_worker/embedded_worker.mojom
index adb7fbbce13..757640bba9a 100644
--- a/chromium/content/common/service_worker/embedded_worker.mojom
+++ b/chromium/content/common/service_worker/embedded_worker.mojom
@@ -17,6 +17,7 @@ import "mojo/public/mojom/base/unguessable_token.mojom";
import "services/service_manager/public/mojom/interface_provider.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom";
+import "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom";
import "third_party/blink/public/platform/web_feature.mojom";
import "third_party/blink/public/web/console_message.mojom";
import "third_party/blink/public/web/devtools_agent.mojom";
@@ -38,6 +39,9 @@ struct EmbeddedWorkerStartParams {
// This service worker's script url:
// https://w3c.github.io/ServiceWorker/#dom-serviceworker-scripturl
url.mojom.Url script_url;
+ // This service worker's script type:
+ // https://w3c.github.io/ServiceWorker/#dfn-type
+ blink.mojom.ScriptType script_type;
// The id to talk with the DevTools agent for the worker.
int32 worker_devtools_agent_route_id;
// Unique token identifying this worker for DevTools.
@@ -106,7 +110,8 @@ interface EmbeddedWorkerInstanceClient {
AddMessageToConsole(blink.mojom.ConsoleMessageLevel level, string message);
// Returns a DevToolsAgent interface for this embedded worker, used for
// remote debugging. See DevToolsAgent for details.
- BindDevToolsAgent(associated blink.mojom.DevToolsAgent& devtools_agent);
+ BindDevToolsAgent(associated blink.mojom.DevToolsAgentHost agent_host,
+ associated blink.mojom.DevToolsAgent& agent);
};
// EmbeddedWorkerInstanceHost is the browser-side ("Host") of
diff --git a/chromium/content/common/service_worker/service_worker.mojom b/chromium/content/common/service_worker/service_worker.mojom
index a764a6023bc..f081c2b80ad 100644
--- a/chromium/content/common/service_worker/service_worker.mojom
+++ b/chromium/content/common/service_worker/service_worker.mojom
@@ -8,7 +8,8 @@ import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/time.mojom";
import "services/network/public/mojom/cookie_manager.mojom";
import "third_party/blink/public/mojom/fetch/fetch_api_response.mojom";
-import "third_party/blink/public/mojom/message_port/message_port.mojom";
+import "third_party/blink/public/mojom/messaging/transferable_message.mojom";
+import "third_party/blink/public/mojom/notifications/notification.mojom";
import "third_party/blink/public/mojom/payments/payment_app.mojom";
import "third_party/blink/public/mojom/service_worker/dispatch_fetch_event_params.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker.mojom";
@@ -18,7 +19,6 @@ import "third_party/blink/public/mojom/service_worker/service_worker_fetch_respo
import "third_party/blink/public/mojom/service_worker/service_worker_object.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom";
import "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom";
-import "third_party/blink/public/platform/modules/notifications/notification.mojom";
import "url/mojom/origin.mojom";
import "url/mojom/url.mojom";
@@ -57,9 +57,10 @@ const int32 kPushEventTimeoutSeconds = 90;
// browser.
//
// USAGE TIP: Those DispatchEvent* messages expecting a
-// (blink.mojom.ServiceWorkerEventStatus, mojo_base.mojom.Time) callback are
-// considered 'simple events'. ServiceWorkerVersion::CreateSimpleEventCallback
-// can be used to create the callback for these.
+// (blink.mojom.ServiceWorkerEventStatus, mojo_base.mojom.TimeTicks) callback
+// are considered 'simple events'.
+// ServiceWorkerVersion::CreateSimpleEventCallback can be used to create the
+// callback for these.
interface ServiceWorker {
// The first message sent on this interface. It is used to associate service
// worker-related interfaces together on the service worker thread, as
@@ -75,10 +76,10 @@ interface ServiceWorker {
DispatchInstallEvent()
=> (blink.mojom.ServiceWorkerEventStatus status,
bool has_fetch_handler,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
DispatchActivateEvent()
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
// These methods dispatch to the ServiceWorkerGlobalScope the events listed on
// https://wicg.github.io/background-fetch/#service-worker-global-events.
@@ -88,19 +89,19 @@ interface ServiceWorker {
DispatchBackgroundFetchAbortEvent(
blink.mojom.BackgroundFetchRegistration registration)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
DispatchBackgroundFetchClickEvent(
blink.mojom.BackgroundFetchRegistration registration)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
DispatchBackgroundFetchFailEvent(
blink.mojom.BackgroundFetchRegistration registration)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
DispatchBackgroundFetchSuccessEvent(
blink.mojom.BackgroundFetchRegistration registration)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
// Dispatches the cookie change events in the Async Cookie API specification.
// https://github.com/WICG/cookie-store/
@@ -110,7 +111,7 @@ interface ServiceWorker {
network.mojom.CanonicalCookie cookie,
network.mojom.CookieChangeCause cause)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
// The Dispatch*FetchEvent() callback is called once the event finishes,
// which means the event handler ran and all outstanding respondWith() and
@@ -121,7 +122,7 @@ interface ServiceWorker {
blink.mojom.DispatchFetchEventParams params,
blink.mojom.ServiceWorkerFetchResponseCallback response_callback)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
DispatchNotificationClickEvent(
string notification_id,
@@ -129,17 +130,17 @@ interface ServiceWorker {
int32 action_index,
mojo_base.mojom.String16? reply)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
DispatchNotificationCloseEvent(
string notification_id,
blink.mojom.NotificationData notification_data)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
// The payload of a push message can be valid with content, valid with empty
// content, or null.
DispatchPushEvent(string? payload)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
// Arguments are passed to the event handler as parameters of SyncEvent.
// Ref: https://wicg.github.io/BackgroundSync/spec/#sync-event
// S13nServiceWorker: |timeout| is the amount of time to allow this event to
@@ -149,31 +150,31 @@ interface ServiceWorker {
bool last_chance,
mojo_base.mojom.TimeDelta timeout)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
DispatchAbortPaymentEvent(
payments.mojom.PaymentHandlerResponseCallback result_of_abort_payment)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
DispatchCanMakePaymentEvent(
payments.mojom.CanMakePaymentEventData event_data,
payments.mojom.PaymentHandlerResponseCallback result_of_can_make_payment)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
DispatchPaymentRequestEvent(
payments.mojom.PaymentRequestEventData request_data,
payments.mojom.PaymentHandlerResponseCallback response_callback)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
DispatchExtendableMessageEvent(ExtendableMessageEvent event)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
// TODO(crbug.com/869714): Remove this code for long living service workers
// when Android Messages no longer requires it.
DispatchExtendableMessageEventWithCustomTimeout(ExtendableMessageEvent event,
mojo_base.mojom.TimeDelta timeout)
=> (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
+ mojo_base.mojom.TimeTicks dispatch_event_time);
// Pings the service worker to check if it is responsive. If the callback is
// not called within a certain period of time, the browser will terminate the
diff --git a/chromium/content/common/service_worker/service_worker_container.mojom b/chromium/content/common/service_worker/service_worker_container.mojom
index b8d4e2fe4cd..fd67fc7a793 100644
--- a/chromium/content/common/service_worker/service_worker_container.mojom
+++ b/chromium/content/common/service_worker/service_worker_container.mojom
@@ -6,7 +6,7 @@ module content.mojom;
import "content/common/service_worker/controller_service_worker.mojom";
import "mojo/public/mojom/base/string16.mojom";
-import "third_party/blink/public/mojom/message_port/message_port.mojom";
+import "third_party/blink/public/mojom/messaging/transferable_message.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_object.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom";
@@ -34,7 +34,6 @@ enum ControllerServiceWorkerPurpose {
// - For shared workers (non-S13nSW):
// Associated with ServiceWorkerDispatcherHost, which is on the
// channel-associated interface to the renderer process.
-// IPC channel.
// - For documents:
// Associated with ServiceWorkerDispatcherHost, which is on the
// channel-associated interface to the renderer process.
@@ -91,9 +90,8 @@ interface ServiceWorkerContainerHost {
ControllerServiceWorkerPurpose purpose);
// S13nServiceWorker:
- // Clones the Mojo end point to the ServiceWorker container host. This is
- // used to communicate with the host from dedicated and shared workers.
- CloneForWorker(ServiceWorkerContainerHost& container_host_for_worker);
+ // Makes a new endpoint to this ServiceWorkerContainerHost.
+ CloneContainerHost(ServiceWorkerContainerHost& container_host);
// Does nothing but calls the callback. Useful for pumping the message pipe
// for this interface and associated interfaces: when the callback is called,
diff --git a/chromium/content/common/service_worker/service_worker_fetch_request.typemap b/chromium/content/common/service_worker/service_worker_fetch_request.typemap
index 70e608f8207..4991157cad4 100644
--- a/chromium/content/common/service_worker/service_worker_fetch_request.typemap
+++ b/chromium/content/common/service_worker/service_worker_fetch_request.typemap
@@ -4,17 +4,12 @@
mojom =
"//third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom"
-public_headers = [
- "//content/common/service_worker/service_worker_types.h",
- "//content/public/common/request_context_type.h",
-]
+public_headers = [ "//content/common/service_worker/service_worker_types.h" ]
traits_headers = [
"//content/common/service_worker/service_worker_fetch_request_mojom_traits.h",
]
sources = [
"//content/common/service_worker/service_worker_fetch_request_mojom_traits.cc",
]
-type_mappings = [
- "blink.mojom.FetchAPIRequest=::content::ServiceWorkerFetchRequest",
- "blink.mojom.RequestContextType=::content::RequestContextType",
-]
+type_mappings =
+ [ "blink.mojom.FetchAPIRequest=::content::ServiceWorkerFetchRequest" ]
diff --git a/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.cc b/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.cc
index 8962b22faf2..7e857e53529 100644
--- a/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.cc
+++ b/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.cc
@@ -10,197 +10,8 @@
namespace mojo {
-using blink::mojom::RequestContextType;
using network::mojom::FetchRequestMode;
-RequestContextType
-EnumTraits<RequestContextType, content::RequestContextType>::ToMojom(
- content::RequestContextType input) {
- switch (input) {
- case content::REQUEST_CONTEXT_TYPE_UNSPECIFIED:
- return RequestContextType::UNSPECIFIED;
- case content::REQUEST_CONTEXT_TYPE_AUDIO:
- return RequestContextType::AUDIO;
- case content::REQUEST_CONTEXT_TYPE_BEACON:
- return RequestContextType::BEACON;
- case content::REQUEST_CONTEXT_TYPE_CSP_REPORT:
- return RequestContextType::CSP_REPORT;
- case content::REQUEST_CONTEXT_TYPE_DOWNLOAD:
- return RequestContextType::DOWNLOAD;
- case content::REQUEST_CONTEXT_TYPE_EMBED:
- return RequestContextType::EMBED;
- case content::REQUEST_CONTEXT_TYPE_EVENT_SOURCE:
- return RequestContextType::EVENT_SOURCE;
- case content::REQUEST_CONTEXT_TYPE_FAVICON:
- return RequestContextType::FAVICON;
- case content::REQUEST_CONTEXT_TYPE_FETCH:
- return RequestContextType::FETCH;
- case content::REQUEST_CONTEXT_TYPE_FONT:
- return RequestContextType::FONT;
- case content::REQUEST_CONTEXT_TYPE_FORM:
- return RequestContextType::FORM;
- case content::REQUEST_CONTEXT_TYPE_FRAME:
- return RequestContextType::FRAME;
- case content::REQUEST_CONTEXT_TYPE_HYPERLINK:
- return RequestContextType::HYPERLINK;
- case content::REQUEST_CONTEXT_TYPE_IFRAME:
- return RequestContextType::IFRAME;
- case content::REQUEST_CONTEXT_TYPE_IMAGE:
- return RequestContextType::IMAGE;
- case content::REQUEST_CONTEXT_TYPE_IMAGE_SET:
- return RequestContextType::IMAGE_SET;
- case content::REQUEST_CONTEXT_TYPE_IMPORT:
- return RequestContextType::IMPORT;
- case content::REQUEST_CONTEXT_TYPE_INTERNAL:
- return RequestContextType::INTERNAL;
- case content::REQUEST_CONTEXT_TYPE_LOCATION:
- return RequestContextType::LOCATION;
- case content::REQUEST_CONTEXT_TYPE_MANIFEST:
- return RequestContextType::MANIFEST;
- case content::REQUEST_CONTEXT_TYPE_OBJECT:
- return RequestContextType::OBJECT;
- case content::REQUEST_CONTEXT_TYPE_PING:
- return RequestContextType::PING;
- case content::REQUEST_CONTEXT_TYPE_PLUGIN:
- return RequestContextType::PLUGIN;
- case content::REQUEST_CONTEXT_TYPE_PREFETCH:
- return RequestContextType::PREFETCH;
- case content::REQUEST_CONTEXT_TYPE_SCRIPT:
- return RequestContextType::SCRIPT;
- case content::REQUEST_CONTEXT_TYPE_SERVICE_WORKER:
- return RequestContextType::SERVICE_WORKER;
- case content::REQUEST_CONTEXT_TYPE_SHARED_WORKER:
- return RequestContextType::SHARED_WORKER;
- case content::REQUEST_CONTEXT_TYPE_SUBRESOURCE:
- return RequestContextType::SUBRESOURCE;
- case content::REQUEST_CONTEXT_TYPE_STYLE:
- return RequestContextType::STYLE;
- case content::REQUEST_CONTEXT_TYPE_TRACK:
- return RequestContextType::TRACK;
- case content::REQUEST_CONTEXT_TYPE_VIDEO:
- return RequestContextType::VIDEO;
- case content::REQUEST_CONTEXT_TYPE_WORKER:
- return RequestContextType::WORKER;
- case content::REQUEST_CONTEXT_TYPE_XML_HTTP_REQUEST:
- return RequestContextType::XML_HTTP_REQUEST;
- case content::REQUEST_CONTEXT_TYPE_XSLT:
- return RequestContextType::XSLT;
- }
-
- NOTREACHED();
- return RequestContextType::UNSPECIFIED;
-}
-
-bool EnumTraits<RequestContextType, content::RequestContextType>::FromMojom(
- RequestContextType input,
- content::RequestContextType* out) {
- switch (input) {
- case RequestContextType::UNSPECIFIED:
- *out = content::REQUEST_CONTEXT_TYPE_UNSPECIFIED;
- return true;
- case RequestContextType::AUDIO:
- *out = content::REQUEST_CONTEXT_TYPE_AUDIO;
- return true;
- case RequestContextType::BEACON:
- *out = content::REQUEST_CONTEXT_TYPE_BEACON;
- return true;
- case RequestContextType::CSP_REPORT:
- *out = content::REQUEST_CONTEXT_TYPE_CSP_REPORT;
- return true;
- case RequestContextType::DOWNLOAD:
- *out = content::REQUEST_CONTEXT_TYPE_DOWNLOAD;
- return true;
- case RequestContextType::EMBED:
- *out = content::REQUEST_CONTEXT_TYPE_EMBED;
- return true;
- case RequestContextType::EVENT_SOURCE:
- *out = content::REQUEST_CONTEXT_TYPE_EVENT_SOURCE;
- return true;
- case RequestContextType::FAVICON:
- *out = content::REQUEST_CONTEXT_TYPE_FAVICON;
- return true;
- case RequestContextType::FETCH:
- *out = content::REQUEST_CONTEXT_TYPE_FETCH;
- return true;
- case RequestContextType::FONT:
- *out = content::REQUEST_CONTEXT_TYPE_FONT;
- return true;
- case RequestContextType::FORM:
- *out = content::REQUEST_CONTEXT_TYPE_FORM;
- return true;
- case RequestContextType::FRAME:
- *out = content::REQUEST_CONTEXT_TYPE_FRAME;
- return true;
- case RequestContextType::HYPERLINK:
- *out = content::REQUEST_CONTEXT_TYPE_HYPERLINK;
- return true;
- case RequestContextType::IFRAME:
- *out = content::REQUEST_CONTEXT_TYPE_IFRAME;
- return true;
- case RequestContextType::IMAGE:
- *out = content::REQUEST_CONTEXT_TYPE_IMAGE;
- return true;
- case RequestContextType::IMAGE_SET:
- *out = content::REQUEST_CONTEXT_TYPE_IMAGE_SET;
- return true;
- case RequestContextType::IMPORT:
- *out = content::REQUEST_CONTEXT_TYPE_IMPORT;
- return true;
- case RequestContextType::INTERNAL:
- *out = content::REQUEST_CONTEXT_TYPE_INTERNAL;
- return true;
- case RequestContextType::LOCATION:
- *out = content::REQUEST_CONTEXT_TYPE_LOCATION;
- return true;
- case RequestContextType::MANIFEST:
- *out = content::REQUEST_CONTEXT_TYPE_MANIFEST;
- return true;
- case RequestContextType::OBJECT:
- *out = content::REQUEST_CONTEXT_TYPE_OBJECT;
- return true;
- case RequestContextType::PING:
- *out = content::REQUEST_CONTEXT_TYPE_PING;
- return true;
- case RequestContextType::PLUGIN:
- *out = content::REQUEST_CONTEXT_TYPE_PLUGIN;
- return true;
- case RequestContextType::PREFETCH:
- *out = content::REQUEST_CONTEXT_TYPE_PREFETCH;
- return true;
- case RequestContextType::SCRIPT:
- *out = content::REQUEST_CONTEXT_TYPE_SCRIPT;
- return true;
- case RequestContextType::SERVICE_WORKER:
- *out = content::REQUEST_CONTEXT_TYPE_SERVICE_WORKER;
- return true;
- case RequestContextType::SHARED_WORKER:
- *out = content::REQUEST_CONTEXT_TYPE_SHARED_WORKER;
- return true;
- case RequestContextType::SUBRESOURCE:
- *out = content::REQUEST_CONTEXT_TYPE_SUBRESOURCE;
- return true;
- case RequestContextType::STYLE:
- *out = content::REQUEST_CONTEXT_TYPE_STYLE;
- return true;
- case RequestContextType::TRACK:
- *out = content::REQUEST_CONTEXT_TYPE_TRACK;
- return true;
- case RequestContextType::VIDEO:
- *out = content::REQUEST_CONTEXT_TYPE_VIDEO;
- return true;
- case RequestContextType::WORKER:
- *out = content::REQUEST_CONTEXT_TYPE_WORKER;
- return true;
- case RequestContextType::XML_HTTP_REQUEST:
- *out = content::REQUEST_CONTEXT_TYPE_XML_HTTP_REQUEST;
- return true;
- case RequestContextType::XSLT:
- *out = content::REQUEST_CONTEXT_TYPE_XSLT;
- return true;
- }
-
- return false;
-}
bool StructTraits<blink::mojom::FetchAPIRequestDataView,
content::ServiceWorkerFetchRequest>::
diff --git a/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.h b/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.h
index 40385d395b5..3a7f35d4b4e 100644
--- a/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.h
+++ b/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.h
@@ -13,15 +13,6 @@
namespace mojo {
-template <>
-struct EnumTraits<blink::mojom::RequestContextType,
- content::RequestContextType> {
- static blink::mojom::RequestContextType ToMojom(
- content::RequestContextType input);
-
- static bool FromMojom(blink::mojom::RequestContextType input,
- content::RequestContextType* out);
-};
template <>
struct StructTraits<blink::mojom::FetchAPIRequestDataView,
@@ -36,7 +27,7 @@ struct StructTraits<blink::mojom::FetchAPIRequestDataView,
return request.is_main_resource_load;
}
- static content::RequestContextType request_context_type(
+ static blink::mojom::RequestContextType request_context_type(
const content::ServiceWorkerFetchRequest& request) {
return request.request_context_type;
}
diff --git a/chromium/content/common/service_worker/service_worker_loader_helpers.cc b/chromium/content/common/service_worker/service_worker_loader_helpers.cc
index 7b3949594f8..1b26bc94e45 100644
--- a/chromium/content/common/service_worker/service_worker_loader_helpers.cc
+++ b/chromium/content/common/service_worker/service_worker_loader_helpers.cc
@@ -4,6 +4,7 @@
#include "content/common/service_worker/service_worker_loader_helpers.h"
+#include <limits>
#include <memory>
#include <string>
#include <utility>
@@ -18,6 +19,7 @@
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "services/network/public/cpp/resource_response.h"
+#include "third_party/blink/public/common/blob/blob_utils.h"
#include "ui/base/page_transition_types.h"
namespace content {
@@ -42,58 +44,6 @@ class BlobCompleteCaller : public blink::mojom::BlobReaderClient {
BlobCompleteCallback callback_;
};
-// Sets |has_range_out| to true if |headers| specify a single range request, and
-// |offset_out| and |size_out| to the range. Returns true on valid input
-// (regardless of |has_range_out|), and false if there is more than one range or
-// if the bounds overflow.
-bool ExtractSinglePartHttpRange(const net::HttpRequestHeaders& headers,
- bool* has_range_out,
- uint64_t* offset_out,
- uint64_t* length_out) {
- std::string range_header;
- *has_range_out = false;
- if (!headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header))
- return true;
-
- std::vector<net::HttpByteRange> ranges;
- if (!net::HttpUtil::ParseRangeHeader(range_header, &ranges))
- return true;
-
- // Multi-part (or invalid) ranges are not supported.
- if (ranges.size() != 1)
- return false;
-
- // Safely parse the single range to our more-sane output format.
- *has_range_out = true;
- const net::HttpByteRange& byte_range = ranges[0];
- if (byte_range.first_byte_position() < 0)
- return false;
- // Allow the range [0, -1] to be valid and specify the entire range.
- if (byte_range.first_byte_position() == 0 &&
- byte_range.last_byte_position() == -1) {
- *has_range_out = false;
- return true;
- }
- if (byte_range.last_byte_position() < 0)
- return false;
-
- uint64_t first_byte_position =
- static_cast<uint64_t>(byte_range.first_byte_position());
- uint64_t last_byte_position =
- static_cast<uint64_t>(byte_range.last_byte_position());
-
- base::CheckedNumeric<uint64_t> length = last_byte_position;
- length -= first_byte_position;
- length += 1;
-
- if (!length.IsValid())
- return false;
-
- *offset_out = static_cast<uint64_t>(byte_range.first_byte_position());
- *length_out = length.ValueOrDie();
- return true;
-}
-
} // namespace
// static
@@ -132,6 +82,11 @@ void ServiceWorkerLoaderHelpers::SaveResponseHeaders(
if (out_head->headers->GetCharset(&charset))
out_head->charset = charset;
}
+
+ // Populate |out_head|'s content length with the value from the HTTP response
+ // headers.
+ if (out_head->content_length == -1)
+ out_head->content_length = out_head->headers->GetContentLength();
}
// static
@@ -156,8 +111,7 @@ void ServiceWorkerLoaderHelpers::SaveResponseInfo(
base::Optional<net::RedirectInfo>
ServiceWorkerLoaderHelpers::ComputeRedirectInfo(
const network::ResourceRequest& original_request,
- const network::ResourceResponseHead& response_head,
- bool token_binding_negotiated) {
+ const network::ResourceResponseHead& response_head) {
std::string new_location;
if (!response_head.headers->IsRedirect(&new_location))
return base::nullopt;
@@ -174,39 +128,31 @@ ServiceWorkerLoaderHelpers::ComputeRedirectInfo(
original_request.referrer_policy,
network::ComputeReferrer(original_request.referrer),
response_head.headers.get(), response_head.headers->response_code(),
- original_request.url.Resolve(new_location), false,
- token_binding_negotiated);
+ original_request.url.Resolve(new_location), false);
}
int ServiceWorkerLoaderHelpers::ReadBlobResponseBody(
blink::mojom::BlobPtr* blob,
- const net::HttpRequestHeaders& headers,
+ uint64_t blob_size,
base::OnceCallback<void(int)> on_blob_read_complete,
mojo::ScopedDataPipeConsumerHandle* handle_out) {
- bool byte_range_set = false;
- uint64_t offset = 0;
- uint64_t length = 0;
- // We don't support multiple range requests in one single URL request,
- // because we need to do multipart encoding here.
- // TODO(falken): Support multipart byte range requests.
- if (!ExtractSinglePartHttpRange(headers, &byte_range_set, &offset, &length)) {
- return net::ERR_REQUEST_RANGE_NOT_SATISFIABLE;
- }
+ MojoCreateDataPipeOptions options;
+ options.struct_size = sizeof(MojoCreateDataPipeOptions);
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
+ options.element_num_bytes = 1;
+ options.capacity_num_bytes = blink::BlobUtils::GetDataPipeCapacity(blob_size);
+
+ mojo::ScopedDataPipeProducerHandle producer_handle;
+ MojoResult rv = mojo::CreateDataPipe(&options, &producer_handle, handle_out);
+ if (rv != MOJO_RESULT_OK)
+ return net::ERR_FAILED;
- mojo::DataPipe data_pipe;
blink::mojom::BlobReaderClientPtr blob_reader_client;
mojo::MakeStrongBinding(
std::make_unique<BlobCompleteCaller>(std::move(on_blob_read_complete)),
mojo::MakeRequest(&blob_reader_client));
- if (byte_range_set) {
- (*blob)->ReadRange(offset, length, std::move(data_pipe.producer_handle),
- std::move(blob_reader_client));
- } else {
- (*blob)->ReadAll(std::move(data_pipe.producer_handle),
- std::move(blob_reader_client));
- }
- *handle_out = std::move(data_pipe.consumer_handle);
+ (*blob)->ReadAll(std::move(producer_handle), std::move(blob_reader_client));
return net::OK;
}
diff --git a/chromium/content/common/service_worker/service_worker_loader_helpers.h b/chromium/content/common/service_worker/service_worker_loader_helpers.h
index 89d36f1facc..5b037576294 100644
--- a/chromium/content/common/service_worker/service_worker_loader_helpers.h
+++ b/chromium/content/common/service_worker/service_worker_loader_helpers.h
@@ -38,16 +38,15 @@ class ServiceWorkerLoaderHelpers {
// Otherwise returns base::nullopt.
static base::Optional<net::RedirectInfo> ComputeRedirectInfo(
const network::ResourceRequest& original_request,
- const network::ResourceResponseHead& response_head,
- bool token_binding_negotiated);
+ const network::ResourceResponseHead& response_head);
- // Reads |blob| using the range in |headers| (if any), writing into
- // |handle_out|. Calls |on_blob_read_complete| when done or if an error
- // occurred. Returns a net error code if the inputs were invalid and reading
- // couldn't start. In that case |on_blob_read_complete| isn't called.
+ // Reads |blob| into |handle_out|. Calls |on_blob_read_complete| when done or
+ // if an error occurred. Currently this always returns net::OK but
+ // the plan is to return an error if reading couldn't start, in
+ // which case |on_blob_read_complete| isn't called.
static int ReadBlobResponseBody(
blink::mojom::BlobPtr* blob,
- const net::HttpRequestHeaders& headers,
+ uint64_t blob_size,
base::OnceCallback<void(int net_error)> on_blob_read_complete,
mojo::ScopedDataPipeConsumerHandle* handle_out);
};
diff --git a/chromium/content/common/service_worker/service_worker_types.cc b/chromium/content/common/service_worker/service_worker_types.cc
index c8c98cd9ed3..d69f31b8d9c 100644
--- a/chromium/content/common/service_worker/service_worker_types.cc
+++ b/chromium/content/common/service_worker/service_worker_types.cc
@@ -5,7 +5,6 @@
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_types.pb.h"
-#include "net/base/load_flags.h"
#include "storage/common/blob_storage/blob_handle.h"
namespace content {
@@ -67,7 +66,8 @@ std::string ServiceWorkerFetchRequest::Serialize() const {
request_proto.set_is_reload(is_reload);
request_proto.set_mode(static_cast<int>(mode));
request_proto.set_is_main_resource_load(is_main_resource_load);
- request_proto.set_request_context_type(request_context_type);
+ request_proto.set_request_context_type(
+ static_cast<int>(request_context_type));
request_proto.set_credentials_mode(static_cast<int>(credentials_mode));
request_proto.set_cache_mode(static_cast<int>(cache_mode));
request_proto.set_redirect_mode(static_cast<int>(redirect_mode));
@@ -111,8 +111,8 @@ ServiceWorkerFetchRequest ServiceWorkerFetchRequest::ParseFromString(
request.mode =
static_cast<network::mojom::FetchRequestMode>(request_proto.mode());
request.is_main_resource_load = request_proto.is_main_resource_load();
- request.request_context_type =
- static_cast<RequestContextType>(request_proto.request_context_type());
+ request.request_context_type = static_cast<blink::mojom::RequestContextType>(
+ request_proto.request_context_type());
request.credentials_mode = static_cast<network::mojom::FetchCredentialsMode>(
request_proto.credentials_mode());
request.cache_mode =
@@ -127,33 +127,4 @@ ServiceWorkerFetchRequest ServiceWorkerFetchRequest::ParseFromString(
return request;
}
-// static
-blink::mojom::FetchCacheMode
-ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(int load_flags) {
- if (load_flags & net::LOAD_DISABLE_CACHE)
- return blink::mojom::FetchCacheMode::kNoStore;
-
- if (load_flags & net::LOAD_VALIDATE_CACHE)
- return blink::mojom::FetchCacheMode::kValidateCache;
-
- if (load_flags & net::LOAD_BYPASS_CACHE) {
- if (load_flags & net::LOAD_ONLY_FROM_CACHE)
- return blink::mojom::FetchCacheMode::kUnspecifiedForceCacheMiss;
- return blink::mojom::FetchCacheMode::kBypassCache;
- }
-
- if (load_flags & net::LOAD_SKIP_CACHE_VALIDATION) {
- if (load_flags & net::LOAD_ONLY_FROM_CACHE)
- return blink::mojom::FetchCacheMode::kOnlyIfCached;
- return blink::mojom::FetchCacheMode::kForceCache;
- }
-
- if (load_flags & net::LOAD_ONLY_FROM_CACHE) {
- DCHECK(!(load_flags & net::LOAD_SKIP_CACHE_VALIDATION));
- DCHECK(!(load_flags & net::LOAD_BYPASS_CACHE));
- return blink::mojom::FetchCacheMode::kUnspecifiedOnlyIfCachedStrict;
- }
- return blink::mojom::FetchCacheMode::kDefault;
-}
-
} // namespace content
diff --git a/chromium/content/common/service_worker/service_worker_types.h b/chromium/content/common/service_worker/service_worker_types.h
index 99f262fce6e..7754680b944 100644
--- a/chromium/content/common/service_worker/service_worker_types.h
+++ b/chromium/content/common/service_worker/service_worker_types.h
@@ -16,8 +16,6 @@
#include "base/time/time.h"
#include "content/common/content_export.h"
#include "content/public/common/referrer.h"
-#include "content/public/common/request_context_type.h"
-#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
@@ -92,7 +90,6 @@ struct CONTENT_EXPORT ServiceWorkerFetchRequest {
size_t EstimatedStructSize();
std::string Serialize() const;
- static blink::mojom::FetchCacheMode GetCacheModeFromLoadFlags(int load_flags);
static ServiceWorkerFetchRequest ParseFromString(
const std::string& serialized);
@@ -101,7 +98,8 @@ struct CONTENT_EXPORT ServiceWorkerFetchRequest {
network::mojom::FetchRequestMode mode =
network::mojom::FetchRequestMode::kNoCORS;
bool is_main_resource_load = false;
- RequestContextType request_context_type = REQUEST_CONTEXT_TYPE_UNSPECIFIED;
+ blink::mojom::RequestContextType request_context_type =
+ blink::mojom::RequestContextType::UNSPECIFIED;
network::mojom::RequestContextFrameType frame_type =
network::mojom::RequestContextFrameType::kNone;
GURL url;
@@ -121,30 +119,6 @@ struct CONTENT_EXPORT ServiceWorkerFetchRequest {
bool is_history_navigation = false;
};
-class ChangedVersionAttributesMask {
- public:
- enum {
- INSTALLING_VERSION = 1 << 0,
- WAITING_VERSION = 1 << 1,
- ACTIVE_VERSION = 1 << 2,
- CONTROLLING_VERSION = 1 << 3,
- };
-
- ChangedVersionAttributesMask() : changed_(0) {}
- explicit ChangedVersionAttributesMask(int changed) : changed_(changed) {}
-
- int changed() const { return changed_; }
-
- void add(int changed_versions) { changed_ |= changed_versions; }
- bool installing_changed() const { return !!(changed_ & INSTALLING_VERSION); }
- bool waiting_changed() const { return !!(changed_ & WAITING_VERSION); }
- bool active_changed() const { return !!(changed_ & ACTIVE_VERSION); }
- bool controller_changed() const { return !!(changed_ & CONTROLLING_VERSION); }
-
- private:
- int changed_;
-};
-
} // namespace content
#endif // CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_TYPES_H_
diff --git a/chromium/content/common/service_worker/service_worker_types_unittest.cc b/chromium/content/common/service_worker/service_worker_types_unittest.cc
index 3de9f20ea9f..8a1fe70cc0a 100644
--- a/chromium/content/common/service_worker/service_worker_types_unittest.cc
+++ b/chromium/content/common/service_worker/service_worker_types_unittest.cc
@@ -2,48 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/common/service_worker/service_worker_types.h"
#include "base/guid.h"
+#include "content/common/service_worker/service_worker_utils.h"
#include "mojo/public/cpp/base/time_mojom_traits.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_response.mojom.h"
#include "url/mojom/url_gurl_mojom_traits.h"
-#include "net/base/load_flags.h"
-
namespace content {
namespace {
-using blink::mojom::FetchCacheMode;
-
-TEST(ServiceWorkerFetchRequestTest, CacheModeTest) {
- EXPECT_EQ(FetchCacheMode::kDefault,
- ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(0));
- EXPECT_EQ(FetchCacheMode::kNoStore,
- ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(
- net::LOAD_DISABLE_CACHE));
- EXPECT_EQ(FetchCacheMode::kValidateCache,
- ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(
- net::LOAD_VALIDATE_CACHE));
- EXPECT_EQ(FetchCacheMode::kBypassCache,
- ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(
- net::LOAD_BYPASS_CACHE));
- EXPECT_EQ(FetchCacheMode::kForceCache,
- ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(
- net::LOAD_SKIP_CACHE_VALIDATION));
- EXPECT_EQ(FetchCacheMode::kOnlyIfCached,
- ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(
- net::LOAD_ONLY_FROM_CACHE | net::LOAD_SKIP_CACHE_VALIDATION));
- EXPECT_EQ(FetchCacheMode::kUnspecifiedOnlyIfCachedStrict,
- ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(
- net::LOAD_ONLY_FROM_CACHE));
- EXPECT_EQ(FetchCacheMode::kUnspecifiedForceCacheMiss,
- ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(
- net::LOAD_ONLY_FROM_CACHE | net::LOAD_BYPASS_CACHE));
-}
-
TEST(ServiceWorkerRequestTest, SerialiazeDeserializeRoundTrip) {
ServiceWorkerFetchRequest request(
GURL("foo.com"), "GET", {{"User-Agent", "Chrome"}},
@@ -53,8 +23,7 @@ TEST(ServiceWorkerRequestTest, SerialiazeDeserializeRoundTrip) {
true);
request.mode = network::mojom::FetchRequestMode::kSameOrigin;
request.is_main_resource_load = true;
- request.request_context_type =
- RequestContextType::REQUEST_CONTEXT_TYPE_IFRAME;
+ request.request_context_type = blink::mojom::RequestContextType::IFRAME;
request.credentials_mode = network::mojom::FetchCredentialsMode::kSameOrigin;
request.cache_mode = blink::mojom::FetchCacheMode::kForceCache;
request.redirect_mode = network::mojom::FetchRedirectMode::kManual;
diff --git a/chromium/content/common/service_worker/service_worker_utils.cc b/chromium/content/common/service_worker/service_worker_utils.cc
index 191ec845603..44d34b8e7e7 100644
--- a/chromium/content/common/service_worker/service_worker_utils.cc
+++ b/chromium/content/common/service_worker/service_worker_utils.cc
@@ -13,6 +13,7 @@
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/origin_util.h"
+#include "net/base/load_flags.h"
#include "net/http/http_byte_range.h"
#include "net/http/http_util.h"
#include "services/network/public/cpp/features.h"
@@ -181,6 +182,35 @@ bool ServiceWorkerUtils::ShouldBypassCacheDueToUpdateViaCache(
return false;
}
+// static
+blink::mojom::FetchCacheMode ServiceWorkerUtils::GetCacheModeFromLoadFlags(
+ int load_flags) {
+ if (load_flags & net::LOAD_DISABLE_CACHE)
+ return blink::mojom::FetchCacheMode::kNoStore;
+
+ if (load_flags & net::LOAD_VALIDATE_CACHE)
+ return blink::mojom::FetchCacheMode::kValidateCache;
+
+ if (load_flags & net::LOAD_BYPASS_CACHE) {
+ if (load_flags & net::LOAD_ONLY_FROM_CACHE)
+ return blink::mojom::FetchCacheMode::kUnspecifiedForceCacheMiss;
+ return blink::mojom::FetchCacheMode::kBypassCache;
+ }
+
+ if (load_flags & net::LOAD_SKIP_CACHE_VALIDATION) {
+ if (load_flags & net::LOAD_ONLY_FROM_CACHE)
+ return blink::mojom::FetchCacheMode::kOnlyIfCached;
+ return blink::mojom::FetchCacheMode::kForceCache;
+ }
+
+ if (load_flags & net::LOAD_ONLY_FROM_CACHE) {
+ DCHECK(!(load_flags & net::LOAD_SKIP_CACHE_VALIDATION));
+ DCHECK(!(load_flags & net::LOAD_BYPASS_CACHE));
+ return blink::mojom::FetchCacheMode::kUnspecifiedOnlyIfCachedStrict;
+ }
+ return blink::mojom::FetchCacheMode::kDefault;
+}
+
bool LongestScopeMatcher::MatchLongest(const GURL& scope) {
if (!ServiceWorkerUtils::ScopeMatches(scope, url_))
return false;
diff --git a/chromium/content/common/service_worker/service_worker_utils.h b/chromium/content/common/service_worker/service_worker_utils.h
index f0f25a65a64..2ba85d2ad40 100644
--- a/chromium/content/common/service_worker/service_worker_utils.h
+++ b/chromium/content/common/service_worker/service_worker_utils.h
@@ -75,6 +75,11 @@ class ServiceWorkerUtils {
bool is_main_script,
blink::mojom::ServiceWorkerUpdateViaCache cache_mode);
+ // Converts an enum defined in net/base/load_flags.h to
+ // blink::mojom::FetchCacheMode.
+ CONTENT_EXPORT static blink::mojom::FetchCacheMode GetCacheModeFromLoadFlags(
+ int load_flags);
+
private:
static bool IsPathRestrictionSatisfiedInternal(
const GURL& scope,
diff --git a/chromium/content/common/service_worker/service_worker_utils_unittest.cc b/chromium/content/common/service_worker/service_worker_utils_unittest.cc
index f75f04c7e2c..f19e682641e 100644
--- a/chromium/content/common/service_worker/service_worker_utils_unittest.cc
+++ b/chromium/content/common/service_worker/service_worker_utils_unittest.cc
@@ -2,11 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/command_line.h"
#include "content/common/service_worker/service_worker_utils.h"
+
+#include "base/command_line.h"
#include "content/public/common/content_switches.h"
+#include "net/base/load_flags.h"
#include "testing/gtest/include/gtest/gtest.h"
+using blink::mojom::FetchCacheMode;
+
namespace content {
namespace {
@@ -440,4 +444,30 @@ TEST(ServiceWorkerUtilsTest, AllOriginsMatchAndCanAccessServiceWorkers) {
filesystem_same_origin));
}
+TEST(ServiceWorkerFetchRequestTest, CacheModeTest) {
+ EXPECT_EQ(FetchCacheMode::kDefault,
+ ServiceWorkerUtils::GetCacheModeFromLoadFlags(0));
+ EXPECT_EQ(
+ FetchCacheMode::kNoStore,
+ ServiceWorkerUtils::GetCacheModeFromLoadFlags(net::LOAD_DISABLE_CACHE));
+ EXPECT_EQ(
+ FetchCacheMode::kValidateCache,
+ ServiceWorkerUtils::GetCacheModeFromLoadFlags(net::LOAD_VALIDATE_CACHE));
+ EXPECT_EQ(
+ FetchCacheMode::kBypassCache,
+ ServiceWorkerUtils::GetCacheModeFromLoadFlags(net::LOAD_BYPASS_CACHE));
+ EXPECT_EQ(FetchCacheMode::kForceCache,
+ ServiceWorkerUtils::GetCacheModeFromLoadFlags(
+ net::LOAD_SKIP_CACHE_VALIDATION));
+ EXPECT_EQ(FetchCacheMode::kOnlyIfCached,
+ ServiceWorkerUtils::GetCacheModeFromLoadFlags(
+ net::LOAD_ONLY_FROM_CACHE | net::LOAD_SKIP_CACHE_VALIDATION));
+ EXPECT_EQ(
+ FetchCacheMode::kUnspecifiedOnlyIfCachedStrict,
+ ServiceWorkerUtils::GetCacheModeFromLoadFlags(net::LOAD_ONLY_FROM_CACHE));
+ EXPECT_EQ(FetchCacheMode::kUnspecifiedForceCacheMiss,
+ ServiceWorkerUtils::GetCacheModeFromLoadFlags(
+ net::LOAD_ONLY_FROM_CACHE | net::LOAD_BYPASS_CACHE));
+}
+
} // namespace content
diff --git a/chromium/content/common/shared_worker/shared_worker.mojom b/chromium/content/common/shared_worker/shared_worker.mojom
index c7539c4f154..6a31c53002a 100644
--- a/chromium/content/common/shared_worker/shared_worker.mojom
+++ b/chromium/content/common/shared_worker/shared_worker.mojom
@@ -19,5 +19,6 @@ interface SharedWorker {
// Binds a DevToolsAgent interface for this shared worker, used for
// remote debugging. See DevToolsAgent for details.
- BindDevToolsAgent(associated blink.mojom.DevToolsAgent& devtools_agent);
+ BindDevToolsAgent(associated blink.mojom.DevToolsAgentHost agent_host,
+ associated blink.mojom.DevToolsAgent& agent);
};
diff --git a/chromium/content/common/shared_worker/shared_worker_factory.mojom b/chromium/content/common/shared_worker/shared_worker_factory.mojom
index 3287a07a4e5..8014029a78d 100644
--- a/chromium/content/common/shared_worker/shared_worker_factory.mojom
+++ b/chromium/content/common/shared_worker/shared_worker_factory.mojom
@@ -4,6 +4,7 @@
module content.mojom;
+import "content/common/service_worker/controller_service_worker.mojom";
import "content/common/service_worker/service_worker_provider.mojom";
import "content/common/shared_worker/shared_worker.mojom";
import "content/common/shared_worker/shared_worker_host.mojom";
@@ -14,6 +15,7 @@ import "content/public/common/renderer_preferences.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "services/network/public/mojom/url_loader_factory.mojom";
import "services/service_manager/public/mojom/interface_provider.mojom";
+import "third_party/blink/public/mojom/shared_worker/shared_worker_main_script_load_params.mojom";
import "third_party/blink/public/web/worker_content_settings_proxy.mojom";
// The name of the InterfaceProviderSpec in service manifests used by the
@@ -49,12 +51,13 @@ interface SharedWorkerFactory {
// is disabled or AppCache doesn't serve resources for this shared worker.
int32 appcache_host_id,
- // S13nServiceWorker:
+ // S13nServiceWorker (non-NetworkService):
// The URLLoaderFactory to use to request the shared worker's script
// (just the main script resource; importScripts() should go through the
// usual loader or the controller service worker if appropriate).
//
- // Null when S13nServiceWorker is disabled.
+ // This is only non-null when S13nServiceWorker is enabled but
+ // NetworkService is disabled.
//
// It doesn't really need to be associated, but a similar associated
// interface ptr is sent for service worker startup, so making this
@@ -62,7 +65,12 @@ interface SharedWorkerFactory {
// ServiceWorkerNetworkProvider::script_loader_factory_ can be an
// associated interface ptr used for both service worker and shared
// worker execution contexts.
- associated network.mojom.URLLoaderFactory? script_loader_factory_ptr_info,
+ associated network.mojom.URLLoaderFactory? main_script_loader_factory,
+
+ // NetworkService (PlzWorker):
+ // Used for passing a main script pre-requested by the browser process and
+ // its redirect information.
+ blink.mojom.SharedWorkerMainScriptLoadParams? main_script_load_params,
// NetworkService:
// When the Network Service is enabled, |subresource_loader_factories|
@@ -72,6 +80,14 @@ interface SharedWorkerFactory {
// loader factory can't load.
URLLoaderFactoryBundle? subresource_loader_factories,
+ // NetworkService (PlzWorker):
+ // Used for setting ServiceWorkerContainer#controller. This is null when
+ // NetworkService is disabled or there're no controller service worker.
+ //
+ // In S13nServiceWorker, the controller is sent via
+ // ServiceWorkerContainer.SetController().
+ ControllerServiceWorkerInfo? controller_info,
+
SharedWorkerHost host,
SharedWorker& shared_worker,
service_manager.mojom.InterfaceProvider interface_provider);
diff --git a/chromium/content/common/swapped_out_messages.cc b/chromium/content/common/swapped_out_messages.cc
index e662d699b12..1235953882b 100644
--- a/chromium/content/common/swapped_out_messages.cc
+++ b/chromium/content/common/swapped_out_messages.cc
@@ -7,6 +7,7 @@
#include "content/common/accessibility_messages.h"
#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/common/content_client.h"
namespace content {
@@ -53,9 +54,9 @@ bool SwappedOutMessages::CanHandleWhileSwappedOut(
// error reply instead, to avoid leaving the renderer in a stuck state.
switch (msg.type()) {
// We allow closing even if we are in the process of swapping out.
- case ViewHostMsg_Close::ID:
+ case WidgetHostMsg_Close::ID:
// Sends an ACK.
- case ViewHostMsg_RequestSetBounds::ID:
+ case WidgetHostMsg_RequestSetBounds::ID:
// Sends an ACK.
case AccessibilityHostMsg_EventBundle::ID:
return true;
diff --git a/chromium/content/common/throttling_url_loader.cc b/chromium/content/common/throttling_url_loader.cc
index 4387f6e4983..d4840a74942 100644
--- a/chromium/content/common/throttling_url_loader.cc
+++ b/chromium/content/common/throttling_url_loader.cc
@@ -4,10 +4,11 @@
#include "content/common/throttling_url_loader.h"
+#include "base/debug/alias.h"
#include "base/single_thread_task_runner.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/public/common/browser_side_navigation_policy.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
@@ -190,6 +191,7 @@ ThrottlingURLLoader::~ThrottlingURLLoader() {
void ThrottlingURLLoader::FollowRedirect(
const base::Optional<net::HttpRequestHeaders>& modified_headers) {
+ debug_log_.emplace_back("FollowRedirect");
const base::Optional<net::HttpRequestHeaders>* modified_headers_to_send =
&modified_headers;
if (modified_request_headers_) {
@@ -218,6 +220,7 @@ void ThrottlingURLLoader::FollowRedirect(
}
void ThrottlingURLLoader::FollowRedirectForcingRestart() {
+ debug_log_.emplace_back("FollowRedirectForcingRestart");
url_loader_.reset();
client_binding_.Close();
@@ -238,8 +241,15 @@ void ThrottlingURLLoader::FollowRedirectForcingRestart() {
void ThrottlingURLLoader::RestartWithFactory(
scoped_refptr<network::SharedURLLoaderFactory> factory,
uint32_t url_loader_options) {
- DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
- DCHECK(!loader_completed_);
+ debug_log_.emplace_back("RestartWithFactory");
+ // TODO(crbug.com/882661): Remove these aliases and turn CHECKs to DCHECKs
+ // when the linked bug is fixed.
+ DeferredStage deferred_stage = deferred_stage_;
+ base::debug::Alias(&deferred_stage);
+ bool loader_completed = loader_completed_;
+ base::debug::Alias(&loader_completed);
+ CHECK_EQ(DEFERRED_NONE, deferred_stage_);
+ CHECK(!loader_completed_);
url_loader_.reset();
client_binding_.Close();
start_info_->url_loader_factory = std::move(factory);
@@ -274,6 +284,7 @@ ThrottlingURLLoader::ThrottlingURLLoader(
client_binding_(this),
traffic_annotation_(traffic_annotation),
weak_factory_(this) {
+ debug_log_.emplace_back("ctor");
throttles_.reserve(throttles.size());
for (auto& throttle : throttles)
throttles_.emplace_back(this, std::move(throttle));
@@ -286,12 +297,10 @@ void ThrottlingURLLoader::Start(
uint32_t options,
network::ResourceRequest* url_request,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ debug_log_.emplace_back("Start");
DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
DCHECK(!loader_completed_);
- if (options & network::mojom::kURLLoadOptionSynchronous)
- is_synchronous_ = true;
-
bool deferred = false;
DCHECK(deferring_throttles_.empty());
if (!throttles_.empty()) {
@@ -312,8 +321,10 @@ void ThrottlingURLLoader::Start(
// URL.
url_request->url = original_url;
}
- if (!HandleThrottleResult(throttle, throttle_deferred, &deferred))
+ if (!HandleThrottleResult(throttle, throttle_deferred, &deferred)) {
+ debug_log_.emplace_back("Start::Return");
return;
+ }
}
// If a throttle had changed the URL, set it in the ResourceRequest struct
@@ -325,14 +336,17 @@ void ThrottlingURLLoader::Start(
start_info_ =
std::make_unique<StartInfo>(factory, routing_id, request_id, options,
url_request, std::move(task_runner));
- if (deferred)
+ if (deferred) {
+ debug_log_.emplace_back("Start::Deferred");
deferred_stage_ = DEFERRED_START;
- else
+ } else {
StartNow();
+ }
}
void ThrottlingURLLoader::StartNow() {
DCHECK(start_info_);
+ debug_log_.emplace_back("StartNow");
if (!throttle_redirect_url_.is_empty()) {
net::RedirectInfo redirect_info;
redirect_info.status_code = net::HTTP_TEMPORARY_REDIRECT;
@@ -350,6 +364,7 @@ void ThrottlingURLLoader::StartNow() {
header_string.c_str(), header_string.length()));
response_head.encoded_data_length = header_string.size();
OnReceiveRedirect(redirect_info, response_head);
+ debug_log_.emplace_back("StartNow::Redirect");
return;
}
@@ -402,6 +417,7 @@ void ThrottlingURLLoader::StopDeferringForThrottle(
void ThrottlingURLLoader::OnReceiveResponse(
const network::ResourceResponseHead& response_head) {
+ debug_log_.emplace_back("OnReceiveResponse");
DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
DCHECK(!loader_completed_);
DCHECK(deferring_throttles_.empty());
@@ -414,24 +430,30 @@ void ThrottlingURLLoader::OnReceiveResponse(
bool throttle_deferred = false;
throttle->WillProcessResponse(response_url_, &response_head_copy,
&throttle_deferred);
- if (!HandleThrottleResult(throttle, throttle_deferred, &deferred))
+ if (!HandleThrottleResult(throttle, throttle_deferred, &deferred)) {
+ debug_log_.emplace_back("OnReceiveResponse::Return");
return;
+ }
}
if (deferred) {
deferred_stage_ = DEFERRED_RESPONSE;
response_info_ = std::make_unique<ResponseInfo>(response_head_copy);
client_binding_.PauseIncomingMethodCallProcessing();
+ debug_log_.emplace_back("OnReceiveResponse::Deferred");
return;
}
}
+ sent_on_receive_response_ = true;
+ debug_log_.emplace_back("OnReceiveResponse::Sent");
forwarding_client_->OnReceiveResponse(response_head_copy);
}
void ThrottlingURLLoader::OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head) {
+ debug_log_.emplace_back("OnReceiveRedirect");
DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
DCHECK(!loader_completed_);
DCHECK(deferring_throttles_.empty());
@@ -449,8 +471,10 @@ void ThrottlingURLLoader::OnReceiveRedirect(
&modified_headers);
if (!weak_ptr)
return;
- if (!HandleThrottleResult(throttle, throttle_deferred, &deferred))
+ if (!HandleThrottleResult(throttle, throttle_deferred, &deferred)) {
+ debug_log_.emplace_back("OnReceiveRedirect::Return");
return;
+ }
if (!to_be_removed_headers.empty()) {
if (to_be_removed_request_headers_) {
@@ -476,6 +500,7 @@ void ThrottlingURLLoader::OnReceiveRedirect(
redirect_info_ =
std::make_unique<RedirectInfo>(redirect_info, response_head);
client_binding_.PauseIncomingMethodCallProcessing();
+ debug_log_.emplace_back("OnReceiveRedirect::Deferred");
return;
}
}
@@ -493,6 +518,7 @@ void ThrottlingURLLoader::OnReceiveRedirect(
// redirect or if it will be cancelled. FollowRedirect would be a more
// suitable place to set this URL but there we do not have the data.
response_url_ = redirect_info.new_url;
+ debug_log_.emplace_back("OnReceiveRedirect::Sent");
forwarding_client_->OnReceiveRedirect(redirect_info, response_head);
}
@@ -524,14 +550,22 @@ void ThrottlingURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
void ThrottlingURLLoader::OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) {
+ debug_log_.emplace_back("OnStartLoadingResponseBody");
+
DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
DCHECK(!loader_completed_);
+ DCHECK(sent_on_receive_response_);
+
+ // TODO(crbug.com/882661): Remove when the linked bug is fixed.
+ if (!sent_on_receive_response_)
+ Crash();
forwarding_client_->OnStartLoadingResponseBody(std::move(body));
}
void ThrottlingURLLoader::OnComplete(
const network::URLLoaderCompletionStatus& status) {
+ debug_log_.emplace_back("OnComplete::Sent");
DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
DCHECK(!loader_completed_);
@@ -545,15 +579,12 @@ void ThrottlingURLLoader::OnComplete(
}
void ThrottlingURLLoader::OnClientConnectionError() {
- // TODO(reillyg): Temporary workaround for crbug.com/756751 where without
- // browser-side navigation this error on async loads will confuse the loading
- // of cross-origin iframes.
- if (is_synchronous_ || content::IsBrowserSideNavigationEnabled())
- CancelWithError(net::ERR_ABORTED, nullptr);
+ CancelWithError(net::ERR_ABORTED, nullptr);
}
void ThrottlingURLLoader::CancelWithError(int error_code,
base::StringPiece custom_reason) {
+ debug_log_.emplace_back("CancelWithError");
if (loader_completed_)
return;
@@ -567,8 +598,11 @@ void ThrottlingURLLoader::CancelWithError(int error_code,
}
void ThrottlingURLLoader::Resume() {
- if (loader_completed_ || deferred_stage_ == DEFERRED_NONE)
+ debug_log_.emplace_back("Resume::" + base::NumberToString(deferred_stage_));
+ if (loader_completed_ || deferred_stage_ == DEFERRED_NONE) {
+ debug_log_.emplace_back("Resume::Return");
return;
+ }
auto prev_deferred_stage = deferred_stage_;
deferred_stage_ = DEFERRED_NONE;
@@ -590,6 +624,7 @@ void ThrottlingURLLoader::Resume() {
}
case DEFERRED_RESPONSE: {
client_binding_.ResumeIncomingMethodCallProcessing();
+ sent_on_receive_response_ = true;
forwarding_client_->OnReceiveResponse(response_info_->response_head);
// Note: |this| may be deleted here.
break;
@@ -662,6 +697,12 @@ void ThrottlingURLLoader::DisconnectClient(base::StringPiece custom_reason) {
loader_completed_ = true;
}
+void ThrottlingURLLoader::Crash() {
+ std::string log = base::JoinString(debug_log_, " ");
+ DEBUG_ALIAS_FOR_CSTR(log_buf, log.c_str(), 2048);
+ CHECK(false);
+}
+
ThrottlingURLLoader::ThrottleEntry::ThrottleEntry(
ThrottlingURLLoader* loader,
std::unique_ptr<URLLoaderThrottle> the_throttle)
diff --git a/chromium/content/common/throttling_url_loader.h b/chromium/content/common/throttling_url_loader.h
index 7c8a6027e57..65cd68fb56d 100644
--- a/chromium/content/common/throttling_url_loader.h
+++ b/chromium/content/common/throttling_url_loader.h
@@ -143,6 +143,9 @@ class CONTENT_EXPORT ThrottlingURLLoader
// Disconnects the client connection and releases the URLLoader.
void DisconnectClient(base::StringPiece custom_description);
+ // TODO(crbug.com/882661): Remove when the linked bug is fixed.
+ void Crash();
+
enum DeferredStage {
DEFERRED_NONE,
DEFERRED_START,
@@ -151,7 +154,6 @@ class CONTENT_EXPORT ThrottlingURLLoader
};
DeferredStage deferred_stage_ = DEFERRED_NONE;
bool loader_completed_ = false;
- bool is_synchronous_ = false;
struct ThrottleEntry {
ThrottleEntry(ThrottlingURLLoader* loader,
@@ -247,6 +249,10 @@ class CONTENT_EXPORT ThrottlingURLLoader
bool response_intercepted_ = false;
+ // TODO(crbug.com/882661): Remove these when the linked bug is fixed.
+ bool sent_on_receive_response_ = false;
+ std::vector<std::string> debug_log_;
+
base::Optional<std::vector<std::string>> to_be_removed_request_headers_;
base::Optional<net::HttpRequestHeaders> modified_request_headers_;
diff --git a/chromium/content/common/throttling_url_loader_unittest.cc b/chromium/content/common/throttling_url_loader_unittest.cc
index 31bcfc4402e..b30c4b28e46 100644
--- a/chromium/content/common/throttling_url_loader_unittest.cc
+++ b/chromium/content/common/throttling_url_loader_unittest.cc
@@ -8,7 +8,6 @@
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
-#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/url_loader_throttle.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
@@ -690,33 +689,7 @@ TEST_F(ThrottlingURLLoaderTest, DeferBeforeResponse) {
EXPECT_EQ(1u, client_.on_complete_called());
}
-TEST_F(ThrottlingURLLoaderTest, PipeClosureBeforeSyncResponse) {
- base::RunLoop run_loop;
- client_.set_on_complete_callback(base::Bind(
- [](const base::Closure& quit_closure, int error) {
- EXPECT_EQ(net::ERR_ABORTED, error);
- quit_closure.Run();
- },
- run_loop.QuitClosure()));
-
- CreateLoaderAndStart(true);
-
- factory_.CloseClientPipe();
-
- run_loop.Run();
-
- EXPECT_EQ(1u, throttle_->will_start_request_called());
- EXPECT_EQ(0u, throttle_->will_redirect_request_called());
- EXPECT_EQ(0u, throttle_->will_process_response_called());
-
- EXPECT_EQ(0u, client_.on_received_response_called());
- EXPECT_EQ(0u, client_.on_received_redirect_called());
- EXPECT_EQ(1u, client_.on_complete_called());
-}
-
-// Once browser-side navigation is the only option these two tests should be
-// merged as the sync and async cases will be identical.
-TEST_F(ThrottlingURLLoaderTest, PipeClosureBeforeAsyncResponse) {
+TEST_F(ThrottlingURLLoaderTest, PipeClosure) {
base::RunLoop run_loop;
client_.set_on_complete_callback(base::Bind(
[](const base::Closure& quit_closure, int error) {
diff --git a/chromium/content/common/typemaps.gni b/chromium/content/common/typemaps.gni
index e78dd1b145c..a9818ee3629 100644
--- a/chromium/content/common/typemaps.gni
+++ b/chromium/content/common/typemaps.gni
@@ -12,7 +12,6 @@ typemaps = [
"//content/common/native_types.typemap",
"//content/common/native_types_mac.typemap",
"//content/common/navigation_params.typemap",
- "//content/common/notifications/notification_types.typemap",
"//content/common/push_messaging.typemap",
"//content/common/render_frame_metadata.typemap",
"//content/common/service_worker/service_worker_fetch_request.typemap",
diff --git a/chromium/content/common/url_loader_factory_bundle.cc b/chromium/content/common/url_loader_factory_bundle.cc
index 8e6726f149a..da7a5bb94ad 100644
--- a/chromium/content/common/url_loader_factory_bundle.cc
+++ b/chromium/content/common/url_loader_factory_bundle.cc
@@ -4,20 +4,40 @@
#include "content/common/url_loader_factory_bundle.h"
+#include <utility>
+
#include "base/logging.h"
+#include "services/network/public/cpp/resource_request.h"
#include "url/gurl.h"
namespace content {
+namespace {
+
+template <typename TKey>
+void BindPtrInfoMapToPtrMap(
+ std::map<TKey, network::mojom::URLLoaderFactoryPtr>* target,
+ std::map<TKey, network::mojom::URLLoaderFactoryPtrInfo> input) {
+ for (auto& it : input) {
+ const TKey& key = it.first;
+ network::mojom::URLLoaderFactoryPtrInfo& factory_info = it.second;
+ (*target)[key].Bind(std::move(factory_info));
+ }
+}
+
+} // namespace
+
URLLoaderFactoryBundleInfo::URLLoaderFactoryBundleInfo() = default;
URLLoaderFactoryBundleInfo::URLLoaderFactoryBundleInfo(
network::mojom::URLLoaderFactoryPtrInfo default_factory_info,
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>
- factories_info,
+ SchemeMap scheme_specific_factory_infos,
+ OriginMap initiator_specific_factory_infos,
bool bypass_redirect_checks)
: default_factory_info_(std::move(default_factory_info)),
- factories_info_(std::move(factories_info)),
+ scheme_specific_factory_infos_(std::move(scheme_specific_factory_infos)),
+ initiator_specific_factory_infos_(
+ std::move(initiator_specific_factory_infos)),
bypass_redirect_checks_(bypass_redirect_checks) {}
URLLoaderFactoryBundleInfo::~URLLoaderFactoryBundleInfo() = default;
@@ -26,7 +46,10 @@ scoped_refptr<network::SharedURLLoaderFactory>
URLLoaderFactoryBundleInfo::CreateFactory() {
auto other = std::make_unique<URLLoaderFactoryBundleInfo>();
other->default_factory_info_ = std::move(default_factory_info_);
- other->factories_info_ = std::move(factories_info_);
+ other->scheme_specific_factory_infos_ =
+ std::move(scheme_specific_factory_infos_);
+ other->initiator_specific_factory_infos_ =
+ std::move(initiator_specific_factory_infos_);
other->bypass_redirect_checks_ = bypass_redirect_checks_;
return base::MakeRefCounted<URLLoaderFactoryBundle>(std::move(other));
@@ -48,22 +71,20 @@ void URLLoaderFactoryBundle::SetDefaultFactory(
default_factory_ = std::move(factory);
}
-void URLLoaderFactoryBundle::RegisterFactory(
- const base::StringPiece& scheme,
- network::mojom::URLLoaderFactoryPtr factory) {
- DCHECK(factory.is_bound());
- auto result = factories_.emplace(std::string(scheme), std::move(factory));
- DCHECK(result.second);
-}
-
-network::mojom::URLLoaderFactory* URLLoaderFactoryBundle::GetFactoryForURL(
- const GURL& url) {
- auto it = factories_.find(url.scheme());
- if (it == factories_.end()) {
- DCHECK(default_factory_.is_bound());
- return default_factory_.get();
+network::mojom::URLLoaderFactory* URLLoaderFactoryBundle::GetFactory(
+ const network::ResourceRequest& request) {
+ auto it = scheme_specific_factories_.find(request.url.scheme());
+ if (it != scheme_specific_factories_.end())
+ return it->second.get();
+
+ if (request.request_initiator.has_value()) {
+ auto it2 =
+ initiator_specific_factories_.find(request.request_initiator.value());
+ if (it2 != initiator_specific_factories_.end())
+ return it2->second.get();
}
- return it->second.get();
+
+ return default_factory_.get();
}
void URLLoaderFactoryBundle::CreateLoaderAndStart(
@@ -74,8 +95,7 @@ void URLLoaderFactoryBundle::CreateLoaderAndStart(
const network::ResourceRequest& request,
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
- network::mojom::URLLoaderFactory* factory_ptr = GetFactoryForURL(request.url);
-
+ network::mojom::URLLoaderFactory* factory_ptr = GetFactory(request);
factory_ptr->CreateLoaderAndStart(std::move(loader), routing_id, request_id,
options, request, std::move(client),
traffic_annotation);
@@ -92,15 +112,10 @@ URLLoaderFactoryBundle::Clone() {
if (default_factory_)
default_factory_->Clone(mojo::MakeRequest(&default_factory_info));
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo> factories_info;
- for (auto& factory : factories_) {
- network::mojom::URLLoaderFactoryPtrInfo factory_info;
- factory.second->Clone(mojo::MakeRequest(&factory_info));
- factories_info.emplace(factory.first, std::move(factory_info));
- }
-
return std::make_unique<URLLoaderFactoryBundleInfo>(
- std::move(default_factory_info), std::move(factories_info),
+ std::move(default_factory_info),
+ ClonePtrMapToPtrInfoMap(scheme_specific_factories_),
+ ClonePtrMapToPtrInfoMap(initiator_specific_factories_),
bypass_redirect_checks_);
}
@@ -112,8 +127,10 @@ void URLLoaderFactoryBundle::Update(
std::unique_ptr<URLLoaderFactoryBundleInfo> info) {
if (info->default_factory_info())
default_factory_.Bind(std::move(info->default_factory_info()));
- for (auto& factory_info : info->factories_info())
- factories_[factory_info.first].Bind(std::move(factory_info.second));
+ BindPtrInfoMapToPtrMap(&scheme_specific_factories_,
+ std::move(info->scheme_specific_factory_infos()));
+ BindPtrInfoMapToPtrMap(&initiator_specific_factories_,
+ std::move(info->initiator_specific_factory_infos()));
bypass_redirect_checks_ = info->bypass_redirect_checks();
}
diff --git a/chromium/content/common/url_loader_factory_bundle.h b/chromium/content/common/url_loader_factory_bundle.h
index 252152ae87b..33622f28816 100644
--- a/chromium/content/common/url_loader_factory_bundle.h
+++ b/chromium/content/common/url_loader_factory_bundle.h
@@ -6,14 +6,19 @@
#define CONTENT_COMMON_URL_LOADER_FACTORY_BUNDLE_H_
#include <map>
+#include <memory>
#include <string>
+#include <utility>
#include "base/macros.h"
#include "content/common/content_export.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "url/origin.h"
-class GURL;
+namespace network {
+struct ResourceRequest;
+};
namespace content {
@@ -22,11 +27,23 @@ namespace content {
class CONTENT_EXPORT URLLoaderFactoryBundleInfo
: public network::SharedURLLoaderFactoryInfo {
public:
+ // Map from URL scheme to URLLoaderFactoryPtrInfo for handling URL requests
+ // for schemes not handled by the |default_factory_info|. See also
+ // URLLoaderFactoryBundle::SchemeMap.
+ using SchemeMap =
+ std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>;
+
+ // Map from origin of request initiator to URLLoaderFactoryPtrInfo for
+ // handling this initiator's requests (e.g. for relaxing CORB for requests
+ // initiated from content scripts).
+ using OriginMap =
+ std::map<url::Origin, network::mojom::URLLoaderFactoryPtrInfo>;
+
URLLoaderFactoryBundleInfo();
URLLoaderFactoryBundleInfo(
network::mojom::URLLoaderFactoryPtrInfo default_factory_info,
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>
- factories_info,
+ SchemeMap scheme_specific_factory_infos,
+ OriginMap initiator_specific_factory_infos,
bool bypass_redirect_checks);
~URLLoaderFactoryBundleInfo() override;
@@ -34,9 +51,11 @@ class CONTENT_EXPORT URLLoaderFactoryBundleInfo
return default_factory_info_;
}
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>&
- factories_info() {
- return factories_info_;
+ SchemeMap& scheme_specific_factory_infos() {
+ return scheme_specific_factory_infos_;
+ }
+ OriginMap& initiator_specific_factory_infos() {
+ return initiator_specific_factory_infos_;
}
bool bypass_redirect_checks() const { return bypass_redirect_checks_; }
@@ -49,8 +68,8 @@ class CONTENT_EXPORT URLLoaderFactoryBundleInfo
scoped_refptr<network::SharedURLLoaderFactory> CreateFactory() override;
network::mojom::URLLoaderFactoryPtrInfo default_factory_info_;
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>
- factories_info_;
+ SchemeMap scheme_specific_factory_infos_;
+ OriginMap initiator_specific_factory_infos_;
bool bypass_redirect_checks_ = false;
DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryBundleInfo);
@@ -70,15 +89,6 @@ class CONTENT_EXPORT URLLoaderFactoryBundle
// |url|.
void SetDefaultFactory(network::mojom::URLLoaderFactoryPtr factory);
- // Registers a new factory to handle requests matching scheme |scheme|.
- void RegisterFactory(const base::StringPiece& scheme,
- network::mojom::URLLoaderFactoryPtr factory);
-
- // Returns a factory which can be used to acquire a loader for |url|. If no
- // registered factory matches |url|'s scheme, the default factory is used. It
- // is undefined behavior to call this when no default factory is set.
- virtual network::mojom::URLLoaderFactory* GetFactoryForURL(const GURL& url);
-
// SharedURLLoaderFactory implementation.
void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader,
int32_t routing_id,
@@ -99,8 +109,39 @@ class CONTENT_EXPORT URLLoaderFactoryBundle
protected:
~URLLoaderFactoryBundle() override;
+ // Returns a factory which can be used to acquire a loader for |request|.
+ virtual network::mojom::URLLoaderFactory* GetFactory(
+ const network::ResourceRequest& request);
+
+ template <typename TKey>
+ static std::map<TKey, network::mojom::URLLoaderFactoryPtrInfo>
+ ClonePtrMapToPtrInfoMap(
+ const std::map<TKey, network::mojom::URLLoaderFactoryPtr>& input) {
+ std::map<TKey, network::mojom::URLLoaderFactoryPtrInfo> output;
+ for (const auto& it : input) {
+ const TKey& key = it.first;
+ const network::mojom::URLLoaderFactoryPtr& factory = it.second;
+ network::mojom::URLLoaderFactoryPtrInfo factory_info;
+ factory->Clone(mojo::MakeRequest(&factory_info));
+ output.emplace(key, std::move(factory_info));
+ }
+ return output;
+ }
+
network::mojom::URLLoaderFactoryPtr default_factory_;
- std::map<std::string, network::mojom::URLLoaderFactoryPtr> factories_;
+
+ // Map from URL scheme to URLLoaderFactoryPtr for handling URL requests for
+ // schemes not handled by the |default_factory_|. See also
+ // URLLoaderFactoryBundleInfo::SchemeMap and
+ // ContentBrowserClient::SchemeToURLLoaderFactoryMap.
+ using SchemeMap = std::map<std::string, network::mojom::URLLoaderFactoryPtr>;
+ SchemeMap scheme_specific_factories_;
+
+ // Map from origin of request initiator to URLLoaderFactoryPtr for handling
+ // this initiator's requests. See also URLLoaderFactoryBundleInfo::OriginMap.
+ using OriginMap = std::map<url::Origin, network::mojom::URLLoaderFactoryPtr>;
+ OriginMap initiator_specific_factories_;
+
bool bypass_redirect_checks_ = false;
};
diff --git a/chromium/content/common/url_loader_factory_bundle.mojom b/chromium/content/common/url_loader_factory_bundle.mojom
index 348f891ffa8..eb99321b865 100644
--- a/chromium/content/common/url_loader_factory_bundle.mojom
+++ b/chromium/content/common/url_loader_factory_bundle.mojom
@@ -5,14 +5,22 @@
module content.mojom;
import "services/network/public/mojom/url_loader_factory.mojom";
+import "url/mojom/origin.mojom";
// Serializes a collection of URLLoaderFactory interfaces.
struct URLLoaderFactoryBundle {
// The default factory to be used when no others apply.
+ //
+ // TODO(jam): https://crbug.com/887109: Remove |default_factory| and put it
+ // inside |scheme_specific_factories| instead.
network.mojom.URLLoaderFactory default_factory;
// A mapping from URL scheme to factory interface.
- map<string, network.mojom.URLLoaderFactory> factories;
+ map<string, network.mojom.URLLoaderFactory> scheme_specific_factories;
+
+ // A mapping from request-initiator-origin to factory interface.
+ map<url.mojom.Origin, network.mojom.URLLoaderFactory>
+ initiator_specific_factories;
// Whether redirect checks should be bypassed, since they are happening in the
// browser.
diff --git a/chromium/content/common/url_loader_factory_bundle_struct_traits.cc b/chromium/content/common/url_loader_factory_bundle_struct_traits.cc
index 60a4538a02a..f0236343f70 100644
--- a/chromium/content/common/url_loader_factory_bundle_struct_traits.cc
+++ b/chromium/content/common/url_loader_factory_bundle_struct_traits.cc
@@ -4,6 +4,11 @@
#include "content/common/url_loader_factory_bundle_struct_traits.h"
+#include <memory>
+#include <utility>
+
+#include "url/mojom/origin_mojom_traits.h"
+
namespace mojo {
using Traits =
@@ -17,9 +22,15 @@ network::mojom::URLLoaderFactoryPtrInfo Traits::default_factory(
}
// static
-std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>
-Traits::factories(BundleInfoType& bundle) {
- return std::move(bundle->factories_info());
+content::URLLoaderFactoryBundleInfo::SchemeMap
+Traits::scheme_specific_factories(BundleInfoType& bundle) {
+ return std::move(bundle->scheme_specific_factory_infos());
+}
+
+// static
+content::URLLoaderFactoryBundleInfo::OriginMap
+Traits::initiator_specific_factories(BundleInfoType& bundle) {
+ return std::move(bundle->initiator_specific_factory_infos());
}
// static
@@ -34,7 +45,11 @@ bool Traits::Read(content::mojom::URLLoaderFactoryBundleDataView data,
(*out_bundle)->default_factory_info() =
data.TakeDefaultFactory<network::mojom::URLLoaderFactoryPtrInfo>();
- if (!data.ReadFactories(&(*out_bundle)->factories_info()))
+ if (!data.ReadSchemeSpecificFactories(
+ &(*out_bundle)->scheme_specific_factory_infos()))
+ return false;
+ if (!data.ReadInitiatorSpecificFactories(
+ &(*out_bundle)->initiator_specific_factory_infos()))
return false;
(*out_bundle)->set_bypass_redirect_checks(data.bypass_redirect_checks());
diff --git a/chromium/content/common/url_loader_factory_bundle_struct_traits.h b/chromium/content/common/url_loader_factory_bundle_struct_traits.h
index 70713c9617b..84f9bb6264f 100644
--- a/chromium/content/common/url_loader_factory_bundle_struct_traits.h
+++ b/chromium/content/common/url_loader_factory_bundle_struct_traits.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_COMMON_URL_LOADER_FACTORY_BUNDLE_STRUCT_TRAITS_H_
#define CONTENT_COMMON_URL_LOADER_FACTORY_BUNDLE_STRUCT_TRAITS_H_
+#include <memory>
+
#include "content/common/url_loader_factory_bundle.h"
#include "content/common/url_loader_factory_bundle.mojom-shared.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
@@ -23,8 +25,11 @@ struct StructTraits<content::mojom::URLLoaderFactoryBundleDataView,
static network::mojom::URLLoaderFactoryPtrInfo default_factory(
BundleInfoType& bundle);
- static std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>
- factories(BundleInfoType& bundle);
+ static content::URLLoaderFactoryBundleInfo::SchemeMap
+ scheme_specific_factories(BundleInfoType& bundle);
+
+ static content::URLLoaderFactoryBundleInfo::OriginMap
+ initiator_specific_factories(BundleInfoType& bundle);
static bool bypass_redirect_checks(BundleInfoType& bundle);
diff --git a/chromium/content/common/url_schemes.cc b/chromium/content/common/url_schemes.cc
index 4113e33fb43..9440dcaba5b 100644
--- a/chromium/content/common/url_schemes.cc
+++ b/chromium/content/common/url_schemes.cc
@@ -10,6 +10,7 @@
#include "base/no_destructor.h"
#include "base/strings/string_util.h"
+#include "build/build_config.h"
#include "content/public/common/content_client.h"
#include "content/public/common/url_constants.h"
#include "url/url_util.h"
@@ -89,6 +90,11 @@ void RegisterContentSchemes(bool lock_schemes) {
for (auto& scheme : schemes.empty_document_schemes)
url::AddEmptyDocumentScheme(scheme.c_str());
+#if defined(OS_ANDROID)
+ if (schemes.allow_non_standard_schemes_in_origins)
+ url::EnableNonStandardSchemesForAndroidWebView();
+#endif
+
// Prevent future modification of the scheme lists. This is to prevent
// accidental creation of data races in the program. Add*Scheme aren't
// threadsafe so must be called when GURL isn't used on any other thread. This
diff --git a/chromium/content/common/user_agent.cc b/chromium/content/common/user_agent.cc
index cf3b6df7b1a..0ceb7311a0f 100644
--- a/chromium/content/common/user_agent.cc
+++ b/chromium/content/common/user_agent.cc
@@ -66,30 +66,7 @@ std::string BuildOSCpuInfo(bool include_android_build_number) {
}
#elif defined(OS_ANDROID)
std::string android_version_str = base::SysInfo::OperatingSystemVersion();
-
- std::string android_info_str;
-
- // Send information about the device.
- bool semicolon_inserted = false;
- std::string android_build_codename = base::SysInfo::GetAndroidBuildCodename();
- std::string android_device_name = base::SysInfo::HardwareModelName();
- if ("REL" == android_build_codename && android_device_name.size() > 0) {
- android_info_str += "; " + android_device_name;
- semicolon_inserted = true;
- }
-
- // Append the build ID.
- if (base::FeatureList::IsEnabled(kAndroidUserAgentStringContainsBuildId) ||
- include_android_build_number) {
- std::string android_build_id = base::SysInfo::GetAndroidBuildID();
- if (android_build_id.size() > 0) {
- if (!semicolon_inserted) {
- android_info_str += ";";
- }
- android_info_str += " Build/" + android_build_id;
- }
- }
-
+ std::string android_info_str = GetAndroidOSInfo(include_android_build_number);
#elif (defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(OS_FUCHSIA)
// Should work on any Posix system.
struct utsname unixinfo;
@@ -164,14 +141,40 @@ std::string BuildUserAgentFromProduct(const std::string& product) {
std::string BuildUserAgentFromProductAndExtraOSInfo(
const std::string& product,
const std::string& extra_os_info,
- const bool include_android_build_number) {
+ bool include_android_build_number) {
std::string os_info;
base::StringAppendF(&os_info, "%s%s%s", getUserAgentPlatform().c_str(),
BuildOSCpuInfo(include_android_build_number).c_str(),
extra_os_info.c_str());
return BuildUserAgentFromOSAndProduct(os_info, product);
}
-#endif
+
+std::string GetAndroidOSInfo(bool include_android_build_number) {
+ std::string android_info_str;
+
+ // Send information about the device.
+ bool semicolon_inserted = false;
+ std::string android_build_codename = base::SysInfo::GetAndroidBuildCodename();
+ std::string android_device_name = base::SysInfo::HardwareModelName();
+ if (!android_device_name.empty() && "REL" == android_build_codename) {
+ android_info_str += "; " + android_device_name;
+ semicolon_inserted = true;
+ }
+
+ // Append the build ID.
+ if (base::FeatureList::IsEnabled(kAndroidUserAgentStringContainsBuildId) ||
+ include_android_build_number) {
+ std::string android_build_id = base::SysInfo::GetAndroidBuildID();
+ if (!android_build_id.empty()) {
+ if (!semicolon_inserted)
+ android_info_str += ";";
+ android_info_str += " Build/" + android_build_id;
+ }
+ }
+
+ return android_info_str;
+}
+#endif // defined(OS_ANDROID)
std::string BuildUserAgentFromOSAndProduct(const std::string& os_info,
const std::string& product) {
diff --git a/chromium/content/common/view_message_enums.h b/chromium/content/common/view_message_enums.h
deleted file mode 100644
index c2f4b455df1..00000000000
--- a/chromium/content/common/view_message_enums.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_COMMON_VIEW_MESSAGE_ENUMS_H_
-#define CONTENT_COMMON_VIEW_MESSAGE_ENUMS_H_
-
-#include "ipc/ipc_message_macros.h"
-
-// Values that may be OR'd together to form the 'flags' parameter of a
-// ViewHostMsg_ResizeOrRepaint_ACK_Params structure.
-struct ViewHostMsg_ResizeOrRepaint_ACK_Flags {
- enum {
- IS_RESIZE_ACK = 1 << 0,
- IS_REPAINT_ACK = 1 << 2,
- };
- static bool is_resize_ack(int flags) {
- return (flags & IS_RESIZE_ACK) != 0;
- }
- static bool is_repaint_ack(int flags) {
- return (flags & IS_REPAINT_ACK) != 0;
- }
-};
-
-#endif // CONTENT_COMMON_VIEW_MESSAGE_ENUMS_H_
diff --git a/chromium/content/common/view_messages.h b/chromium/content/common/view_messages.h
index cb6ce7bcfb3..e931fc06bc3 100644
--- a/chromium/content/common/view_messages.h
+++ b/chromium/content/common/view_messages.h
@@ -28,9 +28,6 @@
#include "content/common/date_time_suggestion.h"
#include "content/common/frame_replication_state.h"
#include "content/common/navigation_gesture.h"
-#include "content/common/text_input_state.h"
-#include "content/common/view_message_enums.h"
-#include "content/common/visual_properties.h"
#include "content/public/common/common_param_traits.h"
#include "content/public/common/menu_item.h"
#include "content/public/common/page_state.h"
@@ -43,21 +40,13 @@
#include "media/base/audio_parameters.h"
#include "media/base/channel_layout.h"
#include "media/base/ipc/media_param_traits.h"
-#include "media/capture/ipc/capture_param_traits.h"
#include "net/base/network_change_notifier.h"
#include "ppapi/buildflags/buildflags.h"
#include "third_party/blink/public/common/manifest/web_display_mode.h"
-#include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h"
-#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_float_rect.h"
-#include "third_party/blink/public/platform/web_intrinsic_sizing_info.h"
-#include "third_party/blink/public/web/web_device_emulation_params.h"
#include "third_party/blink/public/web/web_plugin_action.h"
-#include "third_party/blink/public/web/web_popup_type.h"
#include "third_party/blink/public/web/web_text_direction.h"
#include "ui/base/ime/text_input_mode.h"
#include "ui/base/ime/text_input_type.h"
-#include "ui/base/ui_base_types.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
@@ -78,30 +67,16 @@
#define IPC_MESSAGE_START ViewMsgStart
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebDeviceEmulationParams::ScreenPosition,
- blink::WebDeviceEmulationParams::kScreenPositionLast)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebPluginAction::Type,
blink::WebPluginAction::Type::kTypeLast)
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebPopupType,
- blink::WebPopupType::kWebPopupTypeLast)
-IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::WebScreenOrientationType,
- blink::kWebScreenOrientationUndefined,
- blink::WebScreenOrientationTypeLast)
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebTextDirection,
- blink::WebTextDirection::kWebTextDirectionLast)
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebDisplayMode,
- blink::WebDisplayMode::kWebDisplayModeLast)
IPC_ENUM_TRAITS_MAX_VALUE(content::MenuItem::Type, content::MenuItem::TYPE_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(content::NavigationGesture,
content::NavigationGestureLast)
IPC_ENUM_TRAITS_MIN_MAX_VALUE(content::PageZoom,
content::PageZoom::PAGE_ZOOM_OUT,
content::PageZoom::PAGE_ZOOM_IN)
-IPC_ENUM_TRAITS_MAX_VALUE(content::ScreenOrientationValues,
- content::SCREEN_ORIENTATION_VALUES_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(content::ThreeDAPIType,
content::THREE_D_API_TYPE_LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(ui::TextInputMode, ui::TEXT_INPUT_MODE_MAX)
IPC_ENUM_TRAITS_MAX_VALUE(ui::TextInputType, ui::TEXT_INPUT_TYPE_MAX)
#if defined(OS_MACOSX)
@@ -117,55 +92,6 @@ IPC_STRUCT_TRAITS_BEGIN(blink::WebPluginAction)
IPC_STRUCT_TRAITS_MEMBER(enable)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(blink::WebFloatPoint)
- IPC_STRUCT_TRAITS_MEMBER(x)
- IPC_STRUCT_TRAITS_MEMBER(y)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(blink::WebFloatRect)
- IPC_STRUCT_TRAITS_MEMBER(x)
- IPC_STRUCT_TRAITS_MEMBER(y)
- IPC_STRUCT_TRAITS_MEMBER(width)
- IPC_STRUCT_TRAITS_MEMBER(height)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(blink::WebSize)
- IPC_STRUCT_TRAITS_MEMBER(width)
- IPC_STRUCT_TRAITS_MEMBER(height)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(blink::WebDeviceEmulationParams)
- IPC_STRUCT_TRAITS_MEMBER(screen_position)
- IPC_STRUCT_TRAITS_MEMBER(screen_size)
- IPC_STRUCT_TRAITS_MEMBER(view_position)
- IPC_STRUCT_TRAITS_MEMBER(device_scale_factor)
- IPC_STRUCT_TRAITS_MEMBER(view_size)
- IPC_STRUCT_TRAITS_MEMBER(scale)
- IPC_STRUCT_TRAITS_MEMBER(viewport_offset)
- IPC_STRUCT_TRAITS_MEMBER(viewport_scale)
- IPC_STRUCT_TRAITS_MEMBER(screen_orientation_angle)
- IPC_STRUCT_TRAITS_MEMBER(screen_orientation_type)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(content::VisualProperties)
- IPC_STRUCT_TRAITS_MEMBER(screen_info)
- IPC_STRUCT_TRAITS_MEMBER(auto_resize_enabled)
- IPC_STRUCT_TRAITS_MEMBER(min_size_for_auto_resize)
- IPC_STRUCT_TRAITS_MEMBER(max_size_for_auto_resize)
- IPC_STRUCT_TRAITS_MEMBER(new_size)
- IPC_STRUCT_TRAITS_MEMBER(compositor_viewport_pixel_size)
- IPC_STRUCT_TRAITS_MEMBER(browser_controls_shrink_blink_size)
- IPC_STRUCT_TRAITS_MEMBER(scroll_focused_node_into_view)
- IPC_STRUCT_TRAITS_MEMBER(top_controls_height)
- IPC_STRUCT_TRAITS_MEMBER(bottom_controls_height)
- IPC_STRUCT_TRAITS_MEMBER(local_surface_id)
- IPC_STRUCT_TRAITS_MEMBER(visible_viewport_size)
- IPC_STRUCT_TRAITS_MEMBER(is_fullscreen_granted)
- IPC_STRUCT_TRAITS_MEMBER(display_mode)
- IPC_STRUCT_TRAITS_MEMBER(capture_sequence_number)
- IPC_STRUCT_TRAITS_MEMBER(zoom_level)
-IPC_STRUCT_TRAITS_END()
-
IPC_STRUCT_TRAITS_BEGIN(content::MenuItem)
IPC_STRUCT_TRAITS_MEMBER(label)
IPC_STRUCT_TRAITS_MEMBER(tool_tip)
@@ -184,20 +110,6 @@ IPC_STRUCT_TRAITS_BEGIN(content::DateTimeSuggestion)
IPC_STRUCT_TRAITS_MEMBER(label)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_TRAITS_BEGIN(content::TextInputState)
- IPC_STRUCT_TRAITS_MEMBER(type)
- IPC_STRUCT_TRAITS_MEMBER(mode)
- IPC_STRUCT_TRAITS_MEMBER(flags)
- IPC_STRUCT_TRAITS_MEMBER(value)
- IPC_STRUCT_TRAITS_MEMBER(selection_start)
- IPC_STRUCT_TRAITS_MEMBER(selection_end)
- IPC_STRUCT_TRAITS_MEMBER(composition_start)
- IPC_STRUCT_TRAITS_MEMBER(composition_end)
- IPC_STRUCT_TRAITS_MEMBER(can_compose_inline)
- IPC_STRUCT_TRAITS_MEMBER(show_ime_if_needed)
- IPC_STRUCT_TRAITS_MEMBER(reply_to_request)
-IPC_STRUCT_TRAITS_END()
-
IPC_STRUCT_BEGIN(ViewHostMsg_DateTimeDialogValue_Params)
IPC_STRUCT_MEMBER(ui::TextInputType, dialog_type)
IPC_STRUCT_MEMBER(double, dialog_value)
@@ -207,14 +119,6 @@ IPC_STRUCT_BEGIN(ViewHostMsg_DateTimeDialogValue_Params)
IPC_STRUCT_MEMBER(std::vector<content::DateTimeSuggestion>, suggestions)
IPC_STRUCT_END()
-IPC_STRUCT_BEGIN(ViewHostMsg_SelectionBounds_Params)
- IPC_STRUCT_MEMBER(gfx::Rect, anchor_rect)
- IPC_STRUCT_MEMBER(blink::WebTextDirection, anchor_dir)
- IPC_STRUCT_MEMBER(gfx::Rect, focus_rect)
- IPC_STRUCT_MEMBER(blink::WebTextDirection, focus_dir)
- IPC_STRUCT_MEMBER(bool, is_anchor_first)
-IPC_STRUCT_END()
-
// Messages sent from the browser to the renderer.
#if defined(OS_ANDROID)
@@ -227,14 +131,6 @@ IPC_MESSAGE_ROUTED1(ViewMsg_ReplaceDateTime,
#endif
-// Tells the render side that a ViewHostMsg_LockMouse message has been
-// processed. |succeeded| indicates whether the mouse has been successfully
-// locked or not.
-IPC_MESSAGE_ROUTED1(ViewMsg_LockMouse_ACK,
- bool /* succeeded */)
-// Tells the render side that the mouse has been unlocked.
-IPC_MESSAGE_ROUTED0(ViewMsg_MouseLockLost)
-
// Sends updated preferences to the renderer.
IPC_MESSAGE_ROUTED1(ViewMsg_SetRendererPrefs,
content::RendererPreferences)
@@ -243,49 +139,11 @@ IPC_MESSAGE_ROUTED1(ViewMsg_SetRendererPrefs,
IPC_MESSAGE_ROUTED1(ViewMsg_UpdateWebPreferences,
content::WebPreferences)
-// Tells the render view to close.
-// Expects a Close_ACK message when finished.
-IPC_MESSAGE_ROUTED0(ViewMsg_Close)
-
-// Tells the renderer to update visual properties. A
-// ViewHostMsg_ResizeOrRepaint_ACK message is generated in response provided
-// new_size is not empty and not equal to the view's current size. The
-// generated ViewHostMsg_ResizeOrRepaint_ACK
-// message will have the IS_RESIZE_ACK flag set. It also receives the resizer
-// rect so that we don't have to fetch it every time WebKit asks for it.
-IPC_MESSAGE_ROUTED1(ViewMsg_SynchronizeVisualProperties,
- content::VisualProperties /* params */)
-
-// Enables device emulation. See WebDeviceEmulationParams for description.
-IPC_MESSAGE_ROUTED1(ViewMsg_EnableDeviceEmulation,
- blink::WebDeviceEmulationParams /* params */)
-
-// Disables device emulation, enabled previously by EnableDeviceEmulation.
-IPC_MESSAGE_ROUTED0(ViewMsg_DisableDeviceEmulation)
-
-// Sent to inform the view that it was hidden. This allows it to reduce its
-// resource utilization.
-IPC_MESSAGE_ROUTED0(ViewMsg_WasHidden)
-
-// Tells the render view that it is no longer hidden (see WasHidden), and the
-// render view is expected to respond with a full repaint if needs_repainting
-// is true. If needs_repainting is false, then this message does not trigger a
-// message in response.
-IPC_MESSAGE_ROUTED2(ViewMsg_WasShown,
- bool /* needs_repainting */,
- base::TimeTicks /* show_request_timestamp */)
-
// Tells the renderer to focus the first (last if reverse is true) focusable
// node.
IPC_MESSAGE_ROUTED1(ViewMsg_SetInitialFocus,
bool /* reverse */)
-// Sent to inform the renderer to invoke a context menu.
-// The parameter specifies the location in the render view's coordinates.
-IPC_MESSAGE_ROUTED2(ViewMsg_ShowContextMenu,
- ui::MenuSourceType,
- gfx::Point /* location where menu should be shown */)
-
// Tells the renderer to perform the given action on the plugin located at
// the given point.
IPC_MESSAGE_ROUTED2(ViewMsg_PluginActionAt,
@@ -320,38 +178,14 @@ IPC_MESSAGE_ROUTED0(ViewMsg_ClosePage)
// started.
IPC_MESSAGE_ROUTED0(ViewMsg_MoveOrResizeStarted)
-IPC_MESSAGE_ROUTED2(ViewMsg_UpdateScreenRects,
- gfx::Rect /* view_screen_rect */,
- gfx::Rect /* window_screen_rect */)
-
-// Reply to ViewHostMsg_RequestSetBounds, ViewHostMsg_ShowWidget, and
-// FrameHostMsg_ShowCreatedWindow, to inform the renderer that the browser has
-// processed the bounds-setting. The browser may have ignored the new bounds,
-// but it finished processing. This is used because the renderer keeps a
-// temporary cache of the widget position while these asynchronous operations
-// are in progress.
-IPC_MESSAGE_ROUTED0(ViewMsg_SetBounds_ACK)
-
// Used to instruct the RenderView to send back updates to the preferred size.
IPC_MESSAGE_ROUTED0(ViewMsg_EnablePreferredSizeChangedMode)
-// Changes the text direction of the currently selected input field (if any).
-IPC_MESSAGE_ROUTED1(ViewMsg_SetTextDirection,
- blink::WebTextDirection /* direction */)
-
-// Make the RenderView background transparent or opaque.
-IPC_MESSAGE_ROUTED1(ViewMsg_SetBackgroundOpaque, bool /* opaque */)
-
// Used to tell the renderer not to add scrollbars with height and
// width below a threshold.
IPC_MESSAGE_ROUTED1(ViewMsg_DisableScrollbarsForSmallWindows,
gfx::Size /* disable_scrollbar_size_limit */)
-// Activate/deactivate the RenderView (i.e., set its controls' tint
-// accordingly, etc.).
-IPC_MESSAGE_ROUTED1(ViewMsg_SetActive,
- bool /* active */)
-
// Response message to ViewHostMsg_CreateWorker.
// Sent when the worker has started.
IPC_MESSAGE_ROUTED0(ViewMsg_WorkerCreated)
@@ -379,10 +213,6 @@ IPC_MESSAGE_ROUTED0(ViewMsg_WorkerDestroyed)
IPC_MESSAGE_ROUTED1(ViewMsg_CountFeatureOnSharedWorker,
uint32_t /* feature */)
-// Sent by the browser to synchronize with the next compositor frame. Used only
-// for tests.
-IPC_MESSAGE_ROUTED1(ViewMsg_WaitForNextFrameForTests, int /* routing_id */)
-
#if BUILDFLAG(ENABLE_PLUGINS)
// Reply to ViewHostMsg_OpenChannelToPpapiBroker
// Tells the renderer that the channel to the broker has been created.
@@ -397,31 +227,6 @@ IPC_MESSAGE_ROUTED1(ViewMsg_PpapiBrokerPermissionResult,
bool /* result */)
#endif
-IPC_MESSAGE_ROUTED0(ViewMsg_SelectWordAroundCaret)
-
-// Sent by the browser to ask the renderer to redraw. Robust to events that can
-// happen in renderer (abortion of the commit or draw, loss of output surface
-// etc.).
-IPC_MESSAGE_ROUTED1(ViewMsg_ForceRedraw, int /* snapshot_id */)
-
-// Sets the viewport intersection and compositor raster area on the widget for
-// an out-of-process iframe.
-IPC_MESSAGE_ROUTED3(ViewMsg_SetViewportIntersection,
- gfx::Rect /* viewport_intersection */,
- gfx::Rect /* compositor_visible_rect */,
- bool /* occluded or obscured */)
-
-// Sets the inert bit on an out-of-process iframe.
-IPC_MESSAGE_ROUTED1(ViewMsg_SetIsInert, bool /* inert */)
-
-// Sets the inherited effective touch action on an out-of-process iframe.
-IPC_MESSAGE_ROUTED1(ViewMsg_SetInheritedEffectiveTouchAction, cc::TouchAction)
-
-// Toggles render throttling for an out-of-process iframe.
-IPC_MESSAGE_ROUTED2(ViewMsg_UpdateRenderThrottlingStatus,
- bool /* is_throttled */,
- bool /* subtree_throttled */)
-
// -----------------------------------------------------------------------------
// Messages sent from the renderer to the browser.
@@ -437,30 +242,6 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_ShowWidget,
IPC_MESSAGE_ROUTED1(ViewHostMsg_ShowFullscreenWidget,
int /* route_id */)
-// Sent by the renderer process to request that the browser close the view.
-// This corresponds to the window.close() API, and the browser may ignore
-// this message. Otherwise, the browser will generates a ViewMsg_Close
-// message to close the view.
-IPC_MESSAGE_ROUTED0(ViewHostMsg_Close)
-
-// Sent by the renderer process in response to an earlier ViewMsg_ForceRedraw
-// message. The reply includes the snapshot-id from the request.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_ForceRedrawComplete, int /* snapshot_id */)
-
-// Send in response to a ViewMsg_UpdateScreenRects so that the renderer can
-// throttle these messages.
-IPC_MESSAGE_ROUTED0(ViewHostMsg_UpdateScreenRects_ACK)
-
-// Sent by the renderer process to request that the browser change the bounds of
-// the view. This corresponds to the window.resizeTo() and window.moveTo() APIs,
-// and the browser may ignore this message.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_RequestSetBounds, gfx::Rect /* bounds */)
-
-// Indicates that the render view has been closed in response to a
-// Close message.
-IPC_MESSAGE_CONTROL1(ViewHostMsg_Close_ACK,
- int /* old_route_id */)
-
// Indicates that the current page has been closed, after a ClosePage
// message.
IPC_MESSAGE_ROUTED0(ViewHostMsg_ClosePage_ACK)
@@ -478,16 +259,6 @@ IPC_MESSAGE_ROUTED1(ViewHostMsg_DocumentAvailableInMainFrame,
IPC_MESSAGE_ROUTED0(ViewHostMsg_Focus)
-IPC_MESSAGE_ROUTED1(ViewHostMsg_SetCursor, content::WebCursor)
-
-// Request a non-decelerating synthetic fling animation to be latched on the
-// scroller at the start point, and whose velocity can be changed over time by
-// sending multiple AutoscrollFling gestures. Used for features like
-// middle-click autoscroll.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_AutoscrollStart, gfx::PointF /* start */)
-IPC_MESSAGE_ROUTED1(ViewHostMsg_AutoscrollFling, gfx::Vector2dF /* velocity */)
-IPC_MESSAGE_ROUTED0(ViewHostMsg_AutoscrollEnd)
-
// Get the list of proxies to use for |url|, as a semicolon delimited list
// of "<TYPE> <HOST>:<PORT>" | "DIRECT".
IPC_SYNC_MESSAGE_CONTROL1_2(ViewHostMsg_ResolveProxy,
@@ -503,8 +274,9 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_AppCacheAccessed,
// Used to go to the session history entry at the given offset (ie, -1 will
// return the "back" item).
-IPC_MESSAGE_ROUTED1(ViewHostMsg_GoToEntryAtOffset,
- int /* offset (from current) of history item to get */)
+IPC_MESSAGE_ROUTED2(ViewHostMsg_GoToEntryAtOffset,
+ int /* offset (from current) of history item to get */,
+ bool /* has_user_gesture */)
// Sent from an inactive renderer for the browser to route to the active
// renderer, instructing it to close.
@@ -529,15 +301,6 @@ IPC_MESSAGE_ROUTED3(ViewHostMsg_RequestPpapiBrokerPermission,
base::FilePath /* plugin_path */)
#endif // BUILDFLAG(ENABLE_PLUGINS)
-// Send the tooltip text for the current mouse position to the browser.
-IPC_MESSAGE_ROUTED2(ViewHostMsg_SetTooltipText,
- base::string16 /* tooltip text string */,
- blink::WebTextDirection /* text direction hint */)
-
-// Notification that the selection bounds have changed.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_SelectionBoundsChanged,
- ViewHostMsg_SelectionBounds_Params)
-
// Asks the browser to enumerate a directory. This is equivalent to running
// the file chooser in directory-enumeration mode and having the user select
// the given directory. The result is returned in a
@@ -556,10 +319,6 @@ IPC_MESSAGE_ROUTED1(ViewHostMsg_TakeFocus,
IPC_MESSAGE_ROUTED1(ViewHostMsg_OpenDateTimeDialog,
ViewHostMsg_DateTimeDialogValue_Params /* value */)
-// Required for updating text input state.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_TextInputStateChanged,
- content::TextInputState /* text_input_state */)
-
// Sent when the renderer changes its page scale factor.
IPC_MESSAGE_ROUTED1(ViewHostMsg_PageScaleFactorChanged,
float /* page_scale_factor */)
@@ -572,10 +331,6 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_UpdateZoomLimits,
int /* minimum_percent */,
int /* maximum_percent */)
-IPC_MESSAGE_ROUTED2(ViewHostMsg_FrameSwapMessages,
- uint32_t /* frame_token */,
- std::vector<IPC::Message> /* messages */)
-
// Send back a string to be recorded by UserMetrics.
IPC_MESSAGE_CONTROL1(ViewHostMsg_UserMetricsRecordAction,
std::string /* action */)
@@ -584,32 +339,6 @@ IPC_MESSAGE_CONTROL1(ViewHostMsg_UserMetricsRecordAction,
IPC_MESSAGE_CONTROL1(ViewHostMsg_MediaLogEvents,
std::vector<media::MediaLogEvent> /* events */)
-// Requests to lock the mouse. Will result in a ViewMsg_LockMouse_ACK message
-// being sent back.
-// |privileged| is used by Pepper Flash. If this flag is set to true, we won't
-// pop up a bubble to ask for user permission or take mouse lock content into
-// account.
-IPC_MESSAGE_ROUTED2(ViewHostMsg_LockMouse,
- bool /* user_gesture */,
- bool /* privileged */)
-
-// Requests to tell the renderer for the containing frame of the current
-// renderer of a change in intrinsic sizing info parameters. This is only
-// used for SVG inside of <object>, and not for iframes.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_IntrinsicSizingInfoChanged,
- blink::WebIntrinsicSizingInfo)
-
-// Requests to unlock the mouse. A ViewMsg_MouseLockLost message will be sent
-// whenever the mouse is unlocked (which may or may not be caused by
-// ViewHostMsg_UnlockMouse).
-IPC_MESSAGE_ROUTED0(ViewHostMsg_UnlockMouse)
-
-// Message sent from renderer to the browser when the element that is focused
-// has been touched. A bool is passed in this message which indicates if the
-// node is editable.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_FocusedNodeTouched,
- bool /* editable */)
-
// Sent once a paint happens after the first non empty layout. In other words,
// after the frame widget has painted something.
IPC_MESSAGE_ROUTED0(ViewHostMsg_DidFirstVisuallyNonEmptyPaint)
@@ -617,16 +346,6 @@ IPC_MESSAGE_ROUTED0(ViewHostMsg_DidFirstVisuallyNonEmptyPaint)
// Sent once the RenderWidgetCompositor issues a draw command.
IPC_MESSAGE_ROUTED0(ViewHostMsg_DidCommitAndDrawCompositorFrame)
-// Sent in reply to ViewMsg_WaitForNextFrameForTests.
-IPC_MESSAGE_ROUTED0(ViewHostMsg_WaitForNextFrameForTests_ACK)
-
-// Acknowledges that a SelectWordAroundCaret completed with the specified
-// result and adjustments to the selection offsets.
-IPC_MESSAGE_ROUTED3(ViewHostMsg_SelectWordAroundCaretAck,
- bool /* did_select */,
- int /* start_adjust */,
- int /* end_adjust */)
-
// Adding a new message? Stick to the sort order above: first platform
// independent ViewMsg, then ifdefs for platform specific ViewMsg, then platform
// independent ViewHostMsg, then ifdefs for platform specific ViewHostMsg.
diff --git a/chromium/content/common/widget_messages.h b/chromium/content/common/widget_messages.h
new file mode 100644
index 00000000000..1eafbbab4eb
--- /dev/null
+++ b/chromium/content/common/widget_messages.h
@@ -0,0 +1,319 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_WIDGET_MESSAGES_H_
+#define CONTENT_COMMON_WIDGET_MESSAGES_H_
+
+// IPC messages for controlling painting and input events.
+
+#include "base/time/time.h"
+#include "cc/input/touch_action.h"
+#include "content/common/content_param_traits.h"
+#include "content/common/cursors/webcursor.h"
+#include "content/common/text_input_state.h"
+#include "content/common/visual_properties.h"
+#include "content/public/common/common_param_traits.h"
+#include "ipc/ipc_message_macros.h"
+#include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h"
+#include "third_party/blink/public/platform/web_float_point.h"
+#include "third_party/blink/public/platform/web_float_rect.h"
+#include "third_party/blink/public/platform/web_intrinsic_sizing_info.h"
+#include "third_party/blink/public/web/web_device_emulation_params.h"
+#include "third_party/blink/public/web/web_text_direction.h"
+#include "ui/base/ui_base_types.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/rect.h"
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
+
+#define IPC_MESSAGE_START WidgetMsgStart
+
+// Traits for VisualProperties.
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebDeviceEmulationParams::ScreenPosition,
+ blink::WebDeviceEmulationParams::kScreenPositionLast)
+
+IPC_ENUM_TRAITS_MAX_VALUE(content::ScreenOrientationValues,
+ content::SCREEN_ORIENTATION_VALUES_LAST)
+
+IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::WebScreenOrientationType,
+ blink::kWebScreenOrientationUndefined,
+ blink::WebScreenOrientationTypeLast)
+
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebDisplayMode,
+ blink::WebDisplayMode::kWebDisplayModeLast)
+
+IPC_STRUCT_TRAITS_BEGIN(content::VisualProperties)
+ IPC_STRUCT_TRAITS_MEMBER(screen_info)
+ IPC_STRUCT_TRAITS_MEMBER(auto_resize_enabled)
+ IPC_STRUCT_TRAITS_MEMBER(min_size_for_auto_resize)
+ IPC_STRUCT_TRAITS_MEMBER(max_size_for_auto_resize)
+ IPC_STRUCT_TRAITS_MEMBER(new_size)
+ IPC_STRUCT_TRAITS_MEMBER(compositor_viewport_pixel_size)
+ IPC_STRUCT_TRAITS_MEMBER(browser_controls_shrink_blink_size)
+ IPC_STRUCT_TRAITS_MEMBER(scroll_focused_node_into_view)
+ IPC_STRUCT_TRAITS_MEMBER(top_controls_height)
+ IPC_STRUCT_TRAITS_MEMBER(bottom_controls_height)
+ IPC_STRUCT_TRAITS_MEMBER(local_surface_id)
+ IPC_STRUCT_TRAITS_MEMBER(visible_viewport_size)
+ IPC_STRUCT_TRAITS_MEMBER(is_fullscreen_granted)
+ IPC_STRUCT_TRAITS_MEMBER(display_mode)
+ IPC_STRUCT_TRAITS_MEMBER(capture_sequence_number)
+ IPC_STRUCT_TRAITS_MEMBER(zoom_level)
+IPC_STRUCT_TRAITS_END()
+
+// Traits for WebDeviceEmulationParams.
+IPC_STRUCT_TRAITS_BEGIN(blink::WebFloatPoint)
+ IPC_STRUCT_TRAITS_MEMBER(x)
+ IPC_STRUCT_TRAITS_MEMBER(y)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(blink::WebFloatRect)
+ IPC_STRUCT_TRAITS_MEMBER(x)
+ IPC_STRUCT_TRAITS_MEMBER(y)
+ IPC_STRUCT_TRAITS_MEMBER(width)
+ IPC_STRUCT_TRAITS_MEMBER(height)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(blink::WebSize)
+ IPC_STRUCT_TRAITS_MEMBER(width)
+ IPC_STRUCT_TRAITS_MEMBER(height)
+IPC_STRUCT_TRAITS_END()
+
+IPC_STRUCT_TRAITS_BEGIN(blink::WebDeviceEmulationParams)
+ IPC_STRUCT_TRAITS_MEMBER(screen_position)
+ IPC_STRUCT_TRAITS_MEMBER(screen_size)
+ IPC_STRUCT_TRAITS_MEMBER(view_position)
+ IPC_STRUCT_TRAITS_MEMBER(device_scale_factor)
+ IPC_STRUCT_TRAITS_MEMBER(view_size)
+ IPC_STRUCT_TRAITS_MEMBER(scale)
+ IPC_STRUCT_TRAITS_MEMBER(viewport_offset)
+ IPC_STRUCT_TRAITS_MEMBER(viewport_scale)
+ IPC_STRUCT_TRAITS_MEMBER(screen_orientation_angle)
+ IPC_STRUCT_TRAITS_MEMBER(screen_orientation_type)
+IPC_STRUCT_TRAITS_END()
+
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebTextDirection,
+ blink::WebTextDirection::kWebTextDirectionLast)
+
+IPC_STRUCT_BEGIN(WidgetHostMsg_SelectionBounds_Params)
+ IPC_STRUCT_MEMBER(gfx::Rect, anchor_rect)
+ IPC_STRUCT_MEMBER(blink::WebTextDirection, anchor_dir)
+ IPC_STRUCT_MEMBER(gfx::Rect, focus_rect)
+ IPC_STRUCT_MEMBER(blink::WebTextDirection, focus_dir)
+ IPC_STRUCT_MEMBER(bool, is_anchor_first)
+IPC_STRUCT_END()
+
+// Traits for TextInputState.
+IPC_ENUM_TRAITS_MAX_VALUE(ui::TextInputMode, ui::TEXT_INPUT_MODE_MAX)
+
+IPC_STRUCT_TRAITS_BEGIN(content::TextInputState)
+ IPC_STRUCT_TRAITS_MEMBER(type)
+ IPC_STRUCT_TRAITS_MEMBER(mode)
+ IPC_STRUCT_TRAITS_MEMBER(flags)
+ IPC_STRUCT_TRAITS_MEMBER(value)
+ IPC_STRUCT_TRAITS_MEMBER(selection_start)
+ IPC_STRUCT_TRAITS_MEMBER(selection_end)
+ IPC_STRUCT_TRAITS_MEMBER(composition_start)
+ IPC_STRUCT_TRAITS_MEMBER(composition_end)
+ IPC_STRUCT_TRAITS_MEMBER(can_compose_inline)
+ IPC_STRUCT_TRAITS_MEMBER(show_ime_if_needed)
+ IPC_STRUCT_TRAITS_MEMBER(reply_to_request)
+IPC_STRUCT_TRAITS_END()
+
+//
+// Browser -> Renderer Messages.
+//
+
+// Sent to inform the renderer to invoke a context menu.
+// The parameter specifies the location in the render widget's coordinates.
+IPC_MESSAGE_ROUTED2(WidgetMsg_ShowContextMenu,
+ ui::MenuSourceType,
+ gfx::Point /* location where menu should be shown */)
+
+// Tells the render widget to close.
+// Expects a Close_ACK message when finished.
+IPC_MESSAGE_ROUTED0(WidgetMsg_Close)
+
+// Tells the renderer to update visual properties. The resulting
+// CompositorFrame will produce a RenderFrameMetadata containing a new
+// LocalSurfaceId. This acts as a form of ACK for this message.
+IPC_MESSAGE_ROUTED1(WidgetMsg_SynchronizeVisualProperties,
+ content::VisualProperties /* params */)
+
+// Enables device emulation. See WebDeviceEmulationParams for description.
+IPC_MESSAGE_ROUTED1(WidgetMsg_EnableDeviceEmulation,
+ blink::WebDeviceEmulationParams /* params */)
+
+// Disables device emulation, enabled previously by EnableDeviceEmulation.
+IPC_MESSAGE_ROUTED0(WidgetMsg_DisableDeviceEmulation)
+
+// Sent to inform the widget that it was hidden. This allows it to reduce its
+// resource utilization.
+IPC_MESSAGE_ROUTED0(WidgetMsg_WasHidden)
+
+// Tells the render view that it is no longer hidden (see WasHidden).
+IPC_MESSAGE_ROUTED1(WidgetMsg_WasShown,
+ base::TimeTicks /* show_request_timestamp */)
+
+// Activate/deactivate the RenderWidget (i.e., set its controls' tint
+// accordingly, etc.).
+IPC_MESSAGE_ROUTED1(WidgetMsg_SetActive, bool /* active */)
+
+// Make the RenderWidget background transparent or opaque.
+IPC_MESSAGE_ROUTED1(WidgetMsg_SetBackgroundOpaque, bool /* opaque */)
+
+// Changes the text direction of the currently selected input field (if any).
+IPC_MESSAGE_ROUTED1(WidgetMsg_SetTextDirection,
+ blink::WebTextDirection /* direction */)
+
+// Reply to WidgetHostMsg_RequestSetBounds, WidgetHostMsg_ShowWidget, and
+// FrameHostMsg_ShowCreatedWindow, to inform the renderer that the browser has
+// processed the bounds-setting. The browser may have ignored the new bounds,
+// but it finished processing. This is used because the renderer keeps a
+// temporary cache of the widget position while these asynchronous operations
+// are in progress.
+IPC_MESSAGE_ROUTED0(WidgetMsg_SetBounds_ACK)
+
+// Informs the RenderWidget of its position on the user's screen, as well as
+// the position of the native window holding the RenderWidget.
+IPC_MESSAGE_ROUTED2(WidgetMsg_UpdateScreenRects,
+ gfx::Rect /* widget_screen_rect */,
+ gfx::Rect /* window_screen_rect */)
+
+// Sent by the browser to ask the renderer to redraw. Robust to events that can
+// happen in renderer (abortion of the commit or draw, loss of output surface
+// etc.).
+IPC_MESSAGE_ROUTED1(WidgetMsg_ForceRedraw, int /* snapshot_id */)
+
+// Sets the viewport intersection and compositor raster area on the widget for
+// an out-of-process iframe.
+IPC_MESSAGE_ROUTED3(WidgetMsg_SetViewportIntersection,
+ gfx::Rect /* viewport_intersection */,
+ gfx::Rect /* compositor_visible_rect */,
+ bool /* occluded or obscured */)
+
+// Sent to an OOPIF widget when the browser receives a FrameHostMsg_SetIsInert
+// from the target widget's embedding renderer changing its inertness. When a
+// widget is inert, it is unable to process input events.
+//
+// https://html.spec.whatwg.org/multipage/interaction.html#inert
+IPC_MESSAGE_ROUTED1(WidgetMsg_SetIsInert, bool /* inert */)
+
+// Sets the inherited effective touch action on an out-of-process iframe.
+IPC_MESSAGE_ROUTED1(WidgetMsg_SetInheritedEffectiveTouchAction, cc::TouchAction)
+
+// Toggles render throttling for an out-of-process iframe.
+IPC_MESSAGE_ROUTED2(WidgetMsg_UpdateRenderThrottlingStatus,
+ bool /* is_throttled */,
+ bool /* subtree_throttled */)
+
+// Sent by the browser to synchronize with the next compositor frame by
+// requesting an ACK be queued. Used only for tests.
+IPC_MESSAGE_ROUTED1(WidgetMsg_WaitForNextFrameForTests,
+ int /* main_frame_thread_observer_routing_id */)
+
+// Tells the render side that a WidgetHostMsg_LockMouse message has been
+// processed. |succeeded| indicates whether the mouse has been successfully
+// locked or not.
+IPC_MESSAGE_ROUTED1(WidgetMsg_LockMouse_ACK, bool /* succeeded */)
+// Tells the render side that the mouse has been unlocked.
+IPC_MESSAGE_ROUTED0(WidgetMsg_MouseLockLost)
+
+//
+// Renderer -> Browser Messages.
+//
+
+// Sent by the renderer process to request that the browser close the widget.
+// This corresponds to the window.close() API, and the browser may ignore
+// this message. Otherwise, the browser will generate a WidgetMsg_Close
+// message to close the widget.
+IPC_MESSAGE_ROUTED0(WidgetHostMsg_Close)
+
+// Notification that the selection bounds have changed.
+IPC_MESSAGE_ROUTED1(WidgetHostMsg_SelectionBoundsChanged,
+ WidgetHostMsg_SelectionBounds_Params)
+
+// Sent in response to a WidgetMsg_UpdateScreenRects so that the renderer can
+// throttle these messages.
+IPC_MESSAGE_ROUTED0(WidgetHostMsg_UpdateScreenRects_ACK)
+
+// Only used for SVGs inside of <object> and not for iframes. Informs the
+// browser that hte current frame's intrinsic sizing info has changed. The
+// browser can then notify a containing frame that the frame may need to
+// trigger a new layout.
+//
+// Also see FrameMsg_IntrinsicSizingInfoOfChildChanged.
+IPC_MESSAGE_ROUTED1(WidgetHostMsg_IntrinsicSizingInfoChanged,
+ blink::WebIntrinsicSizingInfo)
+
+// Send the tooltip text for the current mouse position to the browser.
+IPC_MESSAGE_ROUTED2(WidgetHostMsg_SetTooltipText,
+ base::string16 /* tooltip text string */,
+ blink::WebTextDirection /* text direction hint */)
+
+// Updates the current cursor to be used by the browser for indicating the
+// location of a pointing device.
+IPC_MESSAGE_ROUTED1(WidgetHostMsg_SetCursor, content::WebCursor)
+
+// Request a non-decelerating synthetic fling animation to be latched on the
+// scroller at the start point, and whose velocity can be changed over time by
+// sending multiple AutoscrollFling gestures. Used for features like
+// middle-click autoscroll.
+IPC_MESSAGE_ROUTED1(WidgetHostMsg_AutoscrollStart, gfx::PointF /* start */)
+IPC_MESSAGE_ROUTED1(WidgetHostMsg_AutoscrollFling,
+ gfx::Vector2dF /* velocity */)
+IPC_MESSAGE_ROUTED0(WidgetHostMsg_AutoscrollEnd)
+
+// Notifies the browser if the text input state has changed. Primarily useful
+// for IME as they need to know of all changes to update their interpretation
+// of the characters that have been input.
+IPC_MESSAGE_ROUTED1(WidgetHostMsg_TextInputStateChanged,
+ content::TextInputState /* text_input_state */)
+
+// Sent by the renderer process to request that the browser change the bounds of
+// the widget. This corresponds to the window.resizeTo() and window.moveTo()
+// APIs, and the browser may ignore this message.
+IPC_MESSAGE_ROUTED1(WidgetHostMsg_RequestSetBounds, gfx::Rect /* bounds */)
+
+// Requests to lock the mouse. Will result in a WidgetMsg_LockMouse_ACK message
+// being sent back.
+// |privileged| is used by Pepper Flash. If this flag is set to true, we won't
+// pop up a bubble to ask for user permission or take mouse lock content into
+// account.
+IPC_MESSAGE_ROUTED2(WidgetHostMsg_LockMouse,
+ bool /* user_gesture */,
+ bool /* privileged */)
+
+// Requests to unlock the mouse. A WidgetMsg_MouseLockLost message will be sent
+// whenever the mouse is unlocked (which may or may not be caused by
+// WidgetHostMsg_UnlockMouse).
+IPC_MESSAGE_ROUTED0(WidgetHostMsg_UnlockMouse)
+
+// Message sent from renderer to the browser when the element that is focused
+// has been touched. A bool is passed in this message which indicates if the
+// node is editable.
+IPC_MESSAGE_ROUTED1(WidgetHostMsg_FocusedNodeTouched, bool /* editable */)
+
+// Sent by the renderer process in response to an earlier WidgetMsg_ForceRedraw
+// message. The reply includes the snapshot-id from the request.
+IPC_MESSAGE_ROUTED1(WidgetHostMsg_ForceRedrawComplete, int /* snapshot_id */)
+
+// Sends a set of queued messages that were being held until the next
+// CompositorFrame is being submitted from the renderer. These messages are
+// sent before the OnRenderFrameMetadataChanged message is sent (via mojo) and
+// before the CompositorFrame is sent to the viz service. The |frame_token|
+// will match the token in the about-to-be-submitted CompositorFrame.
+IPC_MESSAGE_ROUTED2(WidgetHostMsg_FrameSwapMessages,
+ uint32_t /* frame_token */,
+ std::vector<IPC::Message> /* messages */)
+
+// Indicates that the render widget has been closed in response to a
+// Close message.
+IPC_MESSAGE_CONTROL1(WidgetHostMsg_Close_ACK, int /* old_route_id */)
+
+// Sent in reply to WidgetMsg_WaitForNextFrameForTests.
+IPC_MESSAGE_ROUTED0(WidgetHostMsg_WaitForNextFrameForTests_ACK)
+
+#endif // CONTENT_COMMON_WIDGET_MESSAGES_H_
diff --git a/chromium/content/content_resources.grd b/chromium/content/content_resources.grd
index b178e346317..65784754c3d 100644
--- a/chromium/content/content_resources.grd
+++ b/chromium/content/content_resources.grd
@@ -38,10 +38,12 @@
<include name="IDR_NETWORK_ERROR_LISTING_CSS" file="browser/resources/net/network_errors_listing.css" flattenhtml="true" type="BINDATA" />
<include name="IDR_PROCESS_INTERNALS_HTML" file="browser/resources/process/process_internals.html" flattenhtml="true" allowexternalscript="true" compress="gzip" type="BINDATA" />
<include name="IDR_PROCESS_INTERNALS_MOJO_JS" file="${root_gen_dir}/content/browser/process_internals/process_internals.mojom.js" use_base_dir="false" type="BINDATA" compress="gzip" />
+ <include name="IDR_PROCESS_INTERNALS_CSS" file="browser/resources/process/process_internals.css" flattenhtml="true" compress="gzip" type="BINDATA" />
<include name="IDR_PROCESS_INTERNALS_JS" file="browser/resources/process/process_internals.js" flattenhtml="true" compress="gzip" type="BINDATA" />
<include name="IDR_SERVICE_WORKER_INTERNALS_HTML" file="browser/resources/service_worker/serviceworker_internals.html" flattenhtml="true" allowexternalscript="true" compress="gzip" type="BINDATA" />
<include name="IDR_SERVICE_WORKER_INTERNALS_JS" file="browser/resources/service_worker/serviceworker_internals.js" flattenhtml="true" compress="gzip" type="BINDATA" />
<include name="IDR_SERVICE_WORKER_INTERNALS_CSS" file="browser/resources/service_worker/serviceworker_internals.css" flattenhtml="true" compress="gzip" type="BINDATA" />
+ <include name="IDR_URL_MOJO_JS" file="${root_gen_dir}/url/mojom/url.mojom.js" use_base_dir="false" type="BINDATA" compress="gzip" />
<include name="IDR_WEBRTC_INTERNALS_HTML" file="browser/resources/media/webrtc_internals.html" flattenhtml="true" allowexternalscript="true" compress="gzip" type="BINDATA" />
<include name="IDR_WEBRTC_INTERNALS_JS" file="browser/resources/media/webrtc_internals.js" flattenhtml="true" compress="gzip" type="BINDATA" />
</includes>
diff --git a/chromium/content/gpu/gpu_child_thread.cc b/chromium/content/gpu/gpu_child_thread.cc
index fdcef72b1c6..66a559d42e7 100644
--- a/chromium/content/gpu/gpu_child_thread.cc
+++ b/chromium/content/gpu/gpu_child_thread.cc
@@ -157,27 +157,33 @@ viz::VizMainImpl::ExternalDependencies CreateVizMainDependencies(
} // namespace
-GpuChildThread::GpuChildThread(std::unique_ptr<gpu::GpuInit> gpu_init,
+GpuChildThread::GpuChildThread(base::RepeatingClosure quit_closure,
+ std::unique_ptr<gpu::GpuInit> gpu_init,
viz::VizMainImpl::LogMessages log_messages)
- : GpuChildThread(GetOptions(), std::move(gpu_init)) {
+ : GpuChildThread(std::move(quit_closure),
+ GetOptions(),
+ std::move(gpu_init)) {
viz_main_.SetLogMessagesForHost(std::move(log_messages));
}
GpuChildThread::GpuChildThread(const InProcessChildThreadParams& params,
std::unique_ptr<gpu::GpuInit> gpu_init)
- : GpuChildThread(ChildThreadImpl::Options::Builder()
+ : GpuChildThread(base::DoNothing(),
+ ChildThreadImpl::Options::Builder()
.InBrowserProcess(params)
.AutoStartServiceManagerConnection(false)
.ConnectToBrowser(true)
.Build(),
std::move(gpu_init)) {}
-GpuChildThread::GpuChildThread(const ChildThreadImpl::Options& options,
+GpuChildThread::GpuChildThread(base::RepeatingClosure quit_closure,
+ const ChildThreadImpl::Options& options,
std::unique_ptr<gpu::GpuInit> gpu_init)
- : ChildThreadImpl(options),
+ : ChildThreadImpl(MakeQuitSafelyClosure(), options),
viz_main_(this,
CreateVizMainDependencies(GetConnector()),
std::move(gpu_init)),
+ quit_closure_(std::move(quit_closure)),
weak_factory_(this) {
if (in_process_gpu()) {
DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -272,6 +278,7 @@ void GpuChildThread::OnGpuServiceConnection(viz::GpuServiceImpl* gpu_service) {
service_factory_.reset(new GpuServiceFactory(
gpu_service->gpu_preferences(),
gpu_service->gpu_channel_manager()->gpu_driver_bug_workarounds(),
+ gpu_service->gpu_feature_info(),
gpu_service->media_gpu_channel_manager()->AsWeakPtr(),
std::move(overlay_factory_cb)));
@@ -290,6 +297,10 @@ void GpuChildThread::PostCompositorThreadCreated(
gpu_client->PostCompositorThreadCreated(task_runner);
}
+void GpuChildThread::QuitMainMessageLoop() {
+ quit_closure_.Run();
+}
+
void GpuChildThread::BindServiceFactoryRequest(
service_manager::mojom::ServiceFactoryRequest request) {
DVLOG(1) << "GPU: Binding service_manager::mojom::ServiceFactoryRequest";
@@ -315,6 +326,28 @@ void GpuChildThread::OnPurgeMemory() {
SkGraphics::PurgeAllCaches();
}
+void GpuChildThread::QuitSafelyHelper(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ // Post a new task (even if we're called on the |task_runner|'s thread) to
+ // ensure that we are post-init.
+ task_runner->PostTask(
+ FROM_HERE, base::BindOnce([]() {
+ ChildThreadImpl* current_child_thread = ChildThreadImpl::current();
+ if (!current_child_thread)
+ return;
+ GpuChildThread* gpu_child_thread =
+ static_cast<GpuChildThread*>(current_child_thread);
+ gpu_child_thread->viz_main_.ExitProcess();
+ }));
+}
+
+// Returns a closure which calls into the VizMainImpl to perform shutdown
+// before quitting the main message loop. Must be called on the main thread.
+base::RepeatingClosure GpuChildThread::MakeQuitSafelyClosure() {
+ return base::BindRepeating(&GpuChildThread::QuitSafelyHelper,
+ base::ThreadTaskRunnerHandle::Get());
+}
+
#if defined(OS_ANDROID)
// static
std::unique_ptr<media::AndroidOverlay> GpuChildThread::CreateAndroidOverlay(
diff --git a/chromium/content/gpu/gpu_child_thread.h b/chromium/content/gpu/gpu_child_thread.h
index e3b0094a48c..74560c109cd 100644
--- a/chromium/content/gpu/gpu_child_thread.h
+++ b/chromium/content/gpu/gpu_child_thread.h
@@ -50,7 +50,8 @@ class GpuChildThread : public ChildThreadImpl,
public viz::VizMainImpl::Delegate,
public base::MemoryCoordinatorClient {
public:
- GpuChildThread(std::unique_ptr<gpu::GpuInit> gpu_init,
+ GpuChildThread(base::RepeatingClosure quit_closure,
+ std::unique_ptr<gpu::GpuInit> gpu_init,
viz::VizMainImpl::LogMessages deferred_messages);
GpuChildThread(const InProcessChildThreadParams& params,
@@ -61,7 +62,8 @@ class GpuChildThread : public ChildThreadImpl,
void Init(const base::Time& process_start_time);
private:
- GpuChildThread(const ChildThreadImpl::Options& options,
+ GpuChildThread(base::RepeatingClosure quit_closure,
+ const ChildThreadImpl::Options& options,
std::unique_ptr<gpu::GpuInit> gpu_init);
void CreateVizMainService(viz::mojom::VizMainAssociatedRequest request);
@@ -81,6 +83,7 @@ class GpuChildThread : public ChildThreadImpl,
void OnGpuServiceConnection(viz::GpuServiceImpl* gpu_service) override;
void PostCompositorThreadCreated(
base::SingleThreadTaskRunner* task_runner) override;
+ void QuitMainMessageLoop() override;
// ChildMemoryCoordinatorDelegate implementation.
void OnTrimMemoryImmediately() override;
@@ -92,6 +95,12 @@ class GpuChildThread : public ChildThreadImpl,
void BindServiceFactoryRequest(
service_manager::mojom::ServiceFactoryRequest request);
+ // Returns a closure which calls into the VizMainImpl to perform shutdown
+ // before quitting the main message loop. Must be called on the main thread.
+ static base::RepeatingClosure MakeQuitSafelyClosure();
+ static void QuitSafelyHelper(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
#if defined(OS_ANDROID)
static std::unique_ptr<media::AndroidOverlay> CreateAndroidOverlay(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
@@ -113,6 +122,9 @@ class GpuChildThread : public ChildThreadImpl,
// Holds a closure that releases pending interface requests on the IO thread.
base::Closure release_pending_requests_closure_;
+ // A closure which quits the main message loop.
+ base::RepeatingClosure quit_closure_;
+
std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
base::WeakPtrFactory<GpuChildThread> weak_factory_;
diff --git a/chromium/content/gpu/gpu_main.cc b/chromium/content/gpu/gpu_main.cc
index f589d015d71..8397889b61e 100644
--- a/chromium/content/gpu/gpu_main.cc
+++ b/chromium/content/gpu/gpu_main.cc
@@ -20,6 +20,7 @@
#include "base/timer/hi_res_timer_manager.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "components/tracing/common/tracing_sampler_profiler.h"
#include "components/viz/service/main/viz_main_impl.h"
#include "content/common/content_constants_internal.h"
#include "content/common/content_switches_internal.h"
@@ -326,14 +327,22 @@ int GpuMain(const MainFunctionParams& parameters) {
if (client)
client->PostIOThreadCreated(gpu_process.io_task_runner());
- GpuChildThread* child_thread = new GpuChildThread(
- std::move(gpu_init), std::move(deferred_messages.Get()));
+ base::RunLoop run_loop;
+ GpuChildThread* child_thread =
+ new GpuChildThread(run_loop.QuitClosure(), std::move(gpu_init),
+ std::move(deferred_messages.Get()));
deferred_messages.Get().clear();
child_thread->Init(start_time);
gpu_process.set_main_thread(child_thread);
+ // Setup tracing sampler profiler as early as possible.
+ auto tracing_sampler_profiler =
+ std::make_unique<tracing::TracingSamplerProfiler>(
+ base::PlatformThread::CurrentId());
+ tracing_sampler_profiler->OnMessageLoopStarted();
+
#if defined(OS_ANDROID)
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
tracing::GraphicsMemoryDumpProvider::GetInstance(), "AndroidGraphics",
@@ -344,7 +353,7 @@ int GpuMain(const MainFunctionParams& parameters) {
{
TRACE_EVENT0("gpu", "Run Message Loop");
- base::RunLoop().Run();
+ run_loop.Run();
}
return dead_on_arrival ? RESULT_CODE_GPU_DEAD_ON_ARRIVAL : 0;
diff --git a/chromium/content/gpu/gpu_sandbox_hook_linux.cc b/chromium/content/gpu/gpu_sandbox_hook_linux.cc
index 4806a3f33b7..f154e84b731 100644
--- a/chromium/content/gpu/gpu_sandbox_hook_linux.cc
+++ b/chromium/content/gpu/gpu_sandbox_hook_linux.cc
@@ -77,6 +77,24 @@ inline bool UseLibV4L2() {
#endif
}
+#if defined(OS_CHROMEOS) && defined(__aarch64__)
+static const char kLibGlesPath[] = "/usr/lib64/libGLESv2.so.2";
+static const char kLibEglPath[] = "/usr/lib64/libEGL.so.1";
+static const char kLibMaliPath[] = "/usr/lib64/libmali.so";
+static const char kLibTegraPath[] = "/usr/lib64/libtegrav4l2.so";
+static const char kLibV4l2Path[] = "/usr/lib64/libv4l2.so";
+static const char kLibV4lEncPluginPath[] =
+ "/usr/lib64/libv4l/plugins/libv4l-encplugin.so";
+#else
+static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
+static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";
+static const char kLibMaliPath[] = "/usr/lib/libmali.so";
+static const char kLibTegraPath[] = "/usr/lib/libtegrav4l2.so";
+static const char kLibV4l2Path[] = "/usr/lib/libv4l2.so";
+static const char kLibV4lEncPluginPath[] =
+ "/usr/lib/libv4l/plugins/libv4l-encplugin.so";
+#endif
+
constexpr int dlopen_flag = RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE;
void AddV4L2GpuWhitelist(
@@ -152,9 +170,6 @@ void AddArmGpuWhitelist(std::vector<BrokerFilePermission>* permissions) {
static const char kLdSoCache[] = "/etc/ld.so.cache";
// Files needed by the ARM GPU userspace.
- static const char kLibGlesPath[] = "/usr/lib/libGLESv2.so.2";
- static const char kLibEglPath[] = "/usr/lib/libEGL.so.1";
-
permissions->push_back(BrokerFilePermission::ReadOnly(kXAuthorityPath));
permissions->push_back(BrokerFilePermission::ReadOnly(kLdSoCache));
permissions->push_back(BrokerFilePermission::ReadOnly(kLibGlesPath));
@@ -237,9 +252,14 @@ std::vector<BrokerFilePermission> FilePermissionsForGpu(
}
}
- if (UseChromecastSandboxWhitelist() && IsArchitectureArm()) {
- AddChromecastArmGpuWhitelist(&permissions);
- return permissions;
+ if (UseChromecastSandboxWhitelist()) {
+ if (UseV4L2Codec())
+ AddV4L2GpuWhitelist(&permissions, options);
+
+ if (IsArchitectureArm()) {
+ AddChromecastArmGpuWhitelist(&permissions);
+ return permissions;
+ }
}
AddStandardGpuWhiteList(&permissions);
@@ -256,10 +276,10 @@ void LoadArmGpuLibraries() {
break;
}
} else {
- dlopen("/usr/lib/libmali.so", dlopen_flag);
+ dlopen(kLibMaliPath, dlopen_flag);
// Preload the Tegra V4L2 (video decode acceleration) library.
- dlopen("/usr/lib/libtegrav4l2.so", dlopen_flag);
+ dlopen(kLibTegraPath, dlopen_flag);
}
}
@@ -290,11 +310,11 @@ bool IsAcceleratedVideoEnabled(
void LoadV4L2Libraries(
const service_manager::SandboxSeccompBPF::Options& options) {
if (IsAcceleratedVideoEnabled(options) && UseLibV4L2()) {
- dlopen("/usr/lib/libv4l2.so", dlopen_flag);
+ dlopen(kLibV4l2Path, dlopen_flag);
if (options.accelerated_video_encode_enabled) {
// This is a device-specific encoder plugin.
- dlopen("/usr/lib/libv4l/plugins/libv4l-encplugin.so", dlopen_flag);
+ dlopen(kLibV4lEncPluginPath, dlopen_flag);
}
}
}
diff --git a/chromium/content/gpu/gpu_service_factory.cc b/chromium/content/gpu/gpu_service_factory.cc
index 1f90da0f591..c1b474f5914 100644
--- a/chromium/content/gpu/gpu_service_factory.cc
+++ b/chromium/content/gpu/gpu_service_factory.cc
@@ -25,11 +25,13 @@ namespace content {
GpuServiceFactory::GpuServiceFactory(
const gpu::GpuPreferences& gpu_preferences,
const gpu::GpuDriverBugWorkarounds& gpu_workarounds,
+ const gpu::GpuFeatureInfo& gpu_feature_info,
base::WeakPtr<media::MediaGpuChannelManager> media_gpu_channel_manager,
media::AndroidOverlayMojoFactoryCB android_overlay_factory_cb) {
#if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
gpu_preferences_ = gpu_preferences;
gpu_workarounds_ = gpu_workarounds;
+ gpu_feature_info_ = gpu_feature_info;
task_runner_ = base::ThreadTaskRunnerHandle::Get();
media_gpu_channel_manager_ = std::move(media_gpu_channel_manager);
android_overlay_factory_cb_ = std::move(android_overlay_factory_cb);
@@ -50,8 +52,8 @@ void GpuServiceFactory::RegisterServices(ServiceMap* services) {
service_manager::EmbeddedServiceInfo info;
info.factory = base::BindRepeating(
&media::CreateGpuMediaService, gpu_preferences_, gpu_workarounds_,
- task_runner_, media_gpu_channel_manager_, android_overlay_factory_cb_,
- std::move(cdm_proxy_factory_cb));
+ gpu_feature_info_, task_runner_, media_gpu_channel_manager_,
+ android_overlay_factory_cb_, std::move(cdm_proxy_factory_cb));
// This service will host audio/video decoders, and if these decoding
// operations are blocked, user may hear audio glitch or see video freezing,
// hence "user blocking".
diff --git a/chromium/content/gpu/gpu_service_factory.h b/chromium/content/gpu/gpu_service_factory.h
index 1316a948e2d..a639f340b43 100644
--- a/chromium/content/gpu/gpu_service_factory.h
+++ b/chromium/content/gpu/gpu_service_factory.h
@@ -11,6 +11,7 @@
#include "base/single_thread_task_runner.h"
#include "content/child/service_factory.h"
#include "gpu/config/gpu_driver_bug_workarounds.h"
+#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_preferences.h"
#include "media/base/android_overlay_mojo_factory.h"
#include "media/mojo/buildflags.h"
@@ -27,6 +28,7 @@ class GpuServiceFactory : public ServiceFactory {
GpuServiceFactory(
const gpu::GpuPreferences& gpu_preferences,
const gpu::GpuDriverBugWorkarounds& gpu_workarounds,
+ const gpu::GpuFeatureInfo& gpu_feature_info,
base::WeakPtr<media::MediaGpuChannelManager> media_gpu_channel_manager,
media::AndroidOverlayMojoFactoryCB android_overlay_factory_cb);
~GpuServiceFactory() override;
@@ -45,6 +47,7 @@ class GpuServiceFactory : public ServiceFactory {
media::AndroidOverlayMojoFactoryCB android_overlay_factory_cb_;
gpu::GpuPreferences gpu_preferences_;
gpu::GpuDriverBugWorkarounds gpu_workarounds_;
+ gpu::GpuFeatureInfo gpu_feature_info_;
#endif
DISALLOW_COPY_AND_ASSIGN(GpuServiceFactory);
diff --git a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc
index c88de7f36b3..74cc14d65e9 100644
--- a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc
+++ b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc
@@ -22,7 +22,7 @@
#include "third_party/blink/public/platform/mac/web_sandbox_support.h"
#elif defined(OS_POSIX) && !defined(OS_ANDROID)
#include "content/child/child_process_sandbox_support_impl_linux.h"
-#include "third_party/blink/public/platform/linux/web_fallback_font.h"
+#include "third_party/blink/public/platform/linux/out_of_process_font.h"
#include "third_party/blink/public/platform/linux/web_sandbox_support.h"
#include "third_party/icu/source/common/unicode/utf16.h"
#endif
@@ -53,7 +53,10 @@ class PpapiBlinkPlatformImpl::SandboxSupport : public WebSandboxSupport {
void GetFallbackFontForCharacter(
WebUChar32 character,
const char* preferred_locale,
- blink::WebFallbackFont* fallbackFont) override;
+ blink::OutOfProcessFont* fallbackFont) override;
+ void MatchFontByPostscriptNameOrFullFontName(
+ const char* font_unique_name,
+ blink::OutOfProcessFont* fallback_font) override;
void GetWebFontRenderStyleForStrike(const char* family,
int size,
bool is_bold,
@@ -65,7 +68,7 @@ class PpapiBlinkPlatformImpl::SandboxSupport : public WebSandboxSupport {
// WebKit likes to ask us for the correct font family to use for a set of
// unicode code points. It needs this information frequently so we cache it
// here.
- std::map<int32_t, blink::WebFallbackFont> unicode_font_families_;
+ std::map<int32_t, blink::OutOfProcessFont> unicode_font_families_;
sk_sp<font_service::FontLoader> font_loader_;
// For debugging https://crbug.com/312965
base::SequenceCheckerImpl creation_thread_sequence_checker_;
@@ -91,11 +94,11 @@ PpapiBlinkPlatformImpl::SandboxSupport::SandboxSupport() {}
void PpapiBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter(
WebUChar32 character,
const char* preferred_locale,
- blink::WebFallbackFont* fallbackFont) {
+ blink::OutOfProcessFont* fallbackFont) {
ppapi::ProxyLock::AssertAcquired();
// For debugging crbug.com/312965
CHECK(creation_thread_sequence_checker_.CalledOnValidSequence());
- const std::map<int32_t, blink::WebFallbackFont>::const_iterator iter =
+ const std::map<int32_t, blink::OutOfProcessFont>::const_iterator iter =
unicode_font_families_.find(character);
if (iter != unicode_font_families_.end()) {
fallbackFont->name = iter->second.name;
@@ -124,6 +127,14 @@ void PpapiBlinkPlatformImpl::SandboxSupport::GetWebFontRenderStyleForStrike(
device_scale_factor, out);
}
+void PpapiBlinkPlatformImpl::SandboxSupport::
+ MatchFontByPostscriptNameOrFullFontName(
+ const char* font_unique_name,
+ blink::OutOfProcessFont* uniquely_matched_font) {
+ content::MatchFontByPostscriptNameOrFullFontName(
+ font_loader_, font_unique_name, uniquely_matched_font);
+}
+
#endif
#endif // !defined(OS_ANDROID) && !defined(OS_WIN)
@@ -145,7 +156,7 @@ PpapiBlinkPlatformImpl::~PpapiBlinkPlatformImpl() {
void PpapiBlinkPlatformImpl::Shutdown() {
#if !defined(OS_ANDROID) && !defined(OS_WIN)
- // SandboxSupport contains a map of WebFallbackFont objects, which hold
+ // SandboxSupport contains a map of OutOfProcessFont objects, which hold
// WebStrings and WebVectors, which become invalidated when blink is shut
// down. Hence, we need to clear that map now, just before blink::shutdown()
// is called.
@@ -153,10 +164,6 @@ void PpapiBlinkPlatformImpl::Shutdown() {
#endif
}
-blink::WebThread* PpapiBlinkPlatformImpl::CurrentThread() {
- return BlinkPlatformImpl::CurrentThread();
-}
-
blink::WebSandboxSupport* PpapiBlinkPlatformImpl::GetSandboxSupport() {
#if !defined(OS_ANDROID) && !defined(OS_WIN)
return sandbox_support_.get();
@@ -165,10 +172,6 @@ blink::WebSandboxSupport* PpapiBlinkPlatformImpl::GetSandboxSupport() {
#endif
}
-bool PpapiBlinkPlatformImpl::sandboxEnabled() {
- return true; // Assume PPAPI is always sandboxed.
-}
-
unsigned long long PpapiBlinkPlatformImpl::VisitedLinkHash(
const char* canonical_url,
size_t length) {
diff --git a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h
index 6e96a9571a7..279b8835401 100644
--- a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h
+++ b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h
@@ -29,9 +29,7 @@ class PpapiBlinkPlatformImpl : public BlinkPlatformImpl {
void Shutdown();
// BlinkPlatformImpl methods:
- blink::WebThread* CurrentThread() override;
blink::WebSandboxSupport* GetSandboxSupport() override;
- virtual bool sandboxEnabled();
unsigned long long VisitedLinkHash(const char* canonical_url,
size_t length) override;
bool IsLinkVisited(unsigned long long link_hash) override;
diff --git a/chromium/content/ppapi_plugin/ppapi_broker_main.cc b/chromium/content/ppapi_plugin/ppapi_broker_main.cc
index 176183f686f..54abb280940 100644
--- a/chromium/content/ppapi_plugin/ppapi_broker_main.cc
+++ b/chromium/content/ppapi_plugin/ppapi_broker_main.cc
@@ -29,10 +29,11 @@ int PpapiBrokerMain(const MainFunctionParams& parameters) {
kTraceEventPpapiBrokerProcessSortIndex);
ChildProcess ppapi_broker_process;
- ppapi_broker_process.set_main_thread(
- new PpapiThread(parameters.command_line, true)); // Broker.
+ base::RunLoop run_loop;
+ ppapi_broker_process.set_main_thread(new PpapiThread(
+ run_loop.QuitClosure(), parameters.command_line, true /* Broker */));
- base::RunLoop().Run();
+ run_loop.Run();
DVLOG(1) << "PpapiBrokerMain exiting";
return 0;
}
diff --git a/chromium/content/ppapi_plugin/ppapi_plugin_main.cc b/chromium/content/ppapi_plugin/ppapi_plugin_main.cc
index 0051d878b32..6326ea3deef 100644
--- a/chromium/content/ppapi_plugin/ppapi_plugin_main.cc
+++ b/chromium/content/ppapi_plugin/ppapi_plugin_main.cc
@@ -129,8 +129,10 @@ int PpapiPluginMain(const MainFunctionParams& parameters) {
#endif
ChildProcess ppapi_process;
- ppapi_process.set_main_thread(
- new PpapiThread(parameters.command_line, false)); // Not a broker.
+ base::RunLoop run_loop;
+ ppapi_process.set_main_thread(new PpapiThread(run_loop.QuitClosure(),
+ parameters.command_line,
+ false /* Not a broker */));
#if defined(OS_WIN)
if (!base::win::IsUser32AndGdi32Available())
@@ -152,7 +154,7 @@ int PpapiPluginMain(const MainFunctionParams& parameters) {
subpixel_rendering != gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE);
#endif
- base::RunLoop().Run();
+ run_loop.Run();
#if defined(OS_WIN)
UninitializeDWriteFontProxy();
diff --git a/chromium/content/ppapi_plugin/ppapi_thread.cc b/chromium/content/ppapi_plugin/ppapi_thread.cc
index 7e496c5710d..ceb3838e3b8 100644
--- a/chromium/content/ppapi_plugin/ppapi_thread.cc
+++ b/chromium/content/ppapi_plugin/ppapi_thread.cc
@@ -94,8 +94,11 @@ namespace content {
typedef int32_t (*InitializeBrokerFunc)
(PP_ConnectInstance_Func* connect_instance_func);
-PpapiThread::PpapiThread(const base::CommandLine& command_line, bool is_broker)
- : is_broker_(is_broker),
+PpapiThread::PpapiThread(base::RepeatingClosure quit_closure,
+ const base::CommandLine& command_line,
+ bool is_broker)
+ : ChildThreadImpl(std::move(quit_closure)),
+ is_broker_(is_broker),
plugin_globals_(GetIOTaskRunner()),
connect_instance_func_(nullptr),
local_pp_module_(base::RandInt(0, std::numeric_limits<PP_Module>::max())),
@@ -105,8 +108,7 @@ PpapiThread::PpapiThread(const base::CommandLine& command_line, bool is_broker)
command_line.GetSwitchValueASCII(switches::kPpapiFlashArgs));
blink_platform_impl_.reset(new PpapiBlinkPlatformImpl);
- blink::Platform::Initialize(blink_platform_impl_.get(),
- blink_platform_impl_->CurrentThread());
+ blink::Platform::CreateMainThreadAndInitialize(blink_platform_impl_.get());
if (!is_broker_) {
scoped_refptr<ppapi::proxy::PluginMessageFilter> plugin_filter(
@@ -120,7 +122,7 @@ PpapiThread::PpapiThread(const base::CommandLine& command_line, bool is_broker)
// allocator.
if (!command_line.HasSwitch(switches::kSingleProcess)) {
discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr;
- if (features::IsUsingWindowService()) {
+ if (features::IsMultiProcessMash()) {
#if defined(USE_AURA)
GetServiceManagerConnection()->GetConnector()->BindInterface(
ws::mojom::kServiceName, &manager_ptr);
diff --git a/chromium/content/ppapi_plugin/ppapi_thread.h b/chromium/content/ppapi_plugin/ppapi_thread.h
index b54f4702ab0..b8e25260440 100644
--- a/chromium/content/ppapi_plugin/ppapi_thread.h
+++ b/chromium/content/ppapi_plugin/ppapi_thread.h
@@ -56,7 +56,9 @@ class PpapiThread : public ChildThreadImpl,
public ppapi::proxy::PluginDispatcher::PluginDelegate,
public ppapi::proxy::PluginProxyDelegate {
public:
- PpapiThread(const base::CommandLine& command_line, bool is_broker);
+ PpapiThread(base::RepeatingClosure quit_closure,
+ const base::CommandLine& command_line,
+ bool is_broker);
~PpapiThread() override;
void Shutdown() override;
diff --git a/chromium/content/public/android/BUILD.gn b/chromium/content/public/android/BUILD.gn
index 8135b931c14..86fb816c799 100644
--- a/chromium/content/public/android/BUILD.gn
+++ b/chromium/content/public/android/BUILD.gn
@@ -73,7 +73,7 @@ android_library("content_java") {
"//services/service_manager/public/mojom:mojom_java",
"//services/shape_detection:shape_detection_java",
"//services/shape_detection/public/mojom:mojom_java",
- "//third_party/android_tools:android_support_annotations_java",
+ "//third_party/android_deps:android_support_annotations_java",
"//third_party/blink/public:android_mojo_bindings_java",
"//third_party/blink/public:blink_headers_java",
"//third_party/blink/public/mojom:mojom_core_java",
@@ -104,7 +104,6 @@ android_library("content_java") {
"java/src/org/chromium/content/app/PrivilegedProcessService1.java",
"java/src/org/chromium/content/app/PrivilegedProcessService2.java",
"java/src/org/chromium/content/app/SandboxedProcessService.java",
- "java/src/org/chromium/content/browser/ApiHelperForM.java",
"java/src/org/chromium/content/browser/AppWebMessagePort.java",
"java/src/org/chromium/content/browser/AudioFocusDelegate.java",
"java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java",
@@ -113,6 +112,7 @@ android_library("content_java") {
"java/src/org/chromium/content/browser/ChildProcessCreationParamsImpl.java",
"java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java",
"java/src/org/chromium/content/browser/ChildProcessRanking.java",
+ "java/src/org/chromium/content/browser/ContentApiHelperForM.java",
"java/src/org/chromium/content/browser/ContentChildProcessConstants.java",
"java/src/org/chromium/content/browser/ContentClassFactory.java",
"java/src/org/chromium/content/browser/ContentFeatureList.java",
@@ -219,7 +219,6 @@ android_library("content_java") {
"java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java",
"java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java",
"java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java",
- "java/src/org/chromium/content/browser/webcontents/WebContentsUserData.java",
"java/src/org/chromium/content/common/ContentSwitchUtils.java",
"java/src/org/chromium/content/common/ServiceManagerConnectionImpl.java",
"java/src/org/chromium/content/common/SurfaceWrapper.java",
@@ -436,9 +435,9 @@ android_library("content_javatests") {
"//services/device/public/java:geolocation_java_test_support",
"//services/service_manager/public/java:service_manager_java",
"//services/test/echo/public/mojom:mojom_java",
+ "//third_party/android_deps:android_support_annotations_java",
"//third_party/android_support_test_runner:rules_java",
"//third_party/android_support_test_runner:runner_java",
- "//third_party/android_tools:android_support_annotations_java",
"//third_party/jsr-305:jsr_305_javalib",
"//third_party/junit",
"//ui/android:ui_java",
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/BindingManagerTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/BindingManagerTest.java
new file mode 100644
index 00000000000..90574d52a4c
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/BindingManagerTest.java
@@ -0,0 +1,259 @@
+// 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.
+
+package org.chromium.content.browser;
+
+import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
+import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
+import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
+
+import android.app.Activity;
+import android.app.Application;
+import android.content.ComponentName;
+import android.util.Pair;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowLooper;
+
+import org.chromium.base.process_launcher.ChildProcessConnection;
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.TestChildProcessConnection;
+import org.chromium.base.test.util.Feature;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Unit tests for BindingManager and ChildProcessConnection.
+ *
+ * Default property of being low-end device is overriden, so that both low-end and high-end policies
+ * are tested.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class BindingManagerTest {
+ // Creates a mocked ChildProcessConnection that is optionally added to a BindingManager.
+ private static ChildProcessConnection createTestChildProcessConnection(
+ int pid, BindingManager manager, List<ChildProcessConnection> iterable) {
+ TestChildProcessConnection connection = new TestChildProcessConnection(
+ new ComponentName("org.chromium.test", "TestService"),
+ false /* bindToCallerCheck */, false /* bindAsExternalService */,
+ null /* serviceBundle */);
+ connection.setPid(pid);
+ connection.start(false /* useStrongBinding */, null /* serviceCallback */);
+ manager.addConnection(connection);
+ iterable.add(connection);
+ connection.removeModerateBinding(); // Remove initial binding.
+ return connection;
+ }
+
+ Activity mActivity;
+
+ // Created in setUp() for convenience.
+ BindingManager mManager;
+
+ List<ChildProcessConnection> mIterable;
+
+ @Before
+ public void setUp() {
+ // The tests run on only one thread. Pretend that is the launcher thread so LauncherThread
+ // asserts are not triggered.
+ LauncherThread.setCurrentThreadAsLauncherThread();
+ mActivity = Robolectric.buildActivity(Activity.class).setup().get();
+ mIterable = new ArrayList<>();
+ mManager = new BindingManager(mActivity, 4, mIterable, true);
+ }
+
+ @After
+ public void tearDown() {
+ LauncherThread.setLauncherThreadAsLauncherThread();
+ }
+
+ /**
+ * Verifies that onSentToBackground() drops all the moderate bindings after some delay, and
+ * onBroughtToForeground() doesn't recover them.
+ */
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testModerateBindingDropOnBackground() {
+ final BindingManager manager = mManager;
+
+ ChildProcessConnection[] connections = new ChildProcessConnection[3];
+ for (int i = 0; i < connections.length; i++) {
+ connections[i] = createTestChildProcessConnection(i + 1 /* pid */, manager, mIterable);
+ }
+
+ // Verify that each connection has a moderate binding after binding and releasing a strong
+ // binding.
+ for (ChildProcessConnection connection : connections) {
+ Assert.assertTrue(connection.isModerateBindingBound());
+ }
+
+ ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+
+ // Verify that leaving the application for a short time doesn't clear the moderate bindings.
+ manager.onSentToBackground();
+ for (ChildProcessConnection connection : connections) {
+ Assert.assertTrue(connection.isModerateBindingBound());
+ }
+ manager.onBroughtToForeground();
+ ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+ for (ChildProcessConnection connection : connections) {
+ Assert.assertTrue(connection.isModerateBindingBound());
+ }
+
+ // Call onSentToBackground() and verify that all the moderate bindings drop after some
+ // delay.
+ manager.onSentToBackground();
+ for (ChildProcessConnection connection : connections) {
+ Assert.assertTrue(connection.isModerateBindingBound());
+ }
+ ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+ for (ChildProcessConnection connection : connections) {
+ Assert.assertFalse(connection.isModerateBindingBound());
+ }
+
+ // Call onBroughtToForeground() and verify that the previous moderate bindings aren't
+ // recovered.
+ manager.onBroughtToForeground();
+ for (ChildProcessConnection connection : connections) {
+ Assert.assertFalse(connection.isModerateBindingBound());
+ }
+ }
+
+ /**
+ * Verifies that onLowMemory() drops all the moderate bindings.
+ */
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testModerateBindingDropOnLowMemory() {
+ final Application app = mActivity.getApplication();
+ final BindingManager manager = mManager;
+
+ ChildProcessConnection[] connections = new ChildProcessConnection[4];
+ for (int i = 0; i < connections.length; i++) {
+ connections[i] = createTestChildProcessConnection(i + 1 /* pid */, manager, mIterable);
+ }
+
+ for (ChildProcessConnection connection : connections) {
+ Assert.assertTrue(connection.isModerateBindingBound());
+ }
+
+ // Call onLowMemory() and verify that all the moderate bindings drop.
+ app.onLowMemory();
+ for (ChildProcessConnection connection : connections) {
+ Assert.assertFalse(connection.isModerateBindingBound());
+ }
+ }
+
+ /**
+ * Verifies that onTrimMemory() drops moderate bindings properly.
+ */
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testModerateBindingDropOnTrimMemory() {
+ final Application app = mActivity.getApplication();
+ // This test applies only to the moderate-binding manager.
+ final BindingManager manager = mManager;
+
+ ArrayList<Pair<Integer, Integer>> levelAndExpectedVictimCountList = new ArrayList<>();
+ levelAndExpectedVictimCountList.add(
+ new Pair<Integer, Integer>(TRIM_MEMORY_RUNNING_MODERATE, 1));
+ levelAndExpectedVictimCountList.add(new Pair<Integer, Integer>(TRIM_MEMORY_RUNNING_LOW, 2));
+ levelAndExpectedVictimCountList.add(
+ new Pair<Integer, Integer>(TRIM_MEMORY_RUNNING_CRITICAL, 4));
+
+ ChildProcessConnection[] connections = new ChildProcessConnection[4];
+ for (int i = 0; i < connections.length; i++) {
+ connections[i] = createTestChildProcessConnection(i + 1 /* pid */, manager, mIterable);
+ }
+
+ for (Pair<Integer, Integer> pair : levelAndExpectedVictimCountList) {
+ String message = "Failed for the level=" + pair.first;
+ mIterable.clear();
+ // Verify that each connection has a moderate binding after binding and releasing a
+ // strong binding.
+ for (ChildProcessConnection connection : connections) {
+ manager.addConnection(connection);
+ mIterable.add(connection);
+ Assert.assertTrue(message, connection.isModerateBindingBound());
+ }
+
+ app.onTrimMemory(pair.first);
+ // Verify that some of the moderate bindings have been dropped.
+ for (int i = 0; i < connections.length; i++) {
+ Assert.assertEquals(
+ message, i >= pair.second, connections[i].isModerateBindingBound());
+ }
+ }
+ }
+
+ /*
+ * Test that Chrome is sent to the background, that the initially added moderate bindings are
+ * removed and are not re-added when Chrome is brought back to the foreground.
+ */
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testModerateBindingTillBackgroundedSentToBackground() {
+ BindingManager manager = mManager;
+
+ ChildProcessConnection connection = createTestChildProcessConnection(0, manager, mIterable);
+ Assert.assertTrue(connection.isModerateBindingBound());
+
+ manager.onSentToBackground();
+ ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
+ Assert.assertFalse(connection.isModerateBindingBound());
+
+ // Bringing Chrome to the foreground should not re-add the moderate bindings.
+ manager.onBroughtToForeground();
+ Assert.assertFalse(connection.isModerateBindingBound());
+ }
+
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testOneWaivedConnection() {
+ final BindingManager manager = mManager;
+ ChildProcessConnection[] connections = new ChildProcessConnection[3];
+ for (int i = 0; i < connections.length; i++) {
+ connections[i] = createTestChildProcessConnection(i + 1 /* pid */, manager, mIterable);
+ }
+
+ // Make sure binding is added for all connections.
+ for (ChildProcessConnection c : connections) {
+ Assert.assertTrue(c.isModerateBindingBound());
+ }
+
+ // Move middle connection to be the first (ie lowest ranked).
+ mIterable.set(0, connections[1]);
+ mIterable.set(1, connections[0]);
+ manager.rankingChanged();
+ Assert.assertTrue(connections[0].isModerateBindingBound());
+ Assert.assertFalse(connections[1].isModerateBindingBound());
+ Assert.assertTrue(connections[2].isModerateBindingBound());
+
+ // Swap back.
+ mIterable.set(0, connections[0]);
+ mIterable.set(1, connections[1]);
+ manager.rankingChanged();
+ Assert.assertFalse(connections[0].isModerateBindingBound());
+ Assert.assertTrue(connections[1].isModerateBindingBound());
+ Assert.assertTrue(connections[2].isModerateBindingBound());
+
+ manager.removeConnection(connections[1]);
+ Assert.assertFalse(connections[0].isModerateBindingBound());
+ Assert.assertFalse(connections[1].isModerateBindingBound());
+ Assert.assertTrue(connections[2].isModerateBindingBound());
+
+ manager.removeConnection(connections[0]);
+ Assert.assertFalse(connections[0].isModerateBindingBound());
+ Assert.assertFalse(connections[1].isModerateBindingBound());
+ Assert.assertTrue(connections[2].isModerateBindingBound());
+ }
+}
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/ChildProcessRankingTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/ChildProcessRankingTest.java
new file mode 100644
index 00000000000..3044d4e47bb
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/ChildProcessRankingTest.java
@@ -0,0 +1,216 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import android.content.ComponentName;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.process_launcher.ChildProcessConnection;
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.TestChildProcessConnection;
+import org.chromium.content_public.browser.ChildProcessImportance;
+
+/** Unit tests for ChildProessRanking */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class ChildProcessRankingTest {
+ private ChildProcessConnection createConnection() {
+ return new TestChildProcessConnection(new ComponentName("pkg", "cls"),
+ false /* bindToCallerCheck */, false /* bindAsExternalService */,
+ null /* serviceBundle */);
+ }
+
+ private void assertRankingAndRemoveAll(
+ ChildProcessRanking ranking, ChildProcessConnection[] connections) {
+ int index = connections.length;
+ ChildProcessConnection reverseIterationArray[] =
+ new ChildProcessConnection[connections.length];
+ for (ChildProcessConnection c : ranking) {
+ reverseIterationArray[--index] = c;
+ }
+ Assert.assertArrayEquals(connections, reverseIterationArray);
+ Assert.assertEquals(0, index);
+
+ index = connections.length;
+ ChildProcessConnection reverseRemoveArray[] =
+ new ChildProcessConnection[connections.length];
+ for (int i = 0; i < connections.length; ++i) {
+ ChildProcessConnection c = ranking.getLowestRankedConnection();
+ reverseRemoveArray[--index] = c;
+ ranking.removeConnection(c);
+ }
+ Assert.assertArrayEquals(connections, reverseRemoveArray);
+ Assert.assertNull(ranking.getLowestRankedConnection());
+ }
+
+ @Test
+ public void testRanking() {
+ ChildProcessConnection c1 = createConnection();
+ ChildProcessConnection c2 = createConnection();
+ ChildProcessConnection c3 = createConnection();
+ ChildProcessConnection c4 = createConnection();
+ ChildProcessConnection c5 = createConnection();
+ ChildProcessConnection c6 = createConnection();
+ ChildProcessConnection c7 = createConnection();
+ ChildProcessConnection c8 = createConnection();
+ ChildProcessConnection c9 = createConnection();
+ ChildProcessConnection c10 = createConnection();
+
+ ChildProcessRanking ranking = new ChildProcessRanking(10);
+
+ // Insert in lowest ranked to highest ranked order.
+
+ // Invisible subframe outside of viewport.
+ ranking.addConnection(c1, false /* foreground */, 2 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c2, false /* foreground */, 1 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ // Invisible subframe inside viewport.
+ ranking.addConnection(c3, false /* foreground */, 2 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c4, false /* foreground */, 1 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ // Visible subframe outside viewport.
+ ranking.addConnection(c5, true /* foreground */, 2 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c6, true /* foreground */, 1 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ // Invisible main frame.
+ ranking.addConnection(c7, false /* foreground */, 0 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ // Visible subframe inside viewport.
+ ranking.addConnection(c8, true /* foreground */, 2 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c9, true /* foreground */, 1 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ // Visible main frame.
+ ranking.addConnection(c10, true /* foreground */, 0 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ assertRankingAndRemoveAll(
+ ranking, new ChildProcessConnection[] {c10, c9, c8, c7, c6, c5, c4, c3, c2, c1});
+ }
+
+ @Test
+ public void testRankingWithImportance() {
+ ChildProcessConnection c1 = createConnection();
+ ChildProcessConnection c2 = createConnection();
+ ChildProcessConnection c3 = createConnection();
+ ChildProcessConnection c4 = createConnection();
+
+ ChildProcessRanking ranking = new ChildProcessRanking(4);
+
+ // Insert in lowest ranked to highest ranked order.
+ ranking.addConnection(c1, false /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c2, false /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.MODERATE);
+ ranking.addConnection(c3, false /* foreground */, 1 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.IMPORTANT);
+ ranking.addConnection(c4, false /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.IMPORTANT);
+
+ assertRankingAndRemoveAll(ranking, new ChildProcessConnection[] {c4, c3, c2, c1});
+ }
+
+ @Test
+ public void testUpdate() {
+ ChildProcessConnection c1 = createConnection();
+ ChildProcessConnection c2 = createConnection();
+ ChildProcessConnection c3 = createConnection();
+ ChildProcessConnection c4 = createConnection();
+
+ ChildProcessRanking ranking = new ChildProcessRanking(4);
+
+ // c1,2 are in one tab, and c3,4 are in second tab.
+ ranking.addConnection(c1, true /* foreground */, 1 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c2, true /* foreground */, 0 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c3, false /* foreground */, 1 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c4, false /* foreground */, 0 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ Assert.assertEquals(c3, ranking.getLowestRankedConnection());
+
+ // Switch from tab c1,2 to tab c3,c4.
+ ranking.updateConnection(c1, false /* foreground */, 1 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.updateConnection(c2, false /* foreground */, 0 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.updateConnection(c3, true /* foreground */, 1 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.updateConnection(c4, true /* foreground */, 0 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ assertRankingAndRemoveAll(ranking, new ChildProcessConnection[] {c4, c3, c2, c1});
+ }
+
+ @Test
+ public void testStability() {
+ ChildProcessConnection c1 = createConnection();
+ ChildProcessConnection c2 = createConnection();
+ ChildProcessConnection c3 = createConnection();
+ ChildProcessConnection c4 = createConnection();
+
+ ChildProcessRanking ranking = new ChildProcessRanking(4);
+
+ // Each connection is its own tab.
+ ranking.addConnection(c1, true /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c2, false /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c3, false /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c4, false /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ // Tab through each connection.
+ ranking.updateConnection(c2, true /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.updateConnection(c1, false /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ ranking.updateConnection(c3, true /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.updateConnection(c2, false /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ ranking.updateConnection(c4, true /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.updateConnection(c3, false /* foreground */, 0 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ assertRankingAndRemoveAll(ranking, new ChildProcessConnection[] {c4, c3, c2, c1});
+ }
+
+ @Test
+ public void testIntersectsViewport() {
+ ChildProcessConnection c1 = createConnection();
+ ChildProcessConnection c2 = createConnection();
+ ChildProcessConnection c3 = createConnection();
+
+ ChildProcessRanking ranking = new ChildProcessRanking(4);
+
+ // Insert in lowest ranked to highest ranked order.
+ ranking.addConnection(c1, true /* foreground */, 1 /* frameDepth */,
+ false /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c2, true /* foreground */, 1 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+ ranking.addConnection(c3, true /* foreground */, 0 /* frameDepth */,
+ true /* intersectsViewport */, ChildProcessImportance.NORMAL);
+
+ assertRankingAndRemoveAll(ranking, new ChildProcessConnection[] {c3, c2, c1});
+ }
+}
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/SpareChildConnectionTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/SpareChildConnectionTest.java
new file mode 100644
index 00000000000..b0fe84c0136
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/SpareChildConnectionTest.java
@@ -0,0 +1,232 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowLooper;
+
+import org.chromium.base.process_launcher.ChildConnectionAllocator;
+import org.chromium.base.process_launcher.ChildProcessConnection;
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.TestChildProcessConnection;
+import org.chromium.base.test.util.Feature;
+
+/** Unit tests for the SpareChildConnection class. */
+@Config(manifest = Config.NONE)
+@RunWith(BaseRobolectricTestRunner.class)
+public class SpareChildConnectionTest {
+ @Mock
+ private ChildProcessConnection.ServiceCallback mServiceCallback;
+
+ // A connection allocator not used to create connections.
+ private final ChildConnectionAllocator mWrongConnectionAllocator =
+ ChildConnectionAllocator.createForTest(null, "org.chromium.test", "TestServiceName",
+ 3 /* serviceCount */, false /* bindToCaller */,
+ false /* bindAsExternalService */, false /* useStrongBinding */);
+
+ // The allocator used to allocate the actual connection.
+ private ChildConnectionAllocator mConnectionAllocator;
+
+ private static class TestConnectionFactory
+ implements ChildConnectionAllocator.ConnectionFactory {
+ private TestChildProcessConnection mConnection;
+
+ @Override
+ public ChildProcessConnection createConnection(Context context, ComponentName serviceName,
+ boolean bindToCaller, boolean bindAsExternalService, Bundle serviceBundle) {
+ // We expect to create only one connection in these tests.
+ assert mConnection == null;
+ mConnection = new TestChildProcessConnection(
+ serviceName, bindToCaller, bindAsExternalService, serviceBundle);
+ return mConnection;
+ }
+
+ public void simulateConnectionBindingSuccessfully() {
+ mConnection.getServiceCallback().onChildStarted();
+ }
+
+ public void simulateConnectionFailingToBind() {
+ mConnection.getServiceCallback().onChildStartFailed(mConnection);
+ }
+
+ public void simulateConnectionDied() {
+ mConnection.getServiceCallback().onChildProcessDied(mConnection);
+ }
+ };
+
+ private final TestConnectionFactory mTestConnectionFactory = new TestConnectionFactory();
+
+ private SpareChildConnection mSpareConnection;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ // The tests run on only one thread. Pretend that is the launcher thread so LauncherThread
+ // asserts are not triggered.
+ LauncherThread.setCurrentThreadAsLauncherThread();
+
+ mConnectionAllocator =
+ ChildConnectionAllocator.createForTest(null, "org.chromium.test.spare_connection",
+ "TestServiceName", 5 /* serviceCount */, false /* bindToCaller */,
+ false /* bindAsExternalService */, false /* useStrongBinding */);
+ mConnectionAllocator.setConnectionFactoryForTesting(mTestConnectionFactory);
+ mSpareConnection = new SpareChildConnection(
+ null /* context */, mConnectionAllocator, null /* serviceBundle */);
+ }
+
+ @After
+ public void tearDown() {
+ LauncherThread.setLauncherThreadAsLauncherThread();
+ }
+
+ /** Test creation and retrieval of connection. */
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testCreateAndGet() {
+ // Tests retrieving the connection with the wrong allocator.
+ ChildProcessConnection connection =
+ mSpareConnection.getConnection(mWrongConnectionAllocator, mServiceCallback);
+ assertNull(connection);
+
+ // And with the right one.
+ connection = mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback);
+ assertNotNull(connection);
+
+ // The connection has been used, subsequent calls should return null.
+ connection = mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback);
+ assertNull(connection);
+ }
+
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testCallbackNotCalledWhenNoConnection() {
+ mTestConnectionFactory.simulateConnectionBindingSuccessfully();
+
+ // Retrieve the wrong connection, no callback should be fired.
+ ChildProcessConnection connection =
+ mSpareConnection.getConnection(mWrongConnectionAllocator, mServiceCallback);
+ assertNull(connection);
+ ShadowLooper.runUiThreadTasks();
+ verify(mServiceCallback, times(0)).onChildStarted();
+ verify(mServiceCallback, times(0)).onChildStartFailed(any());
+ verify(mServiceCallback, times(0)).onChildProcessDied(any());
+ }
+
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testCallbackCalledConnectionReady() {
+ mTestConnectionFactory.simulateConnectionBindingSuccessfully();
+
+ assertFalse(mSpareConnection.isEmpty());
+
+ // Now retrieve the connection, the callback should be invoked.
+ ChildProcessConnection connection =
+ mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback);
+ assertNotNull(connection);
+
+ // No more connections are available.
+ assertTrue(mSpareConnection.isEmpty());
+
+ ShadowLooper.runUiThreadTasks();
+ verify(mServiceCallback, times(1)).onChildStarted();
+ verify(mServiceCallback, times(0)).onChildStartFailed(any());
+ }
+
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testCallbackCalledConnectionNotReady() {
+ assertFalse(mSpareConnection.isEmpty());
+
+ // Retrieve the connection before it's bound.
+ ChildProcessConnection connection =
+ mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback);
+ assertNotNull(connection);
+ ShadowLooper.runUiThreadTasks();
+ // No callbacks are called.
+ verify(mServiceCallback, times(0)).onChildStarted();
+ verify(mServiceCallback, times(0)).onChildStartFailed(any());
+
+ // No more connections are available.
+ assertTrue(mSpareConnection.isEmpty());
+
+ // Simulate the connection getting bound, it should trigger the callback.
+ mTestConnectionFactory.simulateConnectionBindingSuccessfully();
+ verify(mServiceCallback, times(1)).onChildStarted();
+ verify(mServiceCallback, times(0)).onChildStartFailed(any());
+ }
+
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testUnretrievedConnectionFailsToBind() {
+ mTestConnectionFactory.simulateConnectionFailingToBind();
+
+ // We should not have a spare connection.
+ ChildProcessConnection connection =
+ mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback);
+ assertNull(connection);
+ }
+
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testRetrievedConnectionFailsToBind() {
+ // Retrieve the spare connection before it's bound.
+ ChildProcessConnection connection =
+ mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback);
+ assertNotNull(connection);
+
+ mTestConnectionFactory.simulateConnectionFailingToBind();
+
+ // We should get a failure callback.
+ verify(mServiceCallback, times(0)).onChildStarted();
+ verify(mServiceCallback, times(1)).onChildStartFailed(connection);
+ }
+
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testRetrievedConnectionStops() {
+ // Retrieve the spare connection before it's bound.
+ ChildProcessConnection connection =
+ mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback);
+ assertNotNull(connection);
+
+ mTestConnectionFactory.simulateConnectionDied();
+
+ // We should get a failure callback.
+ verify(mServiceCallback, times(0)).onChildStarted();
+ verify(mServiceCallback, times(0)).onChildStartFailed(any());
+ verify(mServiceCallback, times(1)).onChildProcessDied(connection);
+ }
+
+ @Test
+ @Feature({"ProcessManagement"})
+ public void testConnectionFreeing() {
+ // Simulate the connection dying.
+ mTestConnectionFactory.simulateConnectionDied();
+
+ // Connection should be gone.
+ ChildProcessConnection connection =
+ mSpareConnection.getConnection(mConnectionAllocator, mServiceCallback);
+ assertNull(connection);
+ }
+}
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/androidoverlay/DialogOverlayCoreTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/androidoverlay/DialogOverlayCoreTest.java
new file mode 100644
index 00000000000..a97ba04ed50
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/androidoverlay/DialogOverlayCoreTest.java
@@ -0,0 +1,360 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.androidoverlay;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.os.Binder;
+import android.os.IBinder;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.WindowManager;
+
+// TODO(liberato): prior to M, this was ...policy.impl.PhoneWindow
+import com.android.internal.policy.PhoneWindow;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.Shadows;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowDialog;
+import org.robolectric.shadows.ShadowPhoneWindow;
+import org.robolectric.shadows.ShadowSurfaceView;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.gfx.mojom.Rect;
+import org.chromium.media.mojom.AndroidOverlayConfig;
+
+/**
+ * Tests for DialogOverlayCore.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class DialogOverlayCoreTest {
+ private Activity mActivity;
+
+ AndroidOverlayConfig mConfig = new AndroidOverlayConfig();
+
+ // Should we request a panel?
+ boolean mAsPanel;
+
+ // DialogCore under test.
+ DialogOverlayCore mCore;
+
+ // The dialog that we've provided to |mCore|.
+ Dialog mDialog;
+
+ // Fake window token that we'll send to |mCore|.
+ IBinder mWindowToken = new Binder();
+
+ // Surface that will be provided by |mDialog|.
+ Surface mSurface = new Surface();
+
+ // SurfaceHolder that will be provided by |mDialog|.
+ SurfaceHolder mHolder = new MyFakeSurfaceHolder(mSurface);
+
+ /**
+ * Robolectric shadow for PhoneWindow. This one keeps track of takeSurface() calls.
+ * TODO(liberato): the @Impl specifies 'minSdk=M' in the robolectric source.
+ */
+ @Implements(value = PhoneWindow.class, isInAndroidSdk = false)
+ public static class MyPhoneWindowShadow extends ShadowPhoneWindow {
+ public MyPhoneWindowShadow() {}
+
+ private SurfaceHolder.Callback2 mCallback;
+ private WindowManager.LayoutParams mLayoutParams;
+ public boolean mDidUpdateParams;
+
+ @Implementation
+ public void takeSurface(SurfaceHolder.Callback2 callback) {
+ mCallback = callback;
+ }
+
+ @Implementation
+ public void setAttributes(WindowManager.LayoutParams layoutParams) {
+ mLayoutParams = layoutParams;
+ mDidUpdateParams = true;
+ }
+ }
+
+ /**
+ * The default fake surface holder doesn't let us provide a surface.
+ */
+ public static class MyFakeSurfaceHolder extends ShadowSurfaceView.FakeSurfaceHolder {
+ private Surface mSurface;
+
+ // @param surface The Surface that we'll provide via getSurface.
+ public MyFakeSurfaceHolder(Surface surface) {
+ mSurface = surface;
+ }
+
+ @Override
+ public Surface getSurface() {
+ return mSurface;
+ }
+ }
+
+ @Before
+ public void setUp() {
+ mActivity = Robolectric.buildActivity(Activity.class).setup().get();
+
+ mConfig = new AndroidOverlayConfig();
+ mConfig.rect = new Rect();
+ mConfig.rect.x = 0;
+ mConfig.rect.y = 1;
+ mConfig.rect.width = 2;
+ mConfig.rect.height = 3;
+ }
+
+ public void createOverlay() {
+ mCore = new DialogOverlayCore();
+ mCore.initialize(mActivity, mConfig, mHost, mAsPanel);
+ mDialog = mCore.getDialog();
+
+ // Nothing should be called yet.
+ checkOverlayDidntCall();
+
+ // The dialog should not be shown yet.
+ checkDialogIsNotShown();
+ }
+
+ // Make sure that the overlay didn't provide us with a surface, or notify us that it was
+ // destroyed, or wait for cleanup.
+ void checkOverlayDidntCall() {
+ assertEquals(null, mHost.surface());
+ assertEquals(0, mHost.destroyedCount());
+ assertEquals(0, mHost.waitCloseCount());
+ assertEquals(0, mHost.enforceCloseCount());
+ }
+
+ // Return the SurfaceHolder callback that was provided to takeSurface(), if any.
+ SurfaceHolder.Callback2 holderCallback() {
+ return ((MyPhoneWindowShadow) Shadows.shadowOf(mDialog.getWindow())).mCallback;
+ }
+
+ // Return the LayoutPararms that was most recently provided to the dialog.
+ WindowManager.LayoutParams layoutParams() {
+ return ((MyPhoneWindowShadow) Shadows.shadowOf(mDialog.getWindow())).mLayoutParams;
+ }
+
+ MyPhoneWindowShadow getShadowWindow() {
+ return ((MyPhoneWindowShadow) Shadows.shadowOf(mDialog.getWindow()));
+ }
+
+ /**
+ * Host impl that counts calls to it.
+ */
+ class HostMock implements DialogOverlayCore.Host {
+ private Surface mSurface;
+ private int mDestroyedCount;
+ private int mWaitCloseCount;
+ private int mEnforceCloseCount;
+
+ @Override
+ public void onSurfaceReady(Surface surface) {
+ mSurface = surface;
+ }
+
+ @Override
+ public void onOverlayDestroyed() {
+ mDestroyedCount++;
+ }
+
+ @Override
+ public void waitForClose() {
+ mWaitCloseCount++;
+ }
+
+ @Override
+ public void enforceClose() {
+ mEnforceCloseCount++;
+ }
+
+ public Surface surface() {
+ return mSurface;
+ }
+
+ public int destroyedCount() {
+ return mDestroyedCount;
+ }
+
+ public int waitCloseCount() {
+ return mWaitCloseCount;
+ }
+
+ public int enforceCloseCount() {
+ return mEnforceCloseCount;
+ }
+ };
+
+ HostMock mHost = new HostMock();
+
+ // Send a window token and provide the surface, so that the overlay is ready for use.
+ void sendTokenAndSurface() {
+ mCore.onWindowToken(mWindowToken);
+ // Make sure that somebody called takeSurface.
+ assertNotNull(holderCallback());
+
+ checkDialogIsShown();
+
+ // Provide the Android Surface.
+ holderCallback().surfaceCreated(mHolder);
+
+ // The host should have been told about the surface.
+ assertEquals(mSurface, mHost.surface());
+ }
+
+ // Verify that the dialog has been shown.
+ void checkDialogIsShown() {
+ assertEquals(mDialog, ShadowDialog.getShownDialogs().get(0));
+ }
+
+ // Verify that the dialog is not currently shown. Note that dismiss() doesn't remove it from
+ // the shown dialog list in Robolectric, so we check for "was never shown or was dismissed".
+ void checkDialogIsNotShown() {
+ assertTrue(ShadowDialog.getShownDialogs().size() == 0
+ || Shadows.shadowOf(mDialog).hasBeenDismissed());
+ }
+
+ // Verify that |mCore| signaled that the overlay was lost to|mHost|.
+ void checkOverlayWasDestroyed() {
+ // |mCore| should have notified the host that it has been destroyed, and also waited for
+ // the host to signal that the client released it.
+ assertEquals(1, mHost.destroyedCount());
+ checkDialogIsNotShown();
+ }
+
+ // Check that releasing an overlay before getting a window token works.
+ @Test
+ @Config(shadows = {MyPhoneWindowShadow.class})
+ public void testReleaseImmediately() {
+ // Release the overlay. |mCore| shouldn't notify us, since we released it.
+ createOverlay();
+ mCore.release();
+ checkOverlayDidntCall();
+ checkDialogIsNotShown();
+ }
+
+ // Create a dialog, then send it a token. Verify that it's shown.
+ @Test
+ @Config(shadows = {MyPhoneWindowShadow.class})
+ public void testTokenThenRelease() {
+ createOverlay();
+ mCore.onWindowToken(mWindowToken);
+ checkDialogIsShown();
+
+ // Release the surface. |mHost| shouldn't be notified, nor should it wait for cleanup.
+ // Note: it might be okay if it checks for cleanup, since cleanup would be complete after
+ // we call release(). However, it's not needed, so we enforce that it isn't.
+ mCore.release();
+ checkOverlayDidntCall();
+ checkDialogIsNotShown();
+ }
+
+ // Create a dialog, send a token, send a surface, then release it.
+ @Test
+ @Config(shadows = {MyPhoneWindowShadow.class})
+ public void testSurfaceThenRelease() {
+ createOverlay();
+ sendTokenAndSurface();
+
+ mCore.release();
+ assertEquals(0, mHost.destroyedCount());
+ assertEquals(0, mHost.waitCloseCount());
+ assertEquals(0, mHost.enforceCloseCount());
+ checkDialogIsNotShown();
+ }
+
+ // Create a dialog, send a surface, then destroy the surface.
+ @Test
+ @Config(shadows = {MyPhoneWindowShadow.class})
+ public void testSurfaceThenDestroy() {
+ createOverlay();
+ sendTokenAndSurface();
+
+ // Destroy the surface.
+ holderCallback().surfaceDestroyed(mHolder);
+ // |mCore| should have waited for cleanup during surfaceDestroyed.
+ assertEquals(1, mHost.waitCloseCount());
+ // Since we waited for cleanup, also pretend that the release was posted during the wait and
+ // will arrive after the wait completes.
+ mCore.release();
+ assertEquals(1, mHost.enforceCloseCount());
+
+ checkOverlayWasDestroyed();
+ }
+
+ // Test that we're notified when the window token changes.
+ @Test
+ @Config(shadows = {MyPhoneWindowShadow.class})
+ public void testChangeWindowToken() {
+ createOverlay();
+ sendTokenAndSurface();
+
+ // Change the window token.
+ mCore.onWindowToken(new Binder());
+
+ checkOverlayWasDestroyed();
+ }
+
+ // Test that we're notified when the window token is lost.
+ @Test
+ @Config(shadows = {MyPhoneWindowShadow.class})
+ public void testLoseWindowToken() {
+ createOverlay();
+ sendTokenAndSurface();
+
+ // Remove the window token.
+ mCore.onWindowToken(null);
+
+ checkOverlayWasDestroyed();
+ }
+
+ // Test that the layout params reflect TYPE_APPLICATION_MEDIA, and that it its geometry matches
+ // what we requested.
+ @Test
+ @Config(shadows = {MyPhoneWindowShadow.class})
+ public void testOverlayTypeAndGeometry() {
+ createOverlay();
+ mCore.onWindowToken(mWindowToken);
+ assertEquals(WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA, layoutParams().type);
+ assertEquals(mConfig.rect.x, layoutParams().x);
+ assertEquals(mConfig.rect.y, layoutParams().y);
+ assertEquals(mConfig.rect.width, layoutParams().width);
+ assertEquals(mConfig.rect.height, layoutParams().height);
+ }
+
+ // Test that the layout params reflect TYPE_APPLICATION_PANEL when we request it.
+ @Test
+ @Config(shadows = {MyPhoneWindowShadow.class})
+ public void testOverlayAsPanel() {
+ mAsPanel = true;
+ createOverlay();
+ mCore.onWindowToken(mWindowToken);
+ assertEquals(layoutParams().type, WindowManager.LayoutParams.TYPE_APPLICATION_PANEL);
+ }
+
+ @Test
+ @Config(shadows = {MyPhoneWindowShadow.class})
+ public void testNoParamsUpdateForSamePositionRect() {
+ createOverlay();
+ mCore.onWindowToken(mWindowToken);
+ assertTrue(getShadowWindow().mDidUpdateParams);
+
+ // Update with the same rect, it should not update the window params.
+ getShadowWindow().mDidUpdateParams = false;
+ mCore.layoutSurface(mConfig.rect);
+ assertFalse(getShadowWindow().mDidUpdateParams);
+ }
+}
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/input/RangeTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/input/RangeTest.java
new file mode 100644
index 00000000000..32dc6be388b
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/input/RangeTest.java
@@ -0,0 +1,68 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.input;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import org.chromium.base.test.util.Feature;
+
+/**
+ * Unit tests for {@Range}.
+ */
+@RunWith(BlockJUnit4ClassRunner.class)
+public class RangeTest {
+ @Test
+ @Feature({"TextInput"})
+ public void testClamp() {
+ // Overlap case #1
+ Range range = new Range(1, 4);
+ range.clamp(2, 5);
+ assertEquals(new Range(2, 4), range);
+ // Overlap case #2
+ range.set(1, 4);
+ range.clamp(0, 2);
+ assertEquals(new Range(1, 2), range);
+ // Clamp on both ends
+ range.set(1, 4);
+ range.clamp(2, 3);
+ assertEquals(new Range(2, 3), range);
+ // No-op
+ range.set(1, 4);
+ range.clamp(0, 5);
+ assertEquals(new Range(1, 4), range);
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ @SuppressWarnings("SelfEquals") // Allow this rather than using guava's EqualsTester.
+ public void testEquals() {
+ assertTrue(new Range(1, 3).equals(new Range(1, 3)));
+ assertFalse(new Range(1, 2).equals(new Range(1, 3)));
+ Range range = new Range(1, 4);
+ assertTrue(range.equals(range));
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testIntersects() {
+ assertTrue(new Range(1, 3).intersects(new Range(0, 2)));
+ assertTrue(new Range(0, 2).intersects(new Range(1, 3)));
+
+ assertTrue(new Range(0, 2).intersects(new Range(2, 3)));
+ assertTrue(new Range(2, 3).intersects(new Range(0, 2)));
+
+ assertFalse(new Range(1, 3).intersects(new Range(4, 6)));
+ assertFalse(new Range(4, 6).intersects(new Range(1, 3)));
+
+ Range range = new Range(1, 3);
+ assertTrue(range.intersects(range));
+ }
+} \ No newline at end of file
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/input/TextInputStateTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/input/TextInputStateTest.java
new file mode 100644
index 00000000000..be056497959
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/input/TextInputStateTest.java
@@ -0,0 +1,47 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.input;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import org.chromium.base.test.util.Feature;
+
+/**
+ * Unit tests for {@TextInputState}.
+ */
+@RunWith(BlockJUnit4ClassRunner.class)
+public class TextInputStateTest {
+ @Test
+ @Feature({"TextInput"})
+ public void testEmptySelection() {
+ TextInputState state =
+ new TextInputState("hello", new Range(3, 3), new Range(-1, -1), false, true);
+ assertEquals("lo", state.getTextAfterSelection(3));
+ assertEquals("lo", state.getTextAfterSelection(2));
+ assertEquals("", state.getTextAfterSelection(0));
+ assertEquals("hel", state.getTextBeforeSelection(3));
+ assertEquals("el", state.getTextBeforeSelection(2));
+ assertEquals("", state.getTextBeforeSelection(0));
+ assertEquals(null, state.getSelectedText());
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testNonEmptySelection() {
+ TextInputState state =
+ new TextInputState("hello", new Range(3, 4), new Range(3, 4), false, true);
+ assertEquals("hel", state.getTextBeforeSelection(4));
+ assertEquals("hel", state.getTextBeforeSelection(3));
+ assertEquals("", state.getTextBeforeSelection(0));
+ assertEquals("o", state.getTextAfterSelection(2));
+ assertEquals("o", state.getTextAfterSelection(1));
+ assertEquals("", state.getTextAfterSelection(0));
+ assertEquals("l", state.getSelectedText());
+ }
+} \ No newline at end of file
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionFactoryTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionFactoryTest.java
new file mode 100644
index 00000000000..b0ba196e490
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionFactoryTest.java
@@ -0,0 +1,289 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.input;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Build;
+import android.os.Handler;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowLooper;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.Feature;
+import org.chromium.content_public.browser.InputMethodManagerWrapper;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Unit tests for {@ThreadedInputConnectionFactory}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.LOLLIPOP)
+public class ThreadedInputConnectionFactoryTest {
+ /**
+ * A testable version of ThreadedInputConnectionFactory.
+ */
+ private class TestFactory extends ThreadedInputConnectionFactory {
+
+ private boolean mSucceeded;
+ private boolean mFailed;
+
+ TestFactory(InputMethodManagerWrapper inputMethodManagerWrapper) {
+ super(inputMethodManagerWrapper);
+ }
+
+ @Override
+ protected ThreadedInputConnectionProxyView createProxyView(Handler handler,
+ View containerView) {
+ return mProxyView;
+ }
+
+ @Override
+ protected InputMethodUma createInputMethodUma() {
+ return null;
+ }
+
+ @Override
+ protected void onRegisterProxyViewSuccess() {
+ mSucceeded = true;
+ }
+
+ @Override
+ protected void onRegisterProxyViewFailure() {
+ mFailed = true;
+ }
+
+ public boolean hasFailed() {
+ return mFailed;
+ }
+
+ public boolean hasSucceeded() {
+ return mSucceeded;
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean gainFocus) {
+ mHasWindowFocus = gainFocus;
+ super.onWindowFocusChanged(gainFocus);
+ }
+ }
+
+ @Mock
+ private ImeAdapterImpl mImeAdapter;
+ @Mock
+ private View mContainerView;
+ @Mock
+ private ThreadedInputConnectionProxyView mProxyView;
+ @Mock
+ private InputMethodManager mInputMethodManager;
+ @Mock
+ private Context mContext;
+
+ private EditorInfo mEditorInfo;
+ private Handler mImeHandler;
+ private Handler mUiHandler;
+ private ShadowLooper mImeShadowLooper;
+ private TestFactory mFactory;
+ private InputConnection mInputConnection;
+ private InOrder mInOrder;
+ private boolean mHasWindowFocus;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mEditorInfo = new EditorInfo();
+ mUiHandler = new Handler();
+
+ mContext = Mockito.mock(Context.class);
+ mContainerView = Mockito.mock(View.class);
+ mImeAdapter = Mockito.mock(ImeAdapterImpl.class);
+ mInputMethodManager = Mockito.mock(InputMethodManager.class);
+
+ mFactory = new TestFactory(new InputMethodManagerWrapperImpl(mContext));
+ mFactory.onWindowFocusChanged(true);
+ mImeHandler = mFactory.getHandler();
+ mImeShadowLooper = (ShadowLooper) Shadow.extract(mImeHandler.getLooper());
+
+ when(mContext.getSystemService(Context.INPUT_METHOD_SERVICE))
+ .thenReturn(mInputMethodManager);
+ when(mContainerView.getContext()).thenReturn(mContext);
+ when(mContainerView.getHandler()).thenReturn(mUiHandler);
+ when(mContainerView.hasFocus()).thenReturn(true);
+ when(mContainerView.hasWindowFocus()).thenReturn(true);
+
+ mProxyView = Mockito.mock(ThreadedInputConnectionProxyView.class);
+ when(mProxyView.getContext()).thenReturn(mContext);
+ when(mProxyView.requestFocus()).thenReturn(true);
+ when(mProxyView.getHandler()).thenReturn(mImeHandler);
+ final Callable<InputConnection> callable = new Callable<InputConnection>() {
+ @Override
+ public InputConnection call() throws Exception {
+ return mFactory.initializeAndGet(
+ mContainerView, mImeAdapter, 1, 0, 0, 0, 0, mEditorInfo);
+ }
+ };
+ when(mProxyView.onCreateInputConnection(any(EditorInfo.class)))
+ .thenAnswer((InvocationOnMock invocation) -> {
+ mFactory.setTriggerDelayedOnCreateInputConnection(false);
+ InputConnection connection =
+ ThreadUtils.runOnUiThreadBlockingNoException(callable);
+ mFactory.setTriggerDelayedOnCreateInputConnection(true);
+ return connection;
+ });
+
+ when(mInputMethodManager.isActive(mContainerView)).thenAnswer(new Answer<Boolean>() {
+ private int mCount;
+
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ mCount++;
+ // To simplify IMM's behavior, let's say that it succeeds input method activation
+ // only when the view has a window focus.
+ if (!mHasWindowFocus) return false;
+ if (mCount == 1) {
+ mInputConnection = mProxyView.onCreateInputConnection(mEditorInfo);
+ return false;
+ }
+ return mHasWindowFocus;
+ }
+ });
+ when(mInputMethodManager.isActive(mProxyView)).thenAnswer(new Answer<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ return mInputConnection != null;
+ }
+ });
+
+ mInOrder = inOrder(mImeAdapter, mInputMethodManager, mContainerView, mProxyView);
+ }
+
+ private void activateInput() {
+ mUiHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ assertNull(mFactory.initializeAndGet(
+ mContainerView, mImeAdapter, 1, 0, 0, 0, 0, mEditorInfo));
+ }
+ });
+ }
+
+ private void runOneUiTask() {
+ assertTrue(Robolectric.getForegroundThreadScheduler().runOneTask());
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testCreateInputConnection_Success() {
+ // Pause all the loopers.
+ Robolectric.getForegroundThreadScheduler().pause();
+ mImeShadowLooper.pause();
+
+ activateInput();
+
+ // The first onCreateInputConnection().
+ runOneUiTask();
+ mInOrder.verify(mContainerView).hasFocus();
+ mInOrder.verify(mContainerView).hasWindowFocus();
+ mInOrder.verify(mProxyView).requestFocus();
+ mInOrder.verify(mContainerView).getHandler();
+ mInOrder.verifyNoMoreInteractions();
+ assertNull(mInputConnection);
+
+ // The second onCreateInputConnection().
+ runOneUiTask();
+ mInOrder.verify(mProxyView).onWindowFocusChanged(true);
+ mInOrder.verify(mInputMethodManager).isActive(mContainerView);
+ mInOrder.verify(mProxyView).onCreateInputConnection(any(EditorInfo.class));
+ mInOrder.verify(mContainerView).getContext(); // BaseInputConnection#<init>
+ mInOrder.verifyNoMoreInteractions();
+ assertNotNull(mInputConnection);
+ assertTrue(ThreadedInputConnection.class.isInstance(mInputConnection));
+
+ // Verification process.
+ mImeShadowLooper.runOneTask();
+ runOneUiTask();
+
+ mInOrder.verify(mInputMethodManager).isActive(mProxyView);
+ mInOrder.verifyNoMoreInteractions();
+
+ assertTrue(mFactory.hasSucceeded());
+ assertFalse(mFactory.hasFailed());
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testCreateInputConnection_Failure() {
+ // Pause all the loopers.
+ Robolectric.getForegroundThreadScheduler().pause();
+ mImeShadowLooper.pause();
+
+ activateInput();
+
+ // The first onCreateInputConnection().
+ runOneUiTask();
+ mInOrder.verify(mContainerView).hasFocus();
+ mInOrder.verify(mContainerView).hasWindowFocus();
+ mInOrder.verify(mProxyView).requestFocus();
+ mInOrder.verify(mContainerView).getHandler();
+ mInOrder.verifyNoMoreInteractions();
+ assertNull(mInputConnection);
+
+ // Now window focus was lost before the second onCreateInputConnection().
+ mFactory.onWindowFocusChanged(false);
+ mInOrder.verify(mProxyView).onOriginalViewWindowFocusChanged(false);
+
+ // The second onCreateInputConnection().
+ runOneUiTask();
+ mInOrder.verify(mProxyView).onWindowFocusChanged(true);
+ mInOrder.verify(mInputMethodManager).isActive(mContainerView);
+ mInOrder.verifyNoMoreInteractions();
+
+ // Window focus is lost and we fail to activate.
+ assertNull(mInputConnection);
+
+ // Verification process.
+ mImeShadowLooper.runOneTask();
+ mInOrder.verify(mContainerView).getHandler();
+ runOneUiTask();
+ mInOrder.verify(mInputMethodManager).isActive(mProxyView);
+
+ // Wait one more UI loop.
+ mInOrder.verify(mContainerView).getHandler();
+ runOneUiTask();
+ mInOrder.verify(mInputMethodManager).isActive(mProxyView);
+
+ mInOrder.verifyNoMoreInteractions();
+ // Failed, but no logging because check has been invalidated.
+ assertNull(mInputConnection);
+ assertFalse(mFactory.hasSucceeded());
+ assertFalse(mFactory.hasFailed());
+ }
+}
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java
new file mode 100644
index 00000000000..23c8fb2c704
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java
@@ -0,0 +1,354 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.input;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Handler;
+import android.view.KeyCharacterMap;
+import android.view.View;
+import android.view.inputmethod.ExtractedText;
+import android.view.inputmethod.ExtractedTextRequest;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.Feature;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Unit tests for {@ThreadedInputConnection}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class ThreadedInputConnectionTest {
+ @Mock
+ ImeAdapterImpl mImeAdapter;
+
+ ThreadedInputConnection mConnection;
+ InOrder mInOrder;
+ View mView;
+ Context mContext;
+ boolean mRunningOnUiThread;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mImeAdapter = Mockito.mock(ImeAdapterImpl.class);
+ mInOrder = inOrder(mImeAdapter);
+
+ // Mocks required to create a ThreadedInputConnection object
+ mView = Mockito.mock(View.class);
+ mContext = Mockito.mock(Context.class);
+ when(mView.getContext()).thenReturn(mContext);
+ when(mContext.getSystemService(Context.INPUT_METHOD_SERVICE)).thenReturn(Mockito.mock(
+ InputMethodManager.class));
+ // Let's create Handler for test thread and pretend that it is running on IME thread.
+ mConnection = new ThreadedInputConnection(mView, mImeAdapter, new Handler()) {
+ @Override
+ protected boolean runningOnUiThread() {
+ return mRunningOnUiThread;
+ }
+ };
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testComposeGetTextFinishGetText() {
+ // IME app calls setComposingText().
+ mConnection.setComposingText("hello", 1);
+ mInOrder.verify(mImeAdapter).sendCompositionToNative("hello", 1, false, 0);
+
+ // Renderer updates states asynchronously.
+ mConnection.updateStateOnUiThread("hello", 5, 5, 0, 5, true, false);
+ mInOrder.verify(mImeAdapter).updateSelection(5, 5, 0, 5);
+ assertEquals(0, mConnection.getQueueForTest().size());
+
+ // Prepare to call requestTextInputStateUpdate.
+ mConnection.updateStateOnUiThread("hello", 5, 5, 0, 5, true, true);
+ assertEquals(1, mConnection.getQueueForTest().size());
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true);
+
+ // IME app calls getTextBeforeCursor().
+ assertEquals("hello", mConnection.getTextBeforeCursor(20, 0));
+
+ // IME app calls finishComposingText().
+ mConnection.finishComposingText();
+ mInOrder.verify(mImeAdapter).finishComposingText();
+ mConnection.updateStateOnUiThread("hello", 5, 5, -1, -1, true, false);
+ mInOrder.verify(mImeAdapter).updateSelection(5, 5, -1, -1);
+
+ // Prepare to call requestTextInputStateUpdate.
+ mConnection.updateStateOnUiThread("hello", 5, 5, -1, -1, true, true);
+ assertEquals(1, mConnection.getQueueForTest().size());
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true);
+
+ // IME app calls getTextBeforeCursor().
+ assertEquals("hello", mConnection.getTextBeforeCursor(20, 0));
+
+ assertEquals(0, mConnection.getQueueForTest().size());
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testPressingDeadKey() {
+ // On default keyboard "Alt+i" produces a dead key '\u0302'.
+ mConnection.setCombiningAccentOnUiThread(0x0302);
+ mConnection.updateComposingText("\u0302", 1, true);
+ mInOrder.verify(mImeAdapter)
+ .sendCompositionToNative(
+ "\u0302", 1, false, 0x0302 | KeyCharacterMap.COMBINING_ACCENT);
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testRenderChangeUpdatesSelection() {
+ // User moves the cursor.
+ mConnection.updateStateOnUiThread("hello", 4, 4, -1, -1, true, false);
+ mInOrder.verify(mImeAdapter).updateSelection(4, 4, -1, -1);
+ assertEquals(0, mConnection.getQueueForTest().size());
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testBatchEdit() {
+ // IME app calls beginBatchEdit().
+ assertTrue(mConnection.beginBatchEdit());
+ // Type hello real fast.
+ mConnection.commitText("hello", 1);
+ mInOrder.verify(mImeAdapter).sendCompositionToNative("hello", 1, true, 0);
+
+ // Renderer updates states asynchronously.
+ mConnection.updateStateOnUiThread("hello", 5, 5, -1, -1, true, false);
+ mInOrder.verify(mImeAdapter, never()).updateSelection(5, 5, -1, -1);
+ assertEquals(0, mConnection.getQueueForTest().size());
+
+ {
+ // Nest another batch edit.
+ assertTrue(mConnection.beginBatchEdit());
+ // Move the cursor to the left.
+ mConnection.setSelection(4, 4);
+ assertTrue(mConnection.endBatchEdit());
+ }
+ // We still have one outer batch edit, so should not update selection yet.
+ mInOrder.verify(mImeAdapter, never()).updateSelection(4, 4, -1, -1);
+
+ // Prepare to call requestTextInputStateUpdate.
+ mConnection.updateStateOnUiThread("hello", 4, 4, -1, -1, true, true);
+ assertEquals(1, mConnection.getQueueForTest().size());
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true);
+
+ // IME app calls endBatchEdit().
+ assertFalse(mConnection.endBatchEdit());
+ // Batch edit is finished, now update selection.
+ mInOrder.verify(mImeAdapter).updateSelection(4, 4, -1, -1);
+ assertEquals(0, mConnection.getQueueForTest().size());
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ @Ignore("crbug/632792")
+ public void testFailToRequestToRenderer() {
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(false);
+ // Should not hang here. Return null to indicate failure.
+ assertNull(null, mConnection.getTextBeforeCursor(10, 0));
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ @Ignore("crbug/632792")
+ public void testRendererCannotUpdateState() {
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true);
+ // We found that renderer cannot update state, e.g., due to a crash.
+ ThreadUtils.postOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ // TODO(changwan): find a way to avoid this.
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ fail();
+ }
+ mConnection.unblockOnUiThread();
+ }
+ });
+ // Should not hang here. Return null to indicate failure.
+ assertEquals(null, mConnection.getTextBeforeCursor(10, 0));
+ }
+
+ // crbug.com/643477
+ @Test
+ @Feature({"TextInput"})
+ public void testUiThreadAccess() {
+ assertTrue(mConnection.commitText("hello", 1));
+ mRunningOnUiThread = true;
+ // Depending on the timing, the result may not be up-to-date.
+ assertNotEquals("hello",
+ ThreadUtils.runOnUiThreadBlockingNoException(new Callable<CharSequence>() {
+ @Override
+ public CharSequence call() {
+ return mConnection.getTextBeforeCursor(10, 0);
+ }
+ }));
+ // Or it could be.
+ mConnection.updateStateOnUiThread("hello", 5, 5, -1, -1, true, false);
+ assertEquals("hello",
+ ThreadUtils.runOnUiThreadBlockingNoException(new Callable<CharSequence>() {
+ @Override
+ public CharSequence call() {
+ return mConnection.getTextBeforeCursor(10, 0);
+ }
+ }));
+
+ mRunningOnUiThread = false;
+ }
+
+ @Test
+ @Feature("TextInput")
+ public void testUpdateSelectionBehaviorWhenUpdatesRequested() throws InterruptedException {
+ // Arrange.
+ final ExtractedTextRequest request = new ExtractedTextRequest();
+
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true);
+
+ // Populate the TextInputState BlockingQueue for the getExtractedText() call.
+ mConnection.updateStateOnUiThread("bello", 1, 1, -1, -1, true, true);
+
+ // Act.
+ final ExtractedText extractedText =
+ mConnection.getExtractedText(request, InputConnection.GET_EXTRACTED_TEXT_MONITOR);
+
+ // Assert.
+ assertEquals("bello", extractedText.text);
+ assertEquals(-1, extractedText.partialStartOffset);
+ assertEquals("bello".length(), extractedText.partialEndOffset);
+ assertEquals(1, extractedText.selectionStart);
+ assertEquals(1, extractedText.selectionEnd);
+
+ // Ensure that the next updateState events will invoke
+ // both updateExtractedText() and updateSelection().
+ mConnection.updateStateOnUiThread("mello", 2, 2, -1, -1, true, false);
+ mInOrder.verify(mImeAdapter).updateExtractedText(anyInt(), any(ExtractedText.class));
+ mInOrder.verify(mImeAdapter).updateSelection(2, 2, -1, -1);
+
+ mConnection.updateStateOnUiThread("cello", 3, 3, -1, -1, true, false);
+ mInOrder.verify(mImeAdapter).updateExtractedText(anyInt(), any(ExtractedText.class));
+ mInOrder.verify(mImeAdapter).updateSelection(3, 3, -1, -1);
+ }
+
+ @Test
+ @Feature("TextInput")
+ public void testUpdateSelectionBehaviorWhenUpdatesNotRequested() throws InterruptedException {
+ // Arrange.
+ final ExtractedTextRequest request = new ExtractedTextRequest();
+
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true);
+
+ // Populate the TextInputState BlockingQueue for the getExtractedText() call.
+ mConnection.updateStateOnUiThread("hello", 1, 2, 3, 4, true, true);
+
+ // Initially we want to monitor extracted text updates.
+ final ExtractedText extractedText1 =
+ mConnection.getExtractedText(request, InputConnection.GET_EXTRACTED_TEXT_MONITOR);
+
+ mConnection.updateStateOnUiThread("bello", 1, 1, 3, 4, true, false);
+
+ // Assert.
+ assertEquals("hello", extractedText1.text);
+ assertEquals(-1, extractedText1.partialStartOffset);
+ assertEquals("hello".length(), extractedText1.partialEndOffset);
+ assertEquals(1, extractedText1.selectionStart);
+ assertEquals(2, extractedText1.selectionEnd);
+
+ mInOrder.verify(mImeAdapter).updateExtractedText(anyInt(), any(ExtractedText.class));
+ mInOrder.verify(mImeAdapter).updateSelection(1, 1, 3, 4);
+
+ // Populate the TextInputState BlockingQueue for the getExtractedText() call.
+ mConnection.updateStateOnUiThread("cello", 2, 2, 3, 4, true, true);
+
+ // Act: Now we want to stop monitoring extracted text changes.
+ final ExtractedText extractedText2 = mConnection.getExtractedText(request, 0);
+
+ // Assert
+ assertEquals("cello", extractedText2.text);
+ assertEquals(-1, extractedText2.partialStartOffset);
+ assertEquals("cello".length(), extractedText2.partialEndOffset);
+ assertEquals(2, extractedText2.selectionStart);
+ assertEquals(2, extractedText2.selectionEnd);
+
+ // Perform another updateState
+ mConnection.updateStateOnUiThread("ello", 0, 0, -1, -1, true, false);
+
+ // Assert: No more update extracted text updates sent to ImeAdapter.
+ mInOrder.verify(mImeAdapter, never())
+ .updateExtractedText(anyInt(), any(ExtractedText.class));
+ mInOrder.verify(mImeAdapter).updateSelection(0, 0, -1, -1);
+ }
+
+ @Test
+ @Feature("TextInput")
+ public void testExtractedTextNotSentAfterInputConnectionReset() throws InterruptedException {
+ // Arrange.
+ final ExtractedTextRequest request = new ExtractedTextRequest();
+
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true);
+
+ // Populate the TextInputState BlockingQueue for the getExtractedText() call.
+ mConnection.updateStateOnUiThread("hello", 1, 2, 3, 4, true, true);
+
+ // Start monitoring for extracted text updates
+ final ExtractedText extractedText =
+ mConnection.getExtractedText(request, InputConnection.GET_EXTRACTED_TEXT_MONITOR);
+
+ // Assert.
+ assertEquals("hello", extractedText.text);
+ assertEquals(-1, extractedText.partialStartOffset);
+ assertEquals("hello".length(), extractedText.partialEndOffset);
+ assertEquals(1, extractedText.selectionStart);
+ assertEquals(2, extractedText.selectionEnd);
+
+ mConnection.updateStateOnUiThread("bello", 1, 1, 3, 4, true, false);
+
+ mInOrder.verify(mImeAdapter).updateExtractedText(anyInt(), any(ExtractedText.class));
+ mInOrder.verify(mImeAdapter).updateSelection(1, 1, 3, 4);
+
+ // Act: Force a connection reset Instead of calling ImeAdapter#onCreateInputConnection()
+ // To stop monitoring extracted text changes.
+ mConnection.resetOnUiThread();
+
+ // Perform another updateState
+ mConnection.updateStateOnUiThread("ello", 0, 0, -1, -1, true, false);
+
+ // Assert: No more update extracted text updates sent to ImeAdapter.
+ mInOrder.verify(mImeAdapter, never())
+ .updateExtractedText(anyInt(), any(ExtractedText.class));
+ mInOrder.verify(mImeAdapter).updateSelection(0, 0, -1, -1);
+ }
+}
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/picker/DateDialogNormalizerTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/picker/DateDialogNormalizerTest.java
new file mode 100644
index 00000000000..5429f6082ba
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/picker/DateDialogNormalizerTest.java
@@ -0,0 +1,160 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.picker;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.Activity;
+import android.widget.DatePicker;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+
+import java.util.TimeZone;
+
+/**
+ * Tests for DateDialogNormalizer.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+// sdk 18 is used due to a bug in Robolectric, crbug.com/635199
+@Config(manifest = Config.NONE, sdk = 18)
+public class DateDialogNormalizerTest {
+ private static final long MILLIS_PER_MINUTE = 60 * 1000;
+ private static final long MILLIS_PER_HOUR = 60 * 60 * 1000;
+ private static final long PST_OFFSET_MILLIS = 8 * MILLIS_PER_HOUR;
+ private static final long JAPAN_OFFSET_MILLIS = -9 * MILLIS_PER_HOUR;
+
+ private static final TimeZone GMT_TIME_ZONE = TimeZone.getTimeZone("GMT");
+ private static final TimeZone PST_TIME_ZONE = TimeZone.getTimeZone("GMT-08");
+ private static final TimeZone JAPAN_TIME_ZONE = TimeZone.getTimeZone("Japan"); // GMT+09
+
+ // Times are milliseconds since the epoch. The time zone is GMT, unless marked as PST or Japan.
+ // The time of day is midnight unless marked otherwise. The calendar is Gregorian, unless
+ // marked with _JULIAN, which indicates a hybrid Julian/Gregorian calendar.
+ private static final long JULY_31_2012 = 1343692800000L;
+ private static final long JULY_31_2012_PST = JULY_31_2012 + PST_OFFSET_MILLIS;
+ private static final long JULY_31_2012_JAPAN = JULY_31_2012 + JAPAN_OFFSET_MILLIS;
+ private static final long JULY_31_2014 = 1406764800000L;
+ private static final long JULY_31_2014_1201AM = JULY_31_2014 + 1 * MILLIS_PER_MINUTE;
+ private static final long JULY_31_2014_9PM = JULY_31_2014 + 21 * MILLIS_PER_HOUR;
+ private static final long JULY_31_2014_PST = JULY_31_2014 + PST_OFFSET_MILLIS;
+ private static final long JULY_31_2014_JAPAN = JULY_31_2014 + JAPAN_OFFSET_MILLIS;
+ private static final long JULY_31_2017 = 1501459200000L;
+ private static final long JULY_31_2017_PST = JULY_31_2017 + PST_OFFSET_MILLIS;
+ private static final long JULY_31_2017_JAPAN = JULY_31_2017 + JAPAN_OFFSET_MILLIS;
+ private static final long JULY_31_2017_5AM = JULY_31_2017 + 5 * MILLIS_PER_HOUR;
+ private static final long JULY_31_2017_1159PM = JULY_31_2017 + 23 * MILLIS_PER_HOUR
+ + 59 * MILLIS_PER_MINUTE;
+ private static final long JULY_31_2018 = 1532995200000L;
+ private static final long JULY_31_2018_PST = JULY_31_2018 + PST_OFFSET_MILLIS;
+
+ private static final long JANUARY_1_0476 = -47146060800000L;
+ private static final long JANUARY_1_0476_JULIAN = -47145974400000L;
+ private static final long AUGUST_2_1580 = -12288758400000L;
+ private static final long AUGUST_2_1580_JULIAN = -12287894400000L;
+ private static final long MARCH_15_3456 = 46899993600000L;
+ private static final long DECEMBER_31_5000 = 95649033600000L;
+
+ private Activity mActivity;
+
+ @Before
+ public void setUp() {
+ mActivity = Robolectric.buildActivity(Activity.class).setup().get();
+ }
+
+ /**
+ * Asserts that after the input* params are passed to DateDialogNormalize.normalize(), that
+ * the DatePicker's state matches the output* params.
+ */
+ private void run(TimeZone defaultTimeZone,
+ int inputYear, int inputMonth, int inputDay, long inputMinMillis, long inputMaxMillis,
+ int outputYear, int outputMonth, int outputDay, long outputMinMillis,
+ long outputMaxMillis) {
+ TimeZone.setDefault(defaultTimeZone);
+ DatePicker picker = new DatePicker(mActivity);
+ DateDialogNormalizer.normalize(picker, null, inputYear, inputMonth, inputDay,
+ inputMinMillis, inputMaxMillis);
+
+ String pickerDate = String.format("%04d-%02d-%02d", picker.getYear(), picker.getMonth() + 1,
+ picker.getDayOfMonth());
+ String expectedDate = String.format("%04d-%02d-%02d", outputYear, outputMonth + 1,
+ outputDay);
+ assertEquals(expectedDate, pickerDate);
+ assertEquals(outputMinMillis, picker.getMinDate());
+ assertEquals(outputMaxMillis, picker.getMaxDate());
+ }
+
+ @Test
+ public void testNormalize() {
+ TimeZone originalDefaultTimeZone = TimeZone.getDefault();
+
+ // Typical case: value is between min and max.
+ run(GMT_TIME_ZONE,
+ 2015, 5, 25, JULY_31_2012, JULY_31_2017,
+ 2015, 5, 25, JULY_31_2012, JULY_31_2017);
+ run(PST_TIME_ZONE,
+ 2015, 5, 25, JULY_31_2012, JULY_31_2017,
+ 2015, 5, 25, JULY_31_2012_PST, JULY_31_2017_PST);
+
+ // Hours/minutes/seconds on min and max dates should be truncated.
+ run(PST_TIME_ZONE,
+ 2015, 5, 25, JULY_31_2014_1201AM, JULY_31_2017_1159PM,
+ 2015, 5, 25, JULY_31_2014_PST, JULY_31_2017_PST);
+ run(JAPAN_TIME_ZONE,
+ 2015, 5, 25, JULY_31_2014_9PM, JULY_31_2017_5AM,
+ 2015, 5, 25, JULY_31_2014_JAPAN, JULY_31_2017_JAPAN);
+
+ // If max < min, then max should be changed to min.
+ run(PST_TIME_ZONE,
+ 2015, 5, 25, JULY_31_2017, JULY_31_2012,
+ 2017, 6, 31, JULY_31_2017_PST, JULY_31_2017_PST);
+
+ // If the picker date is before min, it should be changed to min.
+ run(PST_TIME_ZONE,
+ 2015, 5, 25, JULY_31_2017, JULY_31_2018,
+ 2017, 6, 31, JULY_31_2017_PST, JULY_31_2018_PST);
+
+ // If the picker date is after max, it should be changed to max.
+ run(PST_TIME_ZONE,
+ 2025, 5, 25, JULY_31_2017, JULY_31_2018,
+ 2018, 6, 31, JULY_31_2017_PST, JULY_31_2018_PST);
+ run(JAPAN_TIME_ZONE,
+ 2025, 5, 25, JULY_31_2012, JULY_31_2014,
+ 2014, 6, 31, JULY_31_2012_JAPAN, JULY_31_2014_JAPAN);
+
+ // Ensure that dates before the Julian/Gregorian changeover in 1582 are treated correctly,
+ // as proleptic Gregorian dates, not as Julian dates.
+ run(GMT_TIME_ZONE,
+ 1581, 3, 4, AUGUST_2_1580, MARCH_15_3456,
+ 1581, 3, 4, AUGUST_2_1580_JULIAN, MARCH_15_3456);
+
+ // Ensure time ranges in the distant past and future work correctly.
+ run(GMT_TIME_ZONE,
+ 1215, 5, 15, JANUARY_1_0476, AUGUST_2_1580,
+ 1215, 5, 15, JANUARY_1_0476_JULIAN, AUGUST_2_1580_JULIAN);
+ run(GMT_TIME_ZONE,
+ 1608, 3, 10, JANUARY_1_0476, AUGUST_2_1580,
+ 1580, 7, 2, JANUARY_1_0476_JULIAN, AUGUST_2_1580_JULIAN);
+ run(GMT_TIME_ZONE,
+ 14, 7, 19, JANUARY_1_0476, AUGUST_2_1580,
+ 476, 0, 1, JANUARY_1_0476_JULIAN, AUGUST_2_1580_JULIAN);
+ run(GMT_TIME_ZONE,
+ 4444, 3, 4, MARCH_15_3456, DECEMBER_31_5000,
+ 4444, 3, 4, MARCH_15_3456, DECEMBER_31_5000);
+ run(GMT_TIME_ZONE,
+ 2001, 3, 4, MARCH_15_3456, DECEMBER_31_5000,
+ 3456, 2, 15, MARCH_15_3456, DECEMBER_31_5000);
+ run(GMT_TIME_ZONE,
+ 10001, 3, 4, MARCH_15_3456, DECEMBER_31_5000,
+ 5000, 11, 31, MARCH_15_3456, DECEMBER_31_5000);
+
+ TimeZone.setDefault(originalDefaultTimeZone);
+ }
+}
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectImplTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectImplTest.java
new file mode 100644
index 00000000000..1fbec4dd7f1
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectImplTest.java
@@ -0,0 +1,861 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.remoteobjects;
+
+import static org.mockito.AdditionalMatchers.and;
+import static org.mockito.AdditionalMatchers.aryEq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import org.chromium.blink.mojom.RemoteInvocationArgument;
+import org.chromium.blink.mojom.RemoteInvocationError;
+import org.chromium.blink.mojom.RemoteInvocationResult;
+import org.chromium.blink.mojom.RemoteInvocationResultValue;
+import org.chromium.blink.mojom.RemoteObject;
+import org.chromium.blink.mojom.SingletonJavaScriptValue;
+import org.chromium.mojo_base.mojom.String16;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Arrays;
+import java.util.function.Consumer;
+
+/**
+ * Tests the implementation of the Mojo object which wraps invocations
+ * of Java methods.
+ *
+ * Unchecked cast warnings are suppressed because {@link org.mockito.Mockito#mock(Class)} does not
+ * provide a way to cleanly deal with generics.
+ */
+@SuppressWarnings("unchecked")
+@RunWith(BlockJUnit4ClassRunner.class)
+public final class RemoteObjectImplTest {
+ /**
+ * Annotation which can be used in the way that {@link android.webkit.JavascriptInterface}
+ * would.
+ *
+ * A separate one is used to ensure that RemoteObject is actually respecting the parameter.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.METHOD})
+ private @interface TestJavascriptInterface {}
+
+ @Mock
+ private RemoteObjectImpl.Auditor mAuditor;
+
+ @Mock
+ private RemoteObjectImpl.ObjectIdAllocator mIdAllocator;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testHasMethodWithSafeAnnotationClass() {
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public void exposedMethod() {}
+
+ @TestJavascriptInterface
+ public void anotherExposedMethod() {}
+
+ @TestJavascriptInterface
+ public void anotherExposedMethod(int x) {}
+
+ @TestJavascriptInterface
+ private void privateAnnotatedMethod() {}
+
+ public void unannotatedMethod() {}
+ };
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.HasMethodResponse hasMethodResponse;
+
+ // This method is public and annotated; it should be exposed.
+ hasMethodResponse = mock(RemoteObject.HasMethodResponse.class);
+ remoteObject.hasMethod("exposedMethod", hasMethodResponse);
+ verify(hasMethodResponse).call(true);
+
+ // This method is private; it should not be exposed.
+ hasMethodResponse = mock(RemoteObject.HasMethodResponse.class);
+ remoteObject.hasMethod("privateAnnotatedMethod", hasMethodResponse);
+ verify(hasMethodResponse).call(false);
+
+ // This method is not annotated; it should not be exposed.
+ hasMethodResponse = mock(RemoteObject.HasMethodResponse.class);
+ remoteObject.hasMethod("unannotatedMethod", hasMethodResponse);
+ verify(hasMethodResponse).call(false);
+
+ // getMethods should provide a result consistent with this.
+ // The result must also be in sorted order and have no duplicates.
+ RemoteObject.GetMethodsResponse getMethodsResponse =
+ mock(RemoteObject.GetMethodsResponse.class);
+ remoteObject.getMethods(getMethodsResponse);
+ verify(getMethodsResponse)
+ .call(aryEq(new String[] {"anotherExposedMethod", "exposedMethod"}));
+ }
+
+ @Test
+ public void testHasMethodWithoutSafeAnnotationClass() {
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public void annotatedMethod() {}
+
+ public void unannotatedMethod() {}
+ };
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, null);
+ RemoteObject.HasMethodResponse hasMethodResponse;
+
+ // This method has an annotation; it should be exposed.
+ hasMethodResponse = mock(RemoteObject.HasMethodResponse.class);
+ remoteObject.hasMethod("annotatedMethod", hasMethodResponse);
+ verify(hasMethodResponse).call(true);
+
+ // This method doesn't, but passing null skips the check.
+ hasMethodResponse = mock(RemoteObject.HasMethodResponse.class);
+ remoteObject.hasMethod("unannotatedMethod", hasMethodResponse);
+ verify(hasMethodResponse).call(true);
+
+ // getMethods should provide a result consistent with this.
+ // The result must also be in sorted order.
+ // Note that this includes all of the normal java.lang.Object methods.
+ RemoteObject.GetMethodsResponse getMethodsResponse =
+ mock(RemoteObject.GetMethodsResponse.class);
+ remoteObject.getMethods(getMethodsResponse);
+
+ ArgumentCaptor<String[]> methodsCaptor = ArgumentCaptor.forClass(String[].class);
+ verify(getMethodsResponse).call(methodsCaptor.capture());
+ String[] methods = methodsCaptor.getValue();
+ Assert.assertTrue(Arrays.asList(methods).contains("annotatedMethod"));
+ Assert.assertTrue(Arrays.asList(methods).contains("unannotatedMethod"));
+ Assert.assertTrue(Arrays.asList(methods).contains("hashCode"));
+ String[] sortedMethods = Arrays.copyOf(methods, methods.length);
+ Arrays.sort(sortedMethods);
+ Assert.assertArrayEquals(sortedMethods, methods);
+ }
+
+ @Test
+ public void testInvokeMethodBasic() {
+ final Runnable runnable = mock(Runnable.class);
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public void frobnicate() {
+ runnable.run();
+ }
+ };
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod("frobnicate", new RemoteInvocationArgument[] {}, response);
+ remoteObject.invokeMethod("frobnicate", new RemoteInvocationArgument[] {}, response);
+
+ verify(runnable, times(2)).run();
+ verify(response, times(2)).call(resultIsOk());
+ }
+
+ @Test
+ public void testInvokeMethodOverloadUsingArity() {
+ final Consumer<Integer> consumer = (Consumer<Integer>) mock(Consumer.class);
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public void frobnicate() {
+ consumer.accept(0);
+ }
+
+ @TestJavascriptInterface
+ public void frobnicate(Object argument) {
+ consumer.accept(1);
+ }
+ };
+
+ // The method overload to be called depends on the number of arguments supplied.
+ // TODO(jbroman): Once it's possible to construct a non-trivial argument, do so.
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod("frobnicate", new RemoteInvocationArgument[] {}, response);
+ remoteObject.invokeMethod(
+ "frobnicate", new RemoteInvocationArgument[] {numberArgument(0)}, response);
+
+ InOrder inOrder = inOrder(consumer);
+ inOrder.verify(consumer).accept(0);
+ inOrder.verify(consumer).accept(1);
+ verify(response, times(2)).call(resultIsOk());
+ }
+
+ /**
+ * Reports to the runnable it is given when its static method is called.
+ * Works around the fact that a static method cannot capture variables.
+ */
+ static class ObjectWithStaticMethod {
+ static Runnable sRunnable;
+
+ @TestJavascriptInterface
+ public static void staticMethod() {
+ sRunnable.run();
+ }
+ }
+
+ @Test
+ public void testStaticMethod() {
+ // Static methods should work just like non-static ones.
+
+ Object target = new ObjectWithStaticMethod();
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+
+ Runnable runnable = mock(Runnable.class);
+ ObjectWithStaticMethod.sRunnable = runnable;
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod("staticMethod", new RemoteInvocationArgument[] {}, response);
+ ObjectWithStaticMethod.sRunnable = null;
+ verify(runnable).run();
+ verify(response).call(resultIsOk());
+
+ RemoteObject.HasMethodResponse hasMethodResponse =
+ mock(RemoteObject.HasMethodResponse.class);
+ remoteObject.hasMethod("staticMethod", hasMethodResponse);
+ verify(hasMethodResponse).call(true);
+
+ RemoteObject.GetMethodsResponse getMethodsResponse =
+ mock(RemoteObject.GetMethodsResponse.class);
+ remoteObject.getMethods(getMethodsResponse);
+ verify(getMethodsResponse).call(aryEq(new String[] {"staticMethod"}));
+ }
+
+ @Test
+ public void testInvokeMethodNotFound() {
+ Object target = new Object() {
+ public void unexposedMethod() {
+ Assert.fail("Unexposed method should not be called.");
+ }
+
+ @TestJavascriptInterface
+ public void exposedMethodWithWrongArity(Object argument) {
+ Assert.fail("Exposed method should only be called with the correct arity.");
+ }
+ };
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod("nonexistentMethod", new RemoteInvocationArgument[] {}, response);
+ remoteObject.invokeMethod("unexposedMethod", new RemoteInvocationArgument[] {}, response);
+ remoteObject.invokeMethod(
+ "exposedMethodWithWrongArity", new RemoteInvocationArgument[] {}, response);
+
+ verify(response, times(3)).call(resultHasError(RemoteInvocationError.METHOD_NOT_FOUND));
+ }
+
+ @Test
+ public void testObjectGetClassBlocked() {
+ Object target = new Object();
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ RemoteObject remoteObject = newRemoteObjectImpl(target, null);
+ remoteObject.invokeMethod("getClass", new RemoteInvocationArgument[] {}, response);
+
+ verify(response).call(resultHasError(RemoteInvocationError.OBJECT_GET_CLASS_BLOCKED));
+ verify(mAuditor).onObjectGetClassInvocationAttempt();
+ }
+
+ @Test
+ public void testOverloadedGetClassPermitted() {
+ final Runnable runnable = mock(Runnable.class);
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public void getClass(Object o) {
+ runnable.run();
+ }
+ };
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ remoteObject.invokeMethod(
+ "getClass", new RemoteInvocationArgument[] {numberArgument(0)}, response);
+
+ verify(runnable).run();
+ verify(response).call(resultIsOk());
+ verify(mAuditor, never()).onObjectGetClassInvocationAttempt();
+ }
+
+ @Test
+ public void testMethodReturningArrayIgnored() {
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public int[] returnsIntArray() {
+ Assert.fail("Method returning array should not be called.");
+ return null;
+ }
+ };
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod("returnsIntArray", new RemoteInvocationArgument[] {}, response);
+
+ verify(response).call(resultIsUndefined());
+ }
+
+ @Test
+ public void testInvocationTargetException() {
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public void exceptionThrowingMethod() throws Exception {
+ throw new Exception("This exception is expected during test. Do not be alarmed.");
+ }
+ };
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod(
+ "exceptionThrowingMethod", new RemoteInvocationArgument[] {}, response);
+
+ verify(response).call(resultHasError(RemoteInvocationError.EXCEPTION_THROWN));
+ }
+
+ private static class VariantConsumer {
+ private final Consumer<Object> mConsumer;
+
+ public VariantConsumer(Consumer<Object> consumer) {
+ mConsumer = consumer;
+ }
+
+ @TestJavascriptInterface
+ public void consumeByte(byte b) {
+ mConsumer.accept(b);
+ }
+ @TestJavascriptInterface
+ public void consumeChar(char c) {
+ mConsumer.accept(c);
+ }
+ @TestJavascriptInterface
+ public void consumeShort(short s) {
+ mConsumer.accept(s);
+ }
+ @TestJavascriptInterface
+ public void consumeInt(int i) {
+ mConsumer.accept(i);
+ }
+ @TestJavascriptInterface
+ public void consumeLong(long l) {
+ mConsumer.accept(l);
+ }
+ @TestJavascriptInterface
+ public void consumeFloat(float f) {
+ mConsumer.accept(f);
+ }
+ @TestJavascriptInterface
+ public void consumeDouble(double d) {
+ mConsumer.accept(d);
+ }
+ @TestJavascriptInterface
+ public void consumeBoolean(boolean b) {
+ mConsumer.accept(b);
+ }
+ @TestJavascriptInterface
+ public void consumeString(String s) {
+ mConsumer.accept(s);
+ }
+ @TestJavascriptInterface
+ public void consumeObjectArray(Object[] oa) {
+ mConsumer.accept(oa);
+ }
+ @TestJavascriptInterface
+ public void consumeIntArray(int[] ia) {
+ mConsumer.accept(ia);
+ }
+ @TestJavascriptInterface
+ public void consumeStringArray(String[] sa) {
+ mConsumer.accept(sa);
+ }
+ @TestJavascriptInterface
+ public void consumeObject(Object o) {
+ mConsumer.accept(o);
+ }
+ }
+
+ @Test
+ public void testArgumentConversionNumber() {
+ final Consumer<Object> consumer = (Consumer<Object>) mock(Consumer.class);
+ Object target = new VariantConsumer(consumer);
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod(
+ "consumeByte", new RemoteInvocationArgument[] {numberArgument(356)}, response);
+ remoteObject.invokeMethod(
+ "consumeChar", new RemoteInvocationArgument[] {numberArgument(356)}, response);
+ remoteObject.invokeMethod(
+ "consumeChar", new RemoteInvocationArgument[] {numberArgument(1.5)}, response);
+ remoteObject.invokeMethod(
+ "consumeChar", new RemoteInvocationArgument[] {numberArgument(-0.0)}, response);
+ remoteObject.invokeMethod(
+ "consumeShort", new RemoteInvocationArgument[] {numberArgument(32768)}, response);
+ remoteObject.invokeMethod(
+ "consumeInt", new RemoteInvocationArgument[] {numberArgument(-1.5)}, response);
+ remoteObject.invokeMethod("consumeLong",
+ new RemoteInvocationArgument[] {numberArgument(Double.POSITIVE_INFINITY)},
+ response);
+ remoteObject.invokeMethod("consumeFloat",
+ new RemoteInvocationArgument[] {numberArgument(3.141592654)}, response);
+ remoteObject.invokeMethod("consumeDouble",
+ new RemoteInvocationArgument[] {numberArgument(Double.NaN)}, response);
+ remoteObject.invokeMethod(
+ "consumeBoolean", new RemoteInvocationArgument[] {numberArgument(1)}, response);
+ remoteObject.invokeMethod("consumeString",
+ new RemoteInvocationArgument[] {numberArgument(-1.66666666666)}, response);
+ remoteObject.invokeMethod("consumeString",
+ new RemoteInvocationArgument[] {numberArgument(Double.NaN)}, response);
+ remoteObject.invokeMethod("consumeString",
+ new RemoteInvocationArgument[] {numberArgument(Double.NEGATIVE_INFINITY)},
+ response);
+ remoteObject.invokeMethod(
+ "consumeString", new RemoteInvocationArgument[] {numberArgument(-0.0)}, response);
+ remoteObject.invokeMethod("consumeString",
+ new RemoteInvocationArgument[] {numberArgument(123456789)}, response);
+ remoteObject.invokeMethod("consumeString",
+ new RemoteInvocationArgument[] {numberArgument(123000000.1)}, response);
+ remoteObject.invokeMethod(
+ "consumeObjectArray", new RemoteInvocationArgument[] {numberArgument(6)}, response);
+ remoteObject.invokeMethod(
+ "consumeObject", new RemoteInvocationArgument[] {numberArgument(6)}, response);
+
+ verify(consumer).accept((byte) 100);
+ verify(consumer).accept('\u0164');
+ verify(consumer, times(2)).accept('\u0000');
+ verify(consumer).accept((short) -32768);
+ verify(consumer).accept((int) -1);
+ verify(consumer).accept(Long.MAX_VALUE);
+ verify(consumer).accept((float) 3.141592654);
+ verify(consumer).accept(Double.NaN);
+ verify(consumer).accept(false);
+ verify(consumer).accept("-1.66667");
+ verify(consumer).accept("nan");
+ verify(consumer).accept("-inf");
+ verify(consumer).accept("-0");
+ verify(consumer).accept("123456789");
+ verify(consumer).accept("1.23e+08");
+ verify(consumer, times(2)).accept(null);
+ verify(response, times(18)).call(resultIsOk());
+ }
+
+ @Test
+ public void testArgumentConversionBoolean() {
+ final Consumer<Object> consumer = (Consumer<Object>) mock(Consumer.class);
+ Object target = new VariantConsumer(consumer);
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod(
+ "consumeByte", new RemoteInvocationArgument[] {booleanArgument(true)}, response);
+ remoteObject.invokeMethod(
+ "consumeChar", new RemoteInvocationArgument[] {booleanArgument(true)}, response);
+ remoteObject.invokeMethod(
+ "consumeShort", new RemoteInvocationArgument[] {booleanArgument(true)}, response);
+ remoteObject.invokeMethod(
+ "consumeInt", new RemoteInvocationArgument[] {booleanArgument(true)}, response);
+ remoteObject.invokeMethod(
+ "consumeLong", new RemoteInvocationArgument[] {booleanArgument(true)}, response);
+ remoteObject.invokeMethod(
+ "consumeFloat", new RemoteInvocationArgument[] {booleanArgument(true)}, response);
+ remoteObject.invokeMethod(
+ "consumeDouble", new RemoteInvocationArgument[] {booleanArgument(true)}, response);
+ remoteObject.invokeMethod(
+ "consumeString", new RemoteInvocationArgument[] {booleanArgument(true)}, response);
+ remoteObject.invokeMethod(
+ "consumeString", new RemoteInvocationArgument[] {booleanArgument(false)}, response);
+ remoteObject.invokeMethod("consumeObjectArray",
+ new RemoteInvocationArgument[] {booleanArgument(true)}, response);
+ remoteObject.invokeMethod(
+ "consumeObject", new RemoteInvocationArgument[] {booleanArgument(true)}, response);
+
+ InOrder inOrder = inOrder(consumer);
+ inOrder.verify(consumer).accept((byte) 0);
+ inOrder.verify(consumer).accept('\u0000');
+ inOrder.verify(consumer).accept((short) 0);
+ inOrder.verify(consumer).accept((int) 0);
+ inOrder.verify(consumer).accept((long) 0);
+ inOrder.verify(consumer).accept((float) 0);
+ inOrder.verify(consumer).accept((double) 0);
+ inOrder.verify(consumer).accept("true");
+ inOrder.verify(consumer).accept("false");
+ inOrder.verify(consumer, times(2)).accept(null);
+ }
+
+ @Test
+ public void testArgumentConversionString() {
+ final Consumer<Object> consumer = (Consumer<Object>) mock(Consumer.class);
+ Object target = new VariantConsumer(consumer);
+ String stringWithNonAsciiCharacterAndUnpairedSurrogate = "caf\u00e9\ud800";
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod(
+ "consumeByte", new RemoteInvocationArgument[] {stringArgument("hello")}, response);
+ remoteObject.invokeMethod(
+ "consumeChar", new RemoteInvocationArgument[] {stringArgument("hello")}, response);
+ remoteObject.invokeMethod(
+ "consumeShort", new RemoteInvocationArgument[] {stringArgument("hello")}, response);
+ remoteObject.invokeMethod(
+ "consumeInt", new RemoteInvocationArgument[] {stringArgument("hello")}, response);
+ remoteObject.invokeMethod(
+ "consumeLong", new RemoteInvocationArgument[] {stringArgument("hello")}, response);
+ remoteObject.invokeMethod(
+ "consumeFloat", new RemoteInvocationArgument[] {stringArgument("hello")}, response);
+ remoteObject.invokeMethod("consumeDouble",
+ new RemoteInvocationArgument[] {stringArgument("hello")}, response);
+ remoteObject.invokeMethod("consumeString",
+ new RemoteInvocationArgument[] {stringArgument("hello")}, response);
+ remoteObject.invokeMethod("consumeString",
+ new RemoteInvocationArgument[] {
+ stringArgument(stringWithNonAsciiCharacterAndUnpairedSurrogate)},
+ response);
+ remoteObject.invokeMethod("consumeObjectArray",
+ new RemoteInvocationArgument[] {stringArgument("hello")}, response);
+ remoteObject.invokeMethod("consumeObject",
+ new RemoteInvocationArgument[] {stringArgument("hello")}, response);
+
+ InOrder inOrder = inOrder(consumer);
+ inOrder.verify(consumer).accept((byte) 0);
+ inOrder.verify(consumer).accept('\u0000');
+ inOrder.verify(consumer).accept((short) 0);
+ inOrder.verify(consumer).accept((int) 0);
+ inOrder.verify(consumer).accept((long) 0);
+ inOrder.verify(consumer).accept((float) 0);
+ inOrder.verify(consumer).accept((double) 0);
+ inOrder.verify(consumer).accept("hello");
+ inOrder.verify(consumer).accept(stringWithNonAsciiCharacterAndUnpairedSurrogate);
+ inOrder.verify(consumer, times(2)).accept(null);
+ }
+
+ @Test
+ public void testArgumentConversionNull() {
+ final Consumer<Object> consumer = (Consumer<Object>) mock(Consumer.class);
+ Object target = new VariantConsumer(consumer);
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ RemoteInvocationArgument args[] = {nullArgument()};
+ remoteObject.invokeMethod("consumeByte", args, response);
+ remoteObject.invokeMethod("consumeChar", args, response);
+ remoteObject.invokeMethod("consumeShort", args, response);
+ remoteObject.invokeMethod("consumeInt", args, response);
+ remoteObject.invokeMethod("consumeLong", args, response);
+ remoteObject.invokeMethod("consumeFloat", args, response);
+ remoteObject.invokeMethod("consumeDouble", args, response);
+ remoteObject.invokeMethod("consumeString", args, response);
+ remoteObject.invokeMethod("consumeObjectArray", args, response);
+ remoteObject.invokeMethod("consumeObject", args, response);
+
+ verify(consumer).accept((byte) 0);
+ verify(consumer).accept('\u0000');
+ verify(consumer).accept((short) 0);
+ verify(consumer).accept((int) 0);
+ verify(consumer).accept((long) 0);
+ verify(consumer).accept((float) 0);
+ verify(consumer).accept((double) 0);
+ verify(consumer, times(3)).accept(null);
+ }
+
+ @Test
+ public void testArgumentConversionUndefined() {
+ final Consumer<Object> consumer = (Consumer<Object>) mock(Consumer.class);
+ Object target = new VariantConsumer(consumer);
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ RemoteInvocationArgument args[] = {undefinedArgument()};
+ remoteObject.invokeMethod("consumeByte", args, response);
+ remoteObject.invokeMethod("consumeChar", args, response);
+ remoteObject.invokeMethod("consumeShort", args, response);
+ remoteObject.invokeMethod("consumeInt", args, response);
+ remoteObject.invokeMethod("consumeLong", args, response);
+ remoteObject.invokeMethod("consumeFloat", args, response);
+ remoteObject.invokeMethod("consumeDouble", args, response);
+ remoteObject.invokeMethod("consumeString", args, response);
+ remoteObject.invokeMethod("consumeObjectArray", args, response);
+ remoteObject.invokeMethod("consumeObject", args, response);
+
+ verify(consumer).accept((byte) 0);
+ verify(consumer).accept('\u0000');
+ verify(consumer).accept((short) 0);
+ verify(consumer).accept((int) 0);
+ verify(consumer).accept((long) 0);
+ verify(consumer).accept((float) 0);
+ verify(consumer).accept((double) 0);
+ verify(consumer).accept("undefined");
+ verify(consumer, times(2)).accept(null);
+ }
+
+ @Test
+ public void testArgumentConversionArray() {
+ final Consumer<Object> consumer = (Consumer<Object>) mock(Consumer.class);
+ Object target = new VariantConsumer(consumer);
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ RemoteInvocationArgument args[] = {
+ arrayArgument(numberArgument(3.14159), booleanArgument(true),
+ stringArgument("Hello"), arrayArgument(), undefinedArgument())};
+ remoteObject.invokeMethod("consumeByte", args, response);
+ remoteObject.invokeMethod("consumeChar", args, response);
+ remoteObject.invokeMethod("consumeShort", args, response);
+ remoteObject.invokeMethod("consumeInt", args, response);
+ remoteObject.invokeMethod("consumeLong", args, response);
+ remoteObject.invokeMethod("consumeFloat", args, response);
+ remoteObject.invokeMethod("consumeDouble", args, response);
+ remoteObject.invokeMethod("consumeBoolean", args, response);
+ remoteObject.invokeMethod("consumeString", args, response);
+ remoteObject.invokeMethod("consumeIntArray", args, response);
+ remoteObject.invokeMethod("consumeStringArray", args, response);
+ remoteObject.invokeMethod("consumeObjectArray", args, response);
+ remoteObject.invokeMethod("consumeObject", args, response);
+
+ verify(consumer).accept((byte) 0);
+ verify(consumer).accept('\u0000');
+ verify(consumer).accept((short) 0);
+ verify(consumer).accept((int) 0);
+ verify(consumer).accept((long) 0);
+ verify(consumer).accept((float) 0);
+ verify(consumer).accept((double) 0);
+ verify(consumer).accept(false);
+ verify(consumer).accept("undefined");
+ verify(consumer).accept(aryEq(new int[] {3, 0, 0, 0, 0}));
+ verify(consumer).accept(aryEq(new String[] {null, null, "Hello", null, null}));
+ verify(consumer, times(2)).accept(null);
+ }
+
+ @Test
+ public void testResultConversionVoid() {
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public void returnsVoid() {}
+ };
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod("returnsVoid", new RemoteInvocationArgument[] {}, response);
+
+ verify(response).call(resultIsUndefined());
+ }
+
+ @Test
+ public void testConversionResultNumber() {
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public int returnsInt() {
+ return 42;
+ }
+
+ @TestJavascriptInterface
+ public float returnsFloat() {
+ return -1.5f;
+ }
+
+ @TestJavascriptInterface
+ public char returnsChar() {
+ return '\ufeed';
+ }
+ };
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod("returnsInt", new RemoteInvocationArgument[] {}, response);
+ remoteObject.invokeMethod("returnsFloat", new RemoteInvocationArgument[] {}, response);
+ remoteObject.invokeMethod("returnsChar", new RemoteInvocationArgument[] {}, response);
+
+ verify(response).call(resultIsNumber(42));
+ verify(response).call(resultIsNumber(-1.5f));
+ verify(response).call(resultIsNumber(0xfeed));
+ }
+
+ @Test
+ public void testConversionResultBoolean() {
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public boolean returnsTrue() {
+ return true;
+ }
+
+ @TestJavascriptInterface
+ public boolean returnsFalse() {
+ return false;
+ }
+ };
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod("returnsTrue", new RemoteInvocationArgument[] {}, response);
+ remoteObject.invokeMethod("returnsFalse", new RemoteInvocationArgument[] {}, response);
+
+ InOrder inOrder = inOrder(response);
+ inOrder.verify(response).call(resultIsBoolean(true));
+ inOrder.verify(response).call(resultIsBoolean(false));
+ }
+
+ @Test
+ public void testConversionResultString() {
+ final String stringWithNonAsciiCharacterAndUnpairedSurrogate = "caf\u00e9\ud800";
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public String returnsHello() {
+ return "Hello";
+ }
+
+ @TestJavascriptInterface
+ public String returnsExoticString() {
+ return stringWithNonAsciiCharacterAndUnpairedSurrogate;
+ }
+
+ @TestJavascriptInterface
+ public String returnsNull() {
+ return null;
+ }
+ };
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod("returnsHello", new RemoteInvocationArgument[] {}, response);
+ remoteObject.invokeMethod(
+ "returnsExoticString", new RemoteInvocationArgument[] {}, response);
+ remoteObject.invokeMethod("returnsNull", new RemoteInvocationArgument[] {}, response);
+
+ verify(response).call(resultIsString("Hello"));
+ verify(response).call(resultIsString(stringWithNonAsciiCharacterAndUnpairedSurrogate));
+ verify(response).call(resultIsUndefined());
+ }
+
+ @Test
+ public void testConversionResultObject() {
+ final Object foo = new Object();
+ Object target = new Object() {
+ @TestJavascriptInterface
+ public Object getFoo() {
+ return foo;
+ }
+ };
+
+ when(mIdAllocator.getObjectId(foo)).thenReturn(42);
+
+ RemoteObject remoteObject = newRemoteObjectImpl(target, TestJavascriptInterface.class);
+ RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class);
+ remoteObject.invokeMethod("getFoo", new RemoteInvocationArgument[] {}, response);
+
+ verify(response).call(resultIsObject(42));
+ }
+
+ private RemoteInvocationResult resultHasError(final int error) {
+ return ArgumentMatchers.argThat(result -> result.error == error);
+ }
+
+ private RemoteInvocationResult resultIsOk() {
+ return resultHasError(RemoteInvocationError.OK);
+ }
+
+ private RemoteInvocationResult resultIsUndefined() {
+ return and(resultIsOk(), ArgumentMatchers.argThat(result -> {
+ return result.value != null
+ && result.value.which() == RemoteInvocationResultValue.Tag.SingletonValue
+ && result.value.getSingletonValue() == SingletonJavaScriptValue.UNDEFINED;
+ }));
+ }
+
+ private RemoteInvocationResult resultIsNumber(final double numberValue) {
+ return and(resultIsOk(), ArgumentMatchers.argThat(result -> {
+ return result.value != null
+ && result.value.which() == RemoteInvocationResultValue.Tag.NumberValue
+ && result.value.getNumberValue() == numberValue;
+ }));
+ }
+
+ private RemoteInvocationResult resultIsBoolean(final boolean booleanValue) {
+ return and(resultIsOk(), ArgumentMatchers.argThat(result -> {
+ return result.value != null
+ && result.value.which() == RemoteInvocationResultValue.Tag.BooleanValue
+ && result.value.getBooleanValue() == booleanValue;
+ }));
+ }
+
+ private RemoteInvocationResult resultIsString(String stringValue) {
+ final short[] expectedData = new short[stringValue.length()];
+ for (int i = 0; i < expectedData.length; i++) {
+ expectedData[i] = (short) stringValue.charAt(i);
+ }
+ return and(resultIsOk(), ArgumentMatchers.argThat(result -> {
+ return result.value != null
+ && result.value.which() == RemoteInvocationResultValue.Tag.StringValue
+ && Arrays.equals(result.value.getStringValue().data, expectedData);
+ }));
+ }
+
+ private RemoteInvocationResult resultIsObject(final int objectId) {
+ return and(resultIsOk(), ArgumentMatchers.argThat(result -> {
+ return result.value != null
+ && result.value.which() == RemoteInvocationResultValue.Tag.ObjectId
+ && result.value.getObjectId() == objectId;
+ }));
+ }
+
+ private RemoteInvocationArgument numberArgument(double numberValue) {
+ RemoteInvocationArgument argument = new RemoteInvocationArgument();
+ argument.setNumberValue(numberValue);
+ return argument;
+ }
+
+ private RemoteInvocationArgument booleanArgument(boolean booleanValue) {
+ RemoteInvocationArgument argument = new RemoteInvocationArgument();
+ argument.setBooleanValue(booleanValue);
+ return argument;
+ }
+
+ private RemoteInvocationArgument stringArgument(String stringValue) {
+ String16 string16 = new String16();
+ string16.data = new short[stringValue.length()];
+ for (int i = 0; i < stringValue.length(); i++) {
+ string16.data[i] = (short) stringValue.charAt(i);
+ }
+ RemoteInvocationArgument argument = new RemoteInvocationArgument();
+ argument.setStringValue(string16);
+ return argument;
+ }
+
+ private RemoteInvocationArgument nullArgument() {
+ RemoteInvocationArgument argument = new RemoteInvocationArgument();
+ argument.setSingletonValue(SingletonJavaScriptValue.NULL);
+ return argument;
+ }
+
+ private RemoteInvocationArgument undefinedArgument() {
+ RemoteInvocationArgument argument = new RemoteInvocationArgument();
+ argument.setSingletonValue(SingletonJavaScriptValue.UNDEFINED);
+ return argument;
+ }
+
+ private RemoteInvocationArgument arrayArgument(RemoteInvocationArgument... elements) {
+ RemoteInvocationArgument argument = new RemoteInvocationArgument();
+ argument.setArrayValue(elements);
+ return argument;
+ }
+
+ private RemoteObjectImpl newRemoteObjectImpl(
+ Object target, Class<? extends Annotation> annotation) {
+ return new RemoteObjectImpl(target, annotation, mAuditor, mIdAllocator);
+ }
+}
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectRegistryTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectRegistryTest.java
new file mode 100644
index 00000000000..3b2225cf9b7
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectRegistryTest.java
@@ -0,0 +1,72 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.remoteobjects;
+
+import static org.hamcrest.Matchers.isIn;
+import static org.hamcrest.Matchers.not;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Tests the object registry, which maintains bidirectional object/ID mappings.
+ */
+@RunWith(BlockJUnit4ClassRunner.class)
+public final class RemoteObjectRegistryTest {
+ @Test
+ public void testMaintainsRetainingSet() {
+ // This is how the registry is expected to keep itself alive, despite only being held weakly
+ // from its main consumer.
+ Set<RemoteObjectRegistry> retainingSet = new HashSet<>();
+ RemoteObjectRegistry registry = new RemoteObjectRegistry(retainingSet);
+ Assert.assertThat(registry, isIn(retainingSet));
+ registry.close();
+ Assert.assertThat(registry, not(isIn(retainingSet)));
+ }
+
+ @Test
+ public void testGetObjectId() {
+ // We should get an ID that can be used to retrieve the object.
+ Set<RemoteObjectRegistry> retainingSet = new HashSet<>();
+ RemoteObjectRegistry registry = new RemoteObjectRegistry(retainingSet);
+ Object o = new Object();
+ int id = registry.getObjectId(o);
+ Assert.assertSame(o, registry.getObjectById(id));
+ }
+
+ @Test
+ public void testGetObjectIdSame() {
+ // The ID should be the same if retrieved twice.
+ Set<RemoteObjectRegistry> retainingSet = new HashSet<>();
+ RemoteObjectRegistry registry = new RemoteObjectRegistry(retainingSet);
+ Object o = new Object();
+ int id = registry.getObjectId(o);
+ Assert.assertEquals(id, registry.getObjectId(o));
+ }
+
+ @Test
+ public void testGetObjectIdAfterRemoval() {
+ // It should still work if we have previously added and removed the object.
+ Set<RemoteObjectRegistry> retainingSet = new HashSet<>();
+ RemoteObjectRegistry registry = new RemoteObjectRegistry(retainingSet);
+ Object o = new Object();
+ int id = registry.getObjectId(o);
+ registry.removeObjectById(id);
+ int id2 = registry.getObjectId(o);
+ Assert.assertSame(o, registry.getObjectById(id2));
+ }
+
+ @Test
+ public void testReturnsNullForNonExistentObject() {
+ Set<RemoteObjectRegistry> retainingSet = new HashSet<>();
+ RemoteObjectRegistry registry = new RemoteObjectRegistry(retainingSet);
+ Assert.assertNull(registry.getObjectById(123));
+ }
+}
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/selection/MagnifierAnimatorTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/selection/MagnifierAnimatorTest.java
new file mode 100644
index 00000000000..d69b693b84e
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/selection/MagnifierAnimatorTest.java
@@ -0,0 +1,158 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.selection;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowLog;
+
+import org.chromium.base.test.util.Feature;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+
+/**
+ * Unit tests for MagnifierAnimator.
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class MagnifierAnimatorTest {
+ private MagnifierWrapper mMagnifier;
+ private MagnifierAnimator mAnimator;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ ShadowLog.stream = System.out;
+
+ mMagnifier = Mockito.mock(MagnifierWrapper.class);
+ when(mMagnifier.isAvailable()).thenReturn(true);
+
+ mAnimator = new MagnifierAnimator(mMagnifier);
+ }
+
+ @Test
+ @Feature({"Selection", "TextSelectionMagnifier"})
+ public void testNormalFlow() {
+ InOrder order = inOrder(mMagnifier);
+
+ // Start to move magnifier.
+ mAnimator.handleDragStartedOrMoved(10.f, 10.f);
+ order.verify(mMagnifier).show(10.f, 10.f);
+ assertFalse("Animator shouldn't run before we change position", isAnimatorRunning());
+
+ // Second move doesn't change y-coordinate.
+ mAnimator.handleDragStartedOrMoved(11.f, 10.f);
+ order.verify(mMagnifier).show(11.f, 10.f);
+
+ // Change y-coordinate. Should trigger animator.
+ mAnimator.handleDragStartedOrMoved(11.f, 15.f);
+ assertTrue("Animator should started to run", isAnimatorRunning());
+
+ for (int i = 0; i <= 10; ++i) {
+ final float fraction = 0.1f * i;
+ setAnimatorCurrentFraction(fraction);
+ }
+
+ order.verify(mMagnifier).show(11.f, 15.f);
+
+ mAnimator.handleDragStopped();
+ order.verify(mMagnifier).dismiss();
+ assertFalse("Animator should be cancelled", isAnimatorRunning());
+ }
+
+ @Test
+ @Feature({"Selection", "TextSelectionMagnifier"})
+ public void testTwoConsecutiveYMoves() {
+ InOrder order = inOrder(mMagnifier);
+
+ // Start to move magnifier.
+ mAnimator.handleDragStartedOrMoved(10.f, 10.f);
+ order.verify(mMagnifier).show(10.f, 10.f);
+ assertFalse("Animator shouldn't run before we change position", isAnimatorRunning());
+
+ // Change y-coordinate. Should trigger animator.
+ mAnimator.handleDragStartedOrMoved(11.f, 15.f);
+ order.verify(mMagnifier).show(10.f, 10.f);
+ assertTrue("Animator should started to run", isAnimatorRunning());
+
+ float currentX = 0.f;
+ float currentY = 0.f;
+ // Animation running.
+ for (int i = 0; i < 5; ++i) {
+ final float fraction = 0.1f * i;
+ currentX = currentValue(10.f, 11.f, fraction);
+ currentY = currentValue(10.f, 15.f, fraction);
+ setAnimatorCurrentFraction(fraction);
+ order.verify(mMagnifier).show(currentX, currentY);
+ }
+
+ assertTrue("Animator should still run", isAnimatorRunning());
+ mAnimator.handleDragStartedOrMoved(13.f, 20.f);
+ order.verify(mMagnifier).show(currentX, currentY);
+ assertTrue("Animator should started to run again", isAnimatorRunning());
+
+ for (int i = 0; i <= 10; ++i) {
+ final float fraction = 0.1f * i;
+ setAnimatorCurrentFraction(fraction);
+ }
+
+ order.verify(mMagnifier).show(13.f, 20.f);
+ order.verify(mMagnifier, never()).show(11.f, 15.f);
+ }
+
+ @Test
+ @Feature({"Selection", "TextSelectionMagnifier"})
+ public void testCancelMagnifierDuringAnimation() {
+ InOrder order = inOrder(mMagnifier);
+
+ // Start to move magnifier.
+ mAnimator.handleDragStartedOrMoved(10.f, 10.f);
+ order.verify(mMagnifier).show(10.f, 10.f);
+ assertFalse("Animator shouldn't run before we change position", isAnimatorRunning());
+
+ // Change y-coordinate. Should trigger animator.
+ mAnimator.handleDragStartedOrMoved(11.f, 15.f);
+ // The previous end point is our current start point.
+ order.verify(mMagnifier).show(10.f, 10.f);
+ assertTrue("Animator should started to run", isAnimatorRunning());
+
+ // Animation running.
+ for (int i = 0; i < 5; ++i) {
+ final float fraction = 0.1f * i;
+ final float currentX = currentValue(10.f, 11.f, fraction);
+ final float currentY = currentValue(10.f, 15.f, fraction);
+ setAnimatorCurrentFraction(fraction);
+ order.verify(mMagnifier).show(currentX, currentY);
+ }
+
+ mAnimator.handleDragStopped();
+ order.verify(mMagnifier, never()).show(anyFloat(), anyFloat());
+ order.verify(mMagnifier).dismiss();
+ assertFalse("Animator should be cancelled", isAnimatorRunning());
+ }
+
+ private boolean isAnimatorRunning() {
+ return mAnimator.getValueAnimatorForTesting().isRunning();
+ }
+
+ private void setAnimatorCurrentFraction(float fraction) {
+ mAnimator.getValueAnimatorForTesting().setCurrentFraction(fraction);
+ }
+
+ private float currentValue(float start, float target, float fraction) {
+ return start + (target - start) * fraction;
+ }
+}
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java
new file mode 100644
index 00000000000..8ff9ed999b2
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java
@@ -0,0 +1,551 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.selection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.when;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+import android.view.ActionMode;
+import android.view.ViewGroup;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowLog;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.Feature;
+import org.chromium.content.browser.ContentClassFactory;
+import org.chromium.content.browser.PopupController;
+import org.chromium.content.browser.RenderCoordinatesImpl;
+import org.chromium.content.browser.webcontents.WebContentsImpl;
+import org.chromium.content_public.browser.SelectionClient;
+import org.chromium.content_public.browser.SelectionMetricsLogger;
+import org.chromium.content_public.browser.SelectionPopupController;
+import org.chromium.ui.base.MenuSourceType;
+import org.chromium.ui.base.ViewAndroidDelegate;
+import org.chromium.ui.base.WindowAndroid;
+import org.chromium.ui.touch_selection.SelectionEventType;
+
+/**
+ * Unit tests for {@link SelectionPopupController}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class SelectionPopupControllerTest {
+ private SelectionPopupControllerImpl mController;
+ private Context mContext;
+ private WindowAndroid mWindowAndroid;
+ private WebContentsImpl mWebContents;
+ private ViewGroup mView;
+ private ViewAndroidDelegate mViewAndroidDelegate;
+ private ActionMode mActionMode;
+ private PackageManager mPackageManager;
+ private SmartSelectionMetricsLogger mLogger;
+ private RenderCoordinatesImpl mRenderCoordinates;
+ private ContentResolver mContentResolver;
+ private PopupController mPopupController;
+ private ContentClassFactory mOriginalContentClassFactory;
+
+ private static final String MOUNTAIN_FULL = "585 Franklin Street, Mountain View, CA 94041";
+ private static final String MOUNTAIN = "Mountain";
+ private static final String AMPHITHEATRE_FULL = "1600 Amphitheatre Parkway";
+ private static final String AMPHITHEATRE = "Amphitheatre";
+
+ private static class TestSelectionClient implements SelectionClient {
+ private SelectionClient.Result mResult;
+ private SelectionClient.ResultCallback mResultCallback;
+ private SmartSelectionMetricsLogger mLogger;
+
+ @Override
+ public void onSelectionChanged(String selection) {}
+
+ @Override
+ public void onSelectionEvent(int eventType, float posXPix, float poxYPix) {}
+
+ @Override
+ public void selectWordAroundCaretAck(boolean didSelect, int startAdjust, int endAdjust) {}
+
+ @Override
+ public boolean requestSelectionPopupUpdates(boolean shouldSuggest) {
+ mResultCallback.onClassified(mResult);
+ return true;
+ }
+
+ @Override
+ public void cancelAllRequests() {}
+
+ @Override
+ public SelectionMetricsLogger getSelectionMetricsLogger() {
+ return mLogger;
+ }
+
+ public void setResult(SelectionClient.Result result) {
+ mResult = result;
+ }
+
+ public void setResultCallback(SelectionClient.ResultCallback callback) {
+ mResultCallback = callback;
+ }
+
+ public void setLogger(SmartSelectionMetricsLogger logger) {
+ mLogger = logger;
+ }
+ }
+
+ private static class SelectionClientOnlyReturnTrue extends TestSelectionClient {
+ @Override
+ public boolean requestSelectionPopupUpdates(boolean shouldSuggest) {
+ return true;
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ ShadowLog.stream = System.out;
+
+ mContext = Mockito.mock(Context.class);
+ mWindowAndroid = Mockito.mock(WindowAndroid.class);
+ mWebContents = Mockito.mock(WebContentsImpl.class);
+ mView = Mockito.mock(ViewGroup.class);
+ mViewAndroidDelegate = ViewAndroidDelegate.createBasicDelegate(mView);
+ mActionMode = Mockito.mock(ActionMode.class);
+ mPackageManager = Mockito.mock(PackageManager.class);
+ mRenderCoordinates = Mockito.mock(RenderCoordinatesImpl.class);
+ mLogger = Mockito.mock(SmartSelectionMetricsLogger.class);
+ mPopupController = Mockito.mock(PopupController.class);
+
+ mOriginalContentClassFactory = ContentClassFactory.get();
+ ContentClassFactory mockContentClassFactory = Mockito.mock(ContentClassFactory.class);
+ when(mockContentClassFactory.createHandleObserver(
+ Mockito.any(SelectionPopupControllerImpl.ReadbackViewCallback.class)))
+ .thenReturn(null);
+ ContentClassFactory.set(mockContentClassFactory);
+
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ // To let isDeviceProvisioned() call in showSelectionMenu() return true.
+ Settings.System.putInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED, 1);
+
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ when(mContext.getContentResolver()).thenReturn(mContentResolver);
+ when(mWebContents.getRenderCoordinates()).thenReturn(mRenderCoordinates);
+ when(mRenderCoordinates.getDeviceScaleFactor()).thenReturn(1.f);
+ when(mWebContents.getViewAndroidDelegate()).thenReturn(mViewAndroidDelegate);
+ when(mWebContents.getContext()).thenReturn(mContext);
+ when(mWebContents.getTopLevelNativeWindow()).thenReturn(mWindowAndroid);
+ mController = SelectionPopupControllerImpl.createForTesting(mWebContents, mPopupController);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ ContentClassFactory.set(mOriginalContentClassFactory);
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testSmartSelectionAdjustSelectionRange() {
+ InOrder order = inOrder(mWebContents, mView);
+ SelectionClient.Result result = resultForAmphitheatre();
+
+ // Setup SelectionClient for SelectionPopupController.
+ TestSelectionClient client = new TestSelectionClient();
+ client.setResult(result);
+ client.setResultCallback(mController.getResultCallback());
+ mController.setSelectionClient(client);
+
+ // Long press triggered showSelectionMenu() call.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_LONG_PRESS);
+
+ // adjustSelectionByCharacterOffset() should be called.
+ order.verify(mWebContents)
+ .adjustSelectionByCharacterOffset(result.startAdjust, result.endAdjust, true);
+ assertFalse(mController.isActionModeValid());
+
+ when(mView.startActionMode(any(FloatingActionModeCallback.class), anyInt()))
+ .thenReturn(mActionMode);
+
+ // Call showSelectionMenu again, which is adjustSelectionByCharacterOffset triggered.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+
+ order.verify(mView).startActionMode(
+ isA(FloatingActionModeCallback.class), eq(ActionMode.TYPE_FLOATING));
+
+ SelectionClient.Result returnResult = mController.getClassificationResult();
+ assertEquals(-5, returnResult.startAdjust);
+ assertEquals(8, returnResult.endAdjust);
+ assertEquals("Maps", returnResult.label);
+
+ assertTrue(mController.isActionModeValid());
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testSmartSelectionAnotherLongPressAfterAdjustment() {
+ InOrder order = inOrder(mWebContents, mView);
+ SelectionClient.Result result = resultForAmphitheatre();
+ SelectionClient.Result newResult = resultForMountain();
+
+ // Set SelectionClient for SelectionPopupController.
+ TestSelectionClient client = new TestSelectionClient();
+ client.setResult(result);
+ client.setResultCallback(mController.getResultCallback());
+ mController.setSelectionClient(client);
+
+ // Long press triggered showSelectionMenu() call.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_LONG_PRESS);
+
+ // adjustSelectionByCharacterOffset() should be called.
+ order.verify(mWebContents)
+ .adjustSelectionByCharacterOffset(result.startAdjust, result.endAdjust, true);
+ assertFalse(mController.isActionModeValid());
+
+ // Another long press triggered showSelectionMenu() call.
+ client.setResult(newResult);
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, MOUNTAIN, /* selectionOffset = */ 21,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_LONG_PRESS);
+ order.verify(mWebContents)
+ .adjustSelectionByCharacterOffset(newResult.startAdjust, newResult.endAdjust, true);
+ assertFalse(mController.isActionModeValid());
+
+ when(mView.startActionMode(any(FloatingActionModeCallback.class), anyInt()))
+ .thenReturn(mActionMode);
+
+ // First adjustSelectionByCharacterOffset() triggered.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+
+ SelectionClient.Result returnResult = mController.getClassificationResult();
+ assertEquals(-21, returnResult.startAdjust);
+ assertEquals(15, returnResult.endAdjust);
+ assertEquals("Maps", returnResult.label);
+
+ // Second adjustSelectionByCharacterOffset() triggered.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, MOUNTAIN_FULL, /* selectionOffset = */ 0,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+
+ order.verify(mView).startActionMode(
+ isA(FloatingActionModeCallback.class), eq(ActionMode.TYPE_FLOATING));
+ assertTrue(mController.isActionModeValid());
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testSmartSelectionAnotherLongPressBeforeAdjustment() {
+ InOrder order = inOrder(mWebContents, mView);
+ SelectionClient.Result result = resultForAmphitheatre();
+ SelectionClient.Result newResult = resultForMountain();
+
+ // This client won't call SmartSelectionCallback.
+ TestSelectionClient client = new SelectionClientOnlyReturnTrue();
+ mController.setSelectionClient(client);
+
+ // Long press triggered showSelectionMenu() call.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_LONG_PRESS);
+
+ // Another long press triggered showSelectionMenu() call.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, MOUNTAIN, /* selectionOffset = */ 21,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_LONG_PRESS);
+
+ // Then we done with the first classification.
+ mController.getResultCallback().onClassified(result);
+
+ // Followed by the second classifaction.
+ mController.getResultCallback().onClassified(newResult);
+
+ // adjustSelectionByCharacterOffset() should be called.
+ order.verify(mWebContents)
+ .adjustSelectionByCharacterOffset(result.startAdjust, result.endAdjust, true);
+ order.verify(mWebContents)
+ .adjustSelectionByCharacterOffset(newResult.startAdjust, newResult.endAdjust, true);
+ assertFalse(mController.isActionModeValid());
+
+ when(mView.startActionMode(any(FloatingActionModeCallback.class), anyInt()))
+ .thenReturn(mActionMode);
+
+ // First adjustSelectionByCharacterOffset() triggered.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+
+ SelectionClient.Result returnResult = mController.getClassificationResult();
+ assertEquals(-21, returnResult.startAdjust);
+ assertEquals(15, returnResult.endAdjust);
+ assertEquals("Maps", returnResult.label);
+
+ // Second adjustSelectionByCharacterOffset() triggered.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, MOUNTAIN_FULL, /* selectionOffset = */ 0,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+
+ order.verify(mView).startActionMode(
+ isA(FloatingActionModeCallback.class), eq(ActionMode.TYPE_FLOATING));
+ assertTrue(mController.isActionModeValid());
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testSmartSelectionLoggingExpansion() {
+ InOrder order = inOrder(mLogger);
+ SelectionClient.Result result = resultForAmphitheatre();
+
+ // Setup SelectionClient for SelectionPopupController.
+ TestSelectionClient client = new SelectionClientOnlyReturnTrue();
+ client.setLogger(mLogger);
+ client.setResult(result);
+ client.setResultCallback(mController.getResultCallback());
+ mController.setSelectionClient(client);
+
+ // Long press triggered showSelectionMenu() call.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_LONG_PRESS);
+
+ when(mView.startActionMode(any(FloatingActionModeCallback.class), anyInt()))
+ .thenReturn(mActionMode);
+
+ order.verify(mLogger).logSelectionStarted(AMPHITHEATRE, 5, true);
+
+ mController.getResultCallback().onClassified(result);
+
+ // Call showSelectionMenu again, which is adjustSelectionByCharacterOffset triggered.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE_FULL, /* selectionOffset = */ 0,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_ADJUST_SELECTION);
+
+ order.verify(mLogger).logSelectionModified(
+ eq(AMPHITHEATRE_FULL), eq(0), isA(SelectionClient.Result.class));
+
+ // Dragging selection handle, select "1600 Amphitheatre".
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE_FULL.substring(0, 17),
+ /* selectionOffset = */ 0,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_TOUCH_HANDLE);
+
+ order.verify(mLogger, never())
+ .logSelectionModified(anyString(), anyInt(), any(SelectionClient.Result.class));
+
+ mController.getResultCallback().onClassified(resultForNoChange());
+
+ order.verify(mLogger).logSelectionModified(
+ eq("1600 Amphitheatre"), eq(0), isA(SelectionClient.Result.class));
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testSmartSelectionLoggingNoExpansion() {
+ InOrder order = inOrder(mLogger);
+ SelectionClient.Result result = resultForNoChange();
+
+ // Setup SelectionClient for SelectionPopupController.
+ TestSelectionClient client = new SelectionClientOnlyReturnTrue();
+ client.setLogger(mLogger);
+ client.setResult(result);
+ client.setResultCallback(mController.getResultCallback());
+ mController.setSelectionClient(client);
+
+ // Long press triggered showSelectionMenu() call.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_LONG_PRESS);
+
+ when(mView.startActionMode(any(FloatingActionModeCallback.class), anyInt()))
+ .thenReturn(mActionMode);
+ order.verify(mLogger).logSelectionStarted(AMPHITHEATRE, 5, true);
+
+ // No expansion.
+ mController.getResultCallback().onClassified(result);
+ order.verify(mLogger).logSelectionModified(
+ eq(AMPHITHEATRE), eq(5), any(SelectionClient.Result.class));
+
+ // Dragging selection handle, select "1600 Amphitheatre".
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE_FULL.substring(0, 17),
+ /* selectionOffset = */ 0,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_TOUCH_HANDLE);
+
+ order.verify(mLogger, never())
+ .logSelectionModified(anyString(), anyInt(), any(SelectionClient.Result.class));
+ mController.getResultCallback().onClassified(resultForNoChange());
+ order.verify(mLogger).logSelectionModified(
+ eq("1600 Amphitheatre"), eq(0), isA(SelectionClient.Result.class));
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testBlockSelectionClientWhenUnprovisioned() {
+ // Device is not provisioned.
+ Settings.System.putInt(mContentResolver, Settings.Global.DEVICE_PROVISIONED, 0);
+
+ TestSelectionClient client = Mockito.mock(TestSelectionClient.class);
+ InOrder order = inOrder(mLogger, client);
+ mController.setSelectionClient(client);
+
+ // Long press triggered showSelectionMenu() call.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_LONG_PRESS);
+ order.verify(mLogger, never()).logSelectionStarted(anyString(), anyInt(), anyBoolean());
+ order.verify(client, never()).requestSelectionPopupUpdates(anyBoolean());
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testBlockSelectionClientWhenIncognito() {
+ // Incognito.
+ when(mWebContents.isIncognito()).thenReturn(true);
+
+ TestSelectionClient client = Mockito.mock(TestSelectionClient.class);
+ InOrder order = inOrder(mLogger, client);
+ mController.setSelectionClient(client);
+
+ // Long press triggered showSelectionMenu() call.
+ mController.showSelectionMenu(0, 0, 0, 0, 0, /* isEditable = */ true,
+ /* isPasswordType = */ false, AMPHITHEATRE, /* selectionOffset = */ 5,
+ /* canSelectAll = */ true,
+ /* canRichlyEdit = */ true, /* shouldSuggest = */ true,
+ MenuSourceType.MENU_SOURCE_LONG_PRESS);
+ order.verify(mLogger, never()).logSelectionStarted(anyString(), anyInt(), anyBoolean());
+ order.verify(client, never()).requestSelectionPopupUpdates(anyBoolean());
+ }
+
+ @Test
+ @Feature({"TextInput", "HandleObserver"})
+ public void testHandleObserverSelectionHandle() {
+ SelectionInsertionHandleObserver handleObserver =
+ Mockito.mock(SelectionInsertionHandleObserver.class);
+ InOrder order = inOrder(handleObserver);
+ mController.setSelectionInsertionHandleObserver(handleObserver);
+
+ // Selection handles shown.
+ mController.onSelectionEvent(SelectionEventType.SELECTION_HANDLES_SHOWN, 0, 0, 0, 0);
+
+ // Selection handles drag started.
+ mController.onDragUpdate(0.f, 0.f);
+ order.verify(handleObserver).handleDragStartedOrMoved(0.f, 0.f);
+
+ // Moving.
+ mController.onDragUpdate(5.f, 5.f);
+ order.verify(handleObserver).handleDragStartedOrMoved(5.f, 5.f);
+
+ // Selection handle drag stopped.
+ mController.onSelectionEvent(SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED, 0, 0, 0, 0);
+ order.verify(handleObserver).handleDragStopped();
+ }
+
+ @Test
+ @Feature({"TextInput", "HandleObserver"})
+ public void testHandleObserverInsertionHandle() {
+ SelectionInsertionHandleObserver handleObserver =
+ Mockito.mock(SelectionInsertionHandleObserver.class);
+ InOrder order = inOrder(handleObserver);
+ mController.setSelectionInsertionHandleObserver(handleObserver);
+
+ // Insertion handle shown.
+ mController.onSelectionEvent(SelectionEventType.INSERTION_HANDLE_SHOWN, 0, 0, 0, 0);
+
+ // Insertion handle drag started.
+ mController.onDragUpdate(0.f, 0.f);
+ order.verify(handleObserver).handleDragStartedOrMoved(0.f, 0.f);
+
+ // Moving.
+ mController.onDragUpdate(5.f, 5.f);
+ order.verify(handleObserver).handleDragStartedOrMoved(5.f, 5.f);
+
+ // Insertion handle drag stopped.
+ mController.onSelectionEvent(SelectionEventType.INSERTION_HANDLE_DRAG_STOPPED, 0, 0, 0, 0);
+ order.verify(handleObserver).handleDragStopped();
+ }
+
+ // Result generated by long press "Amphitheatre" in "1600 Amphitheatre Parkway".
+ private SelectionClient.Result resultForAmphitheatre() {
+ SelectionClient.Result result = new SelectionClient.Result();
+ result.startAdjust = -5;
+ result.endAdjust = 8;
+ result.label = "Maps";
+ return result;
+ }
+
+ // Result generated by long press "Mountain" in "585 Franklin Street, Mountain View, CA 94041".
+ private SelectionClient.Result resultForMountain() {
+ SelectionClient.Result result = new SelectionClient.Result();
+ result.startAdjust = -21;
+ result.endAdjust = 15;
+ result.label = "Maps";
+ return result;
+ }
+
+ private SelectionClient.Result resultForNoChange() {
+ SelectionClient.Result result = new SelectionClient.Result();
+ result.startAdjust = 0;
+ result.endAdjust = 0;
+ result.label = "Maps";
+ return result;
+ }
+}
diff --git a/chromium/content/public/android/junit/src/org/chromium/content/browser/selection/SmartSelectionMetricsLoggerTest.java b/chromium/content/public/android/junit/src/org/chromium/content/browser/selection/SmartSelectionMetricsLoggerTest.java
new file mode 100644
index 00000000000..60108346dbf
--- /dev/null
+++ b/chromium/content/public/android/junit/src/org/chromium/content/browser/selection/SmartSelectionMetricsLoggerTest.java
@@ -0,0 +1,451 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.selection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+
+import android.content.Context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowLog;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.Feature;
+import org.chromium.content.browser.selection.SmartSelectionMetricsLogger.ActionType;
+
+import java.text.BreakIterator;
+
+/**
+ * Unit tests for the {@link SmartSelectionMetricsLogger}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class SmartSelectionMetricsLoggerTest {
+ // Char index (in 10s) 0 1 2 3 4
+ // Word index (thou) -7-6 -5-4 -3-2 -1 0 1 2
+ private static String sText = "O Romeo, Romeo! Wherefore art thou Romeo?\n"
+ // 5 6 7
+ // 3 4 5 6 7 8 9 0
+ + "Deny thy father and refuse thy name.\n"
+ // 8 9 0 1 2
+ // 1 2 3 4 5 6 7 8 9 0 1 2 3
+ + "Or, if thou wilt not, be but sworn my love,\n"
+ // 3 4 5
+ // 4 567 8 9 0 1 2 34
+ + "And I’ll no longer be a Capulet.\n";
+ private static class TestSmartSelectionMetricsLogger extends SmartSelectionMetricsLogger {
+ public TestSmartSelectionMetricsLogger(SelectionEventProxy selectionEventProxy) {
+ super(selectionEventProxy);
+ }
+
+ @Override
+ public void logEvent(Object selectionEvent) {
+ // no-op
+ }
+
+ @Override
+ public Object createTracker(Context context, boolean editable) {
+ return new Object();
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ ShadowLog.stream = System.out;
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testOverlap() {
+ assertTrue(SelectionIndicesConverter.overlap(1, 3, 2, 4));
+ assertTrue(SelectionIndicesConverter.overlap(2, 4, 1, 3));
+
+ assertTrue(SelectionIndicesConverter.overlap(1, 4, 2, 3));
+ assertTrue(SelectionIndicesConverter.overlap(2, 3, 1, 4));
+
+ assertTrue(SelectionIndicesConverter.overlap(1, 4, 1, 3));
+ assertTrue(SelectionIndicesConverter.overlap(1, 3, 1, 4));
+
+ assertTrue(SelectionIndicesConverter.overlap(1, 4, 2, 4));
+ assertTrue(SelectionIndicesConverter.overlap(2, 4, 1, 4));
+
+ assertTrue(SelectionIndicesConverter.overlap(1, 4, 1, 4));
+
+ assertFalse(SelectionIndicesConverter.overlap(1, 2, 3, 4));
+ assertFalse(SelectionIndicesConverter.overlap(3, 4, 1, 2));
+
+ assertFalse(SelectionIndicesConverter.overlap(1, 2, 2, 4));
+ assertFalse(SelectionIndicesConverter.overlap(2, 4, 1, 2));
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testContains() {
+ assertFalse(SelectionIndicesConverter.contains(1, 3, 2, 4));
+ assertFalse(SelectionIndicesConverter.contains(2, 4, 1, 3));
+
+ assertTrue(SelectionIndicesConverter.contains(1, 4, 2, 3));
+ assertFalse(SelectionIndicesConverter.contains(2, 3, 1, 4));
+
+ assertTrue(SelectionIndicesConverter.contains(1, 4, 1, 3));
+ assertFalse(SelectionIndicesConverter.contains(1, 3, 1, 4));
+
+ assertTrue(SelectionIndicesConverter.contains(1, 4, 2, 4));
+ assertFalse(SelectionIndicesConverter.contains(2, 4, 1, 4));
+
+ assertTrue(SelectionIndicesConverter.contains(1, 4, 1, 4));
+
+ assertFalse(SelectionIndicesConverter.contains(1, 2, 3, 4));
+ assertFalse(SelectionIndicesConverter.contains(3, 4, 1, 2));
+
+ assertFalse(SelectionIndicesConverter.contains(1, 2, 2, 4));
+ assertFalse(SelectionIndicesConverter.contains(2, 4, 1, 2));
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testUpdateSelectionState() {
+ SelectionIndicesConverter converter = new SelectionIndicesConverter();
+ String address = "1600 Amphitheatre Parkway, Mountain View, CA 94043.";
+ assertTrue(converter.updateSelectionState(address.substring(18, 25), 18));
+ assertEquals("Parkway", converter.getGlobalSelectionText());
+ assertEquals(18, converter.getGlobalStartOffset());
+
+ // Expansion.
+ assertTrue(converter.updateSelectionState(address.substring(5, 35), 5));
+ assertEquals("Amphitheatre Parkway, Mountain", converter.getGlobalSelectionText());
+ assertEquals(5, converter.getGlobalStartOffset());
+
+ // Drag left handle. Select "Mountain".
+ assertTrue(converter.updateSelectionState(address.substring(27, 35), 27));
+ assertEquals("Amphitheatre Parkway, Mountain", converter.getGlobalSelectionText());
+ assertEquals(5, converter.getGlobalStartOffset());
+
+ // Drag left handle. Select " View".
+ assertTrue(converter.updateSelectionState(address.substring(35, 40), 35));
+ assertEquals("Amphitheatre Parkway, Mountain View", converter.getGlobalSelectionText());
+ assertEquals(5, converter.getGlobalStartOffset());
+
+ // Drag left handle. Select "1600 Amphitheatre Parkway, Mountain View".
+ assertTrue(converter.updateSelectionState(address.substring(0, 40), 0));
+ assertEquals(
+ "1600 Amphitheatre Parkway, Mountain View", converter.getGlobalSelectionText());
+ assertEquals(0, converter.getGlobalStartOffset());
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testUpdateSelectionStateOffsets() {
+ SelectionIndicesConverter converter = new SelectionIndicesConverter();
+ String address = "1600 Amphitheatre Parkway, Mountain View, CA 94043.";
+ assertTrue(converter.updateSelectionState(address.substring(18, 25), 18));
+ assertEquals("Parkway", converter.getGlobalSelectionText());
+ assertEquals(18, converter.getGlobalStartOffset());
+
+ // Drag to select "Amphitheatre Parkway". Overlap.
+ assertFalse(converter.updateSelectionState(address.substring(5, 25), 18));
+ assertNull(converter.getGlobalSelectionText());
+
+ // Reset.
+ converter = new SelectionIndicesConverter();
+ assertTrue(converter.updateSelectionState(address.substring(18, 25), 18));
+ assertEquals("Parkway", converter.getGlobalSelectionText());
+ assertEquals(18, converter.getGlobalStartOffset());
+
+ // Drag to select "Amphitheatre Parkway". Overlap.
+ assertFalse(converter.updateSelectionState(address.substring(5, 25), 0));
+ assertNull(converter.getGlobalSelectionText());
+
+ // Reset.
+ converter = new SelectionIndicesConverter();
+ assertTrue(converter.updateSelectionState(address.substring(36, 40), 36));
+ assertEquals("View", converter.getGlobalSelectionText());
+ assertEquals(36, converter.getGlobalStartOffset());
+
+ // Drag to select "Mountain View". Not overlap.
+ assertFalse(converter.updateSelectionState(address.substring(27, 40), 0));
+ assertNull(converter.getGlobalSelectionText());
+
+ // Reset.
+ converter = new SelectionIndicesConverter();
+ assertTrue(converter.updateSelectionState(address.substring(36, 40), 36));
+ assertEquals("View", converter.getGlobalSelectionText());
+ assertEquals(36, converter.getGlobalStartOffset());
+
+ // Drag to select "Mountain View". Adjacent. Wrong case.
+ assertTrue(converter.updateSelectionState(address.substring(27, 40), 40));
+ assertEquals("ViewMountain View", converter.getGlobalSelectionText());
+ assertEquals(36, converter.getGlobalStartOffset());
+
+ String text = "a a a a a";
+ // Reset.
+ converter = new SelectionIndicesConverter();
+ assertTrue(converter.updateSelectionState(text.substring(2, 3), 2));
+ assertEquals("a", converter.getGlobalSelectionText());
+ assertEquals(2, converter.getGlobalStartOffset());
+
+ // Drag to select "a a". Contains. Wrong case.
+ assertTrue(converter.updateSelectionState(text.substring(4, 7), 2));
+ assertEquals("a a", converter.getGlobalSelectionText());
+ assertEquals(2, converter.getGlobalStartOffset());
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testIsWhitespace() {
+ SelectionIndicesConverter converter = new SelectionIndicesConverter();
+ String test = "\u202F\u00A0 \t\n\u000b\f\r";
+ converter.updateSelectionState(test, 0);
+ assertTrue(converter.isWhitespace(0, test.length()));
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testCountWordsBackward() {
+ SelectionIndicesConverter converter = new SelectionIndicesConverter();
+ converter.updateSelectionState(sText, 0);
+ BreakIterator iterator = BreakIterator.getWordInstance();
+ iterator.setText(sText);
+ // End with "Deny" from right.
+ assertEquals(0, converter.countWordsBackward(42, 42, iterator));
+ assertEquals(1, converter.countWordsBackward(43, 42, iterator));
+ assertEquals(8, converter.countWordsBackward(79, 42, iterator));
+ assertEquals(31, converter.countWordsBackward(sText.length(), 42, iterator));
+
+ // End with "e" in "Deny" from right.
+ assertEquals(1, converter.countWordsBackward(44, 43, iterator));
+ assertEquals(8, converter.countWordsBackward(79, 43, iterator));
+ assertEquals(31, converter.countWordsBackward(sText.length(), 43, iterator));
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testCountWordsForward() {
+ SelectionIndicesConverter converter = new SelectionIndicesConverter();
+ converter.updateSelectionState(sText, 0);
+ BreakIterator iterator = BreakIterator.getWordInstance();
+ iterator.setText(sText);
+ // End with "Deny" from left.
+ assertEquals(0, converter.countWordsForward(42, 42, iterator));
+ assertEquals(0, converter.countWordsForward(41, 42, iterator));
+ assertEquals(5, converter.countWordsForward(16, 42, iterator));
+ assertEquals(10, converter.countWordsForward(0, 42, iterator));
+
+ // End with "e" in "Deny" from left.
+ assertEquals(1, converter.countWordsForward(42, 43, iterator));
+ assertEquals(6, converter.countWordsForward(16, 43, iterator));
+ assertEquals(11, converter.countWordsForward(0, 43, iterator));
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testGetWordDelta() {
+ SelectionIndicesConverter converter = new SelectionIndicesConverter();
+ // char offset 0 5 0 5 0 5
+ // -1 0 1 2 3 45
+ String test = "It\u00A0has\nnon breaking\tspaces.";
+ converter.updateSelectionState(test, 0);
+ converter.setInitialStartOffset(3);
+ int[] indices = new int[2];
+ // Whole range. "It\u00A0has\nnon breaking\tspaces."
+ converter.getWordDelta(0, test.length(), indices);
+ assertEquals(-1, indices[0]);
+ assertEquals(5, indices[1]);
+
+ // Itself. "has"
+ converter.getWordDelta(3, 6, indices);
+ assertEquals(0, indices[0]);
+ assertEquals(1, indices[1]);
+
+ // No overlap left. "It"
+ converter.getWordDelta(0, 2, indices);
+ assertEquals(-1, indices[0]);
+ assertEquals(0, indices[1]);
+
+ // No overlap right. "space"
+ converter.getWordDelta(20, 25, indices);
+ assertEquals(3, indices[0]);
+ assertEquals(4, indices[1]);
+
+ // "breaking\tspace"
+ converter.getWordDelta(11, 25, indices);
+ assertEquals(2, indices[0]);
+ assertEquals(4, indices[1]);
+
+ // Extra space case. " breaking\tspace"
+ converter.getWordDelta(10, 25, indices);
+ assertEquals(2, indices[0]);
+ assertEquals(4, indices[1]);
+
+ // Partial word. "re" in "breaking".
+ converter.getWordDelta(12, 14, indices);
+ assertEquals(2, indices[0]);
+ assertEquals(3, indices[1]);
+
+ // Partial word. "t" in "It".
+ converter.getWordDelta(1, 2, indices);
+ assertEquals(-1, indices[0]);
+ assertEquals(0, indices[1]);
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testNormalLoggingFlow() {
+ SmartSelectionMetricsLogger.SelectionEventProxy selectionEventProxy =
+ Mockito.mock(SmartSelectionMetricsLogger.SelectionEventProxy.class);
+ TestSmartSelectionMetricsLogger logger =
+ new TestSmartSelectionMetricsLogger(selectionEventProxy);
+ InOrder order = inOrder(selectionEventProxy);
+
+ // Start to select, selected "thou" in row#1.
+ logger.logSelectionStarted("thou", 30, /* editable = */ false);
+ order.verify(selectionEventProxy).createSelectionStarted(0);
+
+ // Smart Selection, expand to "Wherefore art thou Romeo?".
+ logger.logSelectionModified("Wherefore art thou Romeo?", 16, null);
+ order.verify(selectionEventProxy).createSelectionModified(-2, 3);
+
+ // Smart Selection reset, to the last Romeo in row#1.
+ logger.logSelectionAction("Romeo", 35, ActionType.RESET, null);
+ order.verify(selectionEventProxy).createSelectionAction(1, 2, ActionType.RESET);
+
+ // User clear selection.
+ logger.logSelectionAction("Romeo", 35, ActionType.ABANDON, null);
+ order.verify(selectionEventProxy).createSelectionAction(1, 2, ActionType.ABANDON);
+
+ // User start a new selection without abandon.
+ logger.logSelectionStarted("thou", 30, /* editable = */ false);
+ order.verify(selectionEventProxy).createSelectionStarted(0);
+
+ // Smart Selection, expand to "Wherefore art thou Romeo?".
+ logger.logSelectionModified("Wherefore art thou Romeo?", 16, null);
+ order.verify(selectionEventProxy).createSelectionModified(-2, 3);
+
+ // COPY, PASTE, CUT, SHARE, SMART_SHARE are basically the same.
+ logger.logSelectionAction("Wherefore art thou Romeo?", 16, ActionType.COPY, null);
+ order.verify(selectionEventProxy).createSelectionAction(-2, 3, ActionType.COPY);
+
+ // SELECT_ALL
+ logger.logSelectionStarted("thou", 30, /* editable = */ true);
+ order.verify(selectionEventProxy).createSelectionStarted(0);
+
+ logger.logSelectionAction(sText, 0, ActionType.SELECT_ALL, null);
+ order.verify(selectionEventProxy).createSelectionAction(-7, 34, ActionType.SELECT_ALL);
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testMultipleDrag() {
+ SmartSelectionMetricsLogger.SelectionEventProxy selectionEventProxy =
+ Mockito.mock(SmartSelectionMetricsLogger.SelectionEventProxy.class);
+ TestSmartSelectionMetricsLogger logger =
+ new TestSmartSelectionMetricsLogger(selectionEventProxy);
+ InOrder order = inOrder(selectionEventProxy);
+ // Start new selection. First "Deny" in row#2.
+ logger.logSelectionStarted("Deny", 42, /* editable = */ false);
+ order.verify(selectionEventProxy).createSelectionStarted(0);
+
+ // Drag right handle to "father".
+ logger.logSelectionModified("Deny thy father", 42, null);
+ order.verify(selectionEventProxy).createSelectionModified(0, 3);
+
+ // Drag left handle to " and refuse"
+ logger.logSelectionModified(" and refuse", 57, null);
+ order.verify(selectionEventProxy).createSelectionModified(3, 5);
+
+ // Drag right handle to " Romeo?\nDeny thy father".
+ logger.logSelectionModified(" Romeo?\nDeny thy father", 34, null);
+ order.verify(selectionEventProxy).createSelectionModified(-2, 3);
+
+ // Dismiss the selection.
+ logger.logSelectionAction(" Romeo?\nDeny thy father", 34, ActionType.ABANDON, null);
+ order.verify(selectionEventProxy).createSelectionAction(-2, 3, ActionType.ABANDON);
+
+ // Start a new selection.
+ logger.logSelectionStarted("Deny", 42, /* editable = */ false);
+ order.verify(selectionEventProxy).createSelectionStarted(0);
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testTextShift() {
+ SmartSelectionMetricsLogger.SelectionEventProxy selectionEventProxy =
+ Mockito.mock(SmartSelectionMetricsLogger.SelectionEventProxy.class);
+ TestSmartSelectionMetricsLogger logger =
+ new TestSmartSelectionMetricsLogger(selectionEventProxy);
+ InOrder order = inOrder(selectionEventProxy);
+
+ // Start to select, selected "thou" in row#1.
+ logger.logSelectionStarted("thou", 30, /* editable = */ false);
+ order.verify(selectionEventProxy).createSelectionStarted(0);
+
+ // Smart Selection, expand to "Wherefore art thou Romeo?".
+ logger.logSelectionModified("Wherefore art thou Romeo?", 30, null);
+ order.verify(selectionEventProxy, never()).createSelectionModified(anyInt(), anyInt());
+
+ // Start to select, selected "thou" in row#1.
+ logger.logSelectionStarted("thou", 30, /* editable = */ false);
+ order.verify(selectionEventProxy).createSelectionStarted(0);
+
+ // Drag. Non-intersect case.
+ logger.logSelectionModified("Wherefore art thou", 10, null);
+ order.verify(selectionEventProxy, never()).createSelectionModified(anyInt(), anyInt());
+
+ // Start to select, selected "thou" in row#1.
+ logger.logSelectionStarted("thou", 30, /* editable = */ false);
+ order.verify(selectionEventProxy).createSelectionStarted(0);
+
+ // Drag. Adjacent case, form "Wherefore art thouthou". Wrong case.
+ logger.logSelectionModified("Wherefore art thou", 12, null);
+ order.verify(selectionEventProxy).createSelectionModified(-3, 0);
+ }
+
+ @Test
+ @Feature({"TextInput", "SmartSelection"})
+ public void testSelectionChanged() {
+ SmartSelectionMetricsLogger.SelectionEventProxy selectionEventProxy =
+ Mockito.mock(SmartSelectionMetricsLogger.SelectionEventProxy.class);
+ TestSmartSelectionMetricsLogger logger =
+ new TestSmartSelectionMetricsLogger(selectionEventProxy);
+ InOrder order = inOrder(selectionEventProxy);
+
+ // Start to select, selected "thou" in row#1.
+ logger.logSelectionStarted("thou", 30, /* editable = */ false);
+ order.verify(selectionEventProxy).createSelectionStarted(0);
+
+ // Change "thou" to "math".
+ logger.logSelectionModified("Wherefore art math", 16, null);
+ order.verify(selectionEventProxy, never()).createSelectionModified(anyInt(), anyInt());
+
+ // Start to select, selected "thou" in row#1.
+ logger.logSelectionStarted("thou", 30, /* editable = */ false);
+ order.verify(selectionEventProxy).createSelectionStarted(0);
+
+ // Drag while deleting "art ". Wrong case.
+ logger.logSelectionModified("Wherefore thou", 16, null);
+ order.verify(selectionEventProxy).createSelectionModified(-2, 0);
+
+ // Start to select, selected "thou" in row#1.
+ logger.logSelectionStarted("thou", 30, /* editable = */ false);
+ order.verify(selectionEventProxy).createSelectionStarted(0);
+
+ // Drag while deleting "Wherefore art ".
+ logger.logSelectionModified("thou", 16, null);
+ order.verify(selectionEventProxy, never()).createSelectionModified(anyInt(), anyInt());
+ }
+}
diff --git a/chromium/content/public/app/BUILD.gn b/chromium/content/public/app/BUILD.gn
index 43eab316e9a..ab4f13dca8f 100644
--- a/chromium/content/public/app/BUILD.gn
+++ b/chromium/content/public/app/BUILD.gn
@@ -190,6 +190,7 @@ service_manifest("packaged_services_manifest") {
"//services/audio:manifest",
"//services/data_decoder:manifest",
"//services/device:manifest",
+ "//services/media_session:manifest",
"//services/metrics:manifest",
"//services/network:manifest",
"//services/resource_coordinator:manifest",
diff --git a/chromium/content/public/app/content_jni_onload.h b/chromium/content/public/app/content_jni_onload.h
new file mode 100644
index 00000000000..e8c2c8a25a1
--- /dev/null
+++ b/chromium/content/public/app/content_jni_onload.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 CONTENT_PUBLIC_APP_CONTENT_JNI_ONLOAD_H_
+#define CONTENT_PUBLIC_APP_CONTENT_JNI_ONLOAD_H_
+
+#include <jni.h>
+
+#include "base/android/base_jni_onload.h"
+#include "content/common/content_export.h"
+
+namespace content {
+namespace android {
+
+// Returns true if initialization succeeded.
+CONTENT_EXPORT bool OnJNIOnLoadInit();
+
+} // namespace android
+} // namespace content
+
+#endif // CONTENT_PUBLIC_APP_CONTENT_JNI_ONLOAD_H_
diff --git a/chromium/content/public/app/content_main_delegate.cc b/chromium/content/public/app/content_main_delegate.cc
index c4bdfd36ad0..cf3c71fe0ed 100644
--- a/chromium/content/public/app/content_main_delegate.cc
+++ b/chromium/content/public/app/content_main_delegate.cc
@@ -26,10 +26,6 @@ int ContentMainDelegate::RunProcess(
return -1;
}
-ui::DataPack* ContentMainDelegate::LoadServiceManifestDataPack() {
- return nullptr;
-}
-
#if defined(OS_MACOSX)
bool ContentMainDelegate::ProcessRegistersWithSystemProcess(
@@ -75,6 +71,10 @@ void ContentMainDelegate::OnServiceManagerInitialized(
const base::Closure& quit_closure,
service_manager::BackgroundServiceManager* service_manager) {}
+bool ContentMainDelegate::ShouldCreateFeatureList() {
+ return true;
+}
+
ContentBrowserClient* ContentMainDelegate::CreateContentBrowserClient() {
#if defined(CHROME_MULTIPLE_DLL_CHILD)
return NULL;
diff --git a/chromium/content/public/app/content_main_delegate.h b/chromium/content/public/app/content_main_delegate.h
index 42310279092..d55f5050c8c 100644
--- a/chromium/content/public/app/content_main_delegate.h
+++ b/chromium/content/public/app/content_main_delegate.h
@@ -24,10 +24,6 @@ class Identity;
class ZygoteForkDelegate;
} // namespace service_manager
-namespace ui {
-class DataPack;
-}
-
namespace content {
class ContentBrowserClient;
@@ -63,10 +59,6 @@ class CONTENT_EXPORT ContentMainDelegate {
// Called right before the process exits.
virtual void ProcessExiting(const std::string& process_type) {}
- // This loads the service manifest datapack, takes its ownership and returns
- // the pointer to it.
- virtual ui::DataPack* LoadServiceManifestDataPack();
-
#if defined(OS_MACOSX)
// Returns true if the process registers with the system monitor, so that we
// can allocate an IO port for it before the sandbox is initialized. Embedders
@@ -129,10 +121,17 @@ class CONTENT_EXPORT ContentMainDelegate {
// creating the main message loop.
virtual void PreCreateMainMessageLoop() {}
- // Allows the embedder to perform platform-specific initializatioion. For
- // example, things that should be done right after TaskScheduler starts and
- // the main MessageLoop was installed.
- virtual void PostEarlyInitialization() {}
+ // Returns true if content should create field trials and initialize the
+ // FeatureList instance for this process. Default implementation returns true.
+ // Embedders that need to control when and/or how FeatureList should be
+ // created should override and return false.
+ virtual bool ShouldCreateFeatureList();
+
+ // Allows the embedder to perform its own initialization after content
+ // performed its own and already brought up MessageLoop, TaskScheduler, field
+ // tials and FeatureList (by default).
+ // |is_running_tests| indicates whether it is running in tests.
+ virtual void PostEarlyInitialization(bool is_running_tests) {}
protected:
friend class ContentClientInitializer;
diff --git a/chromium/content/public/app/mojo/content_browser_manifest.json b/chromium/content/public/app/mojo/content_browser_manifest.json
index c2e72da4f59..2fd832399ed 100644
--- a/chromium/content/public/app/mojo/content_browser_manifest.json
+++ b/chromium/content/public/app/mojo/content_browser_manifest.json
@@ -1,6 +1,11 @@
{
"name": "content_browser",
"display_name": "Content (browser process)",
+ "options": {
+ "can_connect_to_other_services_as_any_user": true,
+ "can_connect_to_other_services_with_any_instance_name": true,
+ "can_create_other_service_instances": true
+ },
"interface_provider_specs": {
"service_manager:connector": {
"provides": {
@@ -38,6 +43,7 @@
"blink.mojom.BlobRegistry",
"blink.mojom.BroadcastChannelProvider",
"blink.mojom.ClipboardHost",
+ "blink.mojom.CodeCacheHost",
"blink.mojom.FontUniqueNameLookup",
"blink.mojom.EmbeddedFrameSinkProvider",
"blink.mojom.FileUtilitiesHost",
@@ -64,6 +70,7 @@
"device.mojom.GamepadHapticsManager",
"discardable_memory.mojom.DiscardableSharedMemoryManager",
"media.mojom.KeySystemSupport",
+ "media.mojom.InterfaceFactory",
"media.mojom.VideoCaptureHost",
"media.mojom.VideoDecodePerfHistory",
"memory_coordinator.mojom.MemoryCoordinatorHandle",
@@ -105,11 +112,13 @@
"device:mtp",
"device:nfc",
"device:serial",
+ "device:usb",
"device:vibration",
"device:wake_lock"
],
"file": [ "file:filesystem", "file:leveldb" ],
"media": [ "media:media" ],
+ "media_session": [ "media_session:app" ],
"metrics": [ "url_keyed_metrics" ],
"network": [
"network_service",
@@ -124,10 +133,7 @@
"page_signal"
],
"service_manager": [
- "service_manager:client_process",
- "service_manager:instance_name",
- "service_manager:service_manager",
- "service_manager:user_id"
+ "service_manager:service_manager"
],
"shape_detection": [
"barcode_detection",
@@ -159,6 +165,7 @@
"blink.mojom.CredentialManager",
"blink.mojom.DisplayCutoutHost",
"blink.mojom.DedicatedWorkerFactory",
+ "blink.mojom.FileSystemManager",
"blink.mojom.LockManager",
"blink.mojom.GeolocationService",
"blink.mojom.InsecureInputService",
@@ -224,6 +231,7 @@
"renderer": [
"blink.mojom.CacheStorage",
"blink.mojom.DedicatedWorkerFactory",
+ "blink.mojom.FileSystemManager",
"blink.mojom.LockManager",
"blink.mojom.NotificationService",
"blink.mojom.PermissionService",
@@ -260,6 +268,7 @@
"provides": {
"renderer": [
"blink.mojom.CacheStorage",
+ "blink.mojom.FileSystemManager",
"blink.mojom.LockManager",
"blink.mojom.NotificationService",
"blink.mojom.PermissionService",
diff --git a/chromium/content/public/app/mojo/content_packaged_services_manifest.json b/chromium/content/public/app/mojo/content_packaged_services_manifest.json
index eee8e3b2072..ce69bd3e3f3 100644
--- a/chromium/content/public/app/mojo/content_packaged_services_manifest.json
+++ b/chromium/content/public/app/mojo/content_packaged_services_manifest.json
@@ -9,7 +9,9 @@
"name": "content_packaged_services",
"display_name": "Content Packaged Services",
"options" : {
- "instance_sharing" : "singleton"
+ "instance_sharing" : "singleton",
+ "can_connect_to_other_services_as_any_user": true,
+ "can_create_other_service_instances": true
},
"interface_provider_specs": {
"service_manager:connector": {
@@ -20,11 +22,7 @@
},
"requires": {
"*": [ "app" ],
- "content_browser": [],
- "service_manager": [
- "service_manager:client_process",
- "service_manager:user_id"
- ]
+ "content_browser": []
}
}
}
diff --git a/chromium/content/public/app/mojo/content_renderer_manifest.json b/chromium/content/public/app/mojo/content_renderer_manifest.json
index 4ae4abecffb..e19c5e68bbd 100644
--- a/chromium/content/public/app/mojo/content_renderer_manifest.json
+++ b/chromium/content/public/app/mojo/content_renderer_manifest.json
@@ -5,6 +5,7 @@
"service_manager:connector": {
"provides": {
"browser": [
+ "blink.mojom.CodeCacheHost",
"blink.mojom.CrashMemoryMetricsReporter",
"blink.mojom.LeakDetector",
"blink.mojom.OomIntervention",
@@ -39,7 +40,8 @@
"device": [
"device:power_monitor",
"device:screen_orientation",
- "device:time_zone_monitor"
+ "device:time_zone_monitor",
+ "device:wake_lock"
],
"ui": [
"discardable_memory",
diff --git a/chromium/content/public/browser/BUILD.gn b/chromium/content/public/browser/BUILD.gn
index ed1ba21b7b7..c6a54b6a682 100644
--- a/chromium/content/public/browser/BUILD.gn
+++ b/chromium/content/public/browser/BUILD.gn
@@ -30,6 +30,7 @@ jumbo_source_set("browser_sources") {
"android/compositor_client.h",
"android/content_protocol_handler.h",
"android/devtools_auth.h",
+ "android/gpu_video_accelerator_factories_provider.h",
"android/java_interfaces.h",
"android/motion_event_action.h",
"android/synchronous_compositor.cc",
@@ -100,8 +101,8 @@ jumbo_source_set("browser_sources") {
"color_chooser.h",
"content_browser_client.cc",
"content_browser_client.h",
- "context_factory.h",
"cookie_store_factory.h",
+ "delegate_to_browser_gpu_service_accelerator_factory.h",
"desktop_capture.cc",
"desktop_capture.h",
"desktop_media_id.cc",
@@ -130,6 +131,7 @@ jumbo_source_set("browser_sources") {
"download_utils.h",
"favicon_status.cc",
"favicon_status.h",
+ "file_select_listener.h",
"file_url_loader.h",
"focused_node_details.h",
"font_list_async.h",
@@ -201,6 +203,7 @@ jumbo_source_set("browser_sources") {
"notification_service.h",
"notification_source.h",
"notification_types.h",
+ "origin_policy_error_reason.h",
"overlay_window.h",
"overscroll_configuration.h",
"page_navigator.cc",
@@ -243,13 +246,13 @@ jumbo_source_set("browser_sources") {
"resource_dispatcher_host.h",
"resource_dispatcher_host_delegate.cc",
"resource_dispatcher_host_delegate.h",
- "resource_hints.h",
"resource_request_info.h",
"resource_throttle.cc",
"resource_throttle.h",
"restore_type.h",
"save_page_type.h",
"screen_orientation_delegate.h",
+ "screenlock_observer.h",
"security_style_explanation.cc",
"security_style_explanation.h",
"security_style_explanations.cc",
@@ -260,6 +263,7 @@ jumbo_source_set("browser_sources") {
"service_worker_usage_info.h",
"session_storage_namespace.h",
"session_storage_usage_info.h",
+ "shared_cors_origin_access_list.h",
"shared_worker_service.h",
"site_instance.h",
"site_isolation_policy.cc",
@@ -391,14 +395,27 @@ jumbo_source_set("browser_sources") {
deps += [ "//ui/android" ]
}
+ if (use_aura || is_mac) {
+ sources += [ "context_factory.h" ]
+ }
+
if (use_aura) {
- sources -= [ "context_factory.h" ]
- deps += [ "//ui/aura" ]
+ sources += [ "gpu_interface_provider_factory.h" ]
+ deps += [
+ "//services/ws/public/cpp/host",
+ "//ui/aura",
+ ]
+ }
+
+ if (is_mac) {
+ sources += [
+ "ns_view_bridge_factory_host.h",
+ "ns_view_bridge_factory_impl.h",
+ ]
}
if (!is_android) {
sources += [
- "devtools_frontend_host.h",
"host_zoom_map.h",
"zoom_level_delegate.h",
]
diff --git a/chromium/content/public/browser/DEPS b/chromium/content/public/browser/DEPS
index 40897244c89..13d34fe4c0d 100644
--- a/chromium/content/public/browser/DEPS
+++ b/chromium/content/public/browser/DEPS
@@ -11,6 +11,8 @@ include_rules = [
"+services/network/public/cpp",
"+services/service_manager/sandbox",
"+services/resource_coordinator/public",
+ "+services/video_capture/public/mojom",
+ "+services/ws/public/cpp/host",
"+services/ws/public/mojom",
]
diff --git a/chromium/content/public/browser/android/compositor_client.h b/chromium/content/public/browser/android/compositor_client.h
index 382575219e3..2c519a53b73 100644
--- a/chromium/content/public/browser/android/compositor_client.h
+++ b/chromium/content/public/browser/android/compositor_client.h
@@ -13,6 +13,11 @@ namespace content {
class CONTENT_EXPORT CompositorClient {
public:
+ // Compositor is requesting client to create a new surface and call
+ // SetSurface again. The existing surface if any is cleared from the
+ // compositor before this call.
+ virtual void RecreateSurface() {}
+
// Gives the client a chance to update the layer tree host before compositing.
virtual void UpdateLayerTreeHost() {}
diff --git a/chromium/content/public/browser/android/gpu_video_accelerator_factories_provider.h b/chromium/content/public/browser/android/gpu_video_accelerator_factories_provider.h
new file mode 100644
index 00000000000..ae3e1c581f4
--- /dev/null
+++ b/chromium/content/public/browser/android/gpu_video_accelerator_factories_provider.h
@@ -0,0 +1,29 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_ANDROID_GPU_VIDEO_ACCELERATOR_FACTORIES_PROVIDER_H_
+#define CONTENT_PUBLIC_BROWSER_ANDROID_GPU_VIDEO_ACCELERATOR_FACTORIES_PROVIDER_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "content/common/content_export.h"
+
+namespace media {
+class GpuVideoAcceleratorFactories;
+} // namespace media
+
+namespace content {
+
+using GpuVideoAcceleratorFactoriesCallback = base::OnceCallback<void(
+ std::unique_ptr<media::GpuVideoAcceleratorFactories>)>;
+
+// Provides hardware video decoding contexts in the browser process.
+CONTENT_EXPORT
+void CreateGpuVideoAcceleratorFactories(
+ GpuVideoAcceleratorFactoriesCallback callback);
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_ANDROID_GPU_VIDEO_ACCELERATOR_FACTORIES_PROVIDER_H_
diff --git a/chromium/content/public/browser/authenticator_request_client_delegate.cc b/chromium/content/public/browser/authenticator_request_client_delegate.cc
index 8d771934560..230f8a59da9 100644
--- a/chromium/content/public/browser/authenticator_request_client_delegate.cc
+++ b/chromium/content/public/browser/authenticator_request_client_delegate.cc
@@ -22,7 +22,8 @@ void AuthenticatorRequestClientDelegate::DidFailWithInterestingReason(
void AuthenticatorRequestClientDelegate::RegisterActionCallbacks(
base::OnceClosure cancel_callback,
device::FidoRequestHandlerBase::RequestCallback request_callback,
- base::RepeatingClosure bluetooth_adapter_power_on_callback) {}
+ base::RepeatingClosure bluetooth_adapter_power_on_callback,
+ device::FidoRequestHandlerBase::BlePairingCallback ble_pairing_callback) {}
bool AuthenticatorRequestClientDelegate::ShouldPermitIndividualAttestation(
const std::string& relying_party_id) {
@@ -66,4 +67,11 @@ void AuthenticatorRequestClientDelegate::FidoAuthenticatorAdded(
void AuthenticatorRequestClientDelegate::FidoAuthenticatorRemoved(
base::StringPiece device_id) {}
+void AuthenticatorRequestClientDelegate::FidoAuthenticatorIdChanged(
+ base::StringPiece old_authenticator_id,
+ std::string new_authenticator_id) {}
+
+void AuthenticatorRequestClientDelegate::FidoAuthenticatorPairingModeChanged(
+ base::StringPiece authenticator_id) {}
+
} // namespace content
diff --git a/chromium/content/public/browser/authenticator_request_client_delegate.h b/chromium/content/public/browser/authenticator_request_client_delegate.h
index 4f11a735e1e..49ddb661f62 100644
--- a/chromium/content/public/browser/authenticator_request_client_delegate.h
+++ b/chromium/content/public/browser/authenticator_request_client_delegate.h
@@ -15,6 +15,10 @@
#include "device/fido/fido_request_handler_base.h"
#include "device/fido/fido_transport_protocol.h"
+#if defined(OS_MACOSX)
+#include "device/fido/mac/authenticator_config.h"
+#endif
+
namespace device {
class FidoAuthenticator;
}
@@ -50,7 +54,8 @@ class CONTENT_EXPORT AuthenticatorRequestClientDelegate
virtual void RegisterActionCallbacks(
base::OnceClosure cancel_callback,
device::FidoRequestHandlerBase::RequestCallback request_callback,
- base::RepeatingClosure bluetooth_adapter_power_on_callback);
+ base::RepeatingClosure bluetooth_adapter_power_on_callback,
+ device::FidoRequestHandlerBase::BlePairingCallback ble_pairing_callback);
// Returns true if the given relying party ID is permitted to receive
// individual attestation certificates. This:
@@ -80,18 +85,7 @@ class CONTENT_EXPORT AuthenticatorRequestClientDelegate
virtual bool IsFocused();
#if defined(OS_MACOSX)
- struct TouchIdAuthenticatorConfig {
- // The keychain-access-group value used for WebAuthn credentials
- // stored in the macOS keychain by the built-in Touch ID
- // authenticator. For more information on this, refer to
- // |device::fido::TouchIdAuthenticator|.
- std::string keychain_access_group;
- // The secret used to derive key material when encrypting WebAuthn
- // credential metadata for storage in the macOS keychain. Chrome returns
- // different secrets for each user profile in order to logically separate
- // credentials per profile.
- std::string metadata_secret;
- };
+ using TouchIdAuthenticatorConfig = device::fido::mac::AuthenticatorConfig;
// Returns configuration data for the built-in Touch ID platform
// authenticator. May return nullopt if the authenticator is not used or not
@@ -122,6 +116,10 @@ class CONTENT_EXPORT AuthenticatorRequestClientDelegate
void FidoAuthenticatorAdded(
const device::FidoAuthenticator& authenticator) override;
void FidoAuthenticatorRemoved(base::StringPiece device_id) override;
+ void FidoAuthenticatorIdChanged(base::StringPiece old_authenticator_id,
+ std::string new_authenticator_id) override;
+ void FidoAuthenticatorPairingModeChanged(
+ base::StringPiece authenticator_id) override;
private:
DISALLOW_COPY_AND_ASSIGN(AuthenticatorRequestClientDelegate);
diff --git a/chromium/content/public/browser/ax_event_notification_details.cc b/chromium/content/public/browser/ax_event_notification_details.cc
index fb2694ea914..46a861e033d 100644
--- a/chromium/content/public/browser/ax_event_notification_details.cc
+++ b/chromium/content/public/browser/ax_event_notification_details.cc
@@ -8,7 +8,8 @@
namespace content {
-AXEventNotificationDetails::AXEventNotificationDetails() : ax_tree_id(-1) {}
+AXEventNotificationDetails::AXEventNotificationDetails()
+ : ax_tree_id(ui::AXTreeIDUnknown()) {}
AXEventNotificationDetails::AXEventNotificationDetails(
const AXEventNotificationDetails& other) = default;
@@ -16,9 +17,7 @@ AXEventNotificationDetails::AXEventNotificationDetails(
AXEventNotificationDetails::~AXEventNotificationDetails() {}
AXLocationChangeNotificationDetails::AXLocationChangeNotificationDetails()
- : id(-1),
- ax_tree_id(-1) {
-}
+ : id(-1), ax_tree_id(ui::AXTreeIDUnknown()) {}
AXLocationChangeNotificationDetails::AXLocationChangeNotificationDetails(
const AXLocationChangeNotificationDetails& other) = default;
diff --git a/chromium/content/public/browser/ax_event_notification_details.h b/chromium/content/public/browser/ax_event_notification_details.h
index 7a38ebe7548..7340b2fa2c7 100644
--- a/chromium/content/public/browser/ax_event_notification_details.h
+++ b/chromium/content/public/browser/ax_event_notification_details.h
@@ -25,7 +25,7 @@ struct CONTENT_EXPORT AXEventNotificationDetails {
~AXEventNotificationDetails();
// The unique ID of the accessibility tree this event bundle applies to.
- int ax_tree_id;
+ ui::AXTreeID ax_tree_id;
// Zero or more updates to the accessibility tree to apply first.
std::vector<ui::AXTreeUpdate> updates;
@@ -44,7 +44,7 @@ struct CONTENT_EXPORT AXLocationChangeNotificationDetails {
~AXLocationChangeNotificationDetails();
int id;
- int ax_tree_id;
+ ui::AXTreeID ax_tree_id;
ui::AXRelativeBounds new_location;
};
diff --git a/chromium/content/public/browser/background_fetch_delegate.h b/chromium/content/public/browser/background_fetch_delegate.h
index bff9eb68a7d..46f2e248bff 100644
--- a/chromium/content/public/browser/background_fetch_delegate.h
+++ b/chromium/content/public/browser/background_fetch_delegate.h
@@ -16,6 +16,7 @@
#include "base/optional.h"
#include "content/common/content_export.h"
#include "content/public/browser/resource_request_info.h"
+#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
#include "third_party/skia/include/core/SkBitmap.h"
class GURL;
@@ -38,14 +39,16 @@ struct BackgroundFetchResponse;
struct BackgroundFetchResult;
struct BackgroundFetchDescription;
-// Various reasons a Background Fetch can get aborted.
-enum class BackgroundFetchReasonToAbort {
- NONE,
- CANCELLED_FROM_UI,
- ABORTED_BY_DEVELOPER,
- TOTAL_DOWNLOAD_SIZE_EXCEEDED,
- SERVICE_WORKER_UNAVAILABLE,
- QUOTA_EXCEEDED,
+enum class BackgroundFetchPermission {
+ // Background Fetch is allowed.
+ ALLOWED,
+
+ // Background Fetch should be started in a paused state, to let the user
+ // decide whether to continue.
+ ASK,
+
+ // Background Fetch is blocked.
+ BLOCKED,
};
// Interface for launching background fetches. Implementing classes would
@@ -55,7 +58,8 @@ enum class BackgroundFetchReasonToAbort {
class CONTENT_EXPORT BackgroundFetchDelegate {
public:
using GetIconDisplaySizeCallback = base::OnceCallback<void(const gfx::Size&)>;
- using GetPermissionForOriginCallback = base::OnceCallback<void(bool)>;
+ using GetPermissionForOriginCallback =
+ base::OnceCallback<void(BackgroundFetchPermission)>;
// Client interface that a BackgroundFetchDelegate would use to signal the
// progress of a background fetch.
@@ -67,7 +71,7 @@ class CONTENT_EXPORT BackgroundFetchDelegate {
// e.g. because the user clicked cancel on a notification.
virtual void OnJobCancelled(
const std::string& job_unique_id,
- BackgroundFetchReasonToAbort reason_to_abort) = 0;
+ blink::mojom::BackgroundFetchFailureReason reason_to_abort) = 0;
// Called after the download has started with the initial response
// (including headers and URL chain). Always called on the UI thread.
diff --git a/chromium/content/public/browser/background_fetch_description.cc b/chromium/content/public/browser/background_fetch_description.cc
index 7857bfd244a..cc3b5af2f24 100644
--- a/chromium/content/public/browser/background_fetch_description.cc
+++ b/chromium/content/public/browser/background_fetch_description.cc
@@ -15,7 +15,8 @@ BackgroundFetchDescription::BackgroundFetchDescription(
int total_parts,
int completed_parts_size,
int total_parts_size,
- std::vector<std::string> current_guids)
+ std::vector<std::string> outstanding_guids,
+ bool start_paused)
: job_unique_id(job_unique_id),
title(title),
origin(origin),
@@ -24,7 +25,8 @@ BackgroundFetchDescription::BackgroundFetchDescription(
total_parts(total_parts),
completed_parts_size(completed_parts_size),
total_parts_size(total_parts_size),
- current_guids(std::move(current_guids)) {}
+ outstanding_guids(std::move(outstanding_guids)),
+ start_paused(start_paused) {}
BackgroundFetchDescription::~BackgroundFetchDescription() = default;
diff --git a/chromium/content/public/browser/background_fetch_description.h b/chromium/content/public/browser/background_fetch_description.h
index 40d56f07ba3..be9984d3cb1 100644
--- a/chromium/content/public/browser/background_fetch_description.h
+++ b/chromium/content/public/browser/background_fetch_description.h
@@ -23,7 +23,8 @@ struct CONTENT_EXPORT BackgroundFetchDescription {
int total_parts,
int completed_parts_size,
int total_parts_size,
- std::vector<std::string> current_guids);
+ std::vector<std::string> outstanding_guids,
+ bool start_paused);
~BackgroundFetchDescription();
const std::string job_unique_id;
@@ -34,7 +35,8 @@ struct CONTENT_EXPORT BackgroundFetchDescription {
int total_parts;
int completed_parts_size;
int total_parts_size;
- std::vector<std::string> current_guids;
+ std::vector<std::string> outstanding_guids;
+ bool start_paused;
private:
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchDescription);
diff --git a/chromium/content/public/browser/background_fetch_response.cc b/chromium/content/public/browser/background_fetch_response.cc
index 2866062274f..c6514acac3c 100644
--- a/chromium/content/public/browser/background_fetch_response.cc
+++ b/chromium/content/public/browser/background_fetch_response.cc
@@ -13,16 +13,22 @@ BackgroundFetchResponse::BackgroundFetchResponse(
BackgroundFetchResponse::~BackgroundFetchResponse() = default;
-BackgroundFetchResult::BackgroundFetchResult(base::Time response_time,
- FailureReason failure_reason)
- : response_time(response_time), failure_reason(failure_reason) {}
+BackgroundFetchResult::BackgroundFetchResult(
+ std::unique_ptr<BackgroundFetchResponse> response,
+ base::Time response_time,
+ FailureReason failure_reason)
+ : response(std::move(response)),
+ response_time(response_time),
+ failure_reason(failure_reason) {}
BackgroundFetchResult::BackgroundFetchResult(
+ std::unique_ptr<BackgroundFetchResponse> response,
base::Time response_time,
const base::FilePath& path,
base::Optional<storage::BlobDataHandle> blob_handle,
uint64_t file_size)
- : response_time(response_time),
+ : response(std::move(response)),
+ response_time(response_time),
file_path(path),
blob_handle(blob_handle),
file_size(file_size),
diff --git a/chromium/content/public/browser/background_fetch_response.h b/chromium/content/public/browser/background_fetch_response.h
index 9575776194a..be3f6c919e4 100644
--- a/chromium/content/public/browser/background_fetch_response.h
+++ b/chromium/content/public/browser/background_fetch_response.h
@@ -52,21 +52,26 @@ struct CONTENT_EXPORT BackgroundFetchResult {
// Used when the download was cancelled by the user.
CANCELLED,
- // Used when the failure reason is unknown.
- UNKNOWN,
+ // Catch-all error. Used when the failure reason is unknown or not exposed
+ // to the developer.
+ FETCH_ERROR,
};
// Constructor for failed downloads.
- BackgroundFetchResult(base::Time response_time, FailureReason failure_reason);
+ BackgroundFetchResult(std::unique_ptr<BackgroundFetchResponse> response,
+ base::Time response_time,
+ FailureReason failure_reason);
// Constructor for successful downloads.
- BackgroundFetchResult(base::Time response_time,
+ BackgroundFetchResult(std::unique_ptr<BackgroundFetchResponse> response,
+ base::Time response_time,
const base::FilePath& path,
base::Optional<storage::BlobDataHandle> blob_handle,
uint64_t file_size);
~BackgroundFetchResult();
+ std::unique_ptr<BackgroundFetchResponse> response;
const base::Time response_time;
const base::FilePath file_path;
base::Optional<storage::BlobDataHandle> blob_handle;
diff --git a/chromium/content/public/browser/browser_accessibility_state.h b/chromium/content/public/browser/browser_accessibility_state.h
index 3c969f94b7b..484214bddd9 100644
--- a/chromium/content/public/browser/browser_accessibility_state.h
+++ b/chromium/content/public/browser/browser_accessibility_state.h
@@ -8,7 +8,7 @@
#include "base/callback_forward.h"
#include "content/common/content_export.h"
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
namespace content {
diff --git a/chromium/content/public/browser/browser_associated_interface.h b/chromium/content/public/browser/browser_associated_interface.h
index 7f55cfc960b..ffbbfd782ed 100644
--- a/chromium/content/public/browser/browser_associated_interface.h
+++ b/chromium/content/public/browser/browser_associated_interface.h
@@ -10,8 +10,10 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
+#include "base/task/post_task.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "ipc/ipc_channel_proxy.h"
#include "mojo/public/cpp/bindings/associated_binding_set.h"
@@ -73,8 +75,8 @@ class BrowserAssociatedInterface {
void ClearBindings() {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&InternalState::ClearBindings, this));
return;
}
diff --git a/chromium/content/public/browser/browser_context.h b/chromium/content/public/browser/browser_context.h
index e49eaaa04ab..e26a929290a 100644
--- a/chromium/content/public/browser/browser_context.h
+++ b/chromium/content/public/browser/browser_context.h
@@ -20,6 +20,7 @@
#include "content/common/content_export.h"
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory.h"
+#include "services/network/public/mojom/cors_origin_pattern.mojom.h"
#include "services/service_manager/embedder/embedded_service_info.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
@@ -45,6 +46,10 @@ namespace storage {
class ExternalMountPoints;
}
+namespace url {
+class Origin;
+}
+
namespace media {
class VideoDecodePerfHistory;
}
@@ -77,6 +82,7 @@ class PermissionControllerDelegate;
class PushMessagingService;
class ResourceContext;
class ServiceManagerConnection;
+class SharedCorsOriginAccessList;
class SiteInstance;
class StoragePartition;
class SSLHostStateDelegate;
@@ -215,6 +221,21 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData {
static ServiceManagerConnection* GetServiceManagerConnectionFor(
BrowserContext* browser_context);
+ // Returns a SharedCorsOriginAccessList instance for the |browser_context|.
+ // TODO(toyoshim): Remove this interface once NetworkService is enabled.
+ static const SharedCorsOriginAccessList* GetSharedCorsOriginAccessList(
+ BrowserContext* browser_context);
+
+ // Sets CORS origin access lists. This obtains SharedCorsOriginAccessList
+ // that is bound to |browser_context|, and calls SetForOrigin(...) for legacy
+ // code path, but calls into NetworkService instead if it is enabled.
+ static void SetCorsOriginAccessListsForOrigin(
+ BrowserContext* browser_context,
+ const url::Origin& source_origin,
+ std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
+ std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
+ base::OnceClosure closure);
+
BrowserContext();
~BrowserContext() override;
diff --git a/chromium/content/public/browser/browser_main_parts.cc b/chromium/content/public/browser/browser_main_parts.cc
index 130ad375fea..7d75bc6f5ce 100644
--- a/chromium/content/public/browser/browser_main_parts.cc
+++ b/chromium/content/public/browser/browser_main_parts.cc
@@ -8,10 +8,6 @@
namespace content {
-bool BrowserMainParts::ShouldContentCreateFeatureList() {
- return true;
-}
-
int BrowserMainParts::PreEarlyInitialization() {
return service_manager::RESULT_CODE_NORMAL_EXIT;
}
diff --git a/chromium/content/public/browser/browser_main_parts.h b/chromium/content/public/browser/browser_main_parts.h
index 2013a970877..9001f215297 100644
--- a/chromium/content/public/browser/browser_main_parts.h
+++ b/chromium/content/public/browser/browser_main_parts.h
@@ -54,11 +54,6 @@ class CONTENT_EXPORT BrowserMainParts {
BrowserMainParts() {}
virtual ~BrowserMainParts() {}
- // Returns true if content should create a FeatureList. Default
- // implementation returns true. Embedders that need to control when and/or
- // how FeatureList should be created should override and return false.
- virtual bool ShouldContentCreateFeatureList();
-
// A return value other than RESULT_CODE_NORMAL_EXIT indicates error and is
// used as the exit status.
virtual int PreEarlyInitialization();
diff --git a/chromium/content/public/browser/browser_message_filter.cc b/chromium/content/public/browser/browser_message_filter.cc
index 8f10336a9a9..b9906035754 100644
--- a/chromium/content/public/browser/browser_message_filter.cc
+++ b/chromium/content/public/browser/browser_message_filter.cc
@@ -11,10 +11,12 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/process/process_handle.h"
+#include "base/task/post_task.h"
#include "base/task_runner.h"
#include "build/build_config.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/child_process_launcher.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
#include "ipc/ipc_sync_message.h"
@@ -73,8 +75,8 @@ class BrowserMessageFilter::Internal : public IPC::MessageFilter {
return DispatchMessage(message);
}
- BrowserThread::PostTask(
- thread, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {thread},
base::BindOnce(base::IgnoreResult(&Internal::DispatchMessage), this,
message));
return true;
@@ -144,8 +146,8 @@ bool BrowserMessageFilter::Send(IPC::Message* message) {
}
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(base::IgnoreResult(&BrowserMessageFilter::Send), this,
message));
return true;
diff --git a/chromium/content/public/browser/browser_task_traits.h b/chromium/content/public/browser/browser_task_traits.h
index 8ccee9d9fe4..e5a537cc63c 100644
--- a/chromium/content/public/browser/browser_task_traits.h
+++ b/chromium/content/public/browser/browser_task_traits.h
@@ -32,18 +32,29 @@ struct NonNestable {};
// To obtain a TaskRunner for the UI thread (analogous for the IO thread):
// base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
//
+// Tasks posted to the same BrowserThread with the same traits will be executed
+// in the order they were posted, regardless of the TaskRunners they were
+// posted via.
+//
// See //base/task/post_task.h for more detailed documentation.
//
// Posting to a BrowserThread must only be done after it was initialized (ref.
// BrowserMainLoop::CreateThreads() phase).
class CONTENT_EXPORT BrowserTaskTraitsExtension {
+ using BrowserThreadIDFilter =
+ base::trait_helpers::RequiredEnumTraitFilter<BrowserThread::ID>;
+ using NonNestableFilter =
+ base::trait_helpers::BooleanTraitFilter<NonNestable>;
+
public:
static constexpr uint8_t kExtensionId =
base::TaskTraitsExtensionStorage::kFirstEmbedderExtensionId;
- struct ValidTrait {
- ValidTrait(BrowserThread::ID) {}
- ValidTrait(NonNestable) {}
+ struct ValidTrait : public base::TaskTraits::ValidTrait {
+ using base::TaskTraits::ValidTrait::ValidTrait;
+
+ ValidTrait(BrowserThread::ID);
+ ValidTrait(NonNestable);
};
template <
@@ -51,11 +62,10 @@ class CONTENT_EXPORT BrowserTaskTraitsExtension {
class CheckArgumentsAreValid = std::enable_if_t<
base::trait_helpers::AreValidTraits<ValidTrait, ArgTypes...>::value>>
constexpr BrowserTaskTraitsExtension(ArgTypes... args)
- : browser_thread_(base::trait_helpers::GetValueFromArgList(
- base::trait_helpers::RequiredEnumArgGetter<BrowserThread::ID>(),
- args...)),
- nestable_(!base::trait_helpers::GetValueFromArgList(
- base::trait_helpers::BooleanArgGetter<NonNestable>(),
+ : browser_thread_(
+ base::trait_helpers::GetTraitFromArgList<BrowserThreadIDFilter>(
+ args...)),
+ nestable_(!base::trait_helpers::GetTraitFromArgList<NonNestableFilter>(
args...)) {}
constexpr base::TaskTraitsExtensionStorage Serialize() const {
diff --git a/chromium/content/public/browser/browser_task_traits_unittest.nc b/chromium/content/public/browser/browser_task_traits_unittest.nc
index 3fccbebb141..e74f178bfb0 100644
--- a/chromium/content/public/browser/browser_task_traits_unittest.nc
+++ b/chromium/content/public/browser/browser_task_traits_unittest.nc
@@ -10,7 +10,7 @@
namespace content {
-#if defined(NCTEST_BROWSER_TASK_TRAITS_NO_THREAD) // [r"no member named 'GetDefaultValue' in 'base::trait_helpers::RequiredEnumArgGetter<content::BrowserThread::ID>'"]
+#if defined(NCTEST_BROWSER_TASK_TRAITS_NO_THREAD) // [r"TaskTraits contains a Trait that must be explicity initialized in its constructor."]
constexpr base::TaskTraits traits = {NonNestable()};
#elif defined(NCTEST_BROWSER_TASK_TRAITS_MULTIPLE_THREADS) // [r"Multiple arguments of the same type were provided to the constructor of TaskTraits."]
constexpr base::TaskTraits traits = {BrowserThread::UI,
diff --git a/chromium/content/public/browser/browser_thread.h b/chromium/content/public/browser/browser_thread.h
index 159bc7f1054..279b56912c6 100644
--- a/chromium/content/public/browser/browser_thread.h
+++ b/chromium/content/public/browser/browser_thread.h
@@ -40,7 +40,6 @@ class BrowserThreadImpl;
// message loop.
//
// See browser_task_traits.h for posting Tasks to a BrowserThread.
-// TODO(https://crbug.com/878356): Replace uses with base's post_task.h API.
//
// This class automatically handles the lifetime of different threads. You
// should never need to cache pointers to MessageLoops, since they're not thread
@@ -67,64 +66,11 @@ class CONTENT_EXPORT BrowserThread {
ID_COUNT
};
- // DEPRECATED: Please use the API described in browser_task_traits.h instead.
- // TODO(https://crbug.com/878356): Replace uses with base::PostTaskWithTraits.
- //
- // These are the same methods in message_loop.h, but are guaranteed to either
- // get posted to the MessageLoop if it's still alive, or be deleted otherwise.
- // They return true iff the thread existed and the task was posted. Note that
- // even if the task is posted, there's no guarantee that it will run, since
- // the target thread may already have a Quit message in its queue.
- static bool PostTask(ID identifier,
- const base::Location& from_here,
- base::OnceClosure task);
- static bool PostDelayedTask(ID identifier,
- const base::Location& from_here,
- base::OnceClosure task,
- base::TimeDelta delay);
- static bool PostNonNestableTask(ID identifier,
- const base::Location& from_here,
- base::OnceClosure task);
- static bool PostNonNestableDelayedTask(ID identifier,
- const base::Location& from_here,
- base::OnceClosure task,
- base::TimeDelta delay);
-
- static bool PostTaskAndReply(ID identifier,
- const base::Location& from_here,
- base::OnceClosure task,
- base::OnceClosure reply);
-
- template <typename ReturnType, typename ReplyArgType>
- static bool PostTaskAndReplyWithResult(
- ID identifier,
- const base::Location& from_here,
- base::OnceCallback<ReturnType()> task,
- base::OnceCallback<void(ReplyArgType)> reply) {
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- GetTaskRunnerForThread(identifier);
- return base::PostTaskAndReplyWithResult(task_runner.get(), from_here,
- std::move(task), std::move(reply));
- }
-
- // Callback version of PostTaskAndReplyWithResult above.
- // Though RepeatingCallback is convertible to OnceCallback, we need this since
- // we cannot use template deduction and object conversion at once on the
- // overload resolution.
- // TODO(crbug.com/714018): Update all callers of the Callback version to use
- // OnceCallback.
- template <typename ReturnType, typename ReplyArgType>
- static bool PostTaskAndReplyWithResult(
- ID identifier,
- const base::Location& from_here,
- base::Callback<ReturnType()> task,
- base::Callback<void(ReplyArgType)> reply) {
- return PostTaskAndReplyWithResult(
- identifier, from_here,
- base::OnceCallback<ReturnType()>(std::move(task)),
- base::OnceCallback<void(ReplyArgType)>(std::move(reply)));
- }
+ // NOTE: Task posting APIs have moved to post_task.h. See
+ // browser_task_traits.h.
+ // TODO(crbug.com/878356): Consider replacing callsites of this with
+ // base::CreateTaskRunnerWithTraits({id})->DeleteSoon(..).
template <class T>
static bool DeleteSoon(ID identifier,
const base::Location& from_here,
@@ -153,6 +99,9 @@ class CONTENT_EXPORT BrowserThread {
// When called after the browser startup is complete, will post |task|
// to |task_runner| immediately.
// Note: see related ContentBrowserClient::PostAfterStartupTask.
+ //
+ // TODO(crbug.com/887407): Replace callsites with PostTaskWithTraits and
+ // appropriate traits (TBD).
static void PostAfterStartupTask(
const base::Location& from_here,
const scoped_refptr<base::TaskRunner>& task_runner,
@@ -170,15 +119,6 @@ class CONTENT_EXPORT BrowserThread {
// sets identifier to its ID. Otherwise returns false.
static bool GetCurrentThreadIdentifier(ID* identifier) WARN_UNUSED_RESULT;
- // DEPRECATED: Please use the API described in browser_task_traits.h instead.
- // TODO(https://crbug.com/878356): Replace uses with
- // base::Create*TaskRunnerWithTraits.
- //
- // Callers can hold on to a refcounted task runner beyond the lifetime of the
- // thread.
- static scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunnerForThread(
- ID identifier);
-
// Sets the delegate for BrowserThread::IO.
//
// Only one delegate may be registered at a time. The delegate may be
@@ -245,6 +185,12 @@ class CONTENT_EXPORT BrowserThread {
// Returns an appropriate error message for when DCHECK_CURRENTLY_ON() fails.
static std::string GetDCheckCurrentlyOnErrorMessage(ID expected);
+ protected:
+ // For DeleteSoon(). Requires that the BrowserThread with the provided
+ // |identifier| was started.
+ static scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunnerForThread(
+ ID identifier);
+
private:
friend class BrowserThreadImpl;
diff --git a/chromium/content/public/browser/content_browser_client.cc b/chromium/content/public/browser/content_browser_client.cc
index 8e652e4b66f..6ed69effde7 100644
--- a/chromium/content/public/browser/content_browser_client.cc
+++ b/chromium/content/public/browser/content_browser_client.cc
@@ -126,6 +126,14 @@ void ContentBrowserClient::LogInitiatorSchemeBypassingDocumentBlocking(
int render_process_id,
ResourceType resource_type) {}
+network::mojom::URLLoaderFactoryPtrInfo
+ContentBrowserClient::CreateURLLoaderFactoryForNetworkRequests(
+ RenderProcessHost* process,
+ network::mojom::NetworkContext* network_context,
+ const url::Origin& request_initiator) {
+ return network::mojom::URLLoaderFactoryPtrInfo();
+}
+
void ContentBrowserClient::GetAdditionalViewSourceSchemes(
std::vector<std::string>* additional_schemes) {
GetAdditionalWebUISchemes(additional_schemes);
@@ -160,13 +168,6 @@ bool ContentBrowserClient::IsURLAcceptableForWebUI(
return false;
}
-bool ContentBrowserClient::
- ShouldFrameShareParentSiteInstanceDespiteTopDocumentIsolation(
- const GURL& url,
- SiteInstance* parent_site_instance) {
- return false;
-}
-
bool ContentBrowserClient::ShouldStayInParentProcessForNTP(
const GURL& url,
SiteInstance* parent_site_instance) {
@@ -187,6 +188,11 @@ bool ContentBrowserClient::ShouldTryToUseExistingProcessHost(
return false;
}
+bool ContentBrowserClient::ShouldSubframesTryToReuseExistingProcess(
+ RenderFrameHost* main_frame) {
+ return true;
+}
+
bool ContentBrowserClient::ShouldSwapBrowsingInstancesForNavigation(
SiteInstance* site_instance,
const GURL& current_url,
@@ -382,8 +388,9 @@ void ContentBrowserClient::SelectClientCertificate(
net::ClientCertIdentityList client_certs,
std::unique_ptr<ClientCertificateDelegate> delegate) {}
-net::URLRequestContext* ContentBrowserClient::OverrideRequestContextForURL(
- const GURL& url, ResourceContext* context) {
+net::CookieStore* ContentBrowserClient::OverrideCookieStoreForURL(
+ const GURL& url,
+ ResourceContext* context) {
return nullptr;
}
@@ -671,8 +678,9 @@ bool ContentBrowserClient::WillCreateURLLoaderFactory(
BrowserContext* browser_context,
RenderFrameHost* frame,
bool is_navigation,
- const GURL& url,
- network::mojom::URLLoaderFactoryRequest* factory_request) {
+ const url::Origin& request_initiator,
+ network::mojom::URLLoaderFactoryRequest* factory_request,
+ bool* bypass_redirect_checks) {
return false;
}
@@ -805,4 +813,15 @@ void ContentBrowserClient::RegisterRendererPreferenceWatcherForWorkers(
BrowserContext* browser_context,
mojom::RendererPreferenceWatcherPtr watcher) {}
+base::Optional<std::string> ContentBrowserClient::GetOriginPolicyErrorPage(
+ OriginPolicyErrorReason error_reason,
+ const url::Origin& origin,
+ const GURL& url) {
+ return base::nullopt;
+}
+
+bool ContentBrowserClient::CanIgnoreCertificateErrorIfNeeded() {
+ return false;
+}
+
} // namespace content
diff --git a/chromium/content/public/browser/content_browser_client.h b/chromium/content/public/browser/content_browser_client.h
index bc2b501331e..b33545b865e 100644
--- a/chromium/content/public/browser/content_browser_client.h
+++ b/chromium/content/public/browser/content_browser_client.h
@@ -110,12 +110,12 @@ class AuthCredentials;
class ClientCertIdentity;
using ClientCertIdentityList = std::vector<std::unique_ptr<ClientCertIdentity>>;
class ClientCertStore;
+class CookieStore;
class HttpRequestHeaders;
class NetLog;
class SSLCertRequestInfo;
class SSLInfo;
class URLRequest;
-class URLRequestContext;
} // namespace net
namespace network {
@@ -179,6 +179,7 @@ class URLLoaderThrottle;
class VpnServiceProxy;
class WebContents;
class WebContentsViewDelegate;
+enum class OriginPolicyErrorReason;
struct MainFunctionParams;
struct OpenURLParams;
struct Referrer;
@@ -322,6 +323,28 @@ class CONTENT_EXPORT ContentBrowserClient {
int render_process_id,
ResourceType resource_type);
+ // Called to create a URLLoaderFactory for network requests in the following
+ // cases:
+ // - The default factory to be used by a frame. In this case
+ // |request_initiator| is the origin being committed in the frame (or the
+ // last origin committed in the frame).
+ // - The initiator-specific factory to be used by a frame. This happens for
+ // origins covered via
+ // RenderFrameHost::MarkInitiatorAsRequiringSeparateURLLoaderFactory.
+ //
+ // This method allows the //content embedder to provide a URLLoaderFactory
+ // with |request_initiator|-specific properties (e.g. with relaxed
+ // Cross-Origin Read Blocking enforcement as needed by some extensions).
+ //
+ // If the embedder doesn't want to override the URLLoaderFactory for the given
+ // |request_initiator|, then it should return an invalid
+ // mojo::InterfacePtrInfo.
+ virtual network::mojom::URLLoaderFactoryPtrInfo
+ CreateURLLoaderFactoryForNetworkRequests(
+ RenderProcessHost* process,
+ network::mojom::NetworkContext* network_context,
+ const url::Origin& request_initiator);
+
// Returns a list additional WebUI schemes, if any. These additional schemes
// act as aliases to the chrome: scheme. The additional schemes may or may
// not serve specific WebUI pages depending on the particular URLDataSource
@@ -374,14 +397,6 @@ class CONTENT_EXPORT ContentBrowserClient {
bool* is_renderer_initiated,
content::Referrer* referrer) {}
- // Allows the embedder to override top document isolation for specific frames.
- // |url| is the URL being loaded in the subframe, and |parent_site_instance|
- // is the SiteInstance of the parent frame. Called only for subframes and only
- // when top document isolation mode is enabled.
- virtual bool ShouldFrameShareParentSiteInstanceDespiteTopDocumentIsolation(
- const GURL& url,
- SiteInstance* parent_site_instance);
-
// Temporary hack to determine whether to skip OOPIFs on the new tab page.
// TODO(creis): Remove when https://crbug.com/566091 is fixed.
virtual bool ShouldStayInParentProcessForNTP(
@@ -403,6 +418,15 @@ class CONTENT_EXPORT ContentBrowserClient {
virtual bool ShouldTryToUseExistingProcessHost(
BrowserContext* browser_context, const GURL& url);
+ // Returns whether or not subframes of |main_frame| should try to
+ // aggressively reuse existing processes, even when below process limit.
+ // This gets called when navigating a subframe to a URL that requires a
+ // dedicated process and defaults to true, which minimizes the process count.
+ // The embedder can choose to override this if there is a reason to avoid the
+ // reuse.
+ virtual bool ShouldSubframesTryToReuseExistingProcess(
+ RenderFrameHost* main_frame);
+
// Called when a site instance is first associated with a process.
virtual void SiteInstanceGotProcess(SiteInstance* site_instance) {}
@@ -610,12 +634,11 @@ class CONTENT_EXPORT ContentBrowserClient {
// "1812:e, 00001800-0000-1000-8000-00805f9b34fb:w, ignored:1, alsoignored."
virtual std::string GetWebBluetoothBlocklist();
- // Allow the embedder to override the request context based on the URL for
- // certain operations, like cookie access. Returns nullptr to indicate the
- // regular request context should be used.
+ // Allow the embedder to override the cookie store for a particular URL.
+ // Returns nullptr to indicate the regular cookie store should be used.
// This is called on the IO thread.
- virtual net::URLRequestContext* OverrideRequestContextForURL(
- const GURL& url, ResourceContext* context);
+ virtual net::CookieStore* OverrideCookieStoreForURL(const GURL& url,
+ ResourceContext* context);
// Allows the embedder to override the LocationProvider implementation.
// Return nullptr to indicate the default one for the platform should be
@@ -1122,15 +1145,17 @@ class CONTENT_EXPORT ContentBrowserClient {
NonNetworkURLLoaderFactoryMap* factories);
// Allows the embedder to intercept URLLoaderFactory interfaces used for
- // navigation or being brokered on behalf of a renderer fetching subresources,
- // or for non-navigation requests initiated by the browser on behalf of a
- // BrowserContext.
+ // navigation or being brokered on behalf of a renderer fetching subresources.
//
// |is_navigation| is true when it's a request used for navigation.
- // |url| is set when it's a request for navigations or for a renderer fetching
- // subresources. It's not set in the 3rd case (browser-initiated
- // non-navigation requests) because in that case the factory is cached and it
- // can be used for multiple URLs.
+ //
+ // |request_initiator| indicates which origin will be the initiator of
+ // requests that will use the URLLoaderFactory (see also
+ // |network::ResourceRequest::requests|). |request_initiator| is set when
+ // it's a request for a renderer fetching subresources. It's not set when
+ // creating a factory for navigation requests, because navigation requests are
+ // made on behalf of the browser, rather than on behalf of any particular
+ // origin.
//
// |*factory_request| is always valid upon entry and MUST be valid upon
// return. The embedder may swap out the value of |*factory_request| for its
@@ -1138,18 +1163,18 @@ class CONTENT_EXPORT ContentBrowserClient {
// requests for the URLLoaderFactory. Otherwise |*factory_request| is left
// unmodified and this must return |false|.
//
+ // |bypass_redirect_checks| will be set to true when the embedder will be
+ // handling redirect security checks.
+ //
// Always called on the UI thread and only when the Network Service is
// enabled.
- //
- // Note that |frame| may be null if this is a browser-initiated,
- // non-navigation request, e.g. a request made via
- // |StoragePartition::GetURLLoaderFactoryForBrowserProcess()|.
virtual bool WillCreateURLLoaderFactory(
BrowserContext* browser_context,
RenderFrameHost* frame,
bool is_navigation,
- const GURL& url,
- network::mojom::URLLoaderFactoryRequest* factory_request);
+ const url::Origin& request_initiator,
+ network::mojom::URLLoaderFactoryRequest* factory_request,
+ bool* bypass_redirect_checks);
// Allows the embedder to intercept a WebSocket connection. |*request|
// is always valid upon entry and MUST be valid upon return. The embedder
@@ -1326,6 +1351,19 @@ class CONTENT_EXPORT ContentBrowserClient {
virtual void RegisterRendererPreferenceWatcherForWorkers(
BrowserContext* browser_context,
mojom::RendererPreferenceWatcherPtr watcher);
+
+ // Returns the HTML content of the error page for Origin Policy related
+ // errors.
+ virtual base::Optional<std::string> GetOriginPolicyErrorPage(
+ OriginPolicyErrorReason error_reason,
+ const url::Origin& origin,
+ const GURL& url);
+
+ // Returns true if it is OK to ignore errors for certificates specified by the
+ // --ignore-certificate-errors-spki-list command line flag. The embedder may
+ // perform additional checks, such as requiring --user-data-dir flag too to
+ // make sure that insecure contents will not persist accidentally.
+ virtual bool CanIgnoreCertificateErrorIfNeeded();
};
} // namespace content
diff --git a/chromium/content/public/browser/delegate_to_browser_gpu_service_accelerator_factory.h b/chromium/content/public/browser/delegate_to_browser_gpu_service_accelerator_factory.h
new file mode 100644
index 00000000000..0e8b5f84cf2
--- /dev/null
+++ b/chromium/content/public/browser/delegate_to_browser_gpu_service_accelerator_factory.h
@@ -0,0 +1,25 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_DELEGATE_TO_BROWSER_GPU_SERVICE_ACCELERATOR_FACTORY_H_
+#define CONTENT_PUBLIC_BROWSER_DELEGATE_TO_BROWSER_GPU_SERVICE_ACCELERATOR_FACTORY_H_
+
+#include "content/common/content_export.h"
+#include "services/video_capture/public/mojom/device_factory_provider.mojom.h"
+
+namespace content {
+
+// Implementation of video_capture::mojom::AcceleratorFactor that satisfies
+// requests for a JpegDecodeAccelerator by delegating to the global instance of
+// viz::mojom::GpuService that is accessible from the Browser process.
+class CONTENT_EXPORT DelegateToBrowserGpuServiceAcceleratorFactory
+ : public video_capture::mojom::AcceleratorFactory {
+ public:
+ void CreateJpegDecodeAccelerator(
+ media::mojom::JpegDecodeAcceleratorRequest jda_request) override;
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_DELEGATE_TO_BROWSER_GPU_SERVICE_ACCELERATOR_FACTORY_H_
diff --git a/chromium/content/public/browser/devtools_agent_host.h b/chromium/content/public/browser/devtools_agent_host.h
index 0be97b39183..73e2bcc942c 100644
--- a/chromium/content/public/browser/devtools_agent_host.h
+++ b/chromium/content/public/browser/devtools_agent_host.h
@@ -113,13 +113,9 @@ class CONTENT_EXPORT DevToolsAgentHost
static void RemoveObserver(DevToolsAgentHostObserver*);
// Attaches |client| to this agent host to start debugging.
- virtual void AttachClient(DevToolsAgentHostClient* client) = 0;
-
- // Attaches |client| to this agent host to start debugging.
- // This client will be restricted in certain ways. For example,
- // it will be detached when attempting to debug WebUI pages.
- // Returns |true| on success.
- virtual bool AttachRestrictedClient(DevToolsAgentHostClient* client) = 0;
+ // Returns |true| on success. Note that some policies defined by
+ // embedder or |client| itself may prevent attaching.
+ virtual bool AttachClient(DevToolsAgentHostClient* client) = 0;
// Already attached client detaches from this agent host to stop debugging it.
// Returns true iff detach succeeded.
diff --git a/chromium/content/public/browser/devtools_agent_host_client.cc b/chromium/content/public/browser/devtools_agent_host_client.cc
index 06c611e6737..f5f71bd90e9 100644
--- a/chromium/content/public/browser/devtools_agent_host_client.cc
+++ b/chromium/content/public/browser/devtools_agent_host_client.cc
@@ -12,4 +12,16 @@ bool DevToolsAgentHostClient::MayAttachToRenderer(
return true;
}
+bool DevToolsAgentHostClient::MayAttachToBrowser() {
+ return true;
+}
+
+bool DevToolsAgentHostClient::MayDiscoverTargets() {
+ return true;
+}
+
+bool DevToolsAgentHostClient::MayAffectLocalFiles() {
+ return true;
+}
+
} // namespace content
diff --git a/chromium/content/public/browser/devtools_agent_host_client.h b/chromium/content/public/browser/devtools_agent_host_client.h
index 53e560ae28e..8a93a1d4078 100644
--- a/chromium/content/public/browser/devtools_agent_host_client.h
+++ b/chromium/content/public/browser/devtools_agent_host_client.h
@@ -31,6 +31,17 @@ class CONTENT_EXPORT DevToolsAgentHostClient {
// Note: this method may be called before navigation commits.
virtual bool MayAttachToRenderer(content::RenderFrameHost* render_frame_host,
bool is_webui);
+
+ // Returns true if the client is allowed to attach to the browser agent host.
+ virtual bool MayAttachToBrowser();
+
+ // Returns true if the client is allowed to discover other DevTools targets.
+ // If not, it will be restricted to auto-attaching to related targets.
+ virtual bool MayDiscoverTargets();
+
+ // Returns true if the client is allowed to affect local files over the
+ // protocol. Example would be manipulating a deault downloads path.
+ virtual bool MayAffectLocalFiles();
};
} // namespace content
diff --git a/chromium/content/public/browser/dom_storage_context.h b/chromium/content/public/browser/dom_storage_context.h
index 6862d3cbb25..ef3dfa793d7 100644
--- a/chromium/content/public/browser/dom_storage_context.h
+++ b/chromium/content/public/browser/dom_storage_context.h
@@ -22,16 +22,14 @@ struct SessionStorageUsageInfo;
// Represents the per-BrowserContext Local Storage data.
class DOMStorageContext {
public:
- typedef base::Callback<
- void(const std::vector<LocalStorageUsageInfo>&)>
- GetLocalStorageUsageCallback;
+ using GetLocalStorageUsageCallback =
+ base::OnceCallback<void(const std::vector<LocalStorageUsageInfo>&)>;
- typedef base::OnceCallback<void(const std::vector<SessionStorageUsageInfo>&)>
- GetSessionStorageUsageCallback;
+ using GetSessionStorageUsageCallback =
+ base::OnceCallback<void(const std::vector<SessionStorageUsageInfo>&)>;
// Returns a collection of origins using local storage to the given callback.
- virtual void GetLocalStorageUsage(
- const GetLocalStorageUsageCallback& callback) = 0;
+ virtual void GetLocalStorageUsage(GetLocalStorageUsageCallback callback) = 0;
// Returns a collection of origins using session storage to the given
// callback.
diff --git a/chromium/content/public/browser/file_select_listener.h b/chromium/content/public/browser/file_select_listener.h
new file mode 100644
index 00000000000..a9be3939cab
--- /dev/null
+++ b/chromium/content/public/browser/file_select_listener.h
@@ -0,0 +1,31 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_FILE_SELECT_LISTENER_H_
+#define CONTENT_PUBLIC_BROWSER_FILE_SELECT_LISTENER_H_
+
+#include <vector>
+
+#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
+
+namespace content {
+
+// Callback interface to receive results of RunFileChooser() and
+// EnumerateDirectory() of WebContentsDelegate.
+class FileSelectListener {
+ public:
+ virtual ~FileSelectListener() {}
+
+ // This function should be called if file selection succeeds.
+ virtual void FileSelected(
+ std::vector<blink::mojom::FileChooserFileInfoPtr> files,
+ blink::mojom::FileChooserParams::Mode mode) = 0;
+
+ // This function should be called if a user cancels a file selection
+ // dialog, or we open no file selection dialog for some reason.
+ virtual void FileSelectionCanceled() = 0;
+};
+
+} // namespace content
+#endif // CONTENT_PUBLIC_BROWSER_FILE_SELECT_LISTENER_H_
diff --git a/chromium/content/public/browser/gpu_interface_provider_factory.h b/chromium/content/public/browser/gpu_interface_provider_factory.h
new file mode 100644
index 00000000000..9b81edeb208
--- /dev/null
+++ b/chromium/content/public/browser/gpu_interface_provider_factory.h
@@ -0,0 +1,22 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_GPU_INTERFACE_PROVIDER_FACTORY_H_
+#define CONTENT_PUBLIC_BROWSER_GPU_INTERFACE_PROVIDER_FACTORY_H_
+
+#include <memory>
+
+#include "content/common/content_export.h"
+#include "services/ws/public/cpp/host/gpu_interface_provider.h"
+
+namespace content {
+
+// Creates a GpuInterfaceProvider that forwards to the Gpu implementation in
+// content.
+CONTENT_EXPORT std::unique_ptr<ws::GpuInterfaceProvider>
+CreateGpuInterfaceProvider();
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_GPU_INTERFACE_PROVIDER_FACTORY_H_
diff --git a/chromium/content/public/browser/gpu_service_registry.cc b/chromium/content/public/browser/gpu_service_registry.cc
index 97ab27d3ca6..e326a294678 100644
--- a/chromium/content/public/browser/gpu_service_registry.cc
+++ b/chromium/content/public/browser/gpu_service_registry.cc
@@ -4,13 +4,14 @@
#include "content/public/browser/gpu_service_registry.h"
+#include "components/viz/host/gpu_host_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
namespace content {
void BindInterfaceInGpuProcess(const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {
- GpuProcessHost* host = GpuProcessHost::Get();
+ auto* host = GpuProcessHost::Get()->gpu_host();
return host->BindInterface(interface_name, std::move(interface_pipe));
}
diff --git a/chromium/content/public/browser/gpu_utils.cc b/chromium/content/public/browser/gpu_utils.cc
index fc97755995c..d6162ed6fdc 100644
--- a/chromium/content/public/browser/gpu_utils.cc
+++ b/chromium/content/public/browser/gpu_utils.cc
@@ -11,10 +11,13 @@
#include "base/strings/string_number_conversions.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
+#include "components/viz/common/features.h"
+#include "content/browser/browser_main_loop.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/service_utils.h"
+#include "gpu/config/gpu_finch_features.h"
#include "gpu/config/gpu_switches.h"
#include "media/media_buildflags.h"
@@ -47,6 +50,17 @@ void StopGpuProcessImpl(const base::Closure& callback,
namespace content {
+bool ShouldEnableAndroidSurfaceControl(const base::CommandLine& cmd_line) {
+#if !defined(OS_ANDROID)
+ return false;
+#else
+ if (!base::FeatureList::IsEnabled(features::kVizDisplayCompositor))
+ return false;
+
+ return base::FeatureList::IsEnabled(features::kAndroidSurfaceControl);
+#endif
+}
+
const gpu::GpuPreferences GetGpuPreferencesFromCommandLine() {
DCHECK(base::CommandLine::InitializedForCurrentProcess());
const base::CommandLine* command_line =
@@ -96,12 +110,18 @@ const gpu::GpuPreferences GetGpuPreferencesFromCommandLine() {
gpu_preferences.disable_oop_rasterization =
command_line->HasSwitch(switches::kDisableOopRasterization);
+ gpu_preferences.enable_oop_rasterization_ddl =
+ command_line->HasSwitch(switches::kEnableOopRasterizationDDL);
+
gpu_preferences.enable_vulkan =
command_line->HasSwitch(switches::kEnableVulkan);
gpu_preferences.enable_gpu_benchmarking_extension =
command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking);
+ gpu_preferences.enable_android_surface_control =
+ ShouldEnableAndroidSurfaceControl(*command_line);
+
// Some of these preferences are set or adjusted in
// GpuDataManagerImplPrivate::AppendGpuCommandLine.
return gpu_preferences;
@@ -116,4 +136,9 @@ void StopGpuProcess(const base::Closure& callback) {
base::ThreadTaskRunnerHandle::Get(), callback)));
}
+gpu::GpuChannelEstablishFactory* GetGpuChannelEstablishFactory() {
+ return content::BrowserMainLoop::GetInstance()
+ ->gpu_channel_establish_factory();
+}
+
} // namespace content
diff --git a/chromium/content/public/browser/gpu_utils.h b/chromium/content/public/browser/gpu_utils.h
index e4c9ad2c8b0..a919eb595fa 100644
--- a/chromium/content/public/browser/gpu_utils.h
+++ b/chromium/content/public/browser/gpu_utils.h
@@ -9,12 +9,18 @@
#include "content/common/content_export.h"
#include "gpu/config/gpu_preferences.h"
+namespace gpu {
+class GpuChannelEstablishFactory;
+}
+
namespace content {
CONTENT_EXPORT const gpu::GpuPreferences GetGpuPreferencesFromCommandLine();
CONTENT_EXPORT void StopGpuProcess(const base::Closure& callback);
+CONTENT_EXPORT gpu::GpuChannelEstablishFactory* GetGpuChannelEstablishFactory();
+
} // namespace content
#endif // CONTENT_PUBLIC_BROWSER_GPU_UTILS_H_
diff --git a/chromium/content/public/browser/guest_host.h b/chromium/content/public/browser/guest_host.h
index c955e4616c9..6788264fb5b 100644
--- a/chromium/content/public/browser/guest_host.h
+++ b/chromium/content/public/browser/guest_host.h
@@ -9,6 +9,8 @@
namespace content {
+class WebContents;
+
// A GuestHost is the content API for a guest WebContents.
// Guests are top-level frames that can be embedded within other pages.
// The content module manages routing of input events and compositing, but all
diff --git a/chromium/content/public/browser/media_session.h b/chromium/content/public/browser/media_session.h
index 43df8b22449..b915ccfdae7 100644
--- a/chromium/content/public/browser/media_session.h
+++ b/chromium/content/public/browser/media_session.h
@@ -8,7 +8,7 @@
#include "base/macros.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
-#include "services/media_session/public/mojom/audio_focus.mojom.h"
+#include "services/media_session/public/mojom/media_session.mojom.h"
namespace blink {
namespace mojom {
@@ -28,29 +28,12 @@ class WebContents;
// and allows clients to resume/suspend/stop the managed players.
class MediaSession : public media_session::mojom::MediaSession {
public:
- enum class SuspendType {
- // Suspended by the system because a transient sound needs to be played.
- SYSTEM,
- // Suspended by the UI.
- UI,
- // Suspended by the page via script or user interaction.
- CONTENT,
- };
-
// Returns the MediaSession associated to this WebContents. Creates one if
// none is currently available.
CONTENT_EXPORT static MediaSession* Get(WebContents* contents);
~MediaSession() override = default;
- // Resume the media session.
- // |type| represents the origin of the request.
- virtual void Resume(SuspendType suspend_type) = 0;
-
- // Suspend the media session.
- // |type| represents the origin of the request.
- virtual void Suspend(SuspendType suspend_type) = 0;
-
// Stop the media session.
// |type| represents the origin of the request.
virtual void Stop(SuspendType suspend_type) = 0;
@@ -74,13 +57,33 @@ class MediaSession : public media_session::mojom::MediaSession {
// Set the volume multiplier applied during ducking.
virtual void SetDuckingVolumeMultiplier(double multiplier) = 0;
+ // media_session.mojom.MediaSession overrides -------------------------------
+
+ // Suspend the media session.
+ // |type| represents the origin of the request.
+ void Suspend(SuspendType suspend_type) override = 0;
+
+ // Resume the media session.
+ // |type| represents the origin of the request.
+ void Resume(SuspendType suspend_type) override = 0;
+
// Let the media session start ducking such that the volume multiplier is
// reduced.
- virtual void StartDucking() = 0;
+ void StartDucking() override = 0;
// Let the media session stop ducking such that the volume multiplier is
// recovered.
- virtual void StopDucking() = 0;
+ void StopDucking() override = 0;
+
+ // Returns information about the MediaSession.
+ void GetMediaSessionInfo(GetMediaSessionInfoCallback callback) override = 0;
+
+ // Returns debug information about the MediaSession.
+ void GetDebugInfo(GetDebugInfoCallback callback) override = 0;
+
+ // Adds an observer to listen to events related to this MediaSession.
+ void AddObserver(
+ media_session::mojom::MediaSessionObserverPtr observer) override = 0;
protected:
MediaSession() = default;
diff --git a/chromium/content/public/browser/navigation_controller.cc b/chromium/content/public/browser/navigation_controller.cc
index 31668bd14ef..4a15053f967 100644
--- a/chromium/content/public/browser/navigation_controller.cc
+++ b/chromium/content/public/browser/navigation_controller.cc
@@ -7,6 +7,7 @@
#include "base/memory/ref_counted_memory.h"
#include "build/build_config.h"
#include "content/public/browser/render_frame_host.h"
+#include "content/public/common/was_activated_option.h"
namespace content {
@@ -23,8 +24,8 @@ NavigationController::LoadURLParams::LoadURLParams(const GURL& url)
has_user_gesture(false),
should_clear_history_list(false),
started_from_context_menu(false),
- navigation_ui_data(nullptr) {
-}
+ navigation_ui_data(nullptr),
+ was_activated(WasActivatedOption::kUnknown) {}
NavigationController::LoadURLParams::~LoadURLParams() {
}
diff --git a/chromium/content/public/browser/navigation_controller.h b/chromium/content/public/browser/navigation_controller.h
index 03d9b48e877..120151f2ef5 100644
--- a/chromium/content/public/browser/navigation_controller.h
+++ b/chromium/content/public/browser/navigation_controller.h
@@ -36,6 +36,7 @@ class RefCountedString;
namespace content {
+enum class WasActivatedOption;
class BrowserContext;
class NavigationEntry;
class WebContents;
@@ -197,6 +198,15 @@ class NavigationController {
// ContentBrowserClient::GetNavigationUIData.
std::unique_ptr<NavigationUIData> navigation_ui_data;
+ // Time at which the input leading to this navigation occurred. This field
+ // is set for links clicked by the user; the embedder is recommended to set
+ // it for navigations it initiates.
+ base::TimeTicks input_start;
+
+ // Set to |kYes| if the navigation should propagate user activation. This
+ // is used by embedders where the activation has occurred outside the page.
+ WasActivatedOption was_activated;
+
explicit LoadURLParams(const GURL& url);
~LoadURLParams();
diff --git a/chromium/content/public/browser/navigation_handle.h b/chromium/content/public/browser/navigation_handle.h
index 62c86a08842..bd5c217b3da 100644
--- a/chromium/content/public/browser/navigation_handle.h
+++ b/chromium/content/public/browser/navigation_handle.h
@@ -270,6 +270,9 @@ class CONTENT_EXPORT NavigationHandle {
// Returns true if this navigation was initiated by a form submission.
virtual bool IsFormSubmission() = 0;
+ // Returns true if the target is an inner response of a signed exchange.
+ virtual bool IsSignedExchangeInnerResponse() = 0;
+
// Testing methods ----------------------------------------------------------
//
// The following methods should be used exclusively for writing unit tests.
diff --git a/chromium/content/public/browser/network_quality_observer_factory.h b/chromium/content/public/browser/network_quality_observer_factory.h
index f0ae95b8059..0c6a1cb5a77 100644
--- a/chromium/content/public/browser/network_quality_observer_factory.h
+++ b/chromium/content/public/browser/network_quality_observer_factory.h
@@ -14,18 +14,19 @@
#include "content/public/browser/render_process_host.h"
#include "net/nqe/rtt_throughput_estimates_observer.h"
-namespace net {
-class NetworkQualityEstimator;
+namespace network {
+class NetworkQualityTracker;
}
namespace content {
// Creates network quality observer that listens for changes to the network
// quality and manages sending updates to each RenderProcess.
-CONTENT_EXPORT std::unique_ptr<net::RTTAndThroughputEstimatesObserver>
+CONTENT_EXPORT std::unique_ptr<
+ network::NetworkQualityTracker::RTTAndThroughputEstimatesObserver>
CreateNetworkQualityObserver(
- net::NetworkQualityEstimator* network_quality_estimator);
+ network::NetworkQualityTracker* network_quality_tracker);
} // namespace content
-#endif // CONTENT_PUBLIC_BROWSER_NETWORK_QUALITY_OBSERVER_FACTORY_H_ \ No newline at end of file
+#endif // CONTENT_PUBLIC_BROWSER_NETWORK_QUALITY_OBSERVER_FACTORY_H_
diff --git a/chromium/content/public/browser/network_service_instance.h b/chromium/content/public/browser/network_service_instance.h
index 69678a7abf5..62b15fe7670 100644
--- a/chromium/content/public/browser/network_service_instance.h
+++ b/chromium/content/public/browser/network_service_instance.h
@@ -5,7 +5,9 @@
#ifndef CONTENT_PUBLIC_BROWSER_NETWORK_SERVICE_INSTANCE_H_
#define CONTENT_PUBLIC_BROWSER_NETWORK_SERVICE_INSTANCE_H_
+#include "base/callback.h"
#include "content/common/content_export.h"
+#include "gpu/command_buffer/common/id_type.h"
namespace network {
class NetworkConnectionTracker;
@@ -37,6 +39,28 @@ CONTENT_EXPORT network::mojom::NetworkService* GetNetworkService();
CONTENT_EXPORT network::mojom::NetworkService* GetNetworkServiceFromConnector(
service_manager::Connector* connector);
+// Opaque type identifying a registered NetworkService crash handler.
+class CrashHandlerDummyType;
+using NetworkServiceCrashHandlerId = gpu::IdType32<CrashHandlerDummyType>;
+
+// Registers |handler| to run (on UI thread) after NetworkServicePtr encounters
+// an error. Note that there are no ordering wrt error handlers for other
+// interfaces (e.g. NetworkContextPtr and/or URLLoaderFactoryPtr).
+//
+// The return value can be passed to UnregisterNetworkServiceCrashHandler to
+// unregister the |handler|.
+//
+// Can only be called on the UI thread. No-op if NetworkService is disabled.
+CONTENT_EXPORT NetworkServiceCrashHandlerId
+RegisterNetworkServiceCrashHandler(base::RepeatingClosure handler);
+
+// Unregisters the crash handler with the given |handler_id|. See also
+// RegisterNetworkServiceCrashHandler.
+//
+// Can only be called on the UI thread. No-op if NetworkService is disabled.
+CONTENT_EXPORT void UnregisterNetworkServiceCrashHandler(
+ NetworkServiceCrashHandlerId handler_id);
+
// When network service is disabled, returns the in-process NetworkService
// pointer which is used to ease transition to network service.
// Must only be called on the IO thread. Must not be called if the network
@@ -52,6 +76,14 @@ CONTENT_EXPORT void FlushNetworkServiceInstanceForTesting();
// Must only be called on the UI thread.
CONTENT_EXPORT network::NetworkConnectionTracker* GetNetworkConnectionTracker();
+// Asynchronously calls the given callback with a NetworkConnectionTracker that
+// can be used to subscribe to network change events.
+//
+// This is a helper method for classes that can't easily call
+// GetNetworkConnectionTracker from the UI thread.
+CONTENT_EXPORT void GetNetworkConnectionTrackerFromUIThread(
+ base::OnceCallback<void(network::NetworkConnectionTracker*)> callback);
+
// Sets the NetworkConnectionTracker instance to use. For testing only.
// Must be called on the UI thread. Must be called before the first call to
// GetNetworkConnectionTracker.
diff --git a/chromium/content/public/browser/notification_database_data.h b/chromium/content/public/browser/notification_database_data.h
index 0f8744da64f..d5823b1e53c 100644
--- a/chromium/content/public/browser/notification_database_data.h
+++ b/chromium/content/public/browser/notification_database_data.h
@@ -11,7 +11,7 @@
#include "base/optional.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
-#include "content/public/common/platform_notification_data.h"
+#include "third_party/blink/public/common/notifications/platform_notification_data.h"
#include "url/gurl.h"
namespace content {
@@ -51,7 +51,7 @@ struct CONTENT_EXPORT NotificationDatabaseData {
int64_t service_worker_registration_id = 0;
// Platform data of the notification that's being stored.
- PlatformNotificationData notification_data;
+ blink::PlatformNotificationData notification_data;
// Boolean for if this current notification is replacing an existing
// notification.
diff --git a/chromium/content/public/browser/ns_view_bridge_factory_host.h b/chromium/content/public/browser/ns_view_bridge_factory_host.h
new file mode 100644
index 00000000000..f389d0f6ad1
--- /dev/null
+++ b/chromium/content/public/browser/ns_view_bridge_factory_host.h
@@ -0,0 +1,44 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_NS_VIEW_BRIDGE_FACTORY_HOST_H_
+#define CONTENT_PUBLIC_BROWSER_NS_VIEW_BRIDGE_FACTORY_HOST_H_
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "content/public/common/ns_view_bridge_factory.mojom.h"
+
+namespace content {
+
+// The host interface to the factory that will instantiate content NSViews
+// (RenderWidgetHostView and WebContentsView) in an app shim process. Each
+// app shim will create an instance of this class for to create windows in
+// its app.
+class CONTENT_EXPORT NSViewBridgeFactoryHost {
+ public:
+ NSViewBridgeFactoryHost(mojom::NSViewBridgeFactoryAssociatedRequest* request,
+ uint64_t host_id);
+ ~NSViewBridgeFactoryHost();
+
+ // The host id that refers to creating NSViews in the local process, and
+ // and accessing directly via pointers (instead of through mojo pipes).
+ static const uint64_t kLocalDirectHostId;
+
+ // Look up a NSViewBridgeFactoryHost from the host id. This host id can
+ // be used (e.g, by views::NativeViewHost) to associate different Cocoa
+ // factories that refer to the same app shim process.
+ static NSViewBridgeFactoryHost* GetFromHostId(uint64_t host_id);
+
+ mojom::NSViewBridgeFactory* GetFactory();
+
+ private:
+ const uint64_t host_id_;
+ mojom::NSViewBridgeFactoryAssociatedPtr factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(NSViewBridgeFactoryHost);
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_NS_VIEW_BRIDGE_FACTORY_HOST_H_
diff --git a/chromium/content/public/browser/ns_view_bridge_factory_impl.h b/chromium/content/public/browser/ns_view_bridge_factory_impl.h
new file mode 100644
index 00000000000..0ebebc7a886
--- /dev/null
+++ b/chromium/content/public/browser/ns_view_bridge_factory_impl.h
@@ -0,0 +1,47 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_NS_VIEW_BRIDGE_FACTORY_IMPL_H_
+#define CONTENT_PUBLIC_BROWSER_NS_VIEW_BRIDGE_FACTORY_IMPL_H_
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "content/public/common/ns_view_bridge_factory.mojom.h"
+#include "content/public/common/web_contents_ns_view_bridge.mojom.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
+
+namespace content {
+
+// The factory that creates content NSView (RenderWidgetHostView and, if
+// necessary, WebContentsView) instances. This is a singleton object that is
+// to be instantiated in the app shim process.
+class CONTENT_EXPORT NSViewBridgeFactoryImpl
+ : public mojom::NSViewBridgeFactory {
+ public:
+ // Get the singleton instance of this factory for this app shim process.
+ static NSViewBridgeFactoryImpl* Get();
+ void BindRequest(mojom::NSViewBridgeFactoryAssociatedRequest request);
+
+ // mojom::NSViewBridgeFactory:
+ void CreateRenderWidgetHostNSViewBridge(
+ mojom::StubInterfaceAssociatedPtrInfo client,
+ mojom::StubInterfaceAssociatedRequest bridge_request) override;
+ void CreateWebContentsNSViewBridge(
+ uint64_t view_id,
+ mojom::WebContentsNSViewClientAssociatedPtrInfo client,
+ mojom::WebContentsNSViewBridgeAssociatedRequest bridge_request) override;
+
+ private:
+ friend class base::NoDestructor<NSViewBridgeFactoryImpl>;
+ NSViewBridgeFactoryImpl();
+ ~NSViewBridgeFactoryImpl() override;
+
+ mojo::AssociatedBinding<mojom::NSViewBridgeFactory> binding_;
+
+ DISALLOW_COPY_AND_ASSIGN(NSViewBridgeFactoryImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_NS_VIEW_BRIDGE_FACTORY_IMPL_H_
diff --git a/chromium/content/public/browser/origin_policy_error_reason.h b/chromium/content/public/browser/origin_policy_error_reason.h
new file mode 100644
index 00000000000..50787a1276b
--- /dev/null
+++ b/chromium/content/public/browser/origin_policy_error_reason.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_ORIGIN_POLICY_ERROR_REASON_H_
+#define CONTENT_PUBLIC_BROWSER_ORIGIN_POLICY_ERROR_REASON_H_
+
+namespace content {
+
+// Enumerate the reasons why an origin policy was rejected.
+enum class OriginPolicyErrorReason : int {
+ kCannotLoadPolicy, // The policy document could not be downloaded.
+ kPolicyShouldNotRedirect, // The policy doc request was met with a redirect.
+ kOther,
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_ORIGIN_POLICY_ERROR_REASON_H_
diff --git a/chromium/content/public/browser/overlay_window.h b/chromium/content/public/browser/overlay_window.h
index 04160fd5127..96440e074c5 100644
--- a/chromium/content/public/browser/overlay_window.h
+++ b/chromium/content/public/browser/overlay_window.h
@@ -58,6 +58,7 @@ class OverlayWindow {
virtual void SetPlaybackState(PlaybackState playback_state) = 0;
virtual void SetPictureInPictureCustomControls(
const std::vector<blink::PictureInPictureControlInfo>& controls) = 0;
+ virtual void SetAlwaysHidePlayPauseButton(bool is_visible) = 0;
// Retrieves the ui::Layers corresponding to the window and video.
virtual ui::Layer* GetWindowBackgroundLayer() = 0;
diff --git a/chromium/content/public/browser/permission_type.h b/chromium/content/public/browser/permission_type.h
index 1c256ae28c3..a3a3cf55b13 100644
--- a/chromium/content/public/browser/permission_type.h
+++ b/chromium/content/public/browser/permission_type.h
@@ -29,6 +29,7 @@ enum class PermissionType {
CLIPBOARD_READ = 14,
CLIPBOARD_WRITE = 15,
PAYMENT_HANDLER = 16,
+ BACKGROUND_FETCH = 17,
// Always keep this at the end.
NUM,
diff --git a/chromium/content/public/browser/picture_in_picture_window_controller.h b/chromium/content/public/browser/picture_in_picture_window_controller.h
index 32d5232f7c5..5eba14788e1 100644
--- a/chromium/content/public/browser/picture_in_picture_window_controller.h
+++ b/chromium/content/public/browser/picture_in_picture_window_controller.h
@@ -51,7 +51,6 @@ class PictureInPictureWindowController {
// window was requested to be closed and destroyed by the system.
virtual void OnWindowDestroyed() = 0;
- virtual void ClickCustomControl(const std::string& control_id) = 0;
virtual void SetPictureInPictureCustomControls(
const std::vector<blink::PictureInPictureControlInfo>&) = 0;
virtual void EmbedSurface(const viz::SurfaceId& surface_id,
@@ -62,12 +61,16 @@ class PictureInPictureWindowController {
virtual WebContents* GetInitiatorWebContents() = 0;
virtual void UpdatePlaybackState(bool is_playing,
bool reached_end_of_stream) = 0;
+ virtual void SetAlwaysHidePlayPauseButton(bool is_visible) = 0;
// Commands.
// Returns true if the player is active (i.e. currently playing) after this
// call.
virtual bool TogglePlayPause() = 0;
+ // Called when the user interacts with a custom control.
+ virtual void CustomControlPressed(const std::string& control_id) = 0;
+
protected:
// Use PictureInPictureWindowController::GetOrCreateForWebContents() to
// create an instance.
diff --git a/chromium/content/public/browser/platform_notification_service.h b/chromium/content/public/browser/platform_notification_service.h
index 0e9ce438308..80ffd8d426c 100644
--- a/chromium/content/public/browser/platform_notification_service.h
+++ b/chromium/content/public/browser/platform_notification_service.h
@@ -19,11 +19,14 @@
class GURL;
+namespace blink {
+struct NotificationResources;
+struct PlatformNotificationData;
+} // namespace blink
+
namespace content {
class BrowserContext;
-struct NotificationResources;
-struct PlatformNotificationData;
// The service using which notifications can be presented to the user. There
// should be a unique instance of the PlatformNotificationService depending
@@ -42,8 +45,8 @@ class CONTENT_EXPORT PlatformNotificationService {
BrowserContext* browser_context,
const std::string& notification_id,
const GURL& origin,
- const PlatformNotificationData& notification_data,
- const NotificationResources& notification_resources) = 0;
+ const blink::PlatformNotificationData& notification_data,
+ const blink::NotificationResources& notification_resources) = 0;
// Displays the persistent notification described in |notification_data| to
// the user. This method must be called on the UI thread.
@@ -52,8 +55,8 @@ class CONTENT_EXPORT PlatformNotificationService {
const std::string& notification_id,
const GURL& service_worker_origin,
const GURL& origin,
- const PlatformNotificationData& notification_data,
- const NotificationResources& notification_resources) = 0;
+ const blink::PlatformNotificationData& notification_data,
+ const blink::NotificationResources& notification_resources) = 0;
// Closes the notification identified by |notification_id|. This method must
// be called on the UI thread.
diff --git a/chromium/content/public/browser/push_messaging_service.cc b/chromium/content/public/browser/push_messaging_service.cc
index 7ade5bc90bf..032ef7f5dbd 100644
--- a/chromium/content/public/browser/push_messaging_service.cc
+++ b/chromium/content/public/browser/push_messaging_service.cc
@@ -5,9 +5,11 @@
#include "content/public/browser/push_messaging_service.h"
#include "base/callback.h"
+#include "base/task/post_task.h"
#include "content/browser/push_messaging/push_messaging_manager.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
@@ -28,14 +30,15 @@ void CallStringCallbackFromIO(
DCHECK_EQ(1u, data.size());
result = data[0];
}
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(callback, result, success, not_found));
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::UI},
+ base::BindOnce(callback, result, success, not_found));
}
void CallClosureFromIO(const base::Closure& callback,
blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
+ base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, callback);
}
void GetUserDataOnIO(
@@ -92,8 +95,8 @@ void PushMessagingService::GetSenderId(BrowserContext* browser_context,
int64_t service_worker_registration_id,
const StringCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&GetUserDataOnIO,
GetServiceWorkerContext(browser_context, origin),
service_worker_registration_id,
@@ -107,8 +110,8 @@ void PushMessagingService::ClearPushSubscriptionId(
int64_t service_worker_registration_id,
const base::Closure& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&ClearPushSubscriptionIdOnIO,
GetServiceWorkerContext(browser_context, origin),
service_worker_registration_id, callback));
@@ -123,8 +126,8 @@ void PushMessagingService::StorePushSubscriptionForTesting(
const std::string& sender_id,
const base::Closure& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
+ base::PostTaskWithTraits(
+ FROM_HERE, {BrowserThread::IO},
base::BindOnce(&StorePushSubscriptionOnIOForTesting,
GetServiceWorkerContext(browser_context, origin),
service_worker_registration_id, origin, subscription_id,
diff --git a/chromium/content/public/browser/render_frame_host.h b/chromium/content/public/browser/render_frame_host.h
index eaee051bc83..fb025824a6c 100644
--- a/chromium/content/public/browser/render_frame_host.h
+++ b/chromium/content/public/browser/render_frame_host.h
@@ -12,13 +12,13 @@
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/common/console_message_level.h"
-#include "content/public/common/file_chooser_params.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/blink/public/platform/web_sudden_termination_disabler_type.h"
+#include "ui/accessibility/ax_tree_id.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
#include "url/gurl.h"
@@ -55,7 +55,6 @@ class RenderProcessHost;
class RenderViewHost;
class RenderWidgetHostView;
class SiteInstance;
-struct FileChooserFileInfo;
// The interface provides a communication conduit with a frame in the renderer.
class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
@@ -76,7 +75,7 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
#endif
// Returns a RenderFrameHost given its accessibility tree ID.
- static RenderFrameHost* FromAXTreeID(int ax_tree_id);
+ static RenderFrameHost* FromAXTreeID(ui::AXTreeID ax_tree_id);
// Returns the FrameTreeNode ID corresponding to the specified |process_id|
// and |routing_id|. This routing ID pair may represent a placeholder for
@@ -97,7 +96,7 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
virtual int GetRoutingID() = 0;
// Returns the accessibility tree ID for this RenderFrameHost.
- virtual int GetAXTreeID() = 0;
+ virtual ui::AXTreeID GetAXTreeID() = 0;
// Returns the SiteInstance grouping all RenderFrameHosts that have script
// access to this RenderFrameHost, and must therefore live in the same
@@ -121,6 +120,13 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
// current RenderFrameHost.
virtual RenderFrameHost* GetParent() = 0;
+ // Returns whether or not this RenderFrameHost is a descendant of |ancestor|.
+ // This is equivalent to check that |ancestor| is reached by iterating on
+ // GetParent().
+ // This is a strict relationship, a RenderFrameHost is never an ancestor of
+ // itself.
+ virtual bool IsDescendantOf(RenderFrameHost* ancestor) = 0;
+
// Returns the FrameTreeNode ID for this frame. This ID is browser-global and
// uniquely identifies a frame that hosts content. The identifier is fixed at
// the creation of the frame and stays constant for the lifetime of the frame.
@@ -249,13 +255,6 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
// use by resource metrics.
virtual int GetProxyCount() = 0;
- // Notifies the Listener that one or more files have been chosen by the user
- // from a file chooser dialog for the form. |permissions| is the file
- // selection mode in which the chooser dialog was created.
- virtual void FilesSelectedInChooser(
- const std::vector<content::FileChooserFileInfo>& files,
- FileChooserParams::Mode permissions) = 0;
-
// Returns true if the frame has a selection.
virtual bool HasSelection() = 0;
@@ -321,6 +320,15 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
virtual bool CreateNetworkServiceDefaultFactory(
network::mojom::URLLoaderFactoryRequest default_factory_request) = 0;
+ // Requests that future URLLoaderFactoryBundle(s) sent to the renderer should
+ // use a separate URLLoaderFactory for requests initiated by any of the
+ // origins listed in |request_initiators|. The URLLoaderFactory(s) for each
+ // origin will be created via
+ // ContentBrowserClient::CreateURLLoaderFactoryForNetworkRequests method.
+ virtual void MarkInitiatorsAsRequiringSeparateURLLoaderFactory(
+ std::vector<url::Origin> request_initiators,
+ bool push_to_renderer_now) = 0;
+
private:
// This interface should only be implemented inside content.
friend class RenderFrameHostImpl;
diff --git a/chromium/content/public/browser/render_process_host.h b/chromium/content/public/browser/render_process_host.h
index ef2a04280e1..12d380acb42 100644
--- a/chromium/content/public/browser/render_process_host.h
+++ b/chromium/content/public/browser/render_process_host.h
@@ -396,7 +396,9 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
virtual resource_coordinator::ProcessResourceCoordinator*
GetProcessResourceCoordinator() = 0;
- // Create an URLLoaderFactory for this process.
+ // Create an URLLoaderFactory that can be used by |origin| being hosted in
+ // |this| process.
+ //
// When NetworkService is enabled, |request| will be bound with a new
// URLLoaderFactory created from the storage partition's Network Context. Note
// that the URLLoaderFactory returned by this method does NOT support
@@ -404,6 +406,7 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
// When NetworkService is not enabled, |request| will be bound with a
// URLLoaderFactory which routes requests to ResourceDispatcherHost.
virtual void CreateURLLoaderFactory(
+ const url::Origin& origin,
network::mojom::URLLoaderFactoryRequest request) = 0;
// Whether this process is locked out from ever being reused for sites other
diff --git a/chromium/content/public/browser/render_view_host.h b/chromium/content/public/browser/render_view_host.h
index f376ec12e50..ce8282afe40 100644
--- a/chromium/content/public/browser/render_view_host.h
+++ b/chromium/content/public/browser/render_view_host.h
@@ -133,9 +133,6 @@ class CONTENT_EXPORT RenderViewHost : public IPC::Sender {
// Passes a list of Webkit preferences to the renderer.
virtual void UpdateWebkitPreferences(const WebPreferences& prefs) = 0;
- // Notify the render view host to select the word around the caret.
- virtual void SelectWordAroundCaret() = 0;
-
private:
// This interface should only be implemented inside content.
friend class RenderViewHostImpl;
diff --git a/chromium/content/public/browser/render_widget_host.h b/chromium/content/public/browser/render_widget_host.h
index 514b39fd65c..4b98057e09f 100644
--- a/chromium/content/public/browser/render_widget_host.h
+++ b/chromium/content/public/browser/render_widget_host.h
@@ -165,6 +165,9 @@ class CONTENT_EXPORT RenderWidgetHost : public IPC::Sender {
virtual void Focus() = 0;
virtual void Blur() = 0;
+ // Tests may need to flush IPCs to ensure deterministic behavior.
+ virtual void FlushForTesting() = 0;
+
// Sets whether the renderer should show controls in an active state. On all
// platforms except mac, that's the same as focused. On mac, the frontmost
// window will show active controls even if the focus is not in the web
diff --git a/chromium/content/public/browser/resource_hints.h b/chromium/content/public/browser/resource_hints.h
deleted file mode 100644
index b02d5907d30..00000000000
--- a/chromium/content/public/browser/resource_hints.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_BROWSER_RESOURCE_HINTS_H_
-#define CONTENT_PUBLIC_BROWSER_RESOURCE_HINTS_H_
-
-#include "content/common/content_export.h"
-#include "net/base/completion_callback.h"
-#include "net/dns/host_resolver.h"
-#include "net/http/http_request_info.h"
-#include "url/gurl.h"
-
-class GURL;
-
-namespace net {
-class URLRequestContextGetter;
-}
-
-// TODO(https://crbug.com/565719): Resource hints aren't used nor implemented in
-// content/. Either the preconnect/preresolve code should be moved to content/
-// or this should be moved outside of content/.
-namespace content {
-
-// A Preconnect instance maintains state while a TCP/IP connection is made, and
-// then released into the pool of available connections for future use.
-
-// Tries to preconnect. |count| may be used to request more than one connection
-// be established in parallel. Note that the net stack has logic so multiple
-// calls to preconnect a given url within a short time frame will automatically
-// coalesce. |allow_credentials| corresponds to the fetch spec.
-// Note: This should only be called on the IO thread, with a valid
-// URLRequestContextGetter.
-CONTENT_EXPORT void PreconnectUrl(net::URLRequestContextGetter* getter,
- const GURL& url,
- const GURL& site_for_cookies,
- int count,
- bool allow_credentials);
-
-// Issues a DNS request to |url|. Note that these requests are sent to the host
-// resolver with priority net::IDLE.
-CONTENT_EXPORT int PreresolveUrl(
- net::URLRequestContextGetter* getter,
- const GURL& url,
- const net::CompletionCallback& callback,
- std::unique_ptr<net::HostResolver::Request>* out_req);
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_BROWSER_RESOURCE_HINTS_H_
diff --git a/chromium/content/public/browser/resource_request_info.h b/chromium/content/public/browser/resource_request_info.h
index 607b807f4bc..7d9a8808ccb 100644
--- a/chromium/content/public/browser/resource_request_info.h
+++ b/chromium/content/public/browser/resource_request_info.h
@@ -181,17 +181,6 @@ class ResourceRequestInfo {
// UI thread at the beginning of navigation.
virtual NavigationUIData* GetNavigationUIData() const = 0;
- enum class DevToolsStatus {
- kCanceled,
- // DevTools can internally handle a redirect, so the url request may
- // appear never done. Mark these cases.
- kCanceledAsRedirect,
- kNotCanceled,
- };
-
- // If and why this request was canceled by DevTools. TODO(johannes): Remove.
- virtual DevToolsStatus GetDevToolsStatus() const = 0;
-
// Used to annotate requests blocked using net::ERR_BLOCKED_BY_CLIENT and
// net::ERR_BLOCKED_BY_RESPONSE errors, with a ResourceRequestBlockedReason.
virtual void SetResourceRequestBlockedReason(
diff --git a/chromium/content/public/browser/screenlock_observer.h b/chromium/content/public/browser/screenlock_observer.h
new file mode 100644
index 00000000000..9eff0abeac5
--- /dev/null
+++ b/chromium/content/public/browser/screenlock_observer.h
@@ -0,0 +1,27 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_SCREENLOCK_OBSERVER_H_
+#define CONTENT_PUBLIC_BROWSER_SCREENLOCK_OBSERVER_H_
+
+#include "base/compiler_specific.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class CONTENT_EXPORT ScreenlockObserver {
+ public:
+ // Notification that the screen is locked.
+ virtual void OnScreenLocked() {}
+
+ // Notification that the screen is unlocked.
+ virtual void OnScreenUnlocked() {}
+
+ protected:
+ virtual ~ScreenlockObserver() = default;
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_SCREENLOCK_OBSERVER_H_ \ No newline at end of file
diff --git a/chromium/content/public/browser/shared_cors_origin_access_list.h b/chromium/content/public/browser/shared_cors_origin_access_list.h
new file mode 100644
index 00000000000..6e2854c21ef
--- /dev/null
+++ b/chromium/content/public/browser/shared_cors_origin_access_list.h
@@ -0,0 +1,58 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_SHARED_CORS_ORIGIN_ACCESS_LIST_H_
+#define CONTENT_PUBLIC_BROWSER_SHARED_CORS_ORIGIN_ACCESS_LIST_H_
+
+#include <vector>
+
+#include "base/memory/ref_counted.h"
+#include "content/common/content_export.h"
+#include "services/network/public/mojom/cors_origin_pattern.mojom.h"
+#include "url/origin.h"
+
+namespace network {
+namespace cors {
+class OriginAccessList;
+} // namespace cors
+} // namespace network
+
+namespace content {
+
+// A public interface to manage CORS origin access lists on the UI thread.
+// The shared network::cors::OriginAccessList instance can only be accessed on
+// the IO thread. Callers on UI thread must use this wrapper class.
+// TODO(toyoshim): Remove once the NetworkService is enabled.
+class CONTENT_EXPORT SharedCorsOriginAccessList
+ : public base::RefCountedThreadSafe<SharedCorsOriginAccessList> {
+ public:
+ SharedCorsOriginAccessList() = default;
+
+ // Sets the access list to an internal network::cors::OriginAccessList
+ // instance so that its IsAllowed() method works for all users that refer the
+ // shared network::cors::OriginAccessList instance returned by
+ // origin_access_list() below. |allow_patterns| and |block_patterns| will be
+ // moved so to pass the lists to the IO thread.
+ // Should be called on the UI thread, and |closure| runs on the UI thread too.
+ virtual void SetForOrigin(
+ const url::Origin& source_origin,
+ std::vector<network::mojom::CorsOriginPatternPtr> allow_patterns,
+ std::vector<network::mojom::CorsOriginPatternPtr> block_patterns,
+ base::OnceClosure closure) = 0;
+
+ // Gets a shared OriginAccessList instance pointer. |this| should outlives
+ // callers' OriginAccessList instance uses. Should be called on the IO thread.
+ virtual const network::cors::OriginAccessList& GetOriginAccessList()
+ const = 0;
+
+ protected:
+ virtual ~SharedCorsOriginAccessList() = default;
+
+ private:
+ friend class base::RefCountedThreadSafe<SharedCorsOriginAccessList>;
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_SHARED_CORS_ORIGIN_ACCESS_LIST_H_
diff --git a/chromium/content/public/browser/site_instance.h b/chromium/content/public/browser/site_instance.h
index 1bb348216fe..9c9aa4ee205 100644
--- a/chromium/content/public/browser/site_instance.h
+++ b/chromium/content/public/browser/site_instance.h
@@ -130,11 +130,6 @@ class CONTENT_EXPORT SiteInstance : public base::RefCounted<SiteInstance> {
// process. This only returns true under the "site per process" process model.
virtual bool RequiresDedicatedProcess() = 0;
- // Returns true if this SiteInstance is used as the default SiteInstance for
- // cross-site subframes. This only returns true if "top document isolation" is
- // used.
- virtual bool IsDefaultSubframeSiteInstance() const = 0;
-
// Factory method to create a new SiteInstance. This will create a new
// new BrowsingInstance, so it should only be used when creating a new tab
// from scratch (or similar circumstances).
diff --git a/chromium/content/public/browser/site_isolation_policy.cc b/chromium/content/public/browser/site_isolation_policy.cc
index 721cc826414..ceedf962ae3 100644
--- a/chromium/content/public/browser/site_isolation_policy.cc
+++ b/chromium/content/public/browser/site_isolation_policy.cc
@@ -14,6 +14,7 @@
#include "base/macros.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
#include "base/strings/string_split.h"
#include "base/timer/timer.h"
#include "content/public/browser/content_browser_client.h"
@@ -47,47 +48,16 @@ bool SiteIsolationPolicy::UseDedicatedProcessesForAllSites() {
}
// static
-SiteIsolationPolicy::CrossSiteDocumentBlockingEnabledState
-SiteIsolationPolicy::IsCrossSiteDocumentBlockingEnabled() {
- // --disable-web-security also disables cross-origin response blocking (CORB).
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableWebSecurity)) {
- return XSDB_DISABLED;
- }
-
- if (base::FeatureList::IsEnabled(
- ::features::kCrossSiteDocumentBlockingAlways)) {
- return XSDB_ENABLED_UNCONDITIONALLY;
- }
-
- if (base::FeatureList::IsEnabled(
- ::features::kCrossSiteDocumentBlockingIfIsolating)) {
- return XSDB_ENABLED_IF_ISOLATED;
- }
-
- return XSDB_DISABLED;
-}
-
-// static
void SiteIsolationPolicy::PopulateURLLoaderFactoryParamsPtrForCORB(
network::mojom::URLLoaderFactoryParams* params) {
- switch (IsCrossSiteDocumentBlockingEnabled()) {
- case SiteIsolationPolicy::XSDB_ENABLED_UNCONDITIONALLY:
- params->is_corb_enabled = true;
- break;
- case SiteIsolationPolicy::XSDB_ENABLED_IF_ISOLATED: {
- // TODO(lukasza): Take isolate-origins into account as well.
- params->is_corb_enabled = UseDedicatedProcessesForAllSites();
- break;
- }
- case SiteIsolationPolicy::XSDB_DISABLED:
- params->is_corb_enabled = false;
- break;
- }
-
- if (!params->is_corb_enabled)
+ // --disable-web-security also disables Cross-Origin Read Blocking (CORB).
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableWebSecurity)) {
+ params->is_corb_enabled = false;
return;
+ }
+ params->is_corb_enabled = true;
params->corb_detachable_resource_type = RESOURCE_TYPE_PREFETCH;
params->corb_excluded_resource_type = RESOURCE_TYPE_PLUGIN_RESOURCE;
@@ -100,18 +70,6 @@ void SiteIsolationPolicy::PopulateURLLoaderFactoryParamsPtrForCORB(
}
// static
-bool SiteIsolationPolicy::IsTopDocumentIsolationEnabled() {
- // --site-per-process trumps --top-document-isolation.
- if (UseDedicatedProcessesForAllSites())
- return false;
-
- // The feature needs to be checked last, because checking the feature
- // activates the field trial and assigns the client either to a control or an
- // experiment group - such assignment should be final.
- return base::FeatureList::IsEnabled(::features::kTopDocumentIsolation);
-}
-
-// static
bool SiteIsolationPolicy::AreIsolatedOriginsEnabled() {
// NOTE: Because it is possible for --isolate-origins to be isolating origins
// at a finer-than-site granularity, we do not suppress --isolate-origins when
@@ -145,8 +103,7 @@ bool SiteIsolationPolicy::ShouldPdfCompositorBeEnabledForOopifs() {
// where OOPIF is used such as isolate-extensions, but should be good for
// feature testing purpose. Eventually, we will remove this check and use pdf
// compositor service by default for printing.
- return AreIsolatedOriginsEnabled() || IsTopDocumentIsolationEnabled() ||
- UseDedicatedProcessesForAllSites();
+ return AreIsolatedOriginsEnabled() || UseDedicatedProcessesForAllSites();
}
// static
@@ -155,17 +112,18 @@ SiteIsolationPolicy::GetIsolatedOriginsFromEnvironment() {
std::string cmdline_arg =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kIsolateOrigins);
+ std::vector<url::Origin> origins;
if (!cmdline_arg.empty()) {
- std::vector<url::Origin> cmdline_origins =
- ParseIsolatedOrigins(cmdline_arg);
+ origins = ParseIsolatedOrigins(cmdline_arg);
UMA_HISTOGRAM_COUNTS_1000("SiteIsolation.IsolateOrigins.Size",
- cmdline_origins.size());
- return cmdline_origins;
+ origins.size());
}
+ // --isolate-origins (both command-line flag and enterprise policy) trumps
+ // the opt-out flag.
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableSiteIsolationTrials)) {
- return std::vector<url::Origin>();
+ return origins;
}
// The feature needs to be checked last, because checking the feature
@@ -175,9 +133,13 @@ SiteIsolationPolicy::GetIsolatedOriginsFromEnvironment() {
std::string field_trial_arg = base::GetFieldTrialParamValueByFeature(
features::kIsolateOrigins,
features::kIsolateOriginsFieldTrialParamName);
- return ParseIsolatedOrigins(field_trial_arg);
+ std::vector<url::Origin> field_trial_origins =
+ ParseIsolatedOrigins(field_trial_arg);
+ origins.reserve(origins.size() + field_trial_origins.size());
+ std::move(field_trial_origins.begin(), field_trial_origins.end(),
+ std::back_inserter(origins));
}
- return std::vector<url::Origin>();
+ return origins;
}
// static
@@ -204,7 +166,7 @@ std::vector<url::Origin> SiteIsolationPolicy::ParseIsolatedOrigins(
origins.reserve(origin_strings.size());
for (const base::StringPiece& origin_string : origin_strings) {
url::Origin origin = url::Origin::Create(GURL(origin_string));
- if (!origin.unique())
+ if (!origin.opaque())
origins.push_back(origin);
}
return origins;
@@ -217,8 +179,8 @@ void SiteIsolationPolicy::StartRecordingSiteIsolationFlagUsage() {
// flags can't change dynamically at runtime, collecting these stats daily
// helps determine the overall population of users who run with a given flag
// on any given day.
- CR_DEFINE_STATIC_LOCAL(base::RepeatingTimer, update_stats_timer, ());
- update_stats_timer.Start(
+ static base::NoDestructor<base::RepeatingTimer> update_stats_timer;
+ update_stats_timer->Start(
FROM_HERE, base::TimeDelta::FromHours(24),
base::BindRepeating(&SiteIsolationPolicy::RecordSiteIsolationFlagUsage));
}
diff --git a/chromium/content/public/browser/site_isolation_policy.h b/chromium/content/public/browser/site_isolation_policy.h
index 53d829e5fa0..e33486819b9 100644
--- a/chromium/content/public/browser/site_isolation_policy.h
+++ b/chromium/content/public/browser/site_isolation_policy.h
@@ -33,24 +33,11 @@ class CONTENT_EXPORT SiteIsolationPolicy {
// Returns true if every site should be placed in a dedicated process.
static bool UseDedicatedProcessesForAllSites();
- // Returns whether cross-site document responses can be blocked.
- enum CrossSiteDocumentBlockingEnabledState {
- XSDB_ENABLED_UNCONDITIONALLY,
- XSDB_ENABLED_IF_ISOLATED,
- XSDB_DISABLED,
- };
- static CrossSiteDocumentBlockingEnabledState
- IsCrossSiteDocumentBlockingEnabled();
-
// Populates CORB-related (Cross-Origin Read Blocking related) parts of the
// URLLoaderFactoryParams depending on the current Site Isolation policy.
static void PopulateURLLoaderFactoryParamsPtrForCORB(
network::mojom::URLLoaderFactoryParams* params);
- // Returns true if third-party subframes of a page should be kept in a
- // different process from the main frame.
- static bool IsTopDocumentIsolationEnabled();
-
// Returns true if isolated origins feature is enabled.
static bool AreIsolatedOriginsEnabled();
diff --git a/chromium/content/public/browser/tracing_controller.h b/chromium/content/public/browser/tracing_controller.h
index 3680a37daa9..c2e3e98d8bd 100644
--- a/chromium/content/public/browser/tracing_controller.h
+++ b/chromium/content/public/browser/tracing_controller.h
@@ -66,10 +66,9 @@ class TracingController {
// Once all child processes have acked to the GetCategories request,
// GetCategoriesDoneCallback is called back with a set of category
// groups.
- typedef base::Callback<void(const std::set<std::string>&)>
+ typedef base::OnceCallback<void(const std::set<std::string>&)>
GetCategoriesDoneCallback;
- virtual bool GetCategories(
- const GetCategoriesDoneCallback& callback) = 0;
+ virtual bool GetCategories(GetCategoriesDoneCallback callback) = 0;
// Start tracing (recording traces) on all processes.
//
@@ -89,10 +88,9 @@ class TracingController {
// "-excluded_category1,-excluded_category2"
//
// |trace_config| controls what kind of tracing is enabled.
- typedef base::Callback<void()> StartTracingDoneCallback;
- virtual bool StartTracing(
- const base::trace_event::TraceConfig& trace_config,
- const StartTracingDoneCallback& callback) = 0;
+ typedef base::OnceCallback<void()> StartTracingDoneCallback;
+ virtual bool StartTracing(const base::trace_event::TraceConfig& trace_config,
+ StartTracingDoneCallback callback) = 0;
// Stop tracing (recording traces) on all processes.
//
@@ -119,9 +117,8 @@ class TracingController {
// Get the maximum across processes of trace buffer percent full state.
// When the TraceBufferUsage value is determined, the callback is
// called.
- typedef base::Callback<void(float, size_t)> GetTraceBufferUsageCallback;
- virtual bool GetTraceBufferUsage(
- const GetTraceBufferUsageCallback& callback) = 0;
+ typedef base::OnceCallback<void(float, size_t)> GetTraceBufferUsageCallback;
+ virtual bool GetTraceBufferUsage(GetTraceBufferUsageCallback callback) = 0;
// Check if the tracing system is tracing
virtual bool IsTracing() const = 0;
diff --git a/chromium/content/public/browser/url_data_source.cc b/chromium/content/public/browser/url_data_source.cc
index 2f5c450c634..4056311ccce 100644
--- a/chromium/content/public/browser/url_data_source.cc
+++ b/chromium/content/public/browser/url_data_source.cc
@@ -7,7 +7,9 @@
#include <utility>
#include "base/memory/ptr_util.h"
+#include "base/task/post_task.h"
#include "content/browser/webui/url_data_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/url_constants.h"
#include "net/url_request/url_request.h"
@@ -16,19 +18,13 @@ namespace content {
// static
void URLDataSource::Add(BrowserContext* browser_context,
- URLDataSource* source) {
- Add(browser_context, base::WrapUnique(source));
-}
-
-// static
-void URLDataSource::Add(BrowserContext* browser_context,
std::unique_ptr<URLDataSource> source) {
URLDataManager::AddDataSource(browser_context, std::move(source));
}
scoped_refptr<base::SingleThreadTaskRunner>
URLDataSource::TaskRunnerForRequestPath(const std::string& path) const {
- return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
+ return base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::UI});
}
bool URLDataSource::ShouldReplaceExistingSource() const {
diff --git a/chromium/content/public/browser/url_data_source.h b/chromium/content/public/browser/url_data_source.h
index a636ba6b689..b7d96e7faee 100644
--- a/chromium/content/public/browser/url_data_source.h
+++ b/chromium/content/public/browser/url_data_source.h
@@ -31,9 +31,6 @@ class ResourceContext;
// notify.
class CONTENT_EXPORT URLDataSource {
public:
- // Adds a URL data source to |browser_context|. Deprecated.
- static void Add(BrowserContext* browser_context, URLDataSource* source);
-
// Adds a URL data source to |browser_context|.
static void Add(BrowserContext* browser_context,
std::unique_ptr<URLDataSource> source);
diff --git a/chromium/content/public/browser/web_contents.h b/chromium/content/public/browser/web_contents.h
index 786eecfcb70..f26f7e50166 100644
--- a/chromium/content/public/browser/web_contents.h
+++ b/chromium/content/public/browser/web_contents.h
@@ -31,9 +31,10 @@
#include "content/public/browser/web_ui.h"
#include "content/public/common/stop_find_action.h"
#include "third_party/blink/public/common/frame/sandbox_flags.h"
+#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
#include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom.h"
#include "third_party/skia/include/core/SkColor.h"
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
#include "ui/accessibility/ax_tree_update.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/geometry/rect.h"
@@ -51,10 +52,6 @@ namespace base {
class TimeTicks;
}
-namespace blink {
-struct WebFindOptions;
-}
-
namespace device {
namespace mojom {
class WakeLockContext;
@@ -449,6 +446,7 @@ class WebContents : public PageNavigator,
// parent to child.
// When a navigation request is created, was_discarded is passed on to the
// request and reset to false in FrameTreeNode.
+ virtual bool WasDiscarded() = 0;
virtual void SetWasDiscarded(bool was_discarded) = 0;
// Internal state ------------------------------------------------------------
@@ -522,7 +520,12 @@ class WebContents : public PageNavigator,
// Runs the beforeunload handler for the main frame and all its subframes.
// See also ClosePage in RenderViewHostImpl, which runs the unload handler.
- virtual void DispatchBeforeUnload() = 0;
+ // If |auto_cancel| is true, and the beforeunload handler returns a non-empty
+ // string (indicating the page wants to present a confirmation dialog), then
+ // the beforeunload operation will automatically return with |proceed=false|
+ // and no dialog will be shown to the user. This is used to interrupt a
+ // potential discard without causing the dialog to appear.
+ virtual void DispatchBeforeUnload(bool auto_cancel) = 0;
// Attaches this inner WebContents to its container frame
// |outer_contents_frame| in |outer_web_contents|.
@@ -814,7 +817,7 @@ class WebContents : public PageNavigator,
// Finds text on a page. |search_text| should not be empty.
virtual void Find(int request_id,
const base::string16& search_text,
- const blink::WebFindOptions& options) = 0;
+ blink::mojom::FindOptionsPtr options) = 0;
// Notifies the renderer that the user has closed the FindInPage window
// (and what action to take regarding the selection).
@@ -909,13 +912,6 @@ class WebContents : public PageNavigator,
// scoped to this WebContents. This provides access to interfaces implemented
// in Java in the browser process to C++ code in the browser process.
virtual service_manager::InterfaceProvider* GetJavaInterfaces() = 0;
-#elif defined(OS_MACOSX)
- // Allowing other views disables optimizations which assume that only a single
- // WebContents is present.
- virtual void SetAllowOtherViews(bool allow) = 0;
-
- // Returns true if other views are allowed, false otherwise.
- virtual bool GetAllowOtherViews() = 0;
#endif // OS_ANDROID
// Returns true if the WebContents has completed its first meaningful paint
diff --git a/chromium/content/public/browser/web_contents_delegate.cc b/chromium/content/public/browser/web_contents_delegate.cc
index 9d5eb003555..a216418f844 100644
--- a/chromium/content/public/browser/web_contents_delegate.cc
+++ b/chromium/content/public/browser/web_contents_delegate.cc
@@ -11,6 +11,7 @@
#include "base/memory/singleton.h"
#include "build/build_config.h"
#include "components/viz/common/surfaces/surface_id.h"
+#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/keyboard_event_processing_result.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/security_style_explanations.h"
@@ -158,6 +159,20 @@ content::ColorChooser* WebContentsDelegate::OpenColorChooser(
return nullptr;
}
+void WebContentsDelegate::RunFileChooser(
+ RenderFrameHost* render_frame_host,
+ std::unique_ptr<FileSelectListener> listener,
+ const blink::mojom::FileChooserParams& params) {
+ listener->FileSelectionCanceled();
+}
+
+void WebContentsDelegate::EnumerateDirectory(
+ WebContents* web_contents,
+ std::unique_ptr<FileSelectListener> listener,
+ const base::FilePath& path) {
+ listener->FileSelectionCanceled();
+}
+
void WebContentsDelegate::RequestMediaAccessPermission(
WebContents* web_contents,
const MediaStreamRequest& request,
@@ -256,10 +271,14 @@ int WebContentsDelegate::GetBottomControlsHeight() const {
return 0;
}
-bool WebContentsDelegate::DoBrowserControlsShrinkBlinkSize() const {
+bool WebContentsDelegate::DoBrowserControlsShrinkRendererSize(
+ const WebContents* web_contents) const {
return false;
}
+void WebContentsDelegate::SetTopControlsGestureScrollInProgress(
+ bool in_progress) {}
+
gfx::Size WebContentsDelegate::EnterPictureInPicture(const viz::SurfaceId&,
const gfx::Size&) {
return gfx::Size();
@@ -267,4 +286,12 @@ gfx::Size WebContentsDelegate::EnterPictureInPicture(const viz::SurfaceId&,
void WebContentsDelegate::ExitPictureInPicture() {}
+std::unique_ptr<content::WebContents> WebContentsDelegate::SwapWebContents(
+ content::WebContents* old_contents,
+ std::unique_ptr<content::WebContents> new_contents,
+ bool did_start_load,
+ bool did_finish_load) {
+ return new_contents;
+}
+
} // namespace content
diff --git a/chromium/content/public/browser/web_contents_delegate.h b/chromium/content/public/browser/web_contents_delegate.h
index f7e72b32ee7..df6045dc917 100644
--- a/chromium/content/public/browser/web_contents_delegate.h
+++ b/chromium/content/public/browser/web_contents_delegate.h
@@ -42,8 +42,15 @@ namespace base {
class FilePath;
}
+namespace blink {
+namespace mojom {
+class FileChooserParams;
+}
+} // namespace blink
+
namespace content {
class ColorChooser;
+class FileSelectListener;
class JavaScriptDialogManager;
class RenderFrameHost;
class RenderProcessHost;
@@ -53,7 +60,6 @@ class SiteInstance;
class WebContentsImpl;
struct ContextMenuParams;
struct DropData;
-struct FileChooserParams;
struct NativeWebKeyboardEvent;
struct Referrer;
struct SecurityStyleExplanations;
@@ -319,6 +325,9 @@ class CONTENT_EXPORT WebContentsDelegate {
const GURL& target_url,
WebContents* new_contents) {}
+ // Notifies the embedder that a Portal WebContents was created.
+ virtual void PortalWebContentsCreated(WebContents* portal_web_contents) {}
+
// Notification that one of the frames in the WebContents is hung. |source| is
// the WebContents that is hung, and |render_widget_host| is the
// RenderWidgetHost that, while routing events to it, discovered the hang.
@@ -361,15 +370,20 @@ class CONTENT_EXPORT WebContentsDelegate {
const std::vector<blink::mojom::ColorSuggestionPtr>& suggestions);
// Called when a file selection is to be done.
+ // This function is responsible for calling listener->FileSelected() or
+ // listener->FileSelectionCanceled().
virtual void RunFileChooser(RenderFrameHost* render_frame_host,
- const FileChooserParams& params) {}
+ std::unique_ptr<FileSelectListener> listener,
+ const blink::mojom::FileChooserParams& params);
// Request to enumerate a directory. This is equivalent to running the file
// chooser in directory-enumeration mode and having the user select the given
// directory.
+ // This function is responsible for calling listener->FileSelected() or
+ // listener->FileSelectionCanceled().
virtual void EnumerateDirectory(WebContents* web_contents,
- int request_id,
- const base::FilePath& path) {}
+ std::unique_ptr<FileSelectListener> listener,
+ const base::FilePath& path);
// Shows a chooser for the user to select a nearby Bluetooth device. The
// observer must live at least as long as the returned chooser object.
@@ -551,6 +565,9 @@ class CONTENT_EXPORT WebContentsDelegate {
const url::Origin& origin,
const GURL& resource_url);
+ virtual void SetTopControlsShownRatio(WebContents* web_contents,
+ float ratio) {}
+
// Requests to get browser controls info such as the height of the top/bottom
// controls, and whether they will shrink the Blink's view size.
// Note that they are not complete in the sense that there is no API to tell
@@ -558,7 +575,13 @@ class CONTENT_EXPORT WebContentsDelegate {
// needed by embedder because it's always accompanied by view size change.
virtual int GetTopControlsHeight() const;
virtual int GetBottomControlsHeight() const;
- virtual bool DoBrowserControlsShrinkBlinkSize() const;
+ virtual bool DoBrowserControlsShrinkRendererSize(
+ const WebContents* web_contents) const;
+
+ // Propagates to the browser that gesture scrolling has changed state. This is
+ // used by the browser to assist in controlling the behavior of sliding the
+ // top controls as a result of page gesture scrolling while in tablet mode.
+ virtual void SetTopControlsGestureScrollInProgress(bool in_progress);
// Give WebContentsDelegates the opportunity to adjust the previews state.
virtual void AdjustPreviewsStateForNavigation(
@@ -587,6 +610,26 @@ class CONTENT_EXPORT WebContentsDelegate {
// Picture-in-Picture mode has ended.
virtual void ExitPictureInPicture();
+#if defined(OS_ANDROID)
+ // Updates information to determine whether a user gesture should carryover to
+ // future navigations. This is needed so navigations within a certain
+ // timeframe of a request initiated by a gesture will be treated as if they
+ // were initiated by a gesture too, otherwise the navigation may be blocked.
+ virtual void UpdateUserGestureCarryoverInfo(WebContents* web_contents) {}
+#endif
+
+ // Requests the delegate to replace |old_contents| with |new_contents| in the
+ // container that holds |old_contents|. If the delegate successfully replaces
+ // |old_contents|, the return parameter passes ownership of |old_contents|.
+ // Otherwise, |new_contents| is returned.
+ // |did_finish_load| is true if WebContentsObserver::DidFinishLoad() has
+ // already been called for |new_contents|.
+ virtual std::unique_ptr<content::WebContents> SwapWebContents(
+ content::WebContents* old_contents,
+ std::unique_ptr<content::WebContents> new_contents,
+ bool did_start_load,
+ bool did_finish_load);
+
protected:
virtual ~WebContentsDelegate();
diff --git a/chromium/content/public/browser/web_contents_observer.h b/chromium/content/public/browser/web_contents_observer.h
index 458b71354dd..89ff658d888 100644
--- a/chromium/content/public/browser/web_contents_observer.h
+++ b/chromium/content/public/browser/web_contents_observer.h
@@ -325,6 +325,12 @@ class CONTENT_EXPORT WebContentsObserver : public IPC::Listener {
// failure methods will also be invoked.
virtual void NavigationStopped() {}
+ // This method is invoked when the WebContents reloads all the LoFi images in
+ // the frame. LoFi is a type of Preview where Chrome shows gray boxes in place
+ // of the images on a webpage in order to conserve data for data-sensitive
+ // users. See http://bit.ly/LoFiPublicDoc.
+ virtual void DidReloadLoFiImages() {}
+
// Called when there has been direct user interaction with the WebContents.
// The type argument specifies the kind of interaction. Direct user input
// signalled through this callback includes:
@@ -429,9 +435,11 @@ class CONTENT_EXPORT WebContentsObserver : public IPC::Listener {
// Invoked before a form repost warning is shown.
virtual void BeforeFormRepostWarningShow() {}
- // Invoked when the beforeunload handler fires. The time is from the renderer
- // process.
- virtual void BeforeUnloadFired(const base::TimeTicks& proceed_time) {}
+ // Invoked when the beforeunload handler fires. |proceed| is set to true if
+ // the beforeunload can safely proceed, otherwise it should be interrupted.
+ // The time is from the renderer process.
+ virtual void BeforeUnloadFired(bool proceed,
+ const base::TimeTicks& proceed_time) {}
// Invoked when a user cancels a before unload dialog.
virtual void BeforeUnloadDialogCancelled() {}
diff --git a/chromium/content/public/common/BUILD.gn b/chromium/content/public/common/BUILD.gn
index c94dc1a1fc8..d7b525cf6fb 100644
--- a/chromium/content/public/common/BUILD.gn
+++ b/chromium/content/public/common/BUILD.gn
@@ -147,10 +147,6 @@ jumbo_source_set("common_sources") {
"drop_data.h",
"favicon_url.cc",
"favicon_url.h",
- "file_chooser_file_info.cc",
- "file_chooser_file_info.h",
- "file_chooser_params.cc",
- "file_chooser_params.h",
"font_cache_dispatcher_win.h",
"frame_navigate_params.cc",
"frame_navigate_params.h",
@@ -173,8 +169,6 @@ jumbo_source_set("common_sources") {
"mhtml_generation_params.h",
"mime_handler_view_mode.cc",
"mime_handler_view_mode.h",
- "notification_resources.cc",
- "notification_resources.h",
"origin_util.h",
"page_importance_signals.h",
"page_state.cc",
@@ -184,8 +178,6 @@ jumbo_source_set("common_sources") {
"pepper_plugin_info.cc",
"pepper_plugin_info.h",
"persistent_notification_status.h",
- "platform_notification_data.cc",
- "platform_notification_data.h",
"previews_state.h",
"process_type.h",
"push_subscription_options.h",
@@ -193,7 +185,6 @@ jumbo_source_set("common_sources") {
"referrer.h",
"renderer_preferences.cc",
"renderer_preferences.h",
- "request_context_type.h",
"resource_request_body_android.cc",
"resource_request_body_android.h",
"resource_type.cc",
@@ -223,6 +214,7 @@ jumbo_source_set("common_sources") {
"use_zoom_for_dsf_policy.cc",
"use_zoom_for_dsf_policy.h",
"user_agent.h",
+ "was_activated_option.h",
"web_preferences.cc",
"web_preferences.h",
"webplugininfo.cc",
@@ -230,6 +222,7 @@ jumbo_source_set("common_sources") {
"webplugininfo_param_traits.h",
"webrtc_ip_handling_policy.cc",
"webrtc_ip_handling_policy.h",
+ "widget_type.h",
]
configs += [
@@ -265,6 +258,7 @@ jumbo_source_set("common_sources") {
# needed because of allow_circular_includes_from.
"//content/common:mojo_bindings",
"//media",
+ "//media/mojo/interfaces",
"//ppapi/buildflags",
"//ppapi/c",
"//services/network/public/cpp",
@@ -369,10 +363,18 @@ mojom("interfaces") {
sources += [ "font_cache_win.mojom" ]
}
+ if (is_mac) {
+ sources += [
+ "ns_view_bridge_factory.mojom",
+ "web_contents_ns_view_bridge.mojom",
+ ]
+ }
+
public_deps = [
":resource_type_bindings",
"//services/network/public/mojom",
"//third_party/blink/public:mojo_bindings",
+ "//ui/accessibility:ax_enums_mojo",
"//url/mojom:url_mojom_gurl",
"//url/mojom:url_mojom_origin",
]
diff --git a/chromium/content/public/common/common_param_traits.cc b/chromium/content/public/common/common_param_traits.cc
index 539c53ed326..1d92adb8723 100644
--- a/chromium/content/public/common/common_param_traits.cc
+++ b/chromium/content/public/common/common_param_traits.cc
@@ -36,6 +36,24 @@ void ParamTraits<content::PageState>::Log(
l->append(")");
}
+void ParamTraits<ui::AXTreeID>::Write(base::Pickle* m, const param_type& p) {
+ WriteParam(m, p.ToString());
+}
+
+bool ParamTraits<ui::AXTreeID>::Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r) {
+ std::string value;
+ if (!ReadParam(m, iter, &value))
+ return false;
+ *r = ui::AXTreeID::FromString(value);
+ return true;
+}
+
+void ParamTraits<ui::AXTreeID>::Log(const param_type& p, std::string* l) {
+ l->append("<ui::AXTreeID>");
+}
+
} // namespace IPC
// Generate param traits write methods.
diff --git a/chromium/content/public/common/common_param_traits.h b/chromium/content/public/common/common_param_traits.h
index 366da86000b..5c9f82f8362 100644
--- a/chromium/content/public/common/common_param_traits.h
+++ b/chromium/content/public/common/common_param_traits.h
@@ -23,6 +23,7 @@
#include "content/common/content_export.h"
#include "content/public/common/common_param_traits_macros.h"
#include "ipc/ipc_message_utils.h"
+#include "ui/accessibility/ax_tree_id.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/surface/transport_dib.h"
#include "url/ipc/url_param_traits.h"
@@ -80,6 +81,16 @@ struct ParamTraits<gfx::NativeWindow> {
}
};
+template <>
+struct CONTENT_EXPORT ParamTraits<ui::AXTreeID> {
+ typedef ui::AXTreeID param_type;
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
} // namespace IPC
#endif // CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_H_
diff --git a/chromium/content/public/common/common_param_traits_macros.h b/chromium/content/public/common/common_param_traits_macros.h
index 64de36aa745..09aa0927af7 100644
--- a/chromium/content/public/common/common_param_traits_macros.h
+++ b/chromium/content/public/common/common_param_traits_macros.h
@@ -232,7 +232,6 @@ IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences)
IPC_STRUCT_TRAITS_MEMBER(default_minimum_page_scale_factor)
IPC_STRUCT_TRAITS_MEMBER(default_maximum_page_scale_factor)
IPC_STRUCT_TRAITS_MEMBER(hide_download_ui)
- IPC_STRUCT_TRAITS_MEMBER(background_video_track_optimization_enabled)
IPC_STRUCT_TRAITS_MEMBER(presentation_receiver)
IPC_STRUCT_TRAITS_MEMBER(media_controls_enabled)
IPC_STRUCT_TRAITS_MEMBER(do_not_update_selection_on_mutating_selection_range)
@@ -240,6 +239,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences)
IPC_STRUCT_TRAITS_MEMBER(low_priority_iframes_threshold)
IPC_STRUCT_TRAITS_MEMBER(picture_in_picture_enabled)
IPC_STRUCT_TRAITS_MEMBER(translate_service_available)
+ IPC_STRUCT_TRAITS_MEMBER(network_quality_estimator_web_holdback)
IPC_STRUCT_TRAITS_MEMBER(lazy_frame_loading_distance_thresholds_px)
IPC_STRUCT_TRAITS_END()
@@ -303,9 +303,6 @@ IPC_STRUCT_TRAITS_BEGIN(content::RendererPreferences)
IPC_STRUCT_TRAITS_MEMBER(subpixel_rendering)
IPC_STRUCT_TRAITS_MEMBER(use_subpixel_positioning)
IPC_STRUCT_TRAITS_MEMBER(focus_ring_color)
- IPC_STRUCT_TRAITS_MEMBER(thumb_active_color)
- IPC_STRUCT_TRAITS_MEMBER(thumb_inactive_color)
- IPC_STRUCT_TRAITS_MEMBER(track_color)
IPC_STRUCT_TRAITS_MEMBER(active_selection_bg_color)
IPC_STRUCT_TRAITS_MEMBER(active_selection_fg_color)
IPC_STRUCT_TRAITS_MEMBER(inactive_selection_bg_color)
diff --git a/chromium/content/public/common/content_client.cc b/chromium/content/public/common/content_client.cc
index 998defab191..5683469e581 100644
--- a/chromium/content/public/common/content_client.cc
+++ b/chromium/content/public/common/content_client.cc
@@ -5,6 +5,7 @@
#include "content/public/common/content_client.h"
#include "base/logging.h"
+#include "base/no_destructor.h"
#include "base/strings/string_piece.h"
#include "base/values.h"
#include "build/build_config.h"
@@ -94,8 +95,8 @@ base::RefCountedMemory* ContentClient::GetDataResourceBytes(
}
gfx::Image& ContentClient::GetNativeImageNamed(int resource_id) const {
- CR_DEFINE_STATIC_LOCAL(gfx::Image, kEmptyImage, ());
- return kEmptyImage;
+ static base::NoDestructor<gfx::Image> kEmptyImage;
+ return *kEmptyImage;
}
std::string ContentClient::GetProcessTypeNameInEnglish(int type) {
diff --git a/chromium/content/public/common/content_client.h b/chromium/content/public/common/content_client.h
index b939bc2a9ed..618a328b476 100644
--- a/chromium/content/public/common/content_client.h
+++ b/chromium/content/public/common/content_client.h
@@ -139,6 +139,11 @@ class CONTENT_EXPORT ContentClient {
// Registers a URL scheme as strictly empty documents, allowing them to
// commit synchronously.
std::vector<std::string> empty_document_schemes;
+#if defined(OS_ANDROID)
+ // Normally, non-standard schemes canonicalize to opaque origins. However,
+ // Android WebView requires non-standard schemes to still be preserved.
+ bool allow_non_standard_schemes_in_origins = false;
+#endif
};
virtual void AddAdditionalSchemes(Schemes* schemes) {}
diff --git a/chromium/content/public/common/content_features.cc b/chromium/content/public/common/content_features.cc
index eaa31fc6cdb..df0296b70a8 100644
--- a/chromium/content/public/common/content_features.cc
+++ b/chromium/content/public/common/content_features.cc
@@ -33,11 +33,6 @@ const base::Feature kAllowSignedHTTPExchangeCertsWithoutExtension{
"AllowSignedHTTPExchangeCertsWithoutExtension",
base::FEATURE_DISABLED_BY_DEFAULT};
-// Enables asm.js to WebAssembly V8 backend.
-// http://asmjs.org/spec/latest/
-const base::Feature kAsmJsToWebAssembly{"AsmJsToWebAssembly",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
// Creates audio output and input streams using the audio service.
const base::Feature kAudioServiceAudioStreams{
"AudioServiceAudioStreams", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -50,6 +45,10 @@ const base::Feature kAudioServiceLaunchOnStartup{
const base::Feature kAudioServiceOutOfProcess{
"AudioServiceOutOfProcess", base::FEATURE_DISABLED_BY_DEFAULT};
+// Kill switch for Background Fetch.
+const base::Feature kBackgroundFetch{"BackgroundFetch",
+ base::FEATURE_ENABLED_BY_DEFAULT};
+
// Enable incremental marking for Blink's heap managed by the Oilpan garbage
// collector.
const base::Feature kBlinkHeapIncrementalMarking{
@@ -110,16 +109,6 @@ const base::Feature kCompositeOpaqueScrollers{"CompositeOpaqueScrollers",
const base::Feature kCompositorTouchAction{"CompositorTouchAction",
base::FEATURE_DISABLED_BY_DEFAULT};
-// Enables blocking cross-site document responses (not paying attention to
-// whether a site isolation mode is also enabled).
-const base::Feature kCrossSiteDocumentBlockingAlways{
- "CrossSiteDocumentBlockingAlways", base::FEATURE_ENABLED_BY_DEFAULT};
-
-// Enables blocking cross-site document responses if one of site isolation modes
-// is (e.g. site-per-process or isolate-origins) is enabled.
-const base::Feature kCrossSiteDocumentBlockingIfIsolating{
- "CrossSiteDocumentBlockingIfIsolating", base::FEATURE_ENABLED_BY_DEFAULT};
-
// Enables specification of a target element in the fragment identifier
// via a CSS selector.
const base::Feature kCSSFragmentIdentifiers{"CSSFragmentIdentifiers",
@@ -165,6 +154,12 @@ const base::Feature kGamepadExtensions{"GamepadExtensions",
const base::Feature kGamepadVibration{"GamepadVibration",
base::FEATURE_ENABLED_BY_DEFAULT};
+// Puts network quality estimate related Web APIs in the holdback mode. When the
+// holdback is enabled the related Web APIs return network quality estimate
+// set by the experiment (regardless of the actual quality).
+const base::Feature kNetworkQualityEstimatorWebHoldback{
+ "NetworkQualityEstimatorWebHoldback", base::FEATURE_DISABLED_BY_DEFAULT};
+
// When WebXR Device API is enabled, exposes VR controllers as Gamepads and
// enables additional Gamepad attributes for use with WebXR Device API. Each
// XRInputSource will have a corresponding Gamepad instance.
@@ -184,10 +179,6 @@ const base::Feature kHeapCompaction{"HeapCompaction",
const base::Feature kImageCaptureAPI{"ImageCaptureAPI",
base::FEATURE_ENABLED_BY_DEFAULT};
-// Use the requester origin as a second key to enfore site isolation policy for
-// code caches.
-const base::Feature kIsolatedCodeCache{"IsolatedCodeCache",
- base::FEATURE_DISABLED_BY_DEFAULT};
// Alternative to switches::kIsolateOrigins, for turning on origin isolation.
// List of origins to isolate has to be specified via
@@ -217,10 +208,6 @@ const base::Feature kLazyImageVisibleLoadTimeMetrics{
const base::Feature kLazyInitializeMediaControls{
"LazyInitializeMediaControls", base::FEATURE_ENABLED_BY_DEFAULT};
-// Enables lazily parsing css properties for performance.
-const base::Feature kLazyParseCSS{"LazyParseCSS",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
// Enables lowering the priority of the resources in iframes.
const base::Feature kLowPriorityIframes{"LowPriorityIframes",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -249,14 +236,6 @@ const base::Feature kMemoryCoordinator{"MemoryCoordinator",
const base::Feature kMimeHandlerViewInCrossProcessFrame{
"MimeHandlerViewInCrossProcessFrame", base::FEATURE_DISABLED_BY_DEFAULT};
-// ES6 Modules dynamic imports.
-const base::Feature kModuleScriptsDynamicImport{
- "ModuleScriptsDynamicImport", base::FEATURE_ENABLED_BY_DEFAULT};
-
-// ES6 Modules import.meta.url.
-const base::Feature kModuleScriptsImportMetaUrl{
- "ModuleScriptsImportMetaUrl", base::FEATURE_ENABLED_BY_DEFAULT};
-
// Mojo-based Session Storage.
const base::Feature kMojoSessionStorage{"MojoSessionStorage",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -264,7 +243,7 @@ const base::Feature kMojoSessionStorage{"MojoSessionStorage",
// Enables/disables the video capture service.
const base::Feature kMojoVideoCapture {
"MojoVideoCapture",
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_CHROMEOS)
base::FEATURE_ENABLED_BY_DEFAULT
#else
base::FEATURE_DISABLED_BY_DEFAULT
@@ -367,7 +346,7 @@ const base::Feature kResamplingInputEvents{"ResamplingInputEvents",
// Loading Dispatcher v0 support with ResourceLoadScheduler (crbug.com/729954).
const base::Feature kResourceLoadScheduler{"ResourceLoadScheduler",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
// Run video capture service in the Browser process as opposed to a dedicated
// utility process
@@ -377,7 +356,7 @@ const base::Feature kRunVideoCaptureServiceInBrowserProcess{
// Save the scroll anchor and use it to restore scroll position.
const base::Feature kScrollAnchorSerialization{
- "ScrollAnchorSerialization", base::FEATURE_DISABLED_BY_DEFAULT};
+ "ScrollAnchorSerialization", base::FEATURE_ENABLED_BY_DEFAULT};
// Make sendBeacon throw for a Blob with a non simple type.
const base::Feature kSendBeaconThrowForBlobWithNonSimpleType{
@@ -417,9 +396,16 @@ const base::Feature kSharedArrayBuffer {
const base::Feature kSignedHTTPExchange{"SignedHTTPExchange",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Send "Accept: application/signed-exchange" header to origins who opt-in.
+const base::Feature kSignedHTTPExchangeAcceptHeader{
+ "SignedHTTPExchangeAcceptHeader", base::FEATURE_DISABLED_BY_DEFAULT};
+// Field trial parameter containing the list of origins that opted-in to receive
+// "Accept: application/signed-exchange" header.
+const char kSignedHTTPExchangeAcceptHeaderFieldTrialParamName[] = "OriginsList";
+
// Origin Trial of Origin-Signed HTTP Exchanges (for WebPackage Loading)
const base::Feature kSignedHTTPExchangeOriginTrial{
- "SignedHTTPExchangeOriginTrial", base::FEATURE_DISABLED_BY_DEFAULT};
+ "SignedHTTPExchangeOriginTrial", base::FEATURE_ENABLED_BY_DEFAULT};
// Controls whether SpareRenderProcessHostManager tries to always have a warm
// spare renderer process around for the most recently requested BrowserContext.
@@ -431,18 +417,12 @@ const base::Feature kSpareRendererForSitePerProcess{
const base::Feature kTimerThrottlingForHiddenFrames{
"TimerThrottlingForHiddenFrames", base::FEATURE_ENABLED_BY_DEFAULT};
-// Groups all out-of-process iframes to a different process from the process of
-// the top document. This is a performance isolation mode. Launch bug:
-// https://crbug.com/595987.
-const base::Feature kTopDocumentIsolation{"top-document-isolation",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
// Enables async touchpad pinch zoom events. We check the ACK of the first
// synthetic wheel event in a pinch sequence, then send the rest of the
// synthetic wheel events of the pinch sequence as non-blocking if the first
// event’s ACK is not canceled.
-const base::Feature kTouchpadAsyncPinchEvents{
- "TouchpadAsyncPinchEvents", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kTouchpadAsyncPinchEvents{"TouchpadAsyncPinchEvents",
+ base::FEATURE_ENABLED_BY_DEFAULT};
// An experimental simple user-activation model where the user gesture state is
// tracked through a frame-based state instead of the gesture tokens we use
@@ -466,21 +446,10 @@ const base::Feature kV8Orinoco{"V8Orinoco", base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kV8VmFuture{"V8VmFuture",
base::FEATURE_DISABLED_BY_DEFAULT};
-// Controls the decode acceleration of JPEG images (as opposed to camera
-// captures) in Chrome OS using the VA-API.
-// TODO(andrescj): remove or enable by default in Chrome OS once
-// https://crbug.com/868400 is resolved.
-const base::Feature kVaapiJpegImageDecodeAcceleration{
- "VaapiJpegImageDecodeAcceleration", base::FEATURE_DISABLED_BY_DEFAULT};
-
// Enable WebAssembly structured cloning.
// http://webassembly.org/
const base::Feature kWebAssembly{"WebAssembly",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
-// Enable WebAssembly streamed compilation.
-const base::Feature kWebAssemblyStreaming{"WebAssemblyStreaming",
- base::FEATURE_ENABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
// Enable WebAssembly baseline compilation and tier up.
const base::Feature kWebAssemblyBaseline{"WebAssemblyBaseline",
@@ -528,7 +497,12 @@ const base::Feature kWebAuthCable{"WebAuthenticationCable",
// using pairingless BLE protocol on Windows.
// https://w3c.github.io/webauthn
const base::Feature kWebAuthCableWin{"WebAuthenticationCableWin",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
+
+// Controls whether AuthenticatorAttestationResponse contains a getTransports
+// member to return the set of transports supported by an authenticator.
+const base::Feature kWebAuthGetTransports{"WebAuthenticationGetTransports",
+ base::FEATURE_DISABLED_BY_DEFAULT};
// If WebGL Image Chromium is allowed, this feature controls whether it is
// enabled.
@@ -586,6 +560,12 @@ const base::Feature kWebRtcHybridAgc{"WebRtcHybridAgc",
const base::Feature kWebRtcUseGpuMemoryBufferVideoFrames{
"WebRTC-UseGpuMemoryBufferVideoFrames", base::FEATURE_ENABLED_BY_DEFAULT};
+// Causes WebRTC to replace host ICE candidate IP addresses with generated
+// names ending in ".local" and resolve them using mDNS.
+// http://crbug.com/878465
+const base::Feature kWebRtcHideLocalIpsWithMdns{
+ "WebRtcHideLocalIpsWithMdns", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls whether the WebUSB API is enabled:
// https://wicg.github.io/webusb
const base::Feature kWebUsb{"WebUSB", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -603,7 +583,13 @@ const base::Feature kWebXrHitTest{"WebXRHitTest",
// Controls whether the orientation sensor based device is enabled.
const base::Feature kWebXrOrientationSensorDevice{
- "WebXROrientationSensorDevice", base::FEATURE_DISABLED_BY_DEFAULT};
+ "WebXROrientationSensorDevice",
+#if defined(OS_ANDROID)
+ base::FEATURE_ENABLED_BY_DEFAULT
+#else
+ base::FEATURE_DISABLED_BY_DEFAULT
+#endif
+};
// Wipe corrupt v2 IndexedDB databases.
const base::Feature kWipeCorruptV2IDBDatabases{
@@ -670,11 +656,6 @@ const base::Feature kDeviceMonitorMac{"DeviceMonitorMac",
// Enable IOSurface based screen capturer.
const base::Feature kIOSurfaceCapturer{"IOSurfaceCapturer",
base::FEATURE_ENABLED_BY_DEFAULT};
-
-// The V2 sandbox on MacOS removes the unsandboed warmup phase and sandboxes the
-// entire life of the process.
-const base::Feature kMacV2Sandbox{"MacV2Sandbox",
- base::FEATURE_ENABLED_BY_DEFAULT};
#endif // defined(OS_MACOSX)
enum class VideoCaptureServiceConfiguration {
diff --git a/chromium/content/public/common/content_features.h b/chromium/content/public/common/content_features.h
index 764b0685ab7..9305262478f 100644
--- a/chromium/content/public/common/content_features.h
+++ b/chromium/content/public/common/content_features.h
@@ -21,22 +21,19 @@ CONTENT_EXPORT extern const base::Feature
kAllowContentInitiatedDataUrlNavigations;
CONTENT_EXPORT extern const base::Feature
kAllowSignedHTTPExchangeCertsWithoutExtension;
-CONTENT_EXPORT extern const base::Feature kAsmJsToWebAssembly;
CONTENT_EXPORT extern const base::Feature kAudioServiceAudioStreams;
CONTENT_EXPORT extern const base::Feature kAudioServiceLaunchOnStartup;
CONTENT_EXPORT extern const base::Feature kAudioServiceOutOfProcess;
+CONTENT_EXPORT extern const base::Feature kBackgroundFetch;
CONTENT_EXPORT extern const base::Feature kBlinkHeapIncrementalMarking;
CONTENT_EXPORT extern const base::Feature kBloatedRendererDetection;
CONTENT_EXPORT extern const base::Feature kBlockCredentialedSubresources;
CONTENT_EXPORT extern const base::Feature kBrotliEncoding;
CONTENT_EXPORT extern const base::Feature kCacheInlineScriptCode;
-CONTENT_EXPORT extern const base::Feature kIsolatedCodeCache;
CONTENT_EXPORT extern const base::Feature kCanvas2DImageChromium;
CONTENT_EXPORT extern const base::Feature kCompositeOpaqueFixedPosition;
CONTENT_EXPORT extern const base::Feature kCompositeOpaqueScrollers;
CONTENT_EXPORT extern const base::Feature kCompositorTouchAction;
-CONTENT_EXPORT extern const base::Feature kCrossSiteDocumentBlockingAlways;
-CONTENT_EXPORT extern const base::Feature kCrossSiteDocumentBlockingIfIsolating;
CONTENT_EXPORT extern const base::Feature kCSSFragmentIdentifiers;
CONTENT_EXPORT extern const base::Feature kDataSaverHoldback;
CONTENT_EXPORT extern const base::Feature kExperimentalProductivityFeatures;
@@ -60,16 +57,14 @@ CONTENT_EXPORT extern const base::Feature kLazyFrameVisibleLoadTimeMetrics;
CONTENT_EXPORT extern const base::Feature kLazyImageLoading;
CONTENT_EXPORT extern const base::Feature kLazyImageVisibleLoadTimeMetrics;
CONTENT_EXPORT extern const base::Feature kLazyInitializeMediaControls;
-CONTENT_EXPORT extern const base::Feature kLazyParseCSS;
CONTENT_EXPORT extern const base::Feature kLowPriorityIframes;
CONTENT_EXPORT extern const base::Feature kMediaDevicesSystemMonitorCache;
CONTENT_EXPORT extern const base::Feature kMemoryCoordinator;
CONTENT_EXPORT extern const base::Feature kMimeHandlerViewInCrossProcessFrame;
-CONTENT_EXPORT extern const base::Feature kModuleScriptsDynamicImport;
-CONTENT_EXPORT extern const base::Feature kModuleScriptsImportMetaUrl;
CONTENT_EXPORT extern const base::Feature kMojoSessionStorage;
CONTENT_EXPORT extern const base::Feature kMojoVideoCapture;
CONTENT_EXPORT extern const base::Feature kMojoVideoCaptureSecondary;
+CONTENT_EXPORT extern const base::Feature kNetworkQualityEstimatorWebHoldback;
CONTENT_EXPORT extern const base::Feature kNetworkServiceInProcess;
CONTENT_EXPORT extern const base::Feature kNotificationContentImage;
CONTENT_EXPORT extern const base::Feature kOriginPolicy;
@@ -99,10 +94,12 @@ CONTENT_EXPORT extern const base::Feature kServiceWorkerPaymentApps;
CONTENT_EXPORT extern const base::Feature kServiceWorkerScriptFullCodeCache;
CONTENT_EXPORT extern const base::Feature kSharedArrayBuffer;
CONTENT_EXPORT extern const base::Feature kSignedHTTPExchange;
+CONTENT_EXPORT extern const base::Feature kSignedHTTPExchangeAcceptHeader;
+CONTENT_EXPORT extern const char
+ kSignedHTTPExchangeAcceptHeaderFieldTrialParamName[];
CONTENT_EXPORT extern const base::Feature kSignedHTTPExchangeOriginTrial;
CONTENT_EXPORT extern const base::Feature kSpareRendererForSitePerProcess;
CONTENT_EXPORT extern const base::Feature kTimerThrottlingForHiddenFrames;
-CONTENT_EXPORT extern const base::Feature kTopDocumentIsolation;
CONTENT_EXPORT extern const base::Feature kTouchpadAsyncPinchEvents;
CONTENT_EXPORT extern const base::Feature kTouchpadOverscrollHistoryNavigation;
CONTENT_EXPORT extern const base::Feature kUserActivationV2;
@@ -110,9 +107,7 @@ CONTENT_EXPORT extern const base::Feature kV8ContextSnapshot;
CONTENT_EXPORT extern const base::Feature kV8LowMemoryModeForSubframes;
CONTENT_EXPORT extern const base::Feature kV8Orinoco;
CONTENT_EXPORT extern const base::Feature kV8VmFuture;
-CONTENT_EXPORT extern const base::Feature kVaapiJpegImageDecodeAcceleration;
CONTENT_EXPORT extern const base::Feature kWebAssembly;
-CONTENT_EXPORT extern const base::Feature kWebAssemblyStreaming;
CONTENT_EXPORT extern const base::Feature kWebAssemblyBaseline;
CONTENT_EXPORT extern const base::Feature kWebAssemblyThreads;
CONTENT_EXPORT extern const base::Feature kWebAssemblyTrapHandler;
@@ -120,6 +115,7 @@ CONTENT_EXPORT extern const base::Feature kWebAuth;
CONTENT_EXPORT extern const base::Feature kWebAuthBle;
CONTENT_EXPORT extern const base::Feature kWebAuthCable;
CONTENT_EXPORT extern const base::Feature kWebAuthCableWin;
+CONTENT_EXPORT extern const base::Feature kWebAuthGetTransports;
CONTENT_EXPORT extern const base::Feature kWebContentsOcclusion;
CONTENT_EXPORT extern const base::Feature kWebGLImageChromium;
CONTENT_EXPORT extern const base::Feature kWebPayments;
@@ -131,6 +127,7 @@ CONTENT_EXPORT extern const base::Feature kWebRtcScreenshareSwEncoding;
CONTENT_EXPORT extern const base::Feature kWebRtcUseEchoCanceller3;
CONTENT_EXPORT extern const base::Feature kWebRtcHybridAgc;
CONTENT_EXPORT extern const base::Feature kWebRtcUseGpuMemoryBufferVideoFrames;
+CONTENT_EXPORT extern const base::Feature kWebRtcHideLocalIpsWithMdns;
CONTENT_EXPORT extern const base::Feature kWebUsb;
CONTENT_EXPORT extern const base::Feature kWebVrVsyncAlign;
CONTENT_EXPORT extern const base::Feature kWebXr;
@@ -162,7 +159,6 @@ CONTENT_EXPORT extern const base::Feature kWebUIPolymer2;
#if defined(OS_MACOSX)
CONTENT_EXPORT extern const base::Feature kDeviceMonitorMac;
CONTENT_EXPORT extern const base::Feature kIOSurfaceCapturer;
-CONTENT_EXPORT extern const base::Feature kMacV2Sandbox;
#endif // defined(OS_MACOSX)
// DON'T ADD RANDOM STUFF HERE. Put it in the main section above in
diff --git a/chromium/content/public/common/content_switches.cc b/chromium/content/public/common/content_switches.cc
index 049f139bc7f..5b08a5e5602 100644
--- a/chromium/content/public/common/content_switches.cc
+++ b/chromium/content/public/common/content_switches.cc
@@ -45,6 +45,11 @@ const char kBrowserStartupDialog[] = "browser-startup-dialog";
// Path to the exe to run for the renderer and plugin subprocesses.
const char kBrowserSubprocessPath[] = "browser-subprocess-path";
+// Tells whether the code is running browser tests (this changes the startup URL
+// used by the content shell and also disables features that can make tests
+// flaky [like monitoring of memory pressure]).
+const char kBrowserTest[] = "browser-test";
+
// Sets the tile size used by composited layers.
const char kDefaultTileWidth[] = "default-tile-width";
const char kDefaultTileHeight[] = "default-tile-height";
@@ -478,6 +483,9 @@ const char kDisableOopRasterization[] = "disable-oop-rasterization";
// would have been used. Enables the chromium_raster_transport extension.
const char kEnableOopRasterization[] = "enable-oop-rasterization";
+// Turns on skia deferred display list for out of process raster.
+const char kEnableOopRasterizationDDL[] = "enable-oop-rasterization-ddl";
+
// The number of multisample antialiasing samples for GPU rasterization.
// Requires MSAA support on GPU to have an effect. 0 disables MSAA.
const char kGpuRasterizationMSAASampleCount[] =
@@ -564,15 +572,6 @@ const char kLogFile[] = "log-file";
const char kMainFrameResizesAreOrientationChanges[] =
"main-frame-resizes-are-orientation-changes";
-// Specifies the maximum cache size per an origin for the ApplicationCache.
-// The default value is 5MB.
-const char kMaxAppCacheOriginCacheSizeMb[] =
- "max-appcache-origin-cache-size-mb";
-
-// Specifies the maximum disk cache size for the ApplicationCache. The default
-// value is 250MB.
-const char kMaxAppCacheDiskCacheSizeMb[] = "max-appcache-disk-cache-size-mb";
-
// Sets the maximium decoded image size limitation.
const char kMaxDecodedImageSizeMb[] = "max-decoded-image-size-mb";
diff --git a/chromium/content/public/common/content_switches.h b/chromium/content/public/common/content_switches.h
index 081af901e81..c34999d0ed2 100644
--- a/chromium/content/public/common/content_switches.h
+++ b/chromium/content/public/common/content_switches.h
@@ -24,6 +24,7 @@ CONTENT_EXPORT extern const char kBlinkSettings[];
CONTENT_EXPORT extern const char kBrowserCrashTest[];
CONTENT_EXPORT extern const char kBrowserStartupDialog[];
CONTENT_EXPORT extern const char kBrowserSubprocessPath[];
+CONTENT_EXPORT extern const char kBrowserTest[];
CONTENT_EXPORT extern const char kDefaultTileWidth[];
CONTENT_EXPORT extern const char kDefaultTileHeight[];
CONTENT_EXPORT extern const char kDisable2dCanvasAntialiasing[];
@@ -151,6 +152,7 @@ CONTENT_EXPORT extern const char kForceDisplayList2dCanvas[];
CONTENT_EXPORT extern const char kForceGpuRasterization[];
CONTENT_EXPORT extern const char kDisableOopRasterization[];
CONTENT_EXPORT extern const char kEnableOopRasterization[];
+CONTENT_EXPORT extern const char kEnableOopRasterizationDDL[];
CONTENT_EXPORT extern const char kForceOverlayFullscreenVideo[];
CONTENT_EXPORT extern const char kForcePresentationReceiverForTesting[];
CONTENT_EXPORT extern const char kForceRendererAccessibility[];
@@ -171,8 +173,6 @@ CONTENT_EXPORT extern const char kLogGpuControlListDecisions[];
CONTENT_EXPORT extern const char kLoggingLevel[];
CONTENT_EXPORT extern const char kLogFile[];
CONTENT_EXPORT extern const char kMainFrameResizesAreOrientationChanges[];
-extern const char kMaxAppCacheOriginCacheSizeMb[];
-extern const char kMaxAppCacheDiskCacheSizeMb[];
extern const char kMaxDecodedImageSizeMb[];
extern const char kMaxUntiledLayerHeight[];
extern const char kMaxUntiledLayerWidth[];
diff --git a/chromium/content/public/common/file_chooser_file_info.cc b/chromium/content/public/common/file_chooser_file_info.cc
deleted file mode 100644
index 8605b123c07..00000000000
--- a/chromium/content/public/common/file_chooser_file_info.cc
+++ /dev/null
@@ -1,18 +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 "content/public/common/file_chooser_file_info.h"
-
-namespace content {
-
-FileChooserFileInfo::FileChooserFileInfo() : length(0), is_directory(false) {
-}
-
-FileChooserFileInfo::FileChooserFileInfo(const FileChooserFileInfo& other) =
- default;
-
-FileChooserFileInfo::~FileChooserFileInfo() {
-}
-
-} // namespace content
diff --git a/chromium/content/public/common/file_chooser_file_info.h b/chromium/content/public/common/file_chooser_file_info.h
index 0f338238696..2a6f127a6ab 100644
--- a/chromium/content/public/common/file_chooser_file_info.h
+++ b/chromium/content/public/common/file_chooser_file_info.h
@@ -15,21 +15,23 @@
namespace content {
// Result of file chooser.
+//
+// This represents either a native file or a non-native file. If
+// |file_system_url.is_valid()|, this is a non-native file and |file_path| is
+// empty.
struct CONTENT_EXPORT FileChooserFileInfo {
FileChooserFileInfo();
FileChooserFileInfo(const FileChooserFileInfo& other);
~FileChooserFileInfo();
- base::FilePath file_path;
-
// For native files.
+ base::FilePath file_path;
base::FilePath::StringType display_name;
// For non-native files.
GURL file_system_url;
base::Time modification_time;
int64_t length;
-
bool is_directory;
};
diff --git a/chromium/content/public/common/file_chooser_params.cc b/chromium/content/public/common/file_chooser_params.cc
deleted file mode 100644
index da1ca6f6d97..00000000000
--- a/chromium/content/public/common/file_chooser_params.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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 "content/public/common/file_chooser_params.h"
-
-namespace content {
-
-FileChooserParams::FileChooserParams() : mode(Open), need_local_path(true) {
-}
-
-FileChooserParams::FileChooserParams(const FileChooserParams& other) = default;
-
-FileChooserParams::~FileChooserParams() {
-}
-
-} // namespace content
diff --git a/chromium/content/public/common/file_chooser_params.h b/chromium/content/public/common/file_chooser_params.h
deleted file mode 100644
index c189785370b..00000000000
--- a/chromium/content/public/common/file_chooser_params.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_COMMON_FILE_CHOOSER_PARAMS_H_
-#define CONTENT_PUBLIC_COMMON_FILE_CHOOSER_PARAMS_H_
-
-#include <vector>
-
-#include "base/files/file_path.h"
-#include "base/strings/string16.h"
-#include "build/build_config.h"
-#include "content/common/content_export.h"
-#include "url/gurl.h"
-
-namespace content {
-
-// Struct used by WebContentsDelegate.
-struct CONTENT_EXPORT FileChooserParams {
- FileChooserParams();
- FileChooserParams(const FileChooserParams& other);
- ~FileChooserParams();
-
- enum Mode {
- // Requires that the file exists before allowing the user to pick it.
- Open,
-
- // Like Open, but allows picking multiple files to open.
- OpenMultiple,
-
- // Like Open, but selects a folder for upload.
- UploadFolder,
-
- // Allows picking a nonexistent file, and prompts to overwrite if the file
- // already exists.
- Save,
- };
-
- Mode mode;
-
- // Title to be used for the dialog. This may be empty for the default title,
- // which will be either "Open" or "Save" depending on the mode.
- base::string16 title;
-
- // Default file name to select in the dialog.
- base::FilePath default_file_name;
-
- // A list of valid lower-cased MIME types or file extensions specified in an
- // input element. It is used to restrict selectable files to such types.
- std::vector<base::string16> accept_types;
-
- // Whether the caller needs native file path or not.
- bool need_local_path;
-
-#if defined(OS_ANDROID)
- // See http://www.w3.org/TR/html-media-capture for more information.
- // If true, the data should be obtained using the device's camera/mic/etc.
- bool capture;
-#endif
-
- // If non-empty, represents the URL of the requestor if the request was
- // initiated by a document. Note that this value should be considered
- // untrustworthy since it is specified by the sandbox and not validated.
- GURL requestor;
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_COMMON_FILE_CHOOSER_PARAMS_H_
diff --git a/chromium/content/common/gpu_stream_constants.h b/chromium/content/public/common/gpu_stream_constants.h
index afcf6f5ef6a..ead4164fbad 100644
--- a/chromium/content/common/gpu_stream_constants.h
+++ b/chromium/content/public/common/gpu_stream_constants.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 CONTENT_COMMON_GPU_STREAM_CONSTANTS_H_
-#define CONTENT_COMMON_GPU_STREAM_CONSTANTS_H_
+#ifndef CONTENT_PUBLIC_COMMON_GPU_STREAM_CONSTANTS_H_
+#define CONTENT_PUBLIC_COMMON_GPU_STREAM_CONSTANTS_H_
#include "gpu/command_buffer/common/scheduling_priority.h"
@@ -40,4 +40,4 @@ const gpu::SchedulingPriority kGpuStreamPriorityHighPriorityWebGL =
} // namespace content
-#endif // CONTENT_COMMON_GPU_STREAM_CONSTANTS_H_
+#endif // CONTENT_PUBLIC_COMMON_GPU_STREAM_CONSTANTS_H_
diff --git a/chromium/content/public/common/media_stream_request.cc b/chromium/content/public/common/media_stream_request.cc
index 1f18ec8a0c4..93a5cf90118 100644
--- a/chromium/content/public/common/media_stream_request.cc
+++ b/chromium/content/public/common/media_stream_request.cc
@@ -23,13 +23,20 @@ bool IsVideoInputMediaType(MediaStreamType type) {
}
bool IsScreenCaptureMediaType(MediaStreamType type) {
+ return IsDesktopCaptureMediaType(type) || IsTabCaptureMediaType(type);
+}
+
+bool IsDesktopCaptureMediaType(MediaStreamType type) {
return (type == MEDIA_DISPLAY_VIDEO_CAPTURE ||
- type == MEDIA_GUM_TAB_AUDIO_CAPTURE ||
- type == MEDIA_GUM_TAB_VIDEO_CAPTURE ||
type == MEDIA_GUM_DESKTOP_AUDIO_CAPTURE ||
type == MEDIA_GUM_DESKTOP_VIDEO_CAPTURE);
}
+bool IsTabCaptureMediaType(MediaStreamType type) {
+ return (type == MEDIA_GUM_TAB_AUDIO_CAPTURE ||
+ type == MEDIA_GUM_TAB_VIDEO_CAPTURE);
+}
+
bool IsDeviceMediaType(MediaStreamType type) {
return (type == MEDIA_DEVICE_AUDIO_CAPTURE ||
type == MEDIA_DEVICE_VIDEO_CAPTURE);
@@ -78,10 +85,40 @@ MediaStreamDevice::MediaStreamDevice(MediaStreamType type,
DCHECK(input.IsValid());
}
-MediaStreamDevice::MediaStreamDevice(const MediaStreamDevice& other) = default;
+MediaStreamDevice::MediaStreamDevice(const MediaStreamDevice& other) {
+ type = other.type;
+ id = other.id;
+ video_facing = other.video_facing;
+ group_id = other.group_id;
+ matched_output_device_id = other.matched_output_device_id;
+ name = other.name;
+ input = other.input;
+ session_id = other.session_id;
+ camera_calibration = other.camera_calibration;
+ if (other.display_media_info.has_value())
+ display_media_info = other.display_media_info->Clone();
+}
MediaStreamDevice::~MediaStreamDevice() {}
+MediaStreamDevice& MediaStreamDevice::operator=(
+ const MediaStreamDevice& other) {
+ if (&other == this)
+ return *this;
+ type = other.type;
+ id = other.id;
+ video_facing = other.video_facing;
+ group_id = other.group_id;
+ matched_output_device_id = other.matched_output_device_id;
+ name = other.name;
+ input = other.input;
+ session_id = other.session_id;
+ camera_calibration = other.camera_calibration;
+ if (other.display_media_info.has_value())
+ display_media_info = other.display_media_info->Clone();
+ return *this;
+}
+
bool MediaStreamDevice::IsSameDevice(
const MediaStreamDevice& other_device) const {
return type == other_device.type && name == other_device.name &&
diff --git a/chromium/content/public/common/media_stream_request.h b/chromium/content/public/common/media_stream_request.h
index 66e13851784..8cc1c7a1a35 100644
--- a/chromium/content/public/common/media_stream_request.h
+++ b/chromium/content/public/common/media_stream_request.h
@@ -17,6 +17,7 @@
#include "media/base/audio_parameters.h"
#include "media/base/video_facing.h"
#include "media/capture/video/video_capture_device_descriptor.h"
+#include "media/mojo/interfaces/display_media_information.mojom.h"
#include "ui/gfx/native_widget_types.h"
#include "url/gurl.h"
@@ -84,6 +85,8 @@ using CameraCalibration =
CONTENT_EXPORT bool IsAudioInputMediaType(MediaStreamType type);
CONTENT_EXPORT bool IsVideoInputMediaType(MediaStreamType type);
CONTENT_EXPORT bool IsScreenCaptureMediaType(MediaStreamType type);
+CONTENT_EXPORT bool IsDesktopCaptureMediaType(MediaStreamType type);
+CONTENT_EXPORT bool IsTabCaptureMediaType(MediaStreamType type);
CONTENT_EXPORT bool IsDeviceMediaType(MediaStreamType type);
// TODO(xians): Change the structs to classes.
@@ -115,6 +118,8 @@ struct CONTENT_EXPORT MediaStreamDevice {
~MediaStreamDevice();
+ MediaStreamDevice& operator=(const MediaStreamDevice& other);
+
bool IsSameDevice(const MediaStreamDevice& other_device) const;
// The device's type.
@@ -146,6 +151,9 @@ struct CONTENT_EXPORT MediaStreamDevice {
// This field is optional and available only for some camera models.
base::Optional<CameraCalibration> camera_calibration;
+
+ // This field is optional and available only for display media devices.
+ base::Optional<media::mojom::DisplayMediaInformationPtr> display_media_info;
};
using MediaStreamDevices = std::vector<MediaStreamDevice>;
diff --git a/chromium/content/public/common/notification_resources.cc b/chromium/content/public/common/notification_resources.cc
deleted file mode 100644
index 75619a0a0a6..00000000000
--- a/chromium/content/public/common/notification_resources.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/public/common/notification_resources.h"
-
-namespace content {
-
-NotificationResources::NotificationResources() {}
-
-NotificationResources::NotificationResources(
- const NotificationResources& other) = default;
-
-NotificationResources::~NotificationResources() {}
-
-} // namespace content
diff --git a/chromium/content/public/common/notification_resources.h b/chromium/content/public/common/notification_resources.h
deleted file mode 100644
index e8c56a539ab..00000000000
--- a/chromium/content/public/common/notification_resources.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_COMMON_NOTIFICATION_RESOURCES_H_
-#define CONTENT_PUBLIC_COMMON_NOTIFICATION_RESOURCES_H_
-
-#include <vector>
-
-#include "content/common/content_export.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace content {
-
-// Structure to hold the resources associated with a Web Notification.
-struct CONTENT_EXPORT NotificationResources {
- NotificationResources();
- NotificationResources(const NotificationResources& other);
- ~NotificationResources();
-
- // Image for the notification. The bitmap may be empty if the developer did
- // not provide an image, or fetching of the image failed.
- SkBitmap image;
-
- // Main icon for the notification. The bitmap may be empty if the developer
- // did not provide an icon, or fetching of the icon failed.
- SkBitmap notification_icon;
-
- // Badge for the notification. The bitmap may be empty if the developer
- // did not provide a badge, or fetching of the badge failed.
- SkBitmap badge;
-
- // Icons for the actions. A bitmap may be empty if the developer did not
- // provide an icon, or fetching of the icon failed.
- std::vector<SkBitmap> action_icons;
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_COMMON_NOTIFICATION_RESOURCES_H_
diff --git a/chromium/content/public/common/ns_view_bridge_factory.mojom b/chromium/content/public/common/ns_view_bridge_factory.mojom
new file mode 100644
index 00000000000..29402f35759
--- /dev/null
+++ b/chromium/content/public/common/ns_view_bridge_factory.mojom
@@ -0,0 +1,36 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.mojom;
+
+import "content/public/common/web_contents_ns_view_bridge.mojom";
+
+// Empty interface that is used by NSViewBridgeFactory in place of
+// RenderWidgetHostNSViewBridge and RenderWidgetHostNSViewClient (which are the
+// real interface that should be used). The reason that the correct interfaces
+// cannot be used directly is that they have dependencies on content-internal
+// mojo type serialization (in particular, content wrappings of Blink types).
+// TODO(ccameron): Migrate the interfaces RenderWidgetHostNSViewBridge and
+// RenderWidgetHostNSViewClient from content-internal types to ui types, and
+// then move the interfaces to content/public.
+// https://crbug.com/888290
+interface StubInterface {};
+
+interface NSViewBridgeFactory {
+ // Create and take ownership of the NSView for a RenderWidgetHostView. The
+ // resulting object will be destroyed when the connection is closed.
+ CreateRenderWidgetHostNSViewBridge(
+ associated StubInterface client,
+ associated StubInterface& bridge_request);
+
+ // Create and take ownership of the NSView for a WebContentsView. The
+ // resulting object will be destroyed when the connection is closed.
+ // The value of |view_id| may be used to look up the NSView (e.g, to add
+ // child NSViews.
+ CreateWebContentsNSViewBridge(
+ uint64 view_id,
+ associated WebContentsNSViewClient client,
+ associated WebContentsNSViewBridge& bridge_request);
+};
+
diff --git a/chromium/content/public/common/platform_notification_data.cc b/chromium/content/public/common/platform_notification_data.cc
deleted file mode 100644
index 904015aa701..00000000000
--- a/chromium/content/public/common/platform_notification_data.cc
+++ /dev/null
@@ -1,23 +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 "content/public/common/platform_notification_data.h"
-
-namespace content {
-
-PlatformNotificationAction::PlatformNotificationAction() {}
-
-PlatformNotificationAction::PlatformNotificationAction(
- const PlatformNotificationAction& other) = default;
-
-PlatformNotificationAction::~PlatformNotificationAction() {}
-
-PlatformNotificationData::PlatformNotificationData() {}
-
-PlatformNotificationData::PlatformNotificationData(
- const PlatformNotificationData& other) = default;
-
-PlatformNotificationData::~PlatformNotificationData() {}
-
-} // namespace content
diff --git a/chromium/content/public/common/platform_notification_data.h b/chromium/content/public/common/platform_notification_data.h
deleted file mode 100644
index c6bd563401e..00000000000
--- a/chromium/content/public/common/platform_notification_data.h
+++ /dev/null
@@ -1,123 +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_PUBLIC_COMMON_PLATFORM_NOTIFICATION_DATA_H_
-#define CONTENT_PUBLIC_COMMON_PLATFORM_NOTIFICATION_DATA_H_
-
-#include <stddef.h>
-
-#include <string>
-#include <vector>
-
-#include "base/strings/nullable_string16.h"
-#include "base/strings/string16.h"
-#include "base/time/time.h"
-#include "content/common/content_export.h"
-#include "url/gurl.h"
-
-namespace content {
-
-enum PlatformNotificationActionType {
- PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON = 0,
- PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT,
-};
-
-// A notification action (button or text input); corresponds to Blink
-// WebNotificationAction.
-struct CONTENT_EXPORT PlatformNotificationAction {
- PlatformNotificationAction();
- PlatformNotificationAction(const PlatformNotificationAction& other);
- ~PlatformNotificationAction();
-
- // Type of the action (button or text input).
- PlatformNotificationActionType type =
- PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON;
-
- // Action name that the author can use to distinguish them.
- std::string action;
-
- // Title of the button.
- base::string16 title;
-
- // URL of the icon for the button. May be empty if no url was specified.
- GURL icon;
-
- // Optional text to use as placeholder for text inputs. May be null if it was
- // not specified.
- base::NullableString16 placeholder;
-};
-
-// Structure representing the information associated with a Web Notification.
-// This struct should include the developer-visible information, kept
-// synchronized with the WebNotificationData structure defined in the Blink API.
-struct CONTENT_EXPORT PlatformNotificationData {
- PlatformNotificationData();
- PlatformNotificationData(const PlatformNotificationData& other);
- ~PlatformNotificationData();
-
- enum Direction {
- DIRECTION_LEFT_TO_RIGHT,
- DIRECTION_RIGHT_TO_LEFT,
- DIRECTION_AUTO,
-
- DIRECTION_LAST = DIRECTION_AUTO
- };
-
- // Title to be displayed with the Web Notification.
- base::string16 title;
-
- // Hint to determine the directionality of the displayed notification.
- Direction direction = DIRECTION_LEFT_TO_RIGHT;
-
- // BCP 47 language tag describing the notification's contents. Optional.
- std::string lang;
-
- // Contents of the notification.
- base::string16 body;
-
- // Tag of the notification. Notifications sharing both their origin and their
- // tag will replace the first displayed notification.
- std::string tag;
-
- // URL of the image contents of the notification. May be empty if no url was
- // specified.
- GURL image;
-
- // URL of the icon which is to be displayed with the notification.
- GURL icon;
-
- // URL of the badge for representing the notification. May be empty if no url
- // was specified.
- GURL badge;
-
- // Vibration pattern for the notification, following the syntax of the
- // Vibration API. https://www.w3.org/TR/vibration/
- std::vector<int> vibration_pattern;
-
- // The time at which the event the notification represents took place.
- base::Time timestamp;
-
- // Whether default notification indicators (sound, vibration, light) should
- // be played again if the notification is replacing an older notification.
- bool renotify = false;
-
- // Whether default notification indicators (sound, vibration, light) should
- // be suppressed.
- bool silent = false;
-
- // Whether the notification should remain onscreen indefinitely, rather than
- // being auto-minimized to the notification center (if allowed by platform).
- bool require_interaction = false;
-
- // Developer-provided data associated with the notification, in the form of
- // a serialized string. Must not exceed |kMaximumDeveloperDataSize| bytes.
- std::vector<char> data;
-
- // Actions that should be shown as buttons on the notification.
- std::vector<PlatformNotificationAction> actions;
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_COMMON_PLATFORM_NOTIFICATION_DATA_H_
diff --git a/chromium/content/public/common/previews_state.h b/chromium/content/public/common/previews_state.h
index e87edd62d3f..75e96caf890 100644
--- a/chromium/content/public/common/previews_state.h
+++ b/chromium/content/public/common/previews_state.h
@@ -44,7 +44,9 @@ enum PreviewsTypes {
1 << 8, // Request that an offline page be used if one is stored.
LITE_PAGE_REDIRECT_ON = 1 << 9, // Allow the browser to redirect the resource
// to a Lite Page server.
- PREVIEWS_STATE_LAST = LITE_PAGE_REDIRECT_ON
+ LAZY_IMAGE_LOAD_DEFERRED = 1 << 10, // Request the placeholder version of an
+ // image that was deferred by lazyload.
+ PREVIEWS_STATE_LAST = LAZY_IMAGE_LOAD_DEFERRED
};
// Combination of all previews that are guaranteed not to provide partial
@@ -73,6 +75,8 @@ STATIC_ASSERT_PREVIEWS_ENUM(OFFLINE_PAGE_ON,
blink::WebURLRequest::kOfflinePageOn);
STATIC_ASSERT_PREVIEWS_ENUM(LITE_PAGE_REDIRECT_ON,
blink::WebURLRequest::kLitePageRedirectOn);
+STATIC_ASSERT_PREVIEWS_ENUM(LAZY_IMAGE_LOAD_DEFERRED,
+ blink::WebURLRequest::kLazyImageLoadDeferred);
STATIC_ASSERT_PREVIEWS_ENUM(PREVIEWS_STATE_LAST,
blink::WebURLRequest::kPreviewsStateLast);
diff --git a/chromium/content/public/common/renderer_preferences.cc b/chromium/content/public/common/renderer_preferences.cc
index 2f5c823d475..58ec6b482a9 100644
--- a/chromium/content/public/common/renderer_preferences.cc
+++ b/chromium/content/public/common/renderer_preferences.cc
@@ -19,9 +19,6 @@ RendererPreferences::RendererPreferences()
subpixel_rendering(gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE),
use_subpixel_positioning(false),
focus_ring_color(SkColorSetARGB(255, 229, 151, 0)),
- thumb_active_color(SkColorSetRGB(244, 244, 244)),
- thumb_inactive_color(SkColorSetRGB(234, 234, 234)),
- track_color(SkColorSetRGB(211, 211, 211)),
active_selection_bg_color(SkColorSetRGB(30, 144, 255)),
active_selection_fg_color(SK_ColorWHITE),
inactive_selection_bg_color(SkColorSetRGB(200, 200, 200)),
diff --git a/chromium/content/public/common/renderer_preferences.h b/chromium/content/public/common/renderer_preferences.h
index fa8c2cd5869..87ade6e7511 100644
--- a/chromium/content/public/common/renderer_preferences.h
+++ b/chromium/content/public/common/renderer_preferences.h
@@ -63,12 +63,6 @@ struct CONTENT_EXPORT RendererPreferences {
// The color of the focus ring. Currently only used on Linux.
SkColor focus_ring_color;
- // The color of different parts of the scrollbar. Currently only used on
- // Linux.
- SkColor thumb_active_color;
- SkColor thumb_inactive_color;
- SkColor track_color;
-
// The colors used in selection text. Currently only used on Linux and Ash.
SkColor active_selection_bg_color;
SkColor active_selection_fg_color;
diff --git a/chromium/content/public/common/request_context_type.h b/chromium/content/public/common/request_context_type.h
deleted file mode 100644
index 2a5a60ae814..00000000000
--- a/chromium/content/public/common/request_context_type.h
+++ /dev/null
@@ -1,50 +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_PUBLIC_COMMON_REQUEST_CONTEXT_TYPE_H_
-#define CONTENT_PUBLIC_COMMON_REQUEST_CONTEXT_TYPE_H_
-
-namespace content {
-
-enum RequestContextType {
- REQUEST_CONTEXT_TYPE_UNSPECIFIED = 0,
- REQUEST_CONTEXT_TYPE_AUDIO,
- REQUEST_CONTEXT_TYPE_BEACON,
- REQUEST_CONTEXT_TYPE_CSP_REPORT,
- REQUEST_CONTEXT_TYPE_DOWNLOAD,
- REQUEST_CONTEXT_TYPE_EMBED,
- REQUEST_CONTEXT_TYPE_EVENT_SOURCE,
- REQUEST_CONTEXT_TYPE_FAVICON,
- REQUEST_CONTEXT_TYPE_FETCH,
- REQUEST_CONTEXT_TYPE_FONT,
- REQUEST_CONTEXT_TYPE_FORM,
- REQUEST_CONTEXT_TYPE_FRAME,
- REQUEST_CONTEXT_TYPE_HYPERLINK,
- REQUEST_CONTEXT_TYPE_IFRAME,
- REQUEST_CONTEXT_TYPE_IMAGE,
- REQUEST_CONTEXT_TYPE_IMAGE_SET,
- REQUEST_CONTEXT_TYPE_IMPORT,
- REQUEST_CONTEXT_TYPE_INTERNAL,
- REQUEST_CONTEXT_TYPE_LOCATION,
- REQUEST_CONTEXT_TYPE_MANIFEST,
- REQUEST_CONTEXT_TYPE_OBJECT,
- REQUEST_CONTEXT_TYPE_PING,
- REQUEST_CONTEXT_TYPE_PLUGIN,
- REQUEST_CONTEXT_TYPE_PREFETCH,
- REQUEST_CONTEXT_TYPE_SCRIPT,
- REQUEST_CONTEXT_TYPE_SERVICE_WORKER,
- REQUEST_CONTEXT_TYPE_SHARED_WORKER,
- REQUEST_CONTEXT_TYPE_SUBRESOURCE,
- REQUEST_CONTEXT_TYPE_STYLE,
- REQUEST_CONTEXT_TYPE_TRACK,
- REQUEST_CONTEXT_TYPE_VIDEO,
- REQUEST_CONTEXT_TYPE_WORKER,
- REQUEST_CONTEXT_TYPE_XML_HTTP_REQUEST,
- REQUEST_CONTEXT_TYPE_XSLT,
- REQUEST_CONTEXT_TYPE_LAST = REQUEST_CONTEXT_TYPE_XSLT
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_COMMON_REQUEST_CONTEXT_TYPE_H_
diff --git a/chromium/content/public/common/url_utils.cc b/chromium/content/public/common/url_utils.cc
index fc44c56135a..b0a993802df 100644
--- a/chromium/content/public/common/url_utils.cc
+++ b/chromium/content/public/common/url_utils.cc
@@ -31,10 +31,7 @@ bool IsSavableURL(const GURL& url) {
return false;
}
-// PlzNavigate
bool IsURLHandledByNetworkStack(const GURL& url) {
- CHECK(IsBrowserSideNavigationEnabled());
-
// Javascript URLs, srcdoc, schemes that don't load data should not send a
// request to the network stack.
if (url.SchemeIs(url::kJavaScriptScheme) || url.is_empty() ||
@@ -117,8 +114,11 @@ bool IsRendererDebugURL(const GURL& url) {
bool IsSafeRedirectTarget(const GURL& from_url, const GURL& to_url) {
static base::NoDestructor<std::set<std::string>> kUnsafeSchemes(
std::set<std::string>({
- url::kAboutScheme, url::kDataScheme, url::kFileScheme,
- url::kFileSystemScheme,
+ url::kAboutScheme, url::kDataScheme, url::kFileScheme,
+ url::kFileSystemScheme,
+#if defined(OS_ANDROID)
+ url::kContentScheme,
+#endif
}));
if (HasWebUIScheme(to_url))
return false;
diff --git a/chromium/content/public/common/url_utils_unittest.cc b/chromium/content/public/common/url_utils_unittest.cc
index c7081cf0a13..30d08f05d46 100644
--- a/chromium/content/public/common/url_utils_unittest.cc
+++ b/chromium/content/public/common/url_utils_unittest.cc
@@ -4,37 +4,60 @@
#include "content/public/common/url_utils.h"
+#include "build/build_config.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace content {
+GURL CreateValidURL(const std::string& str) {
+ GURL url(str);
+ EXPECT_TRUE(url.is_valid()) << str;
+ return url;
+}
+
TEST(UrlUtilsTest, IsURLHandledByNetworkStack) {
- EXPECT_TRUE(IsURLHandledByNetworkStack(GURL("http://foo/bar.html")));
- EXPECT_TRUE(IsURLHandledByNetworkStack(GURL("https://foo/bar.html")));
- EXPECT_TRUE(IsURLHandledByNetworkStack(GURL("data://foo")));
- EXPECT_TRUE(IsURLHandledByNetworkStack(GURL("cid:foo@bar")));
-
- EXPECT_FALSE(IsURLHandledByNetworkStack(GURL("about:blank")));
- EXPECT_FALSE(IsURLHandledByNetworkStack(GURL("about:srcdoc")));
- EXPECT_FALSE(IsURLHandledByNetworkStack(GURL("javascript:foo.js")));
+ EXPECT_TRUE(
+ IsURLHandledByNetworkStack(CreateValidURL("http://foo/bar.html")));
+ EXPECT_TRUE(
+ IsURLHandledByNetworkStack(CreateValidURL("https://foo/bar.html")));
+ EXPECT_TRUE(IsURLHandledByNetworkStack(CreateValidURL("data://foo")));
+ EXPECT_TRUE(IsURLHandledByNetworkStack(CreateValidURL("cid:foo@bar")));
+
+ EXPECT_FALSE(IsURLHandledByNetworkStack(CreateValidURL("about:blank")));
+ EXPECT_FALSE(IsURLHandledByNetworkStack(CreateValidURL("about:srcdoc")));
+ EXPECT_FALSE(IsURLHandledByNetworkStack(CreateValidURL("javascript:foo.js")));
EXPECT_FALSE(IsURLHandledByNetworkStack(GURL()));
}
TEST(UrlUtilsTest, IsSafeRedirectTarget) {
- EXPECT_FALSE(IsSafeRedirectTarget(GURL(), GURL("chrome://foo/bar.html")));
- EXPECT_TRUE(IsSafeRedirectTarget(GURL(), GURL("http://foo/bar.html")));
- EXPECT_FALSE(IsSafeRedirectTarget(GURL(), GURL("file:///foo/bar/")));
+ EXPECT_FALSE(
+ IsSafeRedirectTarget(GURL(), CreateValidURL("chrome://foo/bar.html")));
+ EXPECT_TRUE(
+ IsSafeRedirectTarget(GURL(), CreateValidURL("http://foo/bar.html")));
+ EXPECT_FALSE(
+ IsSafeRedirectTarget(GURL(), CreateValidURL("file:///foo/bar/")));
+ EXPECT_FALSE(IsSafeRedirectTarget(GURL(), CreateValidURL("about:blank")));
+ EXPECT_FALSE(IsSafeRedirectTarget(
+ GURL(), CreateValidURL("filesystem:http://foo.com/bar")));
+ EXPECT_FALSE(
+ IsSafeRedirectTarget(GURL(), CreateValidURL("data:text/plain,foo")));
+#if defined(OS_ANDROID)
+ EXPECT_FALSE(
+ IsSafeRedirectTarget(GURL(), CreateValidURL("content://foo.bar")));
+#endif
+ EXPECT_TRUE(IsSafeRedirectTarget(CreateValidURL("file:///foo/bar"),
+ CreateValidURL("file:///foo/bar/")));
+ EXPECT_TRUE(
+ IsSafeRedirectTarget(CreateValidURL("filesystem:http://foo.com/bar"),
+ CreateValidURL("filesystem:http://foo.com/bar")));
EXPECT_TRUE(
- IsSafeRedirectTarget(GURL("file:///foo/bar"), GURL("file:///foo/bar/")));
- EXPECT_TRUE(IsSafeRedirectTarget(GURL("filesystem://foo/bar"),
- GURL("filesystem://foo/bar/")));
- EXPECT_TRUE(IsSafeRedirectTarget(GURL(), GURL("unknown://foo/bar/")));
- EXPECT_FALSE(IsSafeRedirectTarget(GURL("http://foo/bar.html"),
- GURL("file:///foo/bar/")));
- EXPECT_TRUE(IsSafeRedirectTarget(GURL("file:///foo/bar/"),
- GURL("http://foo/bar.html")));
+ IsSafeRedirectTarget(GURL(), CreateValidURL("unknown://foo/bar/")));
+ EXPECT_FALSE(IsSafeRedirectTarget(CreateValidURL("http://foo/bar.html"),
+ CreateValidURL("file:///foo/bar/")));
+ EXPECT_TRUE(IsSafeRedirectTarget(CreateValidURL("file:///foo/bar/"),
+ CreateValidURL("http://foo/bar.html")));
// TODO(cmumford): Capturing current behavior, but should probably prevent
// redirect to invalid URL.
diff --git a/chromium/content/public/common/use_zoom_for_dsf_policy.cc b/chromium/content/public/common/use_zoom_for_dsf_policy.cc
index 05be9f23b85..5519e07ebfa 100644
--- a/chromium/content/public/common/use_zoom_for_dsf_policy.cc
+++ b/chromium/content/public/common/use_zoom_for_dsf_policy.cc
@@ -21,7 +21,7 @@ const base::Feature kUseZoomForDsfEnabledByDefault{
#if defined(OS_ANDROID)
const base::Feature kUseZoomForDsfEnabledByDefault{
- "use-zoom-for-dsf enabled by default", base::FEATURE_DISABLED_BY_DEFAULT};
+ "use-zoom-for-dsf enabled by default", base::FEATURE_ENABLED_BY_DEFAULT};
#endif
bool IsUseZoomForDSFEnabledByDefault() {
diff --git a/chromium/content/public/common/user_agent.h b/chromium/content/public/common/user_agent.h
index fbd7f9f346c..651fcbd050e 100644
--- a/chromium/content/public/common/user_agent.h
+++ b/chromium/content/public/common/user_agent.h
@@ -34,7 +34,10 @@ CONTENT_EXPORT std::string BuildUserAgentFromProduct(
CONTENT_EXPORT std::string BuildUserAgentFromProductAndExtraOSInfo(
const std::string& product,
const std::string& extra_os_info,
- const bool include_android_build_number);
+ bool include_android_build_number);
+
+// Helper function to generate just the OS info.
+CONTENT_EXPORT std::string GetAndroidOSInfo(bool include_android_build_number);
#endif
// Builds a full user agent string given a string describing the OS and a
diff --git a/chromium/content/public/common/was_activated_option.h b/chromium/content/public/common/was_activated_option.h
new file mode 100644
index 00000000000..23b37bfbc66
--- /dev/null
+++ b/chromium/content/public/common/was_activated_option.h
@@ -0,0 +1,27 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_COMMON_WAS_ACTIVATED_OPTION_H_
+#define CONTENT_PUBLIC_COMMON_WAS_ACTIVATED_OPTION_H_
+
+namespace content {
+
+// Whether the navigation should propagate user activation. This can be
+// specified by embedders in NavigationController::LoadURLParams.
+enum class WasActivatedOption {
+ // The content layer should make a decision about whether to propagate user
+ // activation.
+ kUnknown,
+
+ // The navigation should propagate user activation.
+ kYes,
+
+ // The navigation should not propagate user activation.
+ kNo,
+ kMaxValue = kNo,
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_COMMON_WAS_ACTIVATED_OPTION_H_
diff --git a/chromium/content/public/common/web_contents_ns_view_bridge.mojom b/chromium/content/public/common/web_contents_ns_view_bridge.mojom
new file mode 100644
index 00000000000..abd85c2e64b
--- /dev/null
+++ b/chromium/content/public/common/web_contents_ns_view_bridge.mojom
@@ -0,0 +1,31 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.mojom;
+
+import "ui/gfx/geometry/mojo/geometry.mojom";
+
+// Interface through which a WebContentsViewMac communicates with its NSView in
+// another process.
+interface WebContentsNSViewBridge {
+ // Set this to be a child NSView of the NSView mapped to by
+ // |parent_ns_view_id|. In practice, this NSView will always be from a
+ // views::View.
+ SetParentViewsNSView(uint64 parent_ns_view_id);
+
+ // Un-hide the NSView and set its frame in its window to |bounds_in_window|.
+ Show(gfx.mojom.Rect bounds_in_window);
+
+ // Hide the NSView.
+ Hide();
+
+ // Make the NSView be the first responder for its window.
+ MakeFirstResponder();
+};
+
+// Interface through which the NSView in another process communicates with its
+// owning WebContentsViewMac. This interface has no methods yet, but is included
+// for symmetry and future use.
+interface WebContentsNSViewClient {};
+
diff --git a/chromium/content/public/common/web_preferences.cc b/chromium/content/public/common/web_preferences.cc
index bd8facb2d85..581c6666662 100644
--- a/chromium/content/public/common/web_preferences.cc
+++ b/chromium/content/public/common/web_preferences.cc
@@ -187,12 +187,15 @@ WebPreferences::WebPreferences()
user_gesture_required_for_presentation(true),
text_track_margin_percentage(0.0f),
immersive_mode_enabled(false),
+#if defined(OS_ANDROID) || defined(OS_MACOSX)
+ double_tap_to_zoom_enabled(true),
+#else
+ double_tap_to_zoom_enabled(false),
+#endif
#if !defined(OS_ANDROID)
text_autosizing_enabled(false),
- double_tap_to_zoom_enabled(false),
#else
text_autosizing_enabled(true),
- double_tap_to_zoom_enabled(true),
font_scale_factor(1.0f),
device_scale_adjustment(1.0f),
force_enable_zoom(false),
@@ -230,14 +233,15 @@ WebPreferences::WebPreferences()
default_maximum_page_scale_factor(4.f),
#endif
hide_download_ui(false),
- background_video_track_optimization_enabled(false),
presentation_receiver(false),
media_controls_enabled(true),
do_not_update_selection_on_mutating_selection_range(false),
autoplay_policy(AutoplayPolicy::kDocumentUserActivationRequired),
low_priority_iframes_threshold(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
picture_in_picture_enabled(true),
- translate_service_available(false) {
+ translate_service_available(false),
+ network_quality_estimator_web_holdback(
+ net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN) {
standard_font_family_map[kCommonScript] =
base::ASCIIToUTF16("Times New Roman");
fixed_font_family_map[kCommonScript] = base::ASCIIToUTF16("Courier New");
diff --git a/chromium/content/public/common/web_preferences.h b/chromium/content/public/common/web_preferences.h
index eba70c162af..c1881cb04ae 100644
--- a/chromium/content/public/common/web_preferences.h
+++ b/chromium/content/public/common/web_preferences.h
@@ -229,10 +229,10 @@ struct CONTENT_EXPORT WebPreferences {
bool immersive_mode_enabled;
- bool text_autosizing_enabled;
-
bool double_tap_to_zoom_enabled;
+ bool text_autosizing_enabled;
+
#if defined(OS_ANDROID)
float font_scale_factor;
float device_scale_adjustment;
@@ -286,9 +286,6 @@ struct CONTENT_EXPORT WebPreferences {
// Whether download UI should be hidden on this page.
bool hide_download_ui;
- // If enabled, disabled video track when the video is in the background.
- bool background_video_track_optimization_enabled;
-
// Whether it is a presentation receiver.
bool presentation_receiver;
@@ -305,7 +302,7 @@ struct CONTENT_EXPORT WebPreferences {
AutoplayPolicy autoplay_policy;
// Network quality threshold below which resources from iframes are assigned
- // lowest priority.
+ // either kVeryLow or kVeryLow Blink priority.
net::EffectiveConnectionType low_priority_iframes_threshold;
// Whether Picture-in-Picture is enabled.
@@ -316,6 +313,13 @@ struct CONTENT_EXPORT WebPreferences {
// See https://github.com/dtapuska/html-translate
bool translate_service_available;
+ // A value other than net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN implies that the
+ // network quality estimate related Web APIs are in the holdback mode. When
+ // the holdback is enabled, the related Web APIs return network quality
+ // estimate corresponding to |network_quality_estimator_web_holdback|
+ // regardless of the actual quality.
+ net::EffectiveConnectionType network_quality_estimator_web_holdback;
+
// Specifies how close a lazily loaded iframe or image should be from the
// viewport before it should start being loaded in, depending on the effective
// connection type of the current network. Blink will use the default distance
diff --git a/chromium/content/public/renderer/navigation_state.cc b/chromium/content/public/common/widget_type.h
index 1543da32dc3..15f13d563ff 100644
--- a/chromium/content/public/renderer/navigation_state.cc
+++ b/chromium/content/public/common/widget_type.h
@@ -2,10 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/public/renderer/navigation_state.h"
+#ifndef CONTENT_PUBLIC_COMMON_WIDGET_TYPE_H_
+#define CONTENT_PUBLIC_COMMON_WIDGET_TYPE_H_
namespace content {
-NavigationState::~NavigationState() {}
+enum class WidgetType { kFrame, kPopup };
} // namespace content
+
+#endif // CONTENT_PUBLIC_COMMON_WIDGET_TYPE_H_
diff --git a/chromium/content/public/renderer/BUILD.gn b/chromium/content/public/renderer/BUILD.gn
index eb312e8c256..91839ccfc0e 100644
--- a/chromium/content/public/renderer/BUILD.gn
+++ b/chromium/content/public/renderer/BUILD.gn
@@ -52,8 +52,6 @@ target(link_target_type, "renderer_sources") {
"media_stream_video_renderer.h",
"media_stream_video_sink.cc",
"media_stream_video_sink.h",
- "navigation_state.cc",
- "navigation_state.h",
"pepper_plugin_instance.h",
"plugin_instance_throttler.h",
"render_accessibility.h",
diff --git a/chromium/content/public/renderer/associated_resource_fetcher.h b/chromium/content/public/renderer/associated_resource_fetcher.h
index a8be013563e..004974cbb0c 100644
--- a/chromium/content/public/renderer/associated_resource_fetcher.h
+++ b/chromium/content/public/renderer/associated_resource_fetcher.h
@@ -60,7 +60,7 @@ class CONTENT_EXPORT AssociatedResourceFetcher {
// https://fetch.spec.whatwg.org/#concept-request-credentials-mode
virtual void Start(
blink::WebLocalFrame* frame,
- blink::WebURLRequest::RequestContext request_context,
+ blink::mojom::RequestContextType request_context,
network::mojom::FetchRequestMode fetch_request_mode,
network::mojom::FetchCredentialsMode fetch_credentials_mode,
network::mojom::RequestContextFrameType frame_type,
diff --git a/chromium/content/public/renderer/content_renderer_client.cc b/chromium/content/public/renderer/content_renderer_client.cc
index 84f90fab895..668f54b52ee 100644
--- a/chromium/content/public/renderer/content_renderer_client.cc
+++ b/chromium/content/public/renderer/content_renderer_client.cc
@@ -24,7 +24,7 @@ SkBitmap* ContentRendererClient::GetSadWebViewBitmap() {
return nullptr;
}
-bool ContentRendererClient::IsPluginHandledByMimeHandlerView(
+bool ContentRendererClient::MaybeCreateMimeHandlerView(
RenderFrame* embedder_frame,
const blink::WebElement& owner_element,
const GURL& original_url,
@@ -113,10 +113,6 @@ bool ContentRendererClient::HandleNavigation(
bool is_redirect) {
return false;
}
-
-bool ContentRendererClient::ShouldUseMediaPlayerForURL(const GURL& url) {
- return false;
-}
#endif
bool ContentRendererClient::ShouldFork(blink::WebLocalFrame* frame,
@@ -170,10 +166,6 @@ bool ContentRendererClient::IsOriginIsolatedPepperPlugin(
return false;
}
-bool ContentRendererClient::AllowPepperMediaStreamAPI(const GURL& url) {
- return false;
-}
-
void ContentRendererClient::AddSupportedKeySystems(
std::vector<std::unique_ptr<media::KeySystemProperties>>* key_systems) {}
@@ -244,6 +236,11 @@ bool ContentRendererClient::ShouldEnforceWebRTCRoutingPreferences() {
return true;
}
+base::Optional<std::string>
+ContentRendererClient::WebRTCPlatformSpecificAudioProcessingConfiguration() {
+ return base::Optional<std::string>();
+}
+
GURL ContentRendererClient::OverrideFlashEmbedWithHTML(const GURL& url) {
return GURL();
}
diff --git a/chromium/content/public/renderer/content_renderer_client.h b/chromium/content/public/renderer/content_renderer_client.h
index f1c9cc5997c..3166cbe259d 100644
--- a/chromium/content/public/renderer/content_renderer_client.h
+++ b/chromium/content/public/renderer/content_renderer_client.h
@@ -15,6 +15,7 @@
#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
+#include "base/optional.h"
#include "base/strings/string16.h"
#include "base/task/task_scheduler/task_scheduler.h"
#include "build/build_config.h"
@@ -90,7 +91,7 @@ class CONTENT_EXPORT ContentRendererClient {
// Returns true if the embedder renders the contents of the |plugin_element|
// in a cross-process frame using MimeHandlerView.
- virtual bool IsPluginHandledByMimeHandlerView(
+ virtual bool MaybeCreateMimeHandlerView(
RenderFrame* embedder_frame,
const blink::WebElement& plugin_element,
const GURL& original_url,
@@ -221,10 +222,6 @@ class CONTENT_EXPORT ContentRendererClient {
blink::WebNavigationType type,
blink::WebNavigationPolicy default_policy,
bool is_redirect);
-
- // Indicates if the Android MediaPlayer should be used instead of Chrome's
- // built in media player for the given |url|. Defaults to false.
- virtual bool ShouldUseMediaPlayerForURL(const GURL& url);
#endif
// Returns true if we should fork a new process for the given navigation.
@@ -272,9 +269,6 @@ class CONTENT_EXPORT ContentRendererClient {
// language.
virtual bool IsOriginIsolatedPepperPlugin(const base::FilePath& plugin_path);
- // Returns true if the page at |url| can use Pepper MediaStream APIs.
- virtual bool AllowPepperMediaStreamAPI(const GURL& url);
-
// Allows an embedder to provide a MediaStreamRendererFactory.
virtual std::unique_ptr<MediaStreamRendererFactory>
CreateMediaStreamRendererFactory();
@@ -359,6 +353,13 @@ class CONTENT_EXPORT ContentRendererClient {
const GURL& service_worker_scope,
const GURL& script_url) {}
+ // Notifies that a service worker context has finished executing its top-level
+ // JavaScript. This function is called from the worker thread.
+ virtual void DidStartServiceWorkerContextOnWorkerThread(
+ int64_t service_worker_version_id,
+ const GURL& service_worker_scope,
+ const GURL& script_url) {}
+
// Notifies that a service worker context will be destroyed. This function
// is called from the worker thread.
virtual void WillDestroyServiceWorkerContextOnWorkerThread(
@@ -378,6 +379,14 @@ class CONTENT_EXPORT ContentRendererClient {
// routing logic, i.e. allowing multiple routes and non-proxied UDP.
virtual bool ShouldEnforceWebRTCRoutingPreferences();
+ // Provides a default configuration of WebRTC audio processing, in JSON format
+ // with fields corresponding to webrtc::AudioProcessing::Config. Allows for a
+ // more functional tuning on platforms with known implementation and hardware
+ // limitations.
+ // This is currently not supported when running the Chrome audio service.
+ virtual base::Optional<std::string>
+ WebRTCPlatformSpecificAudioProcessingConfiguration();
+
// Notifies that a worker context has been created. This function is called
// from the worker thread.
virtual void DidInitializeWorkerContextOnWorkerThread(
diff --git a/chromium/content/public/renderer/document_state.cc b/chromium/content/public/renderer/document_state.cc
index 283e0d89e06..88e4a354459 100644
--- a/chromium/content/public/renderer/document_state.cc
+++ b/chromium/content/public/renderer/document_state.cc
@@ -4,8 +4,6 @@
#include "content/public/renderer/document_state.h"
-#include "content/public/renderer/navigation_state.h"
-
namespace content {
DocumentState::DocumentState()
@@ -18,8 +16,19 @@ DocumentState::DocumentState()
DocumentState::~DocumentState() {}
-void DocumentState::set_navigation_state(NavigationState* navigation_state) {
- navigation_state_.reset(navigation_state);
+std::unique_ptr<DocumentState> DocumentState::Clone() {
+ std::unique_ptr<DocumentState> new_document_state(new DocumentState());
+ new_document_state->set_was_fetched_via_spdy(was_fetched_via_spdy_);
+ new_document_state->set_was_alpn_negotiated(was_alpn_negotiated_);
+ new_document_state->set_alpn_negotiated_protocol(alpn_negotiated_protocol_);
+ new_document_state->set_was_alternate_protocol_available(
+ was_alternate_protocol_available_);
+ new_document_state->set_connection_info(connection_info_);
+ new_document_state->set_was_load_data_with_base_url_request(
+ was_load_data_with_base_url_request_);
+ new_document_state->set_data_url(data_url_);
+ new_document_state->set_can_load_local_resources(can_load_local_resources_);
+ return new_document_state;
}
} // namespace content
diff --git a/chromium/content/public/renderer/document_state.h b/chromium/content/public/renderer/document_state.h
index b1548b97051..e8d715be759 100644
--- a/chromium/content/public/renderer/document_state.h
+++ b/chromium/content/public/renderer/document_state.h
@@ -18,8 +18,6 @@
namespace content {
-class NavigationState;
-
// The RenderView stores an instance of this class in the "extra data" of each
// WebDocumentLoader (see RenderView::DidCreateDataSource).
class CONTENT_EXPORT DocumentState : public blink::WebDocumentLoader::ExtraData,
@@ -33,6 +31,10 @@ class CONTENT_EXPORT DocumentState : public blink::WebDocumentLoader::ExtraData,
return static_cast<DocumentState*>(document_loader->GetExtraData());
}
+ // Returns a copy of the DocumentState. This is a shallow copy,
+ // user data is not copied.
+ std::unique_ptr<DocumentState> Clone();
+
// Indicator if SPDY was used as part of this page load.
bool was_fetched_via_spdy() const { return was_fetched_via_spdy_; }
void set_was_fetched_via_spdy(bool value) { was_fetched_via_spdy_ = value; }
@@ -79,9 +81,6 @@ class CONTENT_EXPORT DocumentState : public blink::WebDocumentLoader::ExtraData,
data_url_ = data_url;
}
- NavigationState* navigation_state() { return navigation_state_.get(); }
- void set_navigation_state(NavigationState* navigation_state);
-
bool can_load_local_resources() const { return can_load_local_resources_; }
void set_can_load_local_resources(bool can_load) {
can_load_local_resources_ = can_load;
@@ -97,8 +96,6 @@ class CONTENT_EXPORT DocumentState : public blink::WebDocumentLoader::ExtraData,
bool was_load_data_with_base_url_request_;
GURL data_url_;
- std::unique_ptr<NavigationState> navigation_state_;
-
bool can_load_local_resources_;
};
diff --git a/chromium/content/public/renderer/navigation_state.h b/chromium/content/public/renderer/navigation_state.h
deleted file mode 100644
index 10432c1547d..00000000000
--- a/chromium/content/public/renderer/navigation_state.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_RENDERER_NAVIGATION_STATE_H_
-#define CONTENT_PUBLIC_RENDERER_NAVIGATION_STATE_H_
-
-#include <string>
-
-#include "content/common/content_export.h"
-#include "ui/base/page_transition_types.h"
-
-namespace content {
-
-// NavigationState is the portion of DocumentState that is affected by
-// in-document navigation.
-// TODO(simonjam): Move this to HistoryItem's ExtraData.
-class CONTENT_EXPORT NavigationState {
- public:
- virtual ~NavigationState();
-
- // Contains the transition type that the browser specified when it
- // initiated the load.
- virtual ui::PageTransition GetTransitionType() = 0;
-
- // True iff the frame's navigation was within the same document.
- virtual bool WasWithinSameDocument() = 0;
-
- // True if this navigation was not initiated via WebFrame::LoadRequest.
- virtual bool IsContentInitiated() = 0;
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_RENDERER_NAVIGATION_STATE_H
diff --git a/chromium/content/public/renderer/render_frame.h b/chromium/content/public/renderer/render_frame.h
index 292a3abb701..77df96a4485 100644
--- a/chromium/content/public/renderer/render_frame.h
+++ b/chromium/content/public/renderer/render_frame.h
@@ -24,7 +24,7 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/web/web_navigation_policy.h"
#include "third_party/blink/public/web/web_triggering_event_info.h"
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
namespace blink {
class AssociatedInterfaceProvider;
diff --git a/chromium/content/public/renderer/render_frame_observer.h b/chromium/content/public/renderer/render_frame_observer.h
index 88efca34d57..ce1f26c0ab1 100644
--- a/chromium/content/public/renderer/render_frame_observer.h
+++ b/chromium/content/public/renderer/render_frame_observer.h
@@ -21,6 +21,7 @@
#include "third_party/blink/public/platform/web_loading_behavior_flag.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_meaningful_layout.h"
+#include "ui/base/page_transition_types.h"
#include "v8/include/v8.h"
namespace blink {
@@ -72,13 +73,15 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
// Called when a provisional load is about to commit in a frame. This is
// dispatched just before the Javascript unload event.
virtual void WillCommitProvisionalLoad() {}
- virtual void DidCommitProvisionalLoad(bool is_new_navigation,
- bool is_same_document_navigation) {}
+ virtual void DidCommitProvisionalLoad(bool is_same_document_navigation,
+ ui::PageTransition transition) {}
virtual void DidStartProvisionalLoad(
- blink::WebDocumentLoader* document_loader) {}
+ blink::WebDocumentLoader* document_loader,
+ bool is_content_initiated) {}
virtual void DidFailProvisionalLoad(const blink::WebURLError& error) {}
virtual void DidFinishLoad() {}
virtual void DidFinishDocumentLoad() {}
+ virtual void DidHandleOnloadEvents() {}
virtual void DidCreateScriptContext(v8::Local<v8::Context> context,
int world_id) {}
virtual void WillReleaseScriptContext(v8::Local<v8::Context> context,
diff --git a/chromium/content/public/renderer/render_thread.h b/chromium/content/public/renderer/render_thread.h
index 13f0d61c008..2376a114671 100644
--- a/chromium/content/public/renderer/render_thread.h
+++ b/chromium/content/public/renderer/render_thread.h
@@ -83,17 +83,6 @@ class CONTENT_EXPORT RenderThread : virtual public ChildThread {
// Registers the given V8 extension with WebKit.
virtual void RegisterExtension(v8::Extension* extension) = 0;
- // Schedule a call to IdleHandler with the given initial delay.
- virtual void ScheduleIdleHandler(int64_t initial_delay_ms) = 0;
-
- // A task we invoke periodically to assist with idle cleanup.
- virtual void IdleHandler() = 0;
-
- // Get/Set the delay for how often the idle handler is called.
- virtual int64_t GetIdleNotificationDelayInMs() const = 0;
- virtual void SetIdleNotificationDelayInMs(
- int64_t idle_notification_delay_in_ms) = 0;
-
// Post task to all worker threads. Returns number of workers.
virtual int PostTaskToAllWebWorkers(const base::Closure& closure) = 0;
@@ -108,6 +97,10 @@ class CONTENT_EXPORT RenderThread : virtual public ChildThread {
// Retrieve the process ID of the browser process.
virtual int32_t GetClientId() = 0;
+ // Get the online status of the browser - false when there is no network
+ // access.
+ virtual bool IsOnline() = 0;
+
// Set the renderer process type.
virtual void SetRendererProcessType(
blink::scheduler::RendererProcessType type) = 0;
diff --git a/chromium/content/public/renderer/render_view.h b/chromium/content/public/renderer/render_view.h
index 21f3b487f13..4e5b9c88691 100644
--- a/chromium/content/public/renderer/render_view.h
+++ b/chromium/content/public/renderer/render_view.h
@@ -106,7 +106,7 @@ class CONTENT_EXPORT RenderView : public IPC::Sender {
// Returns |renderer_preferences_.accept_languages| value.
virtual const std::string& GetAcceptLanguages() const = 0;
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
virtual void UpdateBrowserControlsState(BrowserControlsState constraints,
BrowserControlsState current,
bool animate) = 0;
diff --git a/chromium/content/public/renderer/render_view_observer.h b/chromium/content/public/renderer/render_view_observer.h
index 4c54de570b8..3eb08a31072 100644
--- a/chromium/content/public/renderer/render_view_observer.h
+++ b/chromium/content/public/renderer/render_view_observer.h
@@ -35,8 +35,6 @@ class CONTENT_EXPORT RenderViewObserver : public IPC::Listener,
virtual void OnDestruct() = 0;
// These match the WebKit API notifications
- virtual void DidStartLoading() {}
- virtual void DidStopLoading() {}
virtual void DidFailProvisionalLoad(blink::WebLocalFrame* frame,
const blink::WebURLError& error) {}
virtual void DidCommitProvisionalLoad(blink::WebLocalFrame* frame,
diff --git a/chromium/content/public/renderer/resource_fetcher.h b/chromium/content/public/renderer/resource_fetcher.h
index aabd44a609b..101c703ea40 100644
--- a/chromium/content/public/renderer/resource_fetcher.h
+++ b/chromium/content/public/renderer/resource_fetcher.h
@@ -64,7 +64,7 @@ class CONTENT_EXPORT ResourceFetcher {
// done.
virtual void Start(
blink::WebLocalFrame* frame,
- blink::WebURLRequest::RequestContext request_context,
+ blink::mojom::RequestContextType request_context,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
const net::NetworkTrafficAnnotationTag& annotation_tag,
Callback callback,
diff --git a/chromium/content/public/test/android/BUILD.gn b/chromium/content/public/test/android/BUILD.gn
index baae99c22c0..2bc36ac4c10 100644
--- a/chromium/content/public/test/android/BUILD.gn
+++ b/chromium/content/public/test/android/BUILD.gn
@@ -4,7 +4,7 @@ import("//build/config/android/rules.gni")
generate_jni("test_support_content_jni_headers") {
jni_package = "content/public/test"
sources = [
- "javatests/src/org/chromium/content/browser/test/NestedSystemMessageHandler.java",
+ "javatests/src/org/chromium/content_public/browser/test/NestedSystemMessageHandler.java",
]
}
@@ -13,7 +13,7 @@ android_library("layouttest_java_support") {
deps = [
"//base:base_java",
]
- java_files = [ "javatests/src/org/chromium/content/browser/test/NestedSystemMessageHandler.java" ]
+ java_files = [ "javatests/src/org/chromium/content_public/browser/test/NestedSystemMessageHandler.java" ]
}
android_library("content_java_test_support") {
@@ -29,32 +29,32 @@ android_library("content_java_test_support") {
"//ui/android:ui_java_test_support",
]
java_files = [
- "javatests/src/org/chromium/content/browser/test/ChildProcessAllocatorSettings.java",
- "javatests/src/org/chromium/content/browser/test/ChildProcessAllocatorSettingsHook.java",
- "javatests/src/org/chromium/content/browser/test/ContentJUnit4ClassRunner.java",
- "javatests/src/org/chromium/content/browser/test/InterstitialPageDelegateAndroid.java",
- "javatests/src/org/chromium/content/browser/test/NativeLibraryTestRule.java",
- "javatests/src/org/chromium/content/browser/test/RenderFrameHostTestExt.java",
- "javatests/src/org/chromium/content/browser/test/mock/MockRenderFrameHost.java",
- "javatests/src/org/chromium/content/browser/test/mock/MockWebContents.java",
- "javatests/src/org/chromium/content/browser/test/util/ClickUtils.java",
- "javatests/src/org/chromium/content/browser/test/util/Coordinates.java",
- "javatests/src/org/chromium/content/browser/test/util/Criteria.java",
- "javatests/src/org/chromium/content/browser/test/util/CriteriaHelper.java",
- "javatests/src/org/chromium/content/browser/test/util/DOMUtils.java",
- "javatests/src/org/chromium/content/browser/test/util/EqualityCriteria.java",
- "javatests/src/org/chromium/content/browser/test/util/HistoryUtils.java",
- "javatests/src/org/chromium/content/browser/test/util/JavaScriptUtils.java",
- "javatests/src/org/chromium/content/browser/test/util/KeyUtils.java",
- "javatests/src/org/chromium/content/browser/test/util/RenderProcessLimit.java",
- "javatests/src/org/chromium/content/browser/test/util/TestCallbackHelperContainer.java",
- "javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java",
- "javatests/src/org/chromium/content/browser/test/util/TestSelectionPopupController.java",
- "javatests/src/org/chromium/content/browser/test/util/TestTouchUtils.java",
- "javatests/src/org/chromium/content/browser/test/util/TestWebContentsObserver.java",
- "javatests/src/org/chromium/content/browser/test/util/TouchCommon.java",
- "javatests/src/org/chromium/content/browser/test/util/UiUtils.java",
- "javatests/src/org/chromium/content/browser/test/util/WebContentsUtils.java",
+ "javatests/src/org/chromium/content_public/browser/test/ChildProcessAllocatorSettings.java",
+ "javatests/src/org/chromium/content_public/browser/test/ChildProcessAllocatorSettingsHook.java",
+ "javatests/src/org/chromium/content_public/browser/test/ContentJUnit4ClassRunner.java",
+ "javatests/src/org/chromium/content_public/browser/test/InterstitialPageDelegateAndroid.java",
+ "javatests/src/org/chromium/content_public/browser/test/NativeLibraryTestRule.java",
+ "javatests/src/org/chromium/content_public/browser/test/RenderFrameHostTestExt.java",
+ "javatests/src/org/chromium/content_public/browser/test/mock/MockRenderFrameHost.java",
+ "javatests/src/org/chromium/content_public/browser/test/mock/MockWebContents.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/ClickUtils.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/Coordinates.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/Criteria.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/CriteriaHelper.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/DOMUtils.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/EqualityCriteria.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/HistoryUtils.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/JavaScriptUtils.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/KeyUtils.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/RenderProcessLimit.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/TestCallbackHelperContainer.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/TestInputMethodManagerWrapper.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/TestSelectionPopupController.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/TestTouchUtils.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/TestWebContentsObserver.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/TouchCommon.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/UiUtils.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/WebContentsUtils.java",
]
}
@@ -62,10 +62,10 @@ generate_jni("content_test_jni") {
testonly = true
jni_package = "content/public/test"
sources = [
- "javatests/src/org/chromium/content/browser/test/InterstitialPageDelegateAndroid.java",
- "javatests/src/org/chromium/content/browser/test/RenderFrameHostTestExt.java",
- "javatests/src/org/chromium/content/browser/test/util/DOMUtils.java",
- "javatests/src/org/chromium/content/browser/test/util/WebContentsUtils.java",
+ "javatests/src/org/chromium/content_public/browser/test/InterstitialPageDelegateAndroid.java",
+ "javatests/src/org/chromium/content_public/browser/test/RenderFrameHostTestExt.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/DOMUtils.java",
+ "javatests/src/org/chromium/content_public/browser/test/util/WebContentsUtils.java",
]
}
diff --git a/chromium/content/renderer/BUILD.gn b/chromium/content/renderer/BUILD.gn
index 0efc1738743..0ec5a2752d5 100644
--- a/chromium/content/renderer/BUILD.gn
+++ b/chromium/content/renderer/BUILD.gn
@@ -109,22 +109,10 @@ target(link_target_type, "renderer") {
"fetchers/multi_resolution_image_resource_fetcher.h",
"fetchers/resource_fetcher_impl.cc",
"fetchers/resource_fetcher_impl.h",
- "file_info_util.cc",
- "file_info_util.h",
- "fileapi/file_system_dispatcher.cc",
- "fileapi/file_system_dispatcher.h",
- "fileapi/webfilesystem_impl.cc",
- "fileapi/webfilesystem_impl.h",
- "fileapi/webfilewriter_base.cc",
- "fileapi/webfilewriter_base.h",
- "fileapi/webfilewriter_impl.cc",
- "fileapi/webfilewriter_impl.h",
"frame_blame_context.cc",
"frame_blame_context.h",
"frame_owner_properties.cc",
"frame_owner_properties.h",
- "gpu/actions_parser.cc",
- "gpu/actions_parser.h",
"gpu/compositor_dependencies.h",
"gpu/frame_swap_message_queue.cc",
"gpu/frame_swap_message_queue.h",
@@ -141,8 +129,6 @@ target(link_target_type, "renderer") {
"history_entry.h",
"history_serialization.cc",
"history_serialization.h",
- "idle_user_detector.cc",
- "idle_user_detector.h",
"image_capture/image_capture_frame_grabber.cc",
"image_capture/image_capture_frame_grabber.h",
"image_downloader/image_downloader_base.cc",
@@ -483,8 +469,8 @@ target(link_target_type, "renderer") {
"mouse_lock_dispatcher.h",
"navigation_client.cc",
"navigation_client.h",
- "navigation_state_impl.cc",
- "navigation_state_impl.h",
+ "navigation_state.cc",
+ "navigation_state.h",
"net_info_helper.cc",
"net_info_helper.h",
"notifications/notification_data_conversions.cc",
@@ -532,7 +518,6 @@ target(link_target_type, "renderer") {
"render_thread_impl.h",
"render_view_impl.cc",
"render_view_impl.h",
- "render_view_impl_android.cc",
"render_view_linux.cc",
"render_view_win.cc",
"render_widget.cc",
@@ -586,12 +571,6 @@ target(link_target_type, "renderer") {
"service_worker/service_worker_type_converters.h",
"service_worker/service_worker_type_util.cc",
"service_worker/service_worker_type_util.h",
- "service_worker/thread_safe_script_container.cc",
- "service_worker/thread_safe_script_container.h",
- "service_worker/web_service_worker_impl.cc",
- "service_worker/web_service_worker_impl.h",
- "service_worker/web_service_worker_installed_scripts_manager_impl.cc",
- "service_worker/web_service_worker_installed_scripts_manager_impl.h",
"service_worker/web_service_worker_provider_impl.cc",
"service_worker/web_service_worker_provider_impl.h",
"service_worker/web_service_worker_registration_impl.cc",
@@ -608,8 +587,6 @@ target(link_target_type, "renderer") {
"skia_benchmarking_extension.h",
"stats_collection_controller.cc",
"stats_collection_controller.h",
- "stats_collection_observer.cc",
- "stats_collection_observer.h",
"storage_util.cc",
"storage_util.h",
"text_input_client_observer.cc",
@@ -732,6 +709,8 @@ target(link_target_type, "renderer") {
"//third_party/webrtc/api:libjingle_logging_api",
"//third_party/webrtc/api:libjingle_peerconnection_api",
"//third_party/webrtc/api:rtc_stats_api",
+ "//third_party/webrtc/api/audio:aec3_config",
+ "//third_party/webrtc/api/audio:aec3_config_json",
"//third_party/webrtc/api/audio:aec3_factory",
"//third_party/webrtc/api/audio_codecs:audio_codecs_api",
"//third_party/webrtc/api/audio_codecs/L16:audio_decoder_L16",
@@ -766,6 +745,7 @@ target(link_target_type, "renderer") {
"//third_party/webrtc/pc:rtc_pc_base",
"//third_party/webrtc/rtc_base:rtc_base",
"//third_party/webrtc/rtc_base:rtc_task_queue",
+ "//third_party/webrtc/rtc_base:timeutils",
# TODO(titovartem) remove dependency on WebRTC internals.
"//third_party/webrtc/rtc_base/third_party/sigslot:sigslot",
@@ -844,20 +824,12 @@ target(link_target_type, "renderer") {
if (enable_plugins) {
sources += [
- "media/pepper/pepper_to_video_track_adapter.cc",
- "media/pepper/pepper_to_video_track_adapter.h",
- "media/pepper/video_track_to_pepper_adapter.cc",
- "media/pepper/video_track_to_pepper_adapter.h",
"pepper/pepper_media_stream_audio_track_host.cc",
"pepper/pepper_media_stream_audio_track_host.h",
"pepper/pepper_media_stream_track_host_base.cc",
"pepper/pepper_media_stream_track_host_base.h",
"pepper/pepper_media_stream_video_track_host.cc",
"pepper/pepper_media_stream_video_track_host.h",
- "pepper/pepper_video_destination_host.cc",
- "pepper/pepper_video_destination_host.h",
- "pepper/pepper_video_source_host.cc",
- "pepper/pepper_video_source_host.h",
]
}
diff --git a/chromium/content/renderer/OWNERS b/chromium/content/renderer/OWNERS
index 13765f89ba8..63ad4d38d60 100644
--- a/chromium/content/renderer/OWNERS
+++ b/chromium/content/renderer/OWNERS
@@ -1,3 +1,4 @@
+dcheng@chromium.org
haraken@chromium.org
# These are for the common case of adding or renaming files. If you're doing
diff --git a/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc b/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc
index d51402b4d1a..a9972bae118 100644
--- a/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc
+++ b/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc
@@ -8,6 +8,24 @@
namespace content {
+ax::mojom::TextStyle AXTextStyleFromBlink(blink::WebAXTextStyle text_style) {
+ uint32_t browser_text_style =
+ static_cast<uint32_t>(ax::mojom::TextStyle::kNone);
+ if (text_style & blink::kWebAXTextStyleBold)
+ browser_text_style |=
+ static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleBold);
+ if (text_style & blink::kWebAXTextStyleItalic)
+ browser_text_style |=
+ static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleItalic);
+ if (text_style & blink::kWebAXTextStyleUnderline)
+ browser_text_style |=
+ static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleUnderline);
+ if (text_style & blink::kWebAXTextStyleLineThrough)
+ browser_text_style |=
+ static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleLineThrough);
+ return static_cast<ax::mojom::TextStyle>(browser_text_style);
+}
+
void AXStateFromBlink(const blink::WebAXObject& o, ui::AXNodeData* dst) {
blink::WebAXExpanded expanded = o.IsExpanded();
if (expanded) {
@@ -20,9 +38,9 @@ void AXStateFromBlink(const blink::WebAXObject& o, ui::AXNodeData* dst) {
if (o.CanSetFocusAttribute())
dst->AddState(ax::mojom::State::kFocusable);
- if (o.HasPopup())
- dst->SetHasPopup(AXHasPopupFromBlink(o.HasPopup()));
- else if (o.Role() == blink::kWebAXRolePopUpButton)
+ if (o.HasPopup() != ax::mojom::HasPopup::kFalse)
+ dst->SetHasPopup(o.HasPopup());
+ else if (o.Role() == ax::mojom::Role::kPopUpButton)
dst->SetHasPopup(ax::mojom::HasPopup::kMenu);
if (o.IsAutofillAvailable())
@@ -72,656 +90,4 @@ void AXStateFromBlink(const blink::WebAXObject& o, ui::AXNodeData* dst) {
dst->AddState(ax::mojom::State::kVisited);
}
-ax::mojom::Role AXRoleFromBlink(blink::WebAXRole role) {
- switch (role) {
- case blink::kWebAXRoleAbbr:
- return ax::mojom::Role::kAbbr;
- case blink::kWebAXRoleAlert:
- return ax::mojom::Role::kAlert;
- case blink::kWebAXRoleAlertDialog:
- return ax::mojom::Role::kAlertDialog;
- case blink::kWebAXRoleAnchor:
- return ax::mojom::Role::kAnchor;
- case blink::kWebAXRoleAnnotation:
- return ax::mojom::Role::kAnnotation;
- case blink::kWebAXRoleApplication:
- return ax::mojom::Role::kApplication;
- case blink::kWebAXRoleArticle:
- return ax::mojom::Role::kArticle;
- case blink::kWebAXRoleAudio:
- return ax::mojom::Role::kAudio;
- case blink::kWebAXRoleBanner:
- return ax::mojom::Role::kBanner;
- case blink::kWebAXRoleBlockquote:
- return ax::mojom::Role::kBlockquote;
- case blink::kWebAXRoleButton:
- return ax::mojom::Role::kButton;
- case blink::kWebAXRoleCanvas:
- return ax::mojom::Role::kCanvas;
- case blink::kWebAXRoleCaption:
- return ax::mojom::Role::kCaption;
- case blink::kWebAXRoleCell:
- return ax::mojom::Role::kCell;
- case blink::kWebAXRoleCheckBox:
- return ax::mojom::Role::kCheckBox;
- case blink::kWebAXRoleColorWell:
- return ax::mojom::Role::kColorWell;
- case blink::kWebAXRoleColumn:
- return ax::mojom::Role::kColumn;
- case blink::kWebAXRoleColumnHeader:
- return ax::mojom::Role::kColumnHeader;
- case blink::kWebAXRoleComboBoxGrouping:
- return ax::mojom::Role::kComboBoxGrouping;
- case blink::kWebAXRoleComboBoxMenuButton:
- return ax::mojom::Role::kComboBoxMenuButton;
- case blink::kWebAXRoleComplementary:
- return ax::mojom::Role::kComplementary;
- case blink::kWebAXRoleContentDeletion:
- return ax::mojom::Role::kContentDeletion;
- case blink::kWebAXRoleContentInsertion:
- return ax::mojom::Role::kContentInsertion;
- case blink::kWebAXRoleContentInfo:
- return ax::mojom::Role::kContentInfo;
- case blink::kWebAXRoleDate:
- return ax::mojom::Role::kDate;
- case blink::kWebAXRoleDateTime:
- return ax::mojom::Role::kDateTime;
- case blink::kWebAXRoleDefinition:
- return ax::mojom::Role::kDefinition;
- case blink::kWebAXRoleDescriptionListDetail:
- return ax::mojom::Role::kDescriptionListDetail;
- case blink::kWebAXRoleDescriptionList:
- return ax::mojom::Role::kDescriptionList;
- case blink::kWebAXRoleDescriptionListTerm:
- return ax::mojom::Role::kDescriptionListTerm;
- case blink::kWebAXRoleDetails:
- return ax::mojom::Role::kDetails;
- case blink::kWebAXRoleDialog:
- return ax::mojom::Role::kDialog;
- case blink::kWebAXRoleDirectory:
- return ax::mojom::Role::kDirectory;
- case blink::kWebAXRoleDisclosureTriangle:
- return ax::mojom::Role::kDisclosureTriangle;
- case blink::kWebAXRoleDocAbstract:
- return ax::mojom::Role::kDocAbstract;
- case blink::kWebAXRoleDocAcknowledgments:
- return ax::mojom::Role::kDocAcknowledgments;
- case blink::kWebAXRoleDocAfterword:
- return ax::mojom::Role::kDocAfterword;
- case blink::kWebAXRoleDocAppendix:
- return ax::mojom::Role::kDocAppendix;
- case blink::kWebAXRoleDocBackLink:
- return ax::mojom::Role::kDocBackLink;
- case blink::kWebAXRoleDocBiblioEntry:
- return ax::mojom::Role::kDocBiblioEntry;
- case blink::kWebAXRoleDocBibliography:
- return ax::mojom::Role::kDocBibliography;
- case blink::kWebAXRoleDocBiblioRef:
- return ax::mojom::Role::kDocBiblioRef;
- case blink::kWebAXRoleDocChapter:
- return ax::mojom::Role::kDocChapter;
- case blink::kWebAXRoleDocColophon:
- return ax::mojom::Role::kDocColophon;
- case blink::kWebAXRoleDocConclusion:
- return ax::mojom::Role::kDocConclusion;
- case blink::kWebAXRoleDocCover:
- return ax::mojom::Role::kDocCover;
- case blink::kWebAXRoleDocCredit:
- return ax::mojom::Role::kDocCredit;
- case blink::kWebAXRoleDocCredits:
- return ax::mojom::Role::kDocCredits;
- case blink::kWebAXRoleDocDedication:
- return ax::mojom::Role::kDocDedication;
- case blink::kWebAXRoleDocEndnote:
- return ax::mojom::Role::kDocEndnote;
- case blink::kWebAXRoleDocEndnotes:
- return ax::mojom::Role::kDocEndnotes;
- case blink::kWebAXRoleDocEpigraph:
- return ax::mojom::Role::kDocEpigraph;
- case blink::kWebAXRoleDocEpilogue:
- return ax::mojom::Role::kDocEpilogue;
- case blink::kWebAXRoleDocErrata:
- return ax::mojom::Role::kDocErrata;
- case blink::kWebAXRoleDocExample:
- return ax::mojom::Role::kDocExample;
- case blink::kWebAXRoleDocFootnote:
- return ax::mojom::Role::kDocFootnote;
- case blink::kWebAXRoleDocForeword:
- return ax::mojom::Role::kDocForeword;
- case blink::kWebAXRoleDocGlossary:
- return ax::mojom::Role::kDocGlossary;
- case blink::kWebAXRoleDocGlossRef:
- return ax::mojom::Role::kDocGlossRef;
- case blink::kWebAXRoleDocIndex:
- return ax::mojom::Role::kDocIndex;
- case blink::kWebAXRoleDocIntroduction:
- return ax::mojom::Role::kDocIntroduction;
- case blink::kWebAXRoleDocNoteRef:
- return ax::mojom::Role::kDocNoteRef;
- case blink::kWebAXRoleDocNotice:
- return ax::mojom::Role::kDocNotice;
- case blink::kWebAXRoleDocPageBreak:
- return ax::mojom::Role::kDocPageBreak;
- case blink::kWebAXRoleDocPageList:
- return ax::mojom::Role::kDocPageList;
- case blink::kWebAXRoleDocPart:
- return ax::mojom::Role::kDocPart;
- case blink::kWebAXRoleDocPreface:
- return ax::mojom::Role::kDocPreface;
- case blink::kWebAXRoleDocPrologue:
- return ax::mojom::Role::kDocPrologue;
- case blink::kWebAXRoleDocPullquote:
- return ax::mojom::Role::kDocPullquote;
- case blink::kWebAXRoleDocQna:
- return ax::mojom::Role::kDocQna;
- case blink::kWebAXRoleDocSubtitle:
- return ax::mojom::Role::kDocSubtitle;
- case blink::kWebAXRoleDocTip:
- return ax::mojom::Role::kDocTip;
- case blink::kWebAXRoleDocToc:
- return ax::mojom::Role::kDocToc;
- case blink::kWebAXRoleDocument:
- return ax::mojom::Role::kDocument;
- case blink::kWebAXRoleEmbeddedObject:
- return ax::mojom::Role::kEmbeddedObject;
- case blink::kWebAXRoleFeed:
- return ax::mojom::Role::kFeed;
- case blink::kWebAXRoleFigcaption:
- return ax::mojom::Role::kFigcaption;
- case blink::kWebAXRoleFigure:
- return ax::mojom::Role::kFigure;
- case blink::kWebAXRoleFooter:
- return ax::mojom::Role::kFooter;
- case blink::kWebAXRoleForm:
- return ax::mojom::Role::kForm;
- case blink::kWebAXRoleGenericContainer:
- return ax::mojom::Role::kGenericContainer;
- case blink::kWebAXRoleGraphicsDocument:
- return ax::mojom::Role::kGraphicsDocument;
- case blink::kWebAXRoleGraphicsObject:
- return ax::mojom::Role::kGraphicsObject;
- case blink::kWebAXRoleGraphicsSymbol:
- return ax::mojom::Role::kGraphicsSymbol;
- case blink::kWebAXRoleGrid:
- return ax::mojom::Role::kGrid;
- case blink::kWebAXRoleGroup:
- return ax::mojom::Role::kGroup;
- case blink::kWebAXRoleHeading:
- return ax::mojom::Role::kHeading;
- case blink::kWebAXRoleIframe:
- return ax::mojom::Role::kIframe;
- case blink::kWebAXRoleIframePresentational:
- return ax::mojom::Role::kIframePresentational;
- case blink::kWebAXRoleIgnored:
- return ax::mojom::Role::kIgnored;
- case blink::kWebAXRoleImage:
- return ax::mojom::Role::kImage;
- case blink::kWebAXRoleImageMap:
- return ax::mojom::Role::kImageMap;
- case blink::kWebAXRoleInlineTextBox:
- return ax::mojom::Role::kInlineTextBox;
- case blink::kWebAXRoleInputTime:
- return ax::mojom::Role::kInputTime;
- case blink::kWebAXRoleLabel:
- return ax::mojom::Role::kLabelText;
- case blink::kWebAXRoleLayoutTable:
- return ax::mojom::Role::kLayoutTable;
- case blink::kWebAXRoleLayoutTableCell:
- return ax::mojom::Role::kLayoutTableCell;
- case blink::kWebAXRoleLayoutTableColumn:
- return ax::mojom::Role::kLayoutTableColumn;
- case blink::kWebAXRoleLayoutTableRow:
- return ax::mojom::Role::kLayoutTableRow;
- case blink::kWebAXRoleLegend:
- return ax::mojom::Role::kLegend;
- case blink::kWebAXRoleLink:
- return ax::mojom::Role::kLink;
- case blink::kWebAXRoleList:
- return ax::mojom::Role::kList;
- case blink::kWebAXRoleListBox:
- return ax::mojom::Role::kListBox;
- case blink::kWebAXRoleListBoxOption:
- return ax::mojom::Role::kListBoxOption;
- case blink::kWebAXRoleListItem:
- return ax::mojom::Role::kListItem;
- case blink::kWebAXRoleListMarker:
- return ax::mojom::Role::kListMarker;
- case blink::kWebAXRoleLog:
- return ax::mojom::Role::kLog;
- case blink::kWebAXRoleMain:
- return ax::mojom::Role::kMain;
- case blink::kWebAXRoleMarquee:
- return ax::mojom::Role::kMarquee;
- case blink::kWebAXRoleMark:
- return ax::mojom::Role::kMark;
- case blink::kWebAXRoleMath:
- return ax::mojom::Role::kMath;
- case blink::kWebAXRoleMenu:
- return ax::mojom::Role::kMenu;
- case blink::kWebAXRoleMenuBar:
- return ax::mojom::Role::kMenuBar;
- case blink::kWebAXRoleMenuButton:
- return ax::mojom::Role::kMenuButton;
- case blink::kWebAXRoleMenuItem:
- return ax::mojom::Role::kMenuItem;
- case blink::kWebAXRoleMenuItemCheckBox:
- return ax::mojom::Role::kMenuItemCheckBox;
- case blink::kWebAXRoleMenuItemRadio:
- return ax::mojom::Role::kMenuItemRadio;
- case blink::kWebAXRoleMenuListOption:
- return ax::mojom::Role::kMenuListOption;
- case blink::kWebAXRoleMenuListPopup:
- return ax::mojom::Role::kMenuListPopup;
- case blink::kWebAXRoleMeter:
- return ax::mojom::Role::kMeter;
- case blink::kWebAXRoleNavigation:
- return ax::mojom::Role::kNavigation;
- case blink::kWebAXRoleNone:
- return ax::mojom::Role::kNone;
- case blink::kWebAXRoleNote:
- return ax::mojom::Role::kNote;
- case blink::kWebAXRoleParagraph:
- return ax::mojom::Role::kParagraph;
- case blink::kWebAXRolePopUpButton:
- return ax::mojom::Role::kPopUpButton;
- case blink::kWebAXRolePre:
- return ax::mojom::Role::kPre;
- case blink::kWebAXRolePresentational:
- return ax::mojom::Role::kPresentational;
- case blink::kWebAXRoleProgressIndicator:
- return ax::mojom::Role::kProgressIndicator;
- case blink::kWebAXRoleRadioButton:
- return ax::mojom::Role::kRadioButton;
- case blink::kWebAXRoleRadioGroup:
- return ax::mojom::Role::kRadioGroup;
- case blink::kWebAXRoleRegion:
- return ax::mojom::Role::kRegion;
- case blink::kWebAXRoleRow:
- return ax::mojom::Role::kRow;
- case blink::kWebAXRoleRuby:
- return ax::mojom::Role::kRuby;
- case blink::kWebAXRoleRowHeader:
- return ax::mojom::Role::kRowHeader;
- case blink::kWebAXRoleSVGRoot:
- return ax::mojom::Role::kSvgRoot;
- case blink::kWebAXRoleScrollBar:
- return ax::mojom::Role::kScrollBar;
- case blink::kWebAXRoleSearch:
- return ax::mojom::Role::kSearch;
- case blink::kWebAXRoleSearchBox:
- return ax::mojom::Role::kSearchBox;
- case blink::kWebAXRoleSlider:
- return ax::mojom::Role::kSlider;
- case blink::kWebAXRoleSliderThumb:
- return ax::mojom::Role::kSliderThumb;
- case blink::kWebAXRoleSpinButton:
- return ax::mojom::Role::kSpinButton;
- case blink::kWebAXRoleSplitter:
- return ax::mojom::Role::kSplitter;
- case blink::kWebAXRoleStaticText:
- return ax::mojom::Role::kStaticText;
- case blink::kWebAXRoleStatus:
- return ax::mojom::Role::kStatus;
- case blink::kWebAXRoleSwitch:
- return ax::mojom::Role::kSwitch;
- case blink::kWebAXRoleTab:
- return ax::mojom::Role::kTab;
- case blink::kWebAXRoleTabList:
- return ax::mojom::Role::kTabList;
- case blink::kWebAXRoleTabPanel:
- return ax::mojom::Role::kTabPanel;
- case blink::kWebAXRoleTable:
- return ax::mojom::Role::kTable;
- case blink::kWebAXRoleTableHeaderContainer:
- return ax::mojom::Role::kTableHeaderContainer;
- case blink::kWebAXRoleTerm:
- return ax::mojom::Role::kTerm;
- case blink::kWebAXRoleTextField:
- return ax::mojom::Role::kTextField;
- case blink::kWebAXRoleTextFieldWithComboBox:
- return ax::mojom::Role::kTextFieldWithComboBox;
- case blink::kWebAXRoleTime:
- return ax::mojom::Role::kTime;
- case blink::kWebAXRoleTimer:
- return ax::mojom::Role::kTimer;
- case blink::kWebAXRoleToggleButton:
- return ax::mojom::Role::kToggleButton;
- case blink::kWebAXRoleToolbar:
- return ax::mojom::Role::kToolbar;
- case blink::kWebAXRoleTree:
- return ax::mojom::Role::kTree;
- case blink::kWebAXRoleTreeGrid:
- return ax::mojom::Role::kTreeGrid;
- case blink::kWebAXRoleTreeItem:
- return ax::mojom::Role::kTreeItem;
- case blink::kWebAXRoleUnknown:
- return ax::mojom::Role::kUnknown;
- case blink::kWebAXRoleUserInterfaceTooltip:
- return ax::mojom::Role::kTooltip;
- case blink::kWebAXRoleVideo:
- return ax::mojom::Role::kVideo;
- case blink::kWebAXRoleWebArea:
- return ax::mojom::Role::kRootWebArea;
- case blink::kWebAXRoleLineBreak:
- return ax::mojom::Role::kLineBreak;
- default:
- return ax::mojom::Role::kUnknown;
- }
-}
-
-ax::mojom::Event AXEventFromBlink(blink::WebAXEvent event) {
- switch (event) {
- case blink::kWebAXEventActiveDescendantChanged:
- return ax::mojom::Event::kActiveDescendantChanged;
- case blink::kWebAXEventAriaAttributeChanged:
- return ax::mojom::Event::kAriaAttributeChanged;
- case blink::kWebAXEventAutocorrectionOccured:
- return ax::mojom::Event::kAutocorrectionOccured;
- case blink::kWebAXEventBlur:
- return ax::mojom::Event::kBlur;
- case blink::kWebAXEventCheckedStateChanged:
- return ax::mojom::Event::kCheckedStateChanged;
- case blink::kWebAXEventChildrenChanged:
- return ax::mojom::Event::kChildrenChanged;
- case blink::kWebAXEventClicked:
- return ax::mojom::Event::kClicked;
- case blink::kWebAXEventDocumentSelectionChanged:
- return ax::mojom::Event::kDocumentSelectionChanged;
- case blink::kWebAXEventDocumentTitleChanged:
- return ax::mojom::Event::kDocumentTitleChanged;
- case blink::kWebAXEventExpandedChanged:
- return ax::mojom::Event::kExpandedChanged;
- case blink::kWebAXEventFocus:
- return ax::mojom::Event::kFocus;
- case blink::kWebAXEventHover:
- return ax::mojom::Event::kHover;
- case blink::kWebAXEventInvalidStatusChanged:
- return ax::mojom::Event::kInvalidStatusChanged;
- case blink::kWebAXEventLayoutComplete:
- return ax::mojom::Event::kLayoutComplete;
- case blink::kWebAXEventLiveRegionChanged:
- return ax::mojom::Event::kLiveRegionChanged;
- case blink::kWebAXEventLoadComplete:
- return ax::mojom::Event::kLoadComplete;
- case blink::kWebAXEventLocationChanged:
- return ax::mojom::Event::kLocationChanged;
- case blink::kWebAXEventMenuListItemSelected:
- return ax::mojom::Event::kMenuListItemSelected;
- case blink::kWebAXEventMenuListItemUnselected:
- return ax::mojom::Event::kMenuListItemSelected;
- case blink::kWebAXEventMenuListValueChanged:
- return ax::mojom::Event::kMenuListValueChanged;
- case blink::kWebAXEventRowCollapsed:
- return ax::mojom::Event::kRowCollapsed;
- case blink::kWebAXEventRowCountChanged:
- return ax::mojom::Event::kRowCountChanged;
- case blink::kWebAXEventRowExpanded:
- return ax::mojom::Event::kRowExpanded;
- case blink::kWebAXEventScrollPositionChanged:
- return ax::mojom::Event::kScrollPositionChanged;
- case blink::kWebAXEventScrolledToAnchor:
- return ax::mojom::Event::kScrolledToAnchor;
- case blink::kWebAXEventSelectedChildrenChanged:
- return ax::mojom::Event::kSelectedChildrenChanged;
- case blink::kWebAXEventSelectedTextChanged:
- return ax::mojom::Event::kTextSelectionChanged;
- case blink::kWebAXEventTextChanged:
- return ax::mojom::Event::kTextChanged;
- case blink::kWebAXEventValueChanged:
- return ax::mojom::Event::kValueChanged;
- default:
- // We can't add an assertion here, that prevents us
- // from adding new event enums in Blink.
- return ax::mojom::Event::kNone;
- }
-}
-
-ax::mojom::DefaultActionVerb AXDefaultActionVerbFromBlink(
- blink::WebAXDefaultActionVerb action_verb) {
- switch (action_verb) {
- case blink::WebAXDefaultActionVerb::kNone:
- return ax::mojom::DefaultActionVerb::kNone;
- case blink::WebAXDefaultActionVerb::kActivate:
- return ax::mojom::DefaultActionVerb::kActivate;
- case blink::WebAXDefaultActionVerb::kCheck:
- return ax::mojom::DefaultActionVerb::kCheck;
- case blink::WebAXDefaultActionVerb::kClick:
- return ax::mojom::DefaultActionVerb::kClick;
- case blink::WebAXDefaultActionVerb::kClickAncestor:
- return ax::mojom::DefaultActionVerb::kClickAncestor;
- case blink::WebAXDefaultActionVerb::kJump:
- return ax::mojom::DefaultActionVerb::kJump;
- case blink::WebAXDefaultActionVerb::kOpen:
- return ax::mojom::DefaultActionVerb::kOpen;
- case blink::WebAXDefaultActionVerb::kPress:
- return ax::mojom::DefaultActionVerb::kPress;
- case blink::WebAXDefaultActionVerb::kSelect:
- return ax::mojom::DefaultActionVerb::kSelect;
- case blink::WebAXDefaultActionVerb::kUncheck:
- return ax::mojom::DefaultActionVerb::kUncheck;
- }
- NOTREACHED();
- return ax::mojom::DefaultActionVerb::kNone;
-}
-
-ax::mojom::MarkerType AXMarkerTypeFromBlink(
- blink::WebAXMarkerType marker_type) {
- switch (marker_type) {
- case blink::kWebAXMarkerTypeSpelling:
- return ax::mojom::MarkerType::kSpelling;
- case blink::kWebAXMarkerTypeGrammar:
- return ax::mojom::MarkerType::kGrammar;
- case blink::kWebAXMarkerTypeTextMatch:
- return ax::mojom::MarkerType::kTextMatch;
- case blink::kWebAXMarkerTypeActiveSuggestion:
- return ax::mojom::MarkerType::kActiveSuggestion;
- case blink::kWebAXMarkerTypeSuggestion:
- return ax::mojom::MarkerType::kSuggestion;
- }
- NOTREACHED();
- return ax::mojom::MarkerType::kNone;
-}
-
-ax::mojom::TextDirection AXTextDirectionFromBlink(
- blink::WebAXTextDirection text_direction) {
- switch (text_direction) {
- case blink::kWebAXTextDirectionLR:
- return ax::mojom::TextDirection::kLtr;
- case blink::kWebAXTextDirectionRL:
- return ax::mojom::TextDirection::kRtl;
- case blink::kWebAXTextDirectionTB:
- return ax::mojom::TextDirection::kTtb;
- case blink::kWebAXTextDirectionBT:
- return ax::mojom::TextDirection::kBtt;
- }
- NOTREACHED();
- return ax::mojom::TextDirection::kNone;
-}
-
-ax::mojom::TextPosition AXTextPositionFromBlink(
- blink::WebAXTextPosition text_position) {
- switch (text_position) {
- case blink::kWebAXTextPositionNone:
- return ax::mojom::TextPosition::kNone;
- case blink::kWebAXTextPositionSubscript:
- return ax::mojom::TextPosition::kSubscript;
- case blink::kWebAXTextPositionSuperscript:
- return ax::mojom::TextPosition::kSuperscript;
- }
- NOTREACHED();
- return ax::mojom::TextPosition::kNone;
-}
-
-ax::mojom::TextStyle AXTextStyleFromBlink(blink::WebAXTextStyle text_style) {
- uint32_t browser_text_style =
- static_cast<uint32_t>(ax::mojom::TextStyle::kNone);
- if (text_style & blink::kWebAXTextStyleBold)
- browser_text_style |=
- static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleBold);
- if (text_style & blink::kWebAXTextStyleItalic)
- browser_text_style |=
- static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleItalic);
- if (text_style & blink::kWebAXTextStyleUnderline)
- browser_text_style |=
- static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleUnderline);
- if (text_style & blink::kWebAXTextStyleLineThrough)
- browser_text_style |=
- static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleLineThrough);
- return static_cast<ax::mojom::TextStyle>(browser_text_style);
-}
-
-ax::mojom::AriaCurrentState AXAriaCurrentStateFromBlink(
- blink::WebAXAriaCurrentState aria_current_state) {
- switch (aria_current_state) {
- case blink::kWebAXAriaCurrentStateUndefined:
- return ax::mojom::AriaCurrentState::kNone;
- case blink::kWebAXAriaCurrentStateFalse:
- return ax::mojom::AriaCurrentState::kFalse;
- case blink::kWebAXAriaCurrentStateTrue:
- return ax::mojom::AriaCurrentState::kTrue;
- case blink::kWebAXAriaCurrentStatePage:
- return ax::mojom::AriaCurrentState::kPage;
- case blink::kWebAXAriaCurrentStateStep:
- return ax::mojom::AriaCurrentState::kStep;
- case blink::kWebAXAriaCurrentStateLocation:
- return ax::mojom::AriaCurrentState::kLocation;
- case blink::kWebAXAriaCurrentStateDate:
- return ax::mojom::AriaCurrentState::kDate;
- case blink::kWebAXAriaCurrentStateTime:
- return ax::mojom::AriaCurrentState::kTime;
- }
-
- NOTREACHED();
- return ax::mojom::AriaCurrentState::kNone;
-}
-
-ax::mojom::HasPopup AXHasPopupFromBlink(blink::WebAXHasPopup has_popup) {
- switch (has_popup) {
- case blink::kWebAXHasPopupFalse:
- return ax::mojom::HasPopup::kFalse;
- case blink::kWebAXHasPopupTrue:
- return ax::mojom::HasPopup::kTrue;
- case blink::kWebAXHasPopupMenu:
- return ax::mojom::HasPopup::kMenu;
- case blink::kWebAXHasPopupListbox:
- return ax::mojom::HasPopup::kListbox;
- case blink::kWebAXHasPopupTree:
- return ax::mojom::HasPopup::kTree;
- case blink::kWebAXHasPopupGrid:
- return ax::mojom::HasPopup::kGrid;
- case blink::kWebAXHasPopupDialog:
- return ax::mojom::HasPopup::kDialog;
- }
-
- NOTREACHED();
- return ax::mojom::HasPopup::kFalse;
-}
-
-ax::mojom::InvalidState AXInvalidStateFromBlink(
- blink::WebAXInvalidState invalid_state) {
- switch (invalid_state) {
- case blink::kWebAXInvalidStateUndefined:
- return ax::mojom::InvalidState::kNone;
- case blink::kWebAXInvalidStateFalse:
- return ax::mojom::InvalidState::kFalse;
- case blink::kWebAXInvalidStateTrue:
- return ax::mojom::InvalidState::kTrue;
- case blink::kWebAXInvalidStateSpelling:
- return ax::mojom::InvalidState::kSpelling;
- case blink::kWebAXInvalidStateGrammar:
- return ax::mojom::InvalidState::kGrammar;
- case blink::kWebAXInvalidStateOther:
- return ax::mojom::InvalidState::kOther;
- }
- NOTREACHED();
- return ax::mojom::InvalidState::kNone;
-}
-
-ax::mojom::CheckedState AXCheckedStateFromBlink(
- blink::WebAXCheckedState checked_state) {
- switch (checked_state) {
- case blink::kWebAXCheckedUndefined:
- return ax::mojom::CheckedState::kNone;
- case blink::kWebAXCheckedTrue:
- return ax::mojom::CheckedState::kTrue;
- case blink::kWebAXCheckedMixed:
- return ax::mojom::CheckedState::kMixed;
- case blink::kWebAXCheckedFalse:
- return ax::mojom::CheckedState::kFalse;
- }
- NOTREACHED();
- return ax::mojom::CheckedState::kNone;
-}
-
-ax::mojom::SortDirection AXSortDirectionFromBlink(
- blink::WebAXSortDirection sort_direction) {
- switch (sort_direction) {
- case blink::kWebAXSortDirectionUndefined:
- return ax::mojom::SortDirection::kNone;
- case blink::kWebAXSortDirectionNone:
- return ax::mojom::SortDirection::kUnsorted;
- case blink::kWebAXSortDirectionAscending:
- return ax::mojom::SortDirection::kAscending;
- case blink::kWebAXSortDirectionDescending:
- return ax::mojom::SortDirection::kDescending;
- case blink::kWebAXSortDirectionOther:
- return ax::mojom::SortDirection::kOther;
- }
- NOTREACHED();
- return ax::mojom::SortDirection::kNone;
-}
-
-ax::mojom::NameFrom AXNameFromFromBlink(blink::WebAXNameFrom name_from) {
- switch (name_from) {
- case blink::kWebAXNameFromUninitialized:
- return ax::mojom::NameFrom::kUninitialized;
- case blink::kWebAXNameFromAttribute:
- return ax::mojom::NameFrom::kAttribute;
- case blink::kWebAXNameFromAttributeExplicitlyEmpty:
- return ax::mojom::NameFrom::kAttributeExplicitlyEmpty;
- case blink::kWebAXNameFromCaption:
- return ax::mojom::NameFrom::kRelatedElement;
- case blink::kWebAXNameFromContents:
- return ax::mojom::NameFrom::kContents;
- case blink::kWebAXNameFromPlaceholder:
- return ax::mojom::NameFrom::kPlaceholder;
- case blink::kWebAXNameFromRelatedElement:
- return ax::mojom::NameFrom::kRelatedElement;
- case blink::kWebAXNameFromValue:
- return ax::mojom::NameFrom::kValue;
- case blink::kWebAXNameFromTitle:
- return ax::mojom::NameFrom::kAttribute;
- }
- NOTREACHED();
- return ax::mojom::NameFrom::kNone;
-}
-
-ax::mojom::DescriptionFrom AXDescriptionFromFromBlink(
- blink::WebAXDescriptionFrom description_from) {
- switch (description_from) {
- case blink::kWebAXDescriptionFromUninitialized:
- return ax::mojom::DescriptionFrom::kUninitialized;
- case blink::kWebAXDescriptionFromAttribute:
- return ax::mojom::DescriptionFrom::kAttribute;
- case blink::kWebAXDescriptionFromContents:
- return ax::mojom::DescriptionFrom::kContents;
- case blink::kWebAXDescriptionFromRelatedElement:
- return ax::mojom::DescriptionFrom::kRelatedElement;
- }
- NOTREACHED();
- return ax::mojom::DescriptionFrom::kNone;
-}
-
-ax::mojom::TextAffinity AXTextAffinityFromBlink(
- blink::WebAXTextAffinity affinity) {
- switch (affinity) {
- case blink::kWebAXTextAffinityUpstream:
- return ax::mojom::TextAffinity::kUpstream;
- case blink::kWebAXTextAffinityDownstream:
- return ax::mojom::TextAffinity::kDownstream;
- }
- NOTREACHED();
- return ax::mojom::TextAffinity::kDownstream;
-}
-
} // namespace content.
diff --git a/chromium/content/renderer/accessibility/blink_ax_enum_conversion.h b/chromium/content/renderer/accessibility/blink_ax_enum_conversion.h
index 0c543f2789e..4ad3f48e2f0 100644
--- a/chromium/content/renderer/accessibility/blink_ax_enum_conversion.h
+++ b/chromium/content/renderer/accessibility/blink_ax_enum_conversion.h
@@ -13,12 +13,7 @@
namespace content {
-// Convert a Blink WebAXRole to an ax::mojom::Role defined in ui/accessibility.
-ax::mojom::Role AXRoleFromBlink(blink::WebAXRole role);
-
-// Convert a Blink WebAXEvent to an ax::mojom::Event defined in
-// ui/accessibility.
-ax::mojom::Event AXEventFromBlink(blink::WebAXEvent event);
+ax::mojom::TextStyle AXTextStyleFromBlink(blink::WebAXTextStyle text_style);
// Provides a conversion between the WebAXObject state
// accessors and a state bitmask stored in an AXNodeData.
@@ -26,41 +21,6 @@ ax::mojom::Event AXEventFromBlink(blink::WebAXEvent event);
// in AXNodeData instead.)
void AXStateFromBlink(const blink::WebAXObject& o, ui::AXNodeData* dst);
-ax::mojom::DefaultActionVerb AXDefaultActionVerbFromBlink(
- blink::WebAXDefaultActionVerb action_verb);
-
-ax::mojom::MarkerType AXMarkerTypeFromBlink(blink::WebAXMarkerType marker_type);
-
-ax::mojom::TextDirection AXTextDirectionFromBlink(
- blink::WebAXTextDirection text_direction);
-
-ax::mojom::TextPosition AXTextPositionFromBlink(
- blink::WebAXTextPosition text_position);
-
-ax::mojom::TextStyle AXTextStyleFromBlink(blink::WebAXTextStyle text_style);
-
-ax::mojom::AriaCurrentState AXAriaCurrentStateFromBlink(
- blink::WebAXAriaCurrentState aria_current_state);
-
-ax::mojom::HasPopup AXHasPopupFromBlink(blink::WebAXHasPopup has_popup);
-
-ax::mojom::InvalidState AXInvalidStateFromBlink(
- blink::WebAXInvalidState invalid_state);
-
-ax::mojom::CheckedState AXCheckedStateFromBlink(
- blink::WebAXCheckedState checked_state);
-
-ax::mojom::SortDirection AXSortDirectionFromBlink(
- blink::WebAXSortDirection sort_direction);
-
-ax::mojom::NameFrom AXNameFromFromBlink(blink::WebAXNameFrom name_from);
-
-ax::mojom::DescriptionFrom AXDescriptionFromFromBlink(
- blink::WebAXDescriptionFrom description_from);
-
-ax::mojom::TextAffinity AXTextAffinityFromBlink(
- blink::WebAXTextAffinity affinity);
-
} // namespace content
#endif // CONTENT_RENDERER_ACCESSIBILITY_BLINK_AX_ENUM_CONVERSION_H_
diff --git a/chromium/content/renderer/accessibility/blink_ax_tree_source.cc b/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
index 6a5030c35d3..02f57f39a2e 100644
--- a/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -321,7 +321,7 @@ bool BlinkAXTreeSource::GetTreeData(AXContentTreeData* tree_data) const {
WebAXObject anchor_object, focus_object;
int anchor_offset, focus_offset;
- blink::WebAXTextAffinity anchor_affinity, focus_affinity;
+ ax::mojom::TextAffinity anchor_affinity, focus_affinity;
root().Selection(anchor_object, anchor_offset, anchor_affinity, focus_object,
focus_offset, focus_affinity);
if (!anchor_object.IsNull() && !focus_object.IsNull() && anchor_offset >= 0 &&
@@ -332,8 +332,8 @@ bool BlinkAXTreeSource::GetTreeData(AXContentTreeData* tree_data) const {
tree_data->sel_anchor_offset = anchor_offset;
tree_data->sel_focus_object_id = focus_id;
tree_data->sel_focus_offset = focus_offset;
- tree_data->sel_anchor_affinity = AXTextAffinityFromBlink(anchor_affinity);
- tree_data->sel_focus_affinity = AXTextAffinityFromBlink(focus_affinity);
+ tree_data->sel_anchor_affinity = anchor_affinity;
+ tree_data->sel_focus_affinity = focus_affinity;
}
// Get the tree ID for this frame and the parent frame.
@@ -373,8 +373,8 @@ void BlinkAXTreeSource::GetChildren(
std::vector<WebAXObject>* out_children) const {
CHECK(frozen_);
- if ((parent.Role() == blink::kWebAXRoleStaticText ||
- parent.Role() == blink::kWebAXRoleLineBreak) &&
+ if ((parent.Role() == ax::mojom::Role::kStaticText ||
+ parent.Role() == ax::mojom::Role::kLineBreak) &&
ShouldLoadInlineTextBoxes(parent)) {
parent.LoadInlineTextBoxes();
}
@@ -398,9 +398,9 @@ void BlinkAXTreeSource::GetChildren(
// Skip table headers and columns, they're only needed on Mac
// and soon we'll get rid of this code entirely.
- if (child.Role() == blink::kWebAXRoleColumn ||
- child.Role() == blink::kWebAXRoleLayoutTableColumn ||
- child.Role() == blink::kWebAXRoleTableHeaderContainer)
+ if (child.Role() == ax::mojom::Role::kColumn ||
+ child.Role() == ax::mojom::Role::kLayoutTableColumn ||
+ child.Role() == ax::mojom::Role::kTableHeaderContainer)
continue;
out_children->push_back(child);
@@ -436,7 +436,7 @@ WebAXObject BlinkAXTreeSource::GetNull() const {
void BlinkAXTreeSource::SerializeNode(WebAXObject src,
AXContentNodeData* dst) const {
- dst->role = AXRoleFromBlink(src.Role());
+ dst->role = src.Role();
AXStateFromBlink(src, dst);
dst->id = src.AxID();
@@ -476,28 +476,27 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
AXContentNodeDataSparseAttributeAdapter sparse_attribute_adapter(dst);
src.GetSparseAXAttributes(sparse_attribute_adapter);
- blink::WebAXNameFrom nameFrom;
+ ax::mojom::NameFrom nameFrom;
blink::WebVector<WebAXObject> nameObjects;
blink::WebString web_name = src.GetName(nameFrom, nameObjects);
if ((!web_name.IsEmpty() && !web_name.IsNull()) ||
- nameFrom == blink::kWebAXNameFromAttributeExplicitlyEmpty) {
+ nameFrom == ax::mojom::NameFrom::kAttributeExplicitlyEmpty) {
TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kName,
web_name.Utf8());
- dst->SetNameFrom(AXNameFromFromBlink(nameFrom));
+ dst->SetNameFrom(nameFrom);
AddIntListAttributeFromWebObjects(
ax::mojom::IntListAttribute::kLabelledbyIds, nameObjects, dst);
}
- blink::WebAXDescriptionFrom descriptionFrom;
+ ax::mojom::DescriptionFrom descriptionFrom;
blink::WebVector<WebAXObject> descriptionObjects;
blink::WebString web_description =
src.Description(nameFrom, descriptionFrom, descriptionObjects);
if (!web_description.IsEmpty()) {
TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kDescription,
web_description.Utf8());
- dst->AddIntAttribute(
- ax::mojom::IntAttribute::kDescriptionFrom,
- static_cast<int32_t>(AXDescriptionFromFromBlink(descriptionFrom)));
+ dst->AddIntAttribute(ax::mojom::IntAttribute::kDescriptionFrom,
+ static_cast<int32_t>(descriptionFrom));
AddIntListAttributeFromWebObjects(
ax::mojom::IntListAttribute::kDescribedbyIds, descriptionObjects, dst);
}
@@ -577,39 +576,36 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
dst->AddFloatAttribute(ax::mojom::FloatAttribute::kFontSize,
src.FontSize());
- if (src.HasPopup())
- dst->SetHasPopup(AXHasPopupFromBlink(src.HasPopup()));
- else if (src.Role() == blink::kWebAXRolePopUpButton)
+ if (src.HasPopup() != ax::mojom::HasPopup::kFalse)
+ dst->SetHasPopup(src.HasPopup());
+ else if (src.Role() == ax::mojom::Role::kPopUpButton)
dst->SetHasPopup(ax::mojom::HasPopup::kMenu);
- if (src.AriaCurrentState()) {
+ if (src.AriaCurrentState() != ax::mojom::AriaCurrentState::kNone) {
dst->AddIntAttribute(ax::mojom::IntAttribute::kAriaCurrentState,
- static_cast<int32_t>(AXAriaCurrentStateFromBlink(
- src.AriaCurrentState())));
+ static_cast<int32_t>(src.AriaCurrentState()));
}
- if (src.InvalidState()) {
- dst->SetInvalidState(AXInvalidStateFromBlink(src.InvalidState()));
- }
- if (src.InvalidState() == blink::kWebAXInvalidStateOther &&
+ if (src.InvalidState() != ax::mojom::InvalidState::kNone)
+ dst->SetInvalidState(src.InvalidState());
+ if (src.InvalidState() == ax::mojom::InvalidState::kOther &&
src.AriaInvalidValue().length()) {
TruncateAndAddStringAttribute(
dst, ax::mojom::StringAttribute::kAriaInvalidValue,
src.AriaInvalidValue().Utf8());
}
- if (src.CheckedState()) {
- dst->SetCheckedState(AXCheckedStateFromBlink(src.CheckedState()));
+ if (src.CheckedState() != ax::mojom::CheckedState::kNone) {
+ dst->SetCheckedState(src.CheckedState());
}
- if (src.GetTextDirection()) {
- dst->SetTextDirection(AXTextDirectionFromBlink(src.GetTextDirection()));
+ if (src.GetTextDirection() != ax::mojom::TextDirection::kNone) {
+ dst->SetTextDirection(src.GetTextDirection());
}
- if (src.GetTextPosition()) {
- dst->AddIntAttribute(
- ax::mojom::IntAttribute::kTextPosition,
- static_cast<int32_t>(AXTextPositionFromBlink(src.GetTextPosition())));
+ if (src.GetTextPosition() != ax::mojom::TextPosition::kNone) {
+ dst->AddIntAttribute(ax::mojom::IntAttribute::kTextPosition,
+ static_cast<int32_t>(src.GetTextPosition()));
}
if (src.TextStyle()) {
@@ -656,8 +652,8 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
src.AriaAutoComplete().Utf8());
}
- if (src.Action() != blink::WebAXDefaultActionVerb::kNone) {
- dst->SetDefaultActionVerb(AXDefaultActionVerbFromBlink(src.Action()));
+ if (src.Action() != ax::mojom::DefaultActionVerb::kNone) {
+ dst->SetDefaultActionVerb(src.Action());
}
if (src.HasComputedStyle()) {
@@ -713,7 +709,7 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
dst->AddBoolAttribute(ax::mojom::BoolAttribute::kCanvasHasFallback, true);
// Spelling, grammar and other document markers.
- WebVector<blink::WebAXMarkerType> src_marker_types;
+ WebVector<ax::mojom::MarkerType> src_marker_types;
WebVector<int> src_marker_starts;
WebVector<int> src_marker_ends;
src.Markers(src_marker_types, src_marker_starts, src_marker_ends);
@@ -728,8 +724,7 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
marker_starts.reserve(src_marker_starts.size());
marker_ends.reserve(src_marker_ends.size());
for (size_t i = 0; i < src_marker_types.size(); ++i) {
- marker_types.push_back(
- static_cast<int32_t>(AXMarkerTypeFromBlink(src_marker_types[i])));
+ marker_types.push_back(static_cast<int32_t>(src_marker_types[i]));
marker_starts.push_back(src_marker_starts[i]);
marker_ends.push_back(src_marker_ends[i]);
}
@@ -832,7 +827,7 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
aria_rowcount);
}
- if (dst->role == ax::mojom::Role::kRow) {
+ if (ui::IsTableRowRole(dst->role)) {
dst->AddIntAttribute(ax::mojom::IntAttribute::kTableRowIndex,
src.RowIndex());
WebAXObject header = src.RowHeader();
@@ -841,39 +836,36 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
header.AxID());
}
- if (dst->role == ax::mojom::Role::kCell ||
- dst->role == ax::mojom::Role::kRowHeader ||
- dst->role == ax::mojom::Role::kColumnHeader ||
- dst->role == ax::mojom::Role::kRow) {
- if (dst->role != ax::mojom::Role::kRow) {
- dst->AddIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex,
- src.CellColumnIndex());
- dst->AddIntAttribute(ax::mojom::IntAttribute::kTableCellColumnSpan,
- src.CellColumnSpan());
- dst->AddIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex,
- src.CellRowIndex());
- dst->AddIntAttribute(ax::mojom::IntAttribute::kTableCellRowSpan,
- src.CellRowSpan());
-
- int aria_colindex = src.AriaColumnIndex();
- if (aria_colindex) {
- dst->AddIntAttribute(ax::mojom::IntAttribute::kAriaCellColumnIndex,
- aria_colindex);
- }
+ if (ui::IsCellOrTableHeaderRole(dst->role)) {
+ dst->AddIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex,
+ src.CellColumnIndex());
+ dst->AddIntAttribute(ax::mojom::IntAttribute::kTableCellColumnSpan,
+ src.CellColumnSpan());
+ dst->AddIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex,
+ src.CellRowIndex());
+ dst->AddIntAttribute(ax::mojom::IntAttribute::kTableCellRowSpan,
+ src.CellRowSpan());
+
+ int aria_colindex = src.AriaColumnIndex();
+ if (aria_colindex) {
+ dst->AddIntAttribute(ax::mojom::IntAttribute::kAriaCellColumnIndex,
+ aria_colindex);
}
+ }
+ if (ui::IsCellOrTableHeaderRole(dst->role) ||
+ ui::IsTableRowRole(dst->role)) {
+ // aria-rowindex is supported on cells, headers and rows.
int aria_rowindex = src.AriaRowIndex();
if (aria_rowindex)
dst->AddIntAttribute(ax::mojom::IntAttribute::kAriaCellRowIndex,
aria_rowindex);
}
- if ((dst->role == ax::mojom::Role::kRowHeader ||
- dst->role == ax::mojom::Role::kColumnHeader) &&
- src.SortDirection()) {
- dst->AddIntAttribute(
- ax::mojom::IntAttribute::kSortDirection,
- static_cast<int32_t>(AXSortDirectionFromBlink(src.SortDirection())));
+ if (ui::IsTableHeaderRole(dst->role) &&
+ src.SortDirection() != ax::mojom::SortDirection::kNone) {
+ dst->AddIntAttribute(ax::mojom::IntAttribute::kSortDirection,
+ static_cast<int32_t>(src.SortDirection()));
}
}
diff --git a/chromium/content/renderer/accessibility/blink_ax_tree_source.h b/chromium/content/renderer/accessibility/blink_ax_tree_source.h
index 2adf7bf8cbe..81e87f0a04e 100644
--- a/chromium/content/renderer/accessibility/blink_ax_tree_source.h
+++ b/chromium/content/renderer/accessibility/blink_ax_tree_source.h
@@ -12,7 +12,7 @@
#include "content/common/ax_content_node_data.h"
#include "third_party/blink/public/web/web_ax_object.h"
#include "third_party/blink/public/web/web_document.h"
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_tree_source.h"
diff --git a/chromium/content/renderer/accessibility/render_accessibility_impl.cc b/chromium/content/renderer/accessibility/render_accessibility_impl.cc
index 31ec8b96133..2dd6dc15615 100644
--- a/chromium/content/renderer/accessibility/render_accessibility_impl.cc
+++ b/chromium/content/renderer/accessibility/render_accessibility_impl.cc
@@ -201,8 +201,23 @@ bool RenderAccessibilityImpl::OnMessageReceived(const IPC::Message& message) {
}
void RenderAccessibilityImpl::HandleWebAccessibilityEvent(
- const blink::WebAXObject& obj, blink::WebAXEvent event) {
- HandleAXEvent(obj, AXEventFromBlink(event));
+ const blink::WebAXObject& obj,
+ ax::mojom::Event event) {
+ HandleAXEvent(obj, event);
+}
+
+void RenderAccessibilityImpl::MarkWebAXObjectDirty(
+ const blink::WebAXObject& obj,
+ bool subtree) {
+ DirtyObject dirty_object;
+ dirty_object.obj = obj;
+ dirty_object.event_from = GetEventFrom();
+ dirty_objects_.push_back(dirty_object);
+
+ if (subtree)
+ serializer_.InvalidateSubtree(obj);
+
+ ScheduleSendAccessibilityEventsIfNeeded();
}
void RenderAccessibilityImpl::HandleAccessibilityFindInPageResult(
@@ -268,7 +283,7 @@ void RenderAccessibilityImpl::HandleAXEvent(const blink::WebAXObject& obj,
// If some cell IDs have been added or removed, we need to update the whole
// table.
- if (obj.Role() == blink::kWebAXRoleRow &&
+ if (obj.Role() == ax::mojom::Role::kRow &&
event == ax::mojom::Event::kChildrenChanged) {
WebAXObject table_like_object = obj.ParentObject();
if (!table_like_object.IsDetached()) {
@@ -279,7 +294,7 @@ void RenderAccessibilityImpl::HandleAXEvent(const blink::WebAXObject& obj,
// If a select tag is opened or closed, all the children must be updated
// because their visibility may have changed.
- if (obj.Role() == blink::kWebAXRoleMenuListPopup &&
+ if (obj.Role() == ax::mojom::Role::kMenuListPopup &&
event == ax::mojom::Event::kChildrenChanged) {
WebAXObject popup_like_object = obj.ParentObject();
if (!popup_like_object.IsDetached()) {
@@ -292,16 +307,7 @@ void RenderAccessibilityImpl::HandleAXEvent(const blink::WebAXObject& obj,
ui::AXEvent acc_event;
acc_event.id = obj.AxID();
acc_event.event_type = event;
-
- if (blink::WebUserGestureIndicator::IsProcessingUserGesture(
- render_frame_->GetWebFrame())) {
- acc_event.event_from = ax::mojom::EventFrom::kUser;
- } else if (during_action_) {
- acc_event.event_from = ax::mojom::EventFrom::kAction;
- } else {
- acc_event.event_from = ax::mojom::EventFrom::kPage;
- }
-
+ acc_event.event_from = GetEventFrom();
acc_event.action_request_id = action_request_id;
// Discard duplicate accessibility events.
@@ -313,6 +319,10 @@ void RenderAccessibilityImpl::HandleAXEvent(const blink::WebAXObject& obj,
}
pending_events_.push_back(acc_event);
+ ScheduleSendAccessibilityEventsIfNeeded();
+}
+
+void RenderAccessibilityImpl::ScheduleSendAccessibilityEventsIfNeeded() {
// Don't send accessibility events for frames that are not in the frame tree
// yet (i.e., provisional frames used for remote-to-local navigations, which
// haven't committed yet). Doing so might trigger layout, which may not work
@@ -333,6 +343,18 @@ void RenderAccessibilityImpl::HandleAXEvent(const blink::WebAXObject& obj,
}
}
+ax::mojom::EventFrom RenderAccessibilityImpl::GetEventFrom() {
+ if (blink::WebUserGestureIndicator::IsProcessingUserGesture(
+ render_frame_->GetWebFrame())) {
+ return ax::mojom::EventFrom::kUser;
+ }
+
+ if (during_action_)
+ return ax::mojom::EventFrom::kAction;
+
+ return ax::mojom::EventFrom::kPage;
+}
+
int RenderAccessibilityImpl::GenerateAXID() {
WebAXObject root = tree_source_.GetRoot();
return root.GenerateAXID();
@@ -408,7 +430,8 @@ void RenderAccessibilityImpl::SendPendingAccessibilityEvents() {
AccessibilityHostMsg_EventBundleParams bundle;
// Keep track of nodes in the tree that need to be updated.
- std::vector<DirtyObject> dirty_objects;
+ std::vector<DirtyObject> dirty_objects = dirty_objects_;
+ dirty_objects_.clear();
// If there's a layout complete message, we need to send location changes.
bool had_layout_complete_messages = false;
@@ -441,12 +464,11 @@ void RenderAccessibilityImpl::SendPendingAccessibilityEvents() {
// Whenever there's a change within a table, invalidate the
// whole table so that row and cell indexes are recomputed.
- ax::mojom::Role role = AXRoleFromBlink(obj.Role());
+ ax::mojom::Role role = obj.Role();
if (ui::IsTableLikeRole(role) || role == ax::mojom::Role::kRow ||
ui::IsCellOrTableHeaderRole(role)) {
auto table = obj;
- while (!table.IsDetached() &&
- !ui::IsTableLikeRole(AXRoleFromBlink(table.Role())))
+ while (!table.IsDetached() && !ui::IsTableLikeRole(table.Role()))
table = table.ParentObject();
if (!table.IsDetached())
serializer_.InvalidateSubtree(table);
@@ -644,14 +666,16 @@ void RenderAccessibilityImpl::OnPerformAction(
case ax::mojom::Action::kShowContextMenu:
target.ShowContextMenu();
break;
- case ax::mojom::Action::kCustomAction:
- case ax::mojom::Action::kReplaceSelectedText:
case ax::mojom::Action::kScrollBackward:
case ax::mojom::Action::kScrollForward:
case ax::mojom::Action::kScrollUp:
case ax::mojom::Action::kScrollDown:
case ax::mojom::Action::kScrollLeft:
case ax::mojom::Action::kScrollRight:
+ Scroll(target, data.action);
+ break;
+ case ax::mojom::Action::kCustomAction:
+ case ax::mojom::Action::kReplaceSelectedText:
case ax::mojom::Action::kNone:
NOTREACHED();
break;
@@ -792,6 +816,65 @@ void RenderAccessibilityImpl::AddPluginTreeToUpdate(
update->has_tree_data = true;
}
+void RenderAccessibilityImpl::Scroll(const WebAXObject& target,
+ ax::mojom::Action scroll_action) {
+ WebAXObject offset_container;
+ WebFloatRect bounds;
+ SkMatrix44 container_transform;
+ target.GetRelativeBounds(offset_container, bounds, container_transform);
+
+ if (bounds.IsEmpty())
+ return;
+
+ WebPoint initial = target.GetScrollOffset();
+ WebPoint min = target.MinimumScrollOffset();
+ WebPoint max = target.MaximumScrollOffset();
+
+ // TODO(zhelfins): This 4/5ths came from the Android implementation, revisit
+ // to find the appropriate modifier to keep enough context onscreen after
+ // scrolling.
+ int page_x = std::max((int)(bounds.width * 4 / 5), 1);
+ int page_y = std::max((int)(bounds.height * 4 / 5), 1);
+
+ // Forward/backward defaults to down/up unless it can only be scrolled
+ // horizontally.
+ if (scroll_action == ax::mojom::Action::kScrollForward)
+ scroll_action = max.y > min.y ? ax::mojom::Action::kScrollDown
+ : ax::mojom::Action::kScrollRight;
+ if (scroll_action == ax::mojom::Action::kScrollBackward)
+ scroll_action = max.y > min.y ? ax::mojom::Action::kScrollUp
+ : ax::mojom::Action::kScrollLeft;
+
+ int x = initial.x;
+ int y = initial.y;
+ switch (scroll_action) {
+ case ax::mojom::Action::kScrollUp:
+ if (initial.y == min.y)
+ return;
+ y = std::max(initial.y - page_y, min.y);
+ break;
+ case ax::mojom::Action::kScrollDown:
+ if (initial.y == max.y)
+ return;
+ y = std::min(initial.y + page_y, max.y);
+ break;
+ case ax::mojom::Action::kScrollLeft:
+ if (initial.x == min.x)
+ return;
+ x = std::max(initial.x - page_x, min.x);
+ break;
+ case ax::mojom::Action::kScrollRight:
+ if (initial.x == max.x)
+ return;
+ x = std::min(initial.x + page_x, max.x);
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ target.SetScrollOffset(WebPoint(x, y));
+}
+
void RenderAccessibilityImpl::ScrollPlugin(int id_to_make_visible) {
// Plugin content doesn't scroll itself, so when we're requested to
// scroll to make a particular plugin node visible, get the
diff --git a/chromium/content/renderer/accessibility/render_accessibility_impl.h b/chromium/content/renderer/accessibility/render_accessibility_impl.h
index 240a0ff6086..5f72b018ee1 100644
--- a/chromium/content/renderer/accessibility/render_accessibility_impl.h
+++ b/chromium/content/renderer/accessibility/render_accessibility_impl.h
@@ -80,7 +80,8 @@ class CONTENT_EXPORT RenderAccessibilityImpl
// Called when an accessibility notification occurs in Blink.
void HandleWebAccessibilityEvent(const blink::WebAXObject& obj,
- blink::WebAXEvent event);
+ ax::mojom::Event event);
+ void MarkWebAXObjectDirty(const blink::WebAXObject& obj, bool subtree);
// Called when a new find in page result is highlighted.
void HandleAccessibilityFindInPageResult(
@@ -131,7 +132,11 @@ class CONTENT_EXPORT RenderAccessibilityImpl
void OnLoadInlineTextBoxes(const blink::WebAXObject& obj);
void OnGetImageData(const blink::WebAXObject& obj, const gfx::Size& max_size);
void AddPluginTreeToUpdate(AXContentTreeUpdate* update);
+ void Scroll(const blink::WebAXObject& target,
+ ax::mojom::Action scroll_action);
void ScrollPlugin(int id_to_make_visible);
+ ax::mojom::EventFrom GetEventFrom();
+ void ScheduleSendAccessibilityEventsIfNeeded();
// The RenderFrameImpl that owns us.
RenderFrameImpl* render_frame_;
@@ -143,6 +148,11 @@ class CONTENT_EXPORT RenderAccessibilityImpl
// sent to the browser.
std::vector<ui::AXEvent> pending_events_;
+ // Objects that need to be re-serialized, the next time
+ // we send an event bundle to the browser - but don't specifically need
+ // an event fired.
+ std::vector<DirtyObject> dirty_objects_;
+
// The adapter that exposes Blink's accessibility tree to AXTreeSerializer.
BlinkAXTreeSource tree_source_;
diff --git a/chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc b/chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
index e812e74632f..eff7934b083 100644
--- a/chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
+++ b/chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
@@ -10,7 +10,6 @@
#include "build/build_config.h"
#include "content/common/accessibility_messages.h"
#include "content/common/frame_messages.h"
-#include "content/common/view_message_enums.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/render_view_test.h"
#include "content/renderer/accessibility/render_accessibility_impl.h"
diff --git a/chromium/content/renderer/appcache/appcache_frontend_impl.cc b/chromium/content/renderer/appcache/appcache_frontend_impl.cc
index 20afc6b86e9..75e398f822a 100644
--- a/chromium/content/renderer/appcache/appcache_frontend_impl.cc
+++ b/chromium/content/renderer/appcache/appcache_frontend_impl.cc
@@ -27,8 +27,7 @@ void AppCacheFrontendImpl::OnCacheSelected(int host_id,
void AppCacheFrontendImpl::OnStatusChanged(const std::vector<int>& host_ids,
AppCacheStatus status) {
- for (std::vector<int>::const_iterator i = host_ids.begin();
- i != host_ids.end(); ++i) {
+ for (auto i = host_ids.begin(); i != host_ids.end(); ++i) {
WebApplicationCacheHostImpl* host = GetHost(*i);
if (host)
host->OnStatusChanged(status);
@@ -42,8 +41,7 @@ void AppCacheFrontendImpl::OnEventRaised(const std::vector<int>& host_ids,
AppCacheEventID::APPCACHE_PROGRESS_EVENT); // See OnProgressEventRaised.
DCHECK_NE(event_id,
AppCacheEventID::APPCACHE_ERROR_EVENT); // See OnErrorEventRaised.
- for (std::vector<int>::const_iterator i = host_ids.begin();
- i != host_ids.end(); ++i) {
+ for (auto i = host_ids.begin(); i != host_ids.end(); ++i) {
WebApplicationCacheHostImpl* host = GetHost(*i);
if (host)
host->OnEventRaised(event_id);
@@ -55,8 +53,7 @@ void AppCacheFrontendImpl::OnProgressEventRaised(
const GURL& url,
int num_total,
int num_complete) {
- for (std::vector<int>::const_iterator i = host_ids.begin();
- i != host_ids.end(); ++i) {
+ for (auto i = host_ids.begin(); i != host_ids.end(); ++i) {
WebApplicationCacheHostImpl* host = GetHost(*i);
if (host)
host->OnProgressEventRaised(url, num_total, num_complete);
@@ -66,8 +63,7 @@ void AppCacheFrontendImpl::OnProgressEventRaised(
void AppCacheFrontendImpl::OnErrorEventRaised(
const std::vector<int>& host_ids,
const AppCacheErrorDetails& details) {
- for (std::vector<int>::const_iterator i = host_ids.begin();
- i != host_ids.end(); ++i) {
+ for (auto i = host_ids.begin(); i != host_ids.end(); ++i) {
WebApplicationCacheHostImpl* host = GetHost(*i);
if (host)
host->OnErrorEventRaised(details);
diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.cc b/chromium/content/renderer/browser_plugin/browser_plugin.cc
index 95a4d2f30c4..9c5002e1f72 100644
--- a/chromium/content/renderer/browser_plugin/browser_plugin.cc
+++ b/chromium/content/renderer/browser_plugin/browser_plugin.cc
@@ -78,7 +78,7 @@ BrowserPlugin* BrowserPlugin::GetFromNode(const blink::WebNode& node) {
return nullptr;
PluginContainerMap* browser_plugins = g_plugin_container_map.Pointer();
- PluginContainerMap::iterator it = browser_plugins->find(container);
+ auto it = browser_plugins->find(container);
return it == browser_plugins->end() ? nullptr : it->second;
}
@@ -103,8 +103,6 @@ BrowserPlugin::BrowserPlugin(
if (delegate_)
delegate_->SetElementInstanceID(browser_plugin_instance_id_);
-
- enable_surface_synchronization_ = features::IsSurfaceSynchronizationEnabled();
}
BrowserPlugin::~BrowserPlugin() {
@@ -136,27 +134,10 @@ bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) {
#endif
IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents,
OnShouldAcceptTouchEvents)
- IPC_MESSAGE_HANDLER(BrowserPluginMsg_FirstSurfaceActivation,
- OnFirstSurfaceActivation)
IPC_END_MESSAGE_MAP()
return handled;
}
-void BrowserPlugin::OnFirstSurfaceActivation(
- int browser_plugin_instance_id,
- const viz::SurfaceInfo& surface_info) {
- if (!attached() || features::IsUsingWindowService())
- return;
-
- if (!enable_surface_synchronization_) {
- compositing_helper_->SetPrimarySurfaceId(
- surface_info.id(), screen_space_rect().size(),
- cc::DeadlinePolicy::UseDefaultDeadline());
- }
- compositing_helper_->SetFallbackSurfaceId(surface_info.id(),
- screen_space_rect().size());
-}
-
void BrowserPlugin::UpdateDOMAttribute(const std::string& attribute_name,
const base::string16& attribute_value) {
if (!Container())
@@ -286,7 +267,7 @@ void BrowserPlugin::SynchronizeVisualProperties() {
if (synchronized_props_changed)
parent_local_surface_id_allocator_.GenerateId();
- if (enable_surface_synchronization_ && frame_sink_id_.is_valid()) {
+ if (frame_sink_id_.is_valid()) {
// If we're synchronizing surfaces, then use an infinite deadline to ensure
// everything is synchronized.
cc::DeadlinePolicy deadline =
@@ -320,7 +301,7 @@ void BrowserPlugin::SynchronizeVisualProperties() {
sent_visual_properties_ = pending_visual_properties_;
#if defined(USE_AURA)
- if (features::IsUsingWindowService() && mus_embedded_frame_) {
+ if (features::IsMultiProcessMash() && mus_embedded_frame_) {
mus_embedded_frame_->SetWindowBounds(GetLocalSurfaceId(),
FrameRectInPixels());
}
@@ -414,7 +395,7 @@ void BrowserPlugin::OnSetMouseLock(int browser_plugin_instance_id,
void BrowserPlugin::OnSetMusEmbedToken(
int instance_id,
const base::UnguessableToken& embed_token) {
- DCHECK(features::IsUsingWindowService());
+ DCHECK(features::IsMultiProcessMash());
if (!attached_) {
pending_embed_token_ = embed_token;
} else {
@@ -722,7 +703,7 @@ bool BrowserPlugin::HandleDragStatusUpdate(blink::WebDragStatus drag_status,
void BrowserPlugin::DidReceiveResponse(const blink::WebURLResponse& response) {}
-void BrowserPlugin::DidReceiveData(const char* data, int data_length) {
+void BrowserPlugin::DidReceiveData(const char* data, size_t data_length) {
if (delegate_)
delegate_->PluginDidReceiveData(data, data_length);
}
@@ -849,19 +830,10 @@ bool BrowserPlugin::HandleMouseLockedInputEvent(
}
#if defined(USE_AURA)
-void BrowserPlugin::OnMusEmbeddedFrameSurfaceChanged(
- const viz::SurfaceInfo& surface_info) {
- if (!attached_)
- return;
-
- compositing_helper_->SetFallbackSurfaceId(surface_info.id(),
- screen_space_rect().size());
-}
-
void BrowserPlugin::OnMusEmbeddedFrameSinkIdAllocated(
const viz::FrameSinkId& frame_sink_id) {
// RendererWindowTreeClient should only call this when mus is hosting viz.
- DCHECK(features::IsUsingWindowService());
+ DCHECK(features::IsMultiProcessMash());
OnGuestReady(browser_plugin_instance_id_, frame_sink_id);
}
#endif
@@ -871,7 +843,8 @@ cc::Layer* BrowserPlugin::GetLayer() {
}
void BrowserPlugin::SetLayer(scoped_refptr<cc::Layer> layer,
- bool prevent_contents_opaque_changes) {
+ bool prevent_contents_opaque_changes,
+ bool is_surface_layer) {
if (container_)
container_->SetCcLayer(layer.get(), prevent_contents_opaque_changes);
embedded_layer_ = std::move(layer);
diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.h b/chromium/content/renderer/browser_plugin/browser_plugin.h
index 9ef2eb19f8a..9ed26734b6a 100644
--- a/chromium/content/renderer/browser_plugin/browser_plugin.h
+++ b/chromium/content/renderer/browser_plugin/browser_plugin.h
@@ -39,10 +39,6 @@ class Layer;
class RenderFrameMetadata;
}
-namespace viz {
-class SurfaceInfo;
-}
-
namespace content {
class BrowserPluginDelegate;
@@ -132,7 +128,7 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
const blink::WebFloatPoint& position,
const blink::WebFloatPoint& screen) override;
void DidReceiveResponse(const blink::WebURLResponse& response) override;
- void DidReceiveData(const char* data, int data_length) override;
+ void DidReceiveData(const char* data, size_t data_length) override;
void DidFinishLoading() override;
void DidFailLoading(const blink::WebURLError& error) override;
bool ExecuteEditCommand(const blink::WebString& name) override;
@@ -206,8 +202,6 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
const gfx::Size& min_size,
const gfx::Size& max_size);
void OnDisableAutoResize(int browser_plugin_instance_id);
- void OnFirstSurfaceActivation(int instance_id,
- const viz::SurfaceInfo& surface_info);
void OnSetContentsOpaque(int instance_id, bool opaque);
void OnSetCursor(int instance_id, const WebCursor& cursor);
void OnSetMouseLock(int instance_id, bool enable);
@@ -219,8 +213,6 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
#if defined(USE_AURA)
// MusEmbeddedFrameDelegate
- void OnMusEmbeddedFrameSurfaceChanged(
- const viz::SurfaceInfo& surface_info) override;
void OnMusEmbeddedFrameSinkIdAllocated(
const viz::FrameSinkId& frame_sink_id) override;
#endif
@@ -228,7 +220,8 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
// ChildFrameCompositor:
cc::Layer* GetLayer() override;
void SetLayer(scoped_refptr<cc::Layer> layer,
- bool prevent_contents_opaque_changes) override;
+ bool prevent_contents_opaque_changes,
+ bool is_surface_layer) override;
SkBitmap* GetSadPageBitmap() override;
// This indicates whether this BrowserPlugin has been attached to a
@@ -264,8 +257,6 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
viz::FrameSinkId frame_sink_id_;
viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
- bool enable_surface_synchronization_ = false;
-
// The last ResizeParams sent to the browser process, if any.
base::Optional<FrameVisualProperties> sent_visual_properties_;
diff --git a/chromium/content/renderer/categorized_worker_pool.cc b/chromium/content/renderer/categorized_worker_pool.cc
index 0235547e93b..30a1737ad15 100644
--- a/chromium/content/renderer/categorized_worker_pool.cc
+++ b/chromium/content/renderer/categorized_worker_pool.cc
@@ -221,7 +221,7 @@ bool CategorizedWorkerPool::PostDelayedTask(const base::Location& from_here,
DCHECK(completed_tasks_.empty());
CollectCompletedTasksWithLockAcquired(namespace_token_, &completed_tasks_);
- cc::Task::Vector::iterator end = std::remove_if(
+ auto end = std::remove_if(
tasks_.begin(), tasks_.end(), [this](const scoped_refptr<cc::Task>& e) {
return std::find(this->completed_tasks_.begin(),
this->completed_tasks_.end(),
diff --git a/chromium/content/renderer/child_frame_compositing_helper.cc b/chromium/content/renderer/child_frame_compositing_helper.cc
index ba7454e3faa..331e0955248 100644
--- a/chromium/content/renderer/child_frame_compositing_helper.cc
+++ b/chromium/content/renderer/child_frame_compositing_helper.cc
@@ -39,7 +39,7 @@ void ChildFrameCompositingHelper::ChildFrameGone(
scoped_refptr<cc::SolidColorLayer> crashed_layer =
cc::SolidColorLayer::Create();
crashed_layer->SetMasksToBounds(true);
- crashed_layer->SetBackgroundColor(SK_ColorBLACK);
+ crashed_layer->SetBackgroundColor(SK_ColorGRAY);
if (child_frame_compositor_->GetLayer()) {
SkBitmap* sad_bitmap = child_frame_compositor_->GetSadPageBitmap();
@@ -67,7 +67,8 @@ void ChildFrameCompositingHelper::ChildFrameGone(
bool prevent_contents_opaque_changes = false;
child_frame_compositor_->SetLayer(std::move(crashed_layer),
- prevent_contents_opaque_changes);
+ prevent_contents_opaque_changes,
+ false /* is_surface_layer */);
}
void ChildFrameCompositingHelper::SetPrimarySurfaceId(
@@ -91,7 +92,8 @@ void ChildFrameCompositingHelper::SetPrimarySurfaceId(
// about the child surface's opacity. https://crbug.com/629851.
bool prevent_contents_opaque_changes = true;
child_frame_compositor_->SetLayer(surface_layer_,
- prevent_contents_opaque_changes);
+ prevent_contents_opaque_changes,
+ true /* is_surface_layer */);
UpdateVisibility(true);
diff --git a/chromium/content/renderer/child_frame_compositing_helper_unittest.cc b/chromium/content/renderer/child_frame_compositing_helper_unittest.cc
index d2c3e498636..3d4d6824b02 100644
--- a/chromium/content/renderer/child_frame_compositing_helper_unittest.cc
+++ b/chromium/content/renderer/child_frame_compositing_helper_unittest.cc
@@ -23,7 +23,8 @@ class MockChildFrameCompositor : public ChildFrameCompositor {
cc::Layer* GetLayer() override { return layer_.get(); }
void SetLayer(scoped_refptr<cc::Layer> layer,
- bool prevent_contents_opaque_changes) override {
+ bool prevent_contents_opaque_changes,
+ bool is_surface_layer) override {
layer_ = std::move(layer);
}
diff --git a/chromium/content/renderer/child_frame_compositor.h b/chromium/content/renderer/child_frame_compositor.h
index f93b026813a..fa0a8759837 100644
--- a/chromium/content/renderer/child_frame_compositor.h
+++ b/chromium/content/renderer/child_frame_compositor.h
@@ -20,7 +20,8 @@ class ChildFrameCompositor {
// Passes ownership of a cc::Layer to the ChildFrameCompositor.
virtual void SetLayer(scoped_refptr<cc::Layer> layer,
- bool prevent_contents_opaque_changes) = 0;
+ bool prevent_contents_opaque_changes,
+ bool is_surface_layer) = 0;
// Returns a sad page bitmap used when the child frame has crashed.
virtual SkBitmap* GetSadPageBitmap() = 0;
diff --git a/chromium/content/renderer/dom_serializer_browsertest.cc b/chromium/content/renderer/dom_serializer_browsertest.cc
index 8dfad4b4b2f..14e32bb534d 100644
--- a/chromium/content/renderer/dom_serializer_browsertest.cc
+++ b/chromium/content/renderer/dom_serializer_browsertest.cc
@@ -139,10 +139,10 @@ class MAYBE_DomSerializerTests : public ContentBrowserTest,
// html contents use UTF-8 encoding.
WebData data(contents.data(), contents.length());
GetMainFrame()->CommitDataNavigation(
- data, "text/html", encoding_info, base_url, WebURL(),
- false /* replace */, blink::WebFrameLoadType::kStandard,
- blink::WebHistoryItem(), false /* is_client_redirect */,
- nullptr /* navigation_params */, nullptr /* navigation_data */);
+ blink::WebURLRequest(base_url), data, "text/html", encoding_info,
+ WebURL(), blink::WebFrameLoadType::kStandard, blink::WebHistoryItem(),
+ false /* is_client_redirect */, nullptr /* navigation_params */,
+ nullptr /* navigation_data */);
}
base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
waiter.Wait();
diff --git a/chromium/content/renderer/dom_storage/dom_storage_cached_area.cc b/chromium/content/renderer/dom_storage/dom_storage_cached_area.cc
index 402c27727ff..a7cdf900661 100644
--- a/chromium/content/renderer/dom_storage/dom_storage_cached_area.cc
+++ b/chromium/content/renderer/dom_storage/dom_storage_cached_area.cc
@@ -144,8 +144,7 @@ void DOMStorageCachedArea::ApplyMutation(
// We have to retain local additions which happened after this
// clear operation from another process.
- std::map<base::string16, int>::iterator iter =
- ignore_key_mutations_.begin();
+ auto iter = ignore_key_mutations_.begin();
while (iter != ignore_key_mutations_.end()) {
base::NullableString16 value = old->GetItem(iter->first);
if (!value.is_null()) {
@@ -240,8 +239,7 @@ void DOMStorageCachedArea::OnSetItemComplete(const base::string16& key,
Reset();
return;
}
- std::map<base::string16, int>::iterator found =
- ignore_key_mutations_.find(key);
+ auto found = ignore_key_mutations_.find(key);
DCHECK(found != ignore_key_mutations_.end());
if (--found->second == 0)
ignore_key_mutations_.erase(found);
@@ -252,8 +250,7 @@ void DOMStorageCachedArea::OnRemoveItemComplete(
blink::WebScopedVirtualTimePauser,
bool success) {
DCHECK(success);
- std::map<base::string16, int>::iterator found =
- ignore_key_mutations_.find(key);
+ auto found = ignore_key_mutations_.find(key);
DCHECK(found != ignore_key_mutations_.end());
if (--found->second == 0)
ignore_key_mutations_.erase(found);
diff --git a/chromium/content/renderer/dom_storage/dom_storage_cached_area_unittest.cc b/chromium/content/renderer/dom_storage/dom_storage_cached_area_unittest.cc
index f4d390d0a07..68607d7551e 100644
--- a/chromium/content/renderer/dom_storage/dom_storage_cached_area_unittest.cc
+++ b/chromium/content/renderer/dom_storage/dom_storage_cached_area_unittest.cc
@@ -9,8 +9,8 @@
#include <memory>
#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
#include "content/renderer/dom_storage/dom_storage_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/fake_renderer_scheduler.h"
@@ -159,7 +159,8 @@ class DOMStorageCachedAreaTest : public testing::Test {
}
protected:
- base::MessageLoop message_loop_; // Needed to construct a RendererScheduler.
+ base::test::ScopedTaskEnvironment
+ task_environment_; // Needed to construct a RendererScheduler.
std::unique_ptr<blink::scheduler::WebThreadScheduler> main_thread_scheduler_;
scoped_refptr<MockProxy> mock_proxy_;
};
diff --git a/chromium/content/renderer/dom_storage/dom_storage_dispatcher.cc b/chromium/content/renderer/dom_storage/dom_storage_dispatcher.cc
index 0a8b4befde3..f7fcb66c7cf 100644
--- a/chromium/content/renderer/dom_storage/dom_storage_dispatcher.cc
+++ b/chromium/content/renderer/dom_storage/dom_storage_dispatcher.cc
@@ -171,7 +171,7 @@ class DomStorageDispatcher::ProxyImpl : public DOMStorageProxy {
}
CachedAreaHolder* GetAreaHolder(const std::string& key) {
- CachedAreaMap::iterator found = cached_areas_.find(key);
+ auto found = cached_areas_.find(key);
if (found == cached_areas_.end())
return nullptr;
return &(found->second);
diff --git a/chromium/content/renderer/dom_storage/local_storage_cached_areas.cc b/chromium/content/renderer/dom_storage/local_storage_cached_areas.cc
index 6ecf2ca4e75..a9513b47e8e 100644
--- a/chromium/content/renderer/dom_storage/local_storage_cached_areas.cc
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_areas.cc
@@ -6,11 +6,11 @@
#include "base/metrics/histogram_macros.h"
#include "base/sys_info.h"
-#include "content/common/dom_storage/dom_storage_namespace_ids.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/public/common/content_features.h"
#include "content/renderer/dom_storage/local_storage_cached_area.h"
#include "content/renderer/render_thread_impl.h"
+#include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h"
#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom.h"
namespace content {
@@ -57,8 +57,9 @@ void LocalStorageCachedAreas::CloneNamespace(
const std::string& source_namespace,
const std::string& destination_namespace) {
DCHECK(base::FeatureList::IsEnabled(features::kMojoSessionStorage));
- DCHECK_EQ(kSessionStorageNamespaceIdLength, source_namespace.size());
- DCHECK_EQ(kSessionStorageNamespaceIdLength, destination_namespace.size());
+ DCHECK_EQ(blink::kSessionStorageNamespaceIdLength, source_namespace.size());
+ DCHECK_EQ(blink::kSessionStorageNamespaceIdLength,
+ destination_namespace.size());
CHECK(sequence_checker_.CalledOnValidSequence());
auto namespace_it = cached_namespaces_.find(source_namespace);
diff --git a/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.cc b/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.cc
index 942003c6d00..9e67bcee25e 100644
--- a/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.cc
+++ b/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.cc
@@ -154,7 +154,7 @@ void AssociatedResourceFetcherImpl::SetLoaderOptions(
void AssociatedResourceFetcherImpl::Start(
blink::WebLocalFrame* frame,
- blink::WebURLRequest::RequestContext request_context,
+ blink::mojom::RequestContextType request_context,
network::mojom::FetchRequestMode fetch_request_mode,
network::mojom::FetchCredentialsMode fetch_credentials_mode,
network::mojom::RequestContextFrameType frame_type,
diff --git a/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.h b/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.h
index 260573928dc..9dba3c9e4f4 100644
--- a/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.h
+++ b/chromium/content/renderer/fetchers/associated_resource_fetcher_impl.h
@@ -33,7 +33,7 @@ class AssociatedResourceFetcherImpl : public AssociatedResourceFetcher {
void SetLoaderOptions(
const blink::WebAssociatedURLLoaderOptions& options) override;
void Start(blink::WebLocalFrame* frame,
- blink::WebURLRequest::RequestContext request_context,
+ blink::mojom::RequestContextType request_context,
network::mojom::FetchRequestMode request_mode,
network::mojom::FetchCredentialsMode fetch_credentials_mode,
network::mojom::RequestContextFrameType frame_type,
diff --git a/chromium/content/renderer/fetchers/manifest_fetcher.cc b/chromium/content/renderer/fetchers/manifest_fetcher.cc
index 855f420d36a..1b9794fd498 100644
--- a/chromium/content/renderer/fetchers/manifest_fetcher.cc
+++ b/chromium/content/renderer/fetchers/manifest_fetcher.cc
@@ -35,7 +35,7 @@ void ManifestFetcher::Start(blink::WebLocalFrame* frame,
// See https://w3c.github.io/manifest/. Use "include" when use_credentials is
// true, and "omit" otherwise.
fetcher_->Start(
- frame, blink::WebURLRequest::kRequestContextManifest,
+ frame, blink::mojom::RequestContextType::MANIFEST,
network::mojom::FetchRequestMode::kCORS,
use_credentials ? network::mojom::FetchCredentialsMode::kInclude
: network::mojom::FetchCredentialsMode::kOmit,
diff --git a/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc b/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc
index 81e681eb2e0..e601eb6be11 100644
--- a/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc
+++ b/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.cc
@@ -26,7 +26,7 @@ MultiResolutionImageResourceFetcher::MultiResolutionImageResourceFetcher(
const GURL& image_url,
WebLocalFrame* frame,
int id,
- WebURLRequest::RequestContext request_context,
+ blink::mojom::RequestContextType request_context,
blink::mojom::FetchCacheMode cache_mode,
Callback callback)
: callback_(std::move(callback)),
@@ -41,7 +41,7 @@ MultiResolutionImageResourceFetcher::MultiResolutionImageResourceFetcher(
// To prevent cache tainting, the favicon requests have to by-pass the service
// workers. This should ideally not happen or at least not all the time.
// See https://crbug.com/448427
- if (request_context == WebURLRequest::kRequestContextFavicon)
+ if (request_context == blink::mojom::RequestContextType::FAVICON)
fetcher_->SetSkipServiceWorker(true);
fetcher_->SetCacheMode(cache_mode);
diff --git a/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h b/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h
index 06117ee0339..7dcc783984d 100644
--- a/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h
+++ b/chromium/content/renderer/fetchers/multi_resolution_image_resource_fetcher.h
@@ -11,7 +11,7 @@
#include "base/callback.h"
#include "base/macros.h"
-#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "url/gurl.h"
@@ -37,7 +37,7 @@ class MultiResolutionImageResourceFetcher {
const GURL& image_url,
blink::WebLocalFrame* frame,
int id,
- blink::WebURLRequest::RequestContext request_context,
+ blink::mojom::RequestContextType request_context,
blink::mojom::FetchCacheMode cache_mode,
Callback callback);
diff --git a/chromium/content/renderer/fetchers/resource_fetcher_browsertest.cc b/chromium/content/renderer/fetchers/resource_fetcher_browsertest.cc
index f6cf6b2b3a5..47f42c31bd0 100644
--- a/chromium/content/renderer/fetchers/resource_fetcher_browsertest.cc
+++ b/chromium/content/renderer/fetchers/resource_fetcher_browsertest.cc
@@ -149,7 +149,7 @@ class ResourceFetcherTests : public ContentBrowserTest {
std::unique_ptr<FetcherDelegate> delegate(new FetcherDelegate);
std::unique_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
- fetcher->Start(frame, WebURLRequest::kRequestContextInternal,
+ fetcher->Start(frame, blink::mojom::RequestContextType::INTERNAL,
RenderFrame::FromWebFrame(frame)->GetURLLoaderFactory(),
TRAFFIC_ANNOTATION_FOR_TESTS, delegate->NewCallback());
@@ -168,7 +168,7 @@ class ResourceFetcherTests : public ContentBrowserTest {
std::unique_ptr<FetcherDelegate> delegate(new FetcherDelegate);
std::unique_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
- fetcher->Start(frame, WebURLRequest::kRequestContextInternal,
+ fetcher->Start(frame, blink::mojom::RequestContextType::INTERNAL,
RenderFrame::FromWebFrame(frame)->GetURLLoaderFactory(),
TRAFFIC_ANNOTATION_FOR_TESTS, delegate->NewCallback());
@@ -187,7 +187,7 @@ class ResourceFetcherTests : public ContentBrowserTest {
std::unique_ptr<FetcherDelegate> delegate(new FetcherDelegate);
std::unique_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
- fetcher->Start(frame, WebURLRequest::kRequestContextInternal,
+ fetcher->Start(frame, blink::mojom::RequestContextType::INTERNAL,
RenderFrame::FromWebFrame(frame)->GetURLLoaderFactory(),
TRAFFIC_ANNOTATION_FOR_TESTS, delegate->NewCallback());
@@ -205,7 +205,7 @@ class ResourceFetcherTests : public ContentBrowserTest {
GURL url("http://localhost:1339/doesnotexist");
std::unique_ptr<FetcherDelegate> delegate(new FetcherDelegate);
std::unique_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
- fetcher->Start(frame, WebURLRequest::kRequestContextInternal,
+ fetcher->Start(frame, blink::mojom::RequestContextType::INTERNAL,
RenderFrame::FromWebFrame(frame)->GetURLLoaderFactory(),
TRAFFIC_ANNOTATION_FOR_TESTS, delegate->NewCallback());
@@ -225,7 +225,7 @@ class ResourceFetcherTests : public ContentBrowserTest {
std::unique_ptr<FetcherDelegate> delegate(new FetcherDelegate);
std::unique_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
- fetcher->Start(frame, WebURLRequest::kRequestContextInternal,
+ fetcher->Start(frame, blink::mojom::RequestContextType::INTERNAL,
RenderFrame::FromWebFrame(frame)->GetURLLoaderFactory(),
TRAFFIC_ANNOTATION_FOR_TESTS, delegate->NewCallback());
fetcher->SetTimeout(base::TimeDelta());
@@ -246,7 +246,7 @@ class ResourceFetcherTests : public ContentBrowserTest {
std::unique_ptr<EvilFetcherDelegate> delegate(new EvilFetcherDelegate);
std::unique_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
- fetcher->Start(frame, WebURLRequest::kRequestContextInternal,
+ fetcher->Start(frame, blink::mojom::RequestContextType::INTERNAL,
RenderFrame::FromWebFrame(frame)->GetURLLoaderFactory(),
TRAFFIC_ANNOTATION_FOR_TESTS, delegate->NewCallback());
fetcher->SetTimeout(base::TimeDelta());
@@ -266,7 +266,7 @@ class ResourceFetcherTests : public ContentBrowserTest {
std::unique_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
fetcher->SetMethod("POST");
fetcher->SetBody(kBody);
- fetcher->Start(frame, WebURLRequest::kRequestContextInternal,
+ fetcher->Start(frame, blink::mojom::RequestContextType::INTERNAL,
RenderFrame::FromWebFrame(frame)->GetURLLoaderFactory(),
TRAFFIC_ANNOTATION_FOR_TESTS, delegate->NewCallback());
@@ -285,7 +285,7 @@ class ResourceFetcherTests : public ContentBrowserTest {
std::unique_ptr<FetcherDelegate> delegate(new FetcherDelegate);
std::unique_ptr<ResourceFetcher> fetcher(ResourceFetcher::Create(url));
fetcher->SetHeader("header", kHeader);
- fetcher->Start(frame, WebURLRequest::kRequestContextInternal,
+ fetcher->Start(frame, blink::mojom::RequestContextType::INTERNAL,
RenderFrame::FromWebFrame(frame)->GetURLLoaderFactory(),
TRAFFIC_ANNOTATION_FOR_TESTS, delegate->NewCallback());
diff --git a/chromium/content/renderer/fetchers/resource_fetcher_impl.cc b/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
index 98c8c10ed36..2919ab244aa 100644
--- a/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
+++ b/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
@@ -285,7 +285,7 @@ void ResourceFetcherImpl::SetHeader(const std::string& header,
void ResourceFetcherImpl::Start(
blink::WebLocalFrame* frame,
- blink::WebURLRequest::RequestContext request_context,
+ blink::mojom::RequestContextType request_context,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
const net::NetworkTrafficAnnotationTag& annotation_tag,
Callback callback,
@@ -302,7 +302,7 @@ void ResourceFetcherImpl::Start(
<< "GETs can't have bodies.";
}
- request_.fetch_request_context_type = request_context;
+ request_.fetch_request_context_type = static_cast<int>(request_context);
request_.site_for_cookies = frame->GetDocument().SiteForCookies();
if (!frame->GetDocument().GetSecurityOrigin().IsNull()) {
request_.request_initiator =
@@ -310,7 +310,7 @@ void ResourceFetcherImpl::Start(
SetHeader(kAccessControlAllowOriginHeader,
blink::WebSecurityOrigin::CreateUnique().ToString().Ascii());
}
- request_.resource_type = WebURLRequestContextToResourceType(request_context);
+ request_.resource_type = RequestContextToResourceType(request_context);
client_ = std::make_unique<ClientImpl>(
this, std::move(callback), maximum_download_size,
diff --git a/chromium/content/renderer/fetchers/resource_fetcher_impl.h b/chromium/content/renderer/fetchers/resource_fetcher_impl.h
index 04d71b9bfcc..ef6540498d6 100644
--- a/chromium/content/renderer/fetchers/resource_fetcher_impl.h
+++ b/chromium/content/renderer/fetchers/resource_fetcher_impl.h
@@ -32,7 +32,7 @@ class ResourceFetcherImpl : public ResourceFetcher {
void SetBody(const std::string& body) override;
void SetHeader(const std::string& header, const std::string& value) override;
void Start(blink::WebLocalFrame* frame,
- blink::WebURLRequest::RequestContext request_context,
+ blink::mojom::RequestContextType request_context,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
const net::NetworkTrafficAnnotationTag& annotation_tag,
Callback callback,
diff --git a/chromium/content/renderer/file_info_util.cc b/chromium/content/renderer/file_info_util.cc
deleted file mode 100644
index 85ca2cfe359..00000000000
--- a/chromium/content/renderer/file_info_util.cc
+++ /dev/null
@@ -1,30 +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 "content/renderer/file_info_util.h"
-
-#include "base/logging.h"
-#include "third_party/blink/public/platform/web_file_info.h"
-
-namespace content {
-
-void FileInfoToWebFileInfo(const base::File::Info& file_info,
- blink::WebFileInfo* web_file_info) {
- DCHECK(web_file_info);
- // Blink now expects NaN as uninitialized/null Date.
- if (file_info.last_modified.is_null())
- web_file_info->modification_time = std::numeric_limits<double>::quiet_NaN();
- else
- web_file_info->modification_time = file_info.last_modified.ToJsTime();
- web_file_info->length = file_info.size;
- if (file_info.is_directory)
- web_file_info->type = blink::WebFileInfo::kTypeDirectory;
- else
- web_file_info->type = blink::WebFileInfo::kTypeFile;
-}
-
-static_assert(std::numeric_limits<double>::has_quiet_NaN,
- "should have quiet NaN");
-
-} // namespace content
diff --git a/chromium/content/renderer/file_info_util.h b/chromium/content/renderer/file_info_util.h
deleted file mode 100644
index 662a7e9dbce..00000000000
--- a/chromium/content/renderer/file_info_util.h
+++ /dev/null
@@ -1,22 +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_FILE_INFO_UTIL_H_
-#define CONTENT_RENDERER_FILE_INFO_UTIL_H_
-
-#include "base/files/file.h"
-
-namespace blink {
-struct WebFileInfo;
-}
-
-namespace content {
-
-// File info conversion
-void FileInfoToWebFileInfo(const base::File::Info& file_info,
- blink::WebFileInfo* web_file_info);
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_FILE_INFO_UTIL_H_
diff --git a/chromium/content/renderer/fileapi/OWNERS b/chromium/content/renderer/fileapi/OWNERS
deleted file mode 100644
index 6269c8b39df..00000000000
--- a/chromium/content/renderer/fileapi/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-file://content/browser/fileapi/OWNERS
-
-# TEAM: storage-dev@chromium.org
-# COMPONENT: Blink>Storage>FileSystem
diff --git a/chromium/content/renderer/fileapi/file_system_dispatcher.cc b/chromium/content/renderer/fileapi/file_system_dispatcher.cc
deleted file mode 100644
index 2d5f84f7378..00000000000
--- a/chromium/content/renderer/fileapi/file_system_dispatcher.cc
+++ /dev/null
@@ -1,739 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/fileapi/file_system_dispatcher.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/callback.h"
-#include "base/files/file_util.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/no_destructor.h"
-#include "base/process/process.h"
-#include "components/services/filesystem/public/interfaces/types.mojom.h"
-#include "content/child/child_thread_impl.h"
-#include "content/public/common/service_names.mojom.h"
-#include "content/public/renderer/worker_thread.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "storage/common/fileapi/file_system_info.h"
-#include "storage/common/fileapi/file_system_type_converters.h"
-
-namespace content {
-
-class FileSystemDispatcher::CallbackDispatcher {
- public:
- static std::unique_ptr<CallbackDispatcher> Create(
- const StatusCallback& callback) {
- auto dispatcher = base::WrapUnique(new CallbackDispatcher);
- dispatcher->status_callback_ = callback;
- dispatcher->error_callback_ = callback;
- return dispatcher;
- }
- static std::unique_ptr<CallbackDispatcher> Create(
- const MetadataCallback& callback,
- const StatusCallback& error_callback) {
- auto dispatcher = base::WrapUnique(new CallbackDispatcher);
- dispatcher->metadata_callback_ = callback;
- dispatcher->error_callback_ = error_callback;
- return dispatcher;
- }
- static std::unique_ptr<CallbackDispatcher> Create(
- const CreateSnapshotFileCallback& callback,
- const StatusCallback& error_callback) {
- auto dispatcher = base::WrapUnique(new CallbackDispatcher);
- dispatcher->snapshot_callback_ = callback;
- dispatcher->error_callback_ = error_callback;
- return dispatcher;
- }
- static std::unique_ptr<CallbackDispatcher> Create(
- const ReadDirectoryCallback& callback,
- const StatusCallback& error_callback) {
- auto dispatcher = base::WrapUnique(new CallbackDispatcher);
- dispatcher->directory_callback_ = callback;
- dispatcher->error_callback_ = error_callback;
- return dispatcher;
- }
- static std::unique_ptr<CallbackDispatcher> Create(
- const OpenFileSystemCallback& callback,
- const StatusCallback& error_callback) {
- auto dispatcher = base::WrapUnique(new CallbackDispatcher);
- dispatcher->filesystem_callback_ = callback;
- dispatcher->error_callback_ = error_callback;
- return dispatcher;
- }
- static std::unique_ptr<CallbackDispatcher> Create(
- const ResolveURLCallback& callback,
- const StatusCallback& error_callback) {
- auto dispatcher = base::WrapUnique(new CallbackDispatcher);
- dispatcher->resolve_callback_ = callback;
- dispatcher->error_callback_ = error_callback;
- return dispatcher;
- }
- static std::unique_ptr<CallbackDispatcher> Create(
- const WriteCallback& callback,
- const StatusCallback& error_callback) {
- auto dispatcher = base::WrapUnique(new CallbackDispatcher);
- dispatcher->write_callback_ = callback;
- dispatcher->error_callback_ = error_callback;
- return dispatcher;
- }
-
- ~CallbackDispatcher() {}
-
- void DidSucceed() { status_callback_.Run(base::File::FILE_OK); }
-
- void DidFail(base::File::Error error_code) {
- error_callback_.Run(error_code);
- }
-
- void DidReadMetadata(const base::File::Info& file_info) {
- metadata_callback_.Run(file_info);
- }
-
- void DidCreateSnapshotFile(
- const base::File::Info& file_info,
- const base::FilePath& platform_path,
- base::Optional<blink::mojom::ReceivedSnapshotListenerPtr> opt_listener,
- int request_id) {
- snapshot_callback_.Run(file_info, platform_path, std::move(opt_listener),
- request_id);
- }
-
- void DidReadDirectory(
- const std::vector<filesystem::mojom::DirectoryEntry>& entries,
- bool has_more) {
- directory_callback_.Run(entries, has_more);
- }
-
- void DidOpenFileSystem(const std::string& name, const GURL& root) {
- filesystem_callback_.Run(name, root);
- }
-
- void DidResolveURL(const storage::FileSystemInfo& info,
- const base::FilePath& file_path,
- bool is_directory) {
- resolve_callback_.Run(info, file_path, is_directory);
- }
-
- void DidWrite(int64_t bytes, bool complete) {
- write_callback_.Run(bytes, complete);
- }
-
- private:
- CallbackDispatcher() {}
-
- StatusCallback status_callback_;
- MetadataCallback metadata_callback_;
- CreateSnapshotFileCallback snapshot_callback_;
- ReadDirectoryCallback directory_callback_;
- OpenFileSystemCallback filesystem_callback_;
- ResolveURLCallback resolve_callback_;
- WriteCallback write_callback_;
-
- StatusCallback error_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(CallbackDispatcher);
-};
-
-class FileSystemDispatcher::FileSystemOperationListenerImpl
- : public blink::mojom::FileSystemOperationListener {
- public:
- FileSystemOperationListenerImpl(int request_id,
- FileSystemDispatcher* dispatcher)
- : request_id_(request_id), dispatcher_(dispatcher) {}
-
- private:
- // blink::mojom::FileSystemOperationListener
- void ResultsRetrieved(
- std::vector<filesystem::mojom::DirectoryEntryPtr> entries,
- bool has_more) override;
- void ErrorOccurred(base::File::Error error_code) override;
- void DidWrite(int64_t byte_count, bool complete) override;
-
- const int request_id_;
- FileSystemDispatcher* const dispatcher_;
-};
-
-FileSystemDispatcher::FileSystemDispatcher(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
- : main_thread_task_runner_(std::move(main_thread_task_runner)) {}
-
-FileSystemDispatcher::~FileSystemDispatcher() {
- // Make sure we fire all the remaining callbacks.
- for (base::IDMap<std::unique_ptr<CallbackDispatcher>>::iterator iter(
- &dispatchers_);
- !iter.IsAtEnd(); iter.Advance()) {
- int request_id = iter.GetCurrentKey();
- CallbackDispatcher* dispatcher = iter.GetCurrentValue();
- DCHECK(dispatcher);
- dispatcher->DidFail(base::File::FILE_ERROR_ABORT);
- dispatchers_.Remove(request_id);
- }
-}
-
-blink::mojom::FileSystemManager& FileSystemDispatcher::GetFileSystemManager() {
- auto BindInterfaceOnMainThread =
- [](blink::mojom::FileSystemManagerRequest request) {
- DCHECK(ChildThreadImpl::current());
- ChildThreadImpl::current()->GetConnector()->BindInterface(
- mojom::kBrowserServiceName, std::move(request));
- };
- if (!file_system_manager_ptr_) {
- if (WorkerThread::GetCurrentId()) {
- blink::mojom::FileSystemManagerRequest request =
- mojo::MakeRequest(&file_system_manager_ptr_);
- main_thread_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(BindInterfaceOnMainThread, std::move(request)));
- } else {
- BindInterfaceOnMainThread(mojo::MakeRequest(&file_system_manager_ptr_));
- }
- }
- return *file_system_manager_ptr_;
-}
-
-void FileSystemDispatcher::OpenFileSystem(
- const GURL& origin_url,
- storage::FileSystemType type,
- const OpenFileSystemCallback& success_callback,
- const StatusCallback& error_callback) {
- int request_id = dispatchers_.Add(
- CallbackDispatcher::Create(success_callback, error_callback));
- GetFileSystemManager().Open(
- origin_url, mojo::ConvertTo<blink::mojom::FileSystemType>(type),
- base::BindOnce(&FileSystemDispatcher::DidOpenFileSystem,
- base::Unretained(this), request_id));
-}
-
-void FileSystemDispatcher::OpenFileSystemSync(
- const GURL& origin_url,
- storage::FileSystemType type,
- const OpenFileSystemCallback& success_callback,
- const StatusCallback& error_callback) {
- int request_id = dispatchers_.Add(
- CallbackDispatcher::Create(success_callback, error_callback));
- std::string name;
- GURL root_url;
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().Open(
- origin_url, mojo::ConvertTo<blink::mojom::FileSystemType>(type), &name,
- &root_url, &error_code);
- DidOpenFileSystem(request_id, std::move(name), root_url, error_code);
-}
-
-void FileSystemDispatcher::ResolveURL(
- const GURL& filesystem_url,
- const ResolveURLCallback& success_callback,
- const StatusCallback& error_callback) {
- int request_id = dispatchers_.Add(
- CallbackDispatcher::Create(success_callback, error_callback));
- GetFileSystemManager().ResolveURL(
- filesystem_url, base::BindOnce(&FileSystemDispatcher::DidResolveURL,
- base::Unretained(this), request_id));
-}
-
-void FileSystemDispatcher::ResolveURLSync(
- const GURL& filesystem_url,
- const ResolveURLCallback& success_callback,
- const StatusCallback& error_callback) {
- int request_id = dispatchers_.Add(
- CallbackDispatcher::Create(success_callback, error_callback));
- blink::mojom::FileSystemInfoPtr info;
- base::FilePath file_path;
- bool is_directory;
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().ResolveURL(filesystem_url, &info, &file_path,
- &is_directory, &error_code);
- DidResolveURL(request_id, std::move(info), std::move(file_path), is_directory,
- error_code);
-}
-
-void FileSystemDispatcher::Move(const GURL& src_path,
- const GURL& dest_path,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- GetFileSystemManager().Move(
- src_path, dest_path,
- base::BindOnce(&FileSystemDispatcher::DidFinish, base::Unretained(this),
- request_id));
-}
-
-void FileSystemDispatcher::MoveSync(const GURL& src_path,
- const GURL& dest_path,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().Move(src_path, dest_path, &error_code);
- DidFinish(request_id, error_code);
-}
-
-void FileSystemDispatcher::Copy(const GURL& src_path,
- const GURL& dest_path,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- GetFileSystemManager().Copy(
- src_path, dest_path,
- base::BindOnce(&FileSystemDispatcher::DidFinish, base::Unretained(this),
- request_id));
-}
-
-void FileSystemDispatcher::CopySync(const GURL& src_path,
- const GURL& dest_path,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().Copy(src_path, dest_path, &error_code);
- DidFinish(request_id, error_code);
-}
-
-void FileSystemDispatcher::Remove(const GURL& path,
- bool recursive,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- GetFileSystemManager().Remove(
- path, recursive,
- base::BindOnce(&FileSystemDispatcher::DidFinish, base::Unretained(this),
- request_id));
-}
-
-void FileSystemDispatcher::RemoveSync(const GURL& path,
- bool recursive,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().Remove(path, recursive, &error_code);
- DidFinish(request_id, error_code);
-}
-
-void FileSystemDispatcher::ReadMetadata(
- const GURL& path,
- const MetadataCallback& success_callback,
- const StatusCallback& error_callback) {
- int request_id = dispatchers_.Add(
- CallbackDispatcher::Create(success_callback, error_callback));
- GetFileSystemManager().ReadMetadata(
- path, base::BindOnce(&FileSystemDispatcher::DidReadMetadata,
- base::Unretained(this), request_id));
-}
-
-void FileSystemDispatcher::ReadMetadataSync(
- const GURL& path,
- const MetadataCallback& success_callback,
- const StatusCallback& error_callback) {
- int request_id = dispatchers_.Add(
- CallbackDispatcher::Create(success_callback, error_callback));
- base::File::Info file_info;
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().ReadMetadata(path, &file_info, &error_code);
- DidReadMetadata(request_id, std::move(file_info), error_code);
-}
-
-void FileSystemDispatcher::CreateFile(const GURL& path,
- bool exclusive,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- GetFileSystemManager().Create(
- path, exclusive, /*is_directory=*/false, /*is_recursive=*/false,
- base::BindOnce(&FileSystemDispatcher::DidFinish, base::Unretained(this),
- request_id));
-}
-
-void FileSystemDispatcher::CreateFileSync(const GURL& path,
- bool exclusive,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().Create(path, exclusive, /*is_directory=*/false,
- /*is_recursive=*/false, &error_code);
- DidFinish(request_id, error_code);
-}
-
-void FileSystemDispatcher::CreateDirectory(const GURL& path,
- bool exclusive,
- bool recursive,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- GetFileSystemManager().Create(
- path, exclusive, true, recursive,
- base::BindOnce(&FileSystemDispatcher::DidFinish, base::Unretained(this),
- request_id));
-}
-
-void FileSystemDispatcher::CreateDirectorySync(const GURL& path,
- bool exclusive,
- bool recursive,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().Create(path, exclusive, true, recursive, &error_code);
- DidFinish(request_id, error_code);
-}
-
-void FileSystemDispatcher::Exists(const GURL& path,
- bool is_directory,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- GetFileSystemManager().Exists(
- path, is_directory,
- base::BindOnce(&FileSystemDispatcher::DidFinish, base::Unretained(this),
- request_id));
-}
-
-void FileSystemDispatcher::ExistsSync(const GURL& path,
- bool is_directory,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().Exists(path, is_directory, &error_code);
- DidFinish(request_id, error_code);
-}
-
-void FileSystemDispatcher::ReadDirectory(
- const GURL& path,
- const ReadDirectoryCallback& success_callback,
- const StatusCallback& error_callback) {
- int request_id = dispatchers_.Add(
- CallbackDispatcher::Create(success_callback, error_callback));
- blink::mojom::FileSystemOperationListenerPtr ptr;
- blink::mojom::FileSystemOperationListenerRequest request =
- mojo::MakeRequest(&ptr);
- op_listeners_.AddBinding(
- std::make_unique<FileSystemOperationListenerImpl>(request_id, this),
- std::move(request));
- GetFileSystemManager().ReadDirectory(path, std::move(ptr));
-}
-
-void FileSystemDispatcher::ReadDirectorySync(
- const GURL& path,
- const ReadDirectoryCallback& success_callback,
- const StatusCallback& error_callback) {
- int request_id = dispatchers_.Add(
- CallbackDispatcher::Create(success_callback, error_callback));
- std::vector<filesystem::mojom::DirectoryEntryPtr> entries;
- base::File::Error result = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().ReadDirectorySync(path, &entries, &result);
- if (result == base::File::FILE_OK)
- DidReadDirectory(request_id, std::move(entries), /*has_more=*/false);
- else
- DidFail(request_id, result);
-}
-
-void FileSystemDispatcher::Truncate(const GURL& path,
- int64_t offset,
- int* request_id_out,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- blink::mojom::FileSystemCancellableOperationPtr op_ptr;
- blink::mojom::FileSystemCancellableOperationRequest op_request =
- mojo::MakeRequest(&op_ptr);
- op_ptr.set_connection_error_handler(
- base::BindOnce(&FileSystemDispatcher::RemoveOperationPtr,
- base::Unretained(this), request_id));
- cancellable_operations_[request_id] = std::move(op_ptr);
- GetFileSystemManager().Truncate(
- path, offset, std::move(op_request),
- base::BindOnce(&FileSystemDispatcher::DidTruncate, base::Unretained(this),
- request_id));
-
- if (request_id_out)
- *request_id_out = request_id;
-}
-
-void FileSystemDispatcher::TruncateSync(const GURL& path,
- int64_t offset,
- const StatusCallback& callback) {
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().TruncateSync(path, offset, &error_code);
- std::move(callback).Run(error_code);
-}
-
-void FileSystemDispatcher::Write(const GURL& path,
- const std::string& blob_id,
- int64_t offset,
- int* request_id_out,
- const WriteCallback& success_callback,
- const StatusCallback& error_callback) {
- int request_id = dispatchers_.Add(
- CallbackDispatcher::Create(success_callback, error_callback));
-
- blink::mojom::FileSystemCancellableOperationPtr op_ptr;
- blink::mojom::FileSystemCancellableOperationRequest op_request =
- mojo::MakeRequest(&op_ptr);
- op_ptr.set_connection_error_handler(
- base::BindOnce(&FileSystemDispatcher::RemoveOperationPtr,
- base::Unretained(this), request_id));
- cancellable_operations_[request_id] = std::move(op_ptr);
-
- blink::mojom::FileSystemOperationListenerPtr listener_ptr;
- blink::mojom::FileSystemOperationListenerRequest request =
- mojo::MakeRequest(&listener_ptr);
- op_listeners_.AddBinding(
- std::make_unique<FileSystemOperationListenerImpl>(request_id, this),
- std::move(request));
-
- GetFileSystemManager().Write(path, blob_id, offset, std::move(op_request),
- std::move(listener_ptr));
-
- if (request_id_out)
- *request_id_out = request_id;
-}
-
-void FileSystemDispatcher::WriteSync(const GURL& path,
- const std::string& blob_id,
- int64_t offset,
- const WriteCallback& success_callback,
- const StatusCallback& error_callback) {
- int64_t byte_count;
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- GetFileSystemManager().WriteSync(path, blob_id, offset, &byte_count,
- &error_code);
- if (error_code == base::File::FILE_OK)
- std::move(success_callback).Run(byte_count, /*complete=*/true);
- else
- std::move(error_callback).Run(error_code);
-}
-
-void FileSystemDispatcher::Cancel(int request_id_to_cancel,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- if (cancellable_operations_.find(request_id_to_cancel) ==
- cancellable_operations_.end()) {
- DidFail(request_id, base::File::FILE_ERROR_INVALID_OPERATION);
- return;
- }
- cancellable_operations_[request_id_to_cancel]->Cancel(
- base::BindOnce(&FileSystemDispatcher::DidCancel, base::Unretained(this),
- request_id, request_id_to_cancel));
-}
-
-void FileSystemDispatcher::TouchFile(const GURL& path,
- const base::Time& last_access_time,
- const base::Time& last_modified_time,
- const StatusCallback& callback) {
- int request_id = dispatchers_.Add(CallbackDispatcher::Create(callback));
- GetFileSystemManager().TouchFile(
- path, last_access_time, last_modified_time,
- base::BindOnce(&FileSystemDispatcher::DidFinish, base::Unretained(this),
- request_id));
-}
-
-void FileSystemDispatcher::CreateSnapshotFile(
- const GURL& file_path,
- const CreateSnapshotFileCallback& success_callback,
- const StatusCallback& error_callback) {
- int request_id = dispatchers_.Add(
- CallbackDispatcher::Create(success_callback, error_callback));
- GetFileSystemManager().CreateSnapshotFile(
- file_path, base::BindOnce(&FileSystemDispatcher::DidCreateSnapshotFile,
- base::Unretained(this), request_id));
-}
-
-void FileSystemDispatcher::CreateSnapshotFileSync(
- const GURL& file_path,
- const CreateSnapshotFileCallback& success_callback,
- const StatusCallback& error_callback) {
- int request_id = dispatchers_.Add(
- CallbackDispatcher::Create(success_callback, error_callback));
- base::File::Info file_info;
- base::FilePath platform_path;
- base::File::Error error_code = base::File::FILE_ERROR_FAILED;
- blink::mojom::ReceivedSnapshotListenerPtr listener;
- GetFileSystemManager().CreateSnapshotFile(
- file_path, &file_info, &platform_path, &error_code, &listener);
- DidCreateSnapshotFile(request_id, std::move(file_info),
- std::move(platform_path), error_code,
- std::move(listener));
-}
-
-void FileSystemDispatcher::CreateFileWriter(
- const GURL& file_path,
- std::unique_ptr<CreateFileWriterCallbacks> callbacks) {
- GetFileSystemManager().CreateWriter(
- file_path,
- base::BindOnce(
- [](std::unique_ptr<CreateFileWriterCallbacks> callbacks,
- base::File::Error result, blink::mojom::FileWriterPtr writer) {
- if (result != base::File::FILE_OK) {
- callbacks->OnError(result);
- } else {
- callbacks->OnSuccess(writer.PassInterface().PassHandle());
- }
- },
- std::move(callbacks)));
-}
-
-void FileSystemDispatcher::ChooseEntry(
- int render_frame_id,
- std::unique_ptr<ChooseEntryCallbacks> callbacks) {
- GetFileSystemManager().ChooseEntry(
- render_frame_id,
- base::BindOnce(
- [](std::unique_ptr<ChooseEntryCallbacks> callbacks,
- base::File::Error result,
- std::vector<blink::mojom::FileSystemEntryPtr> entries) {
- if (result != base::File::FILE_OK) {
- callbacks->OnError(result);
- } else {
- blink::WebVector<blink::WebFileSystem::FileSystemEntry>
- web_entries(entries.size());
- for (size_t i = 0; i < entries.size(); ++i) {
- web_entries[i].file_system_id =
- blink::WebString::FromASCII(entries[i]->file_system_id);
- web_entries[i].base_name =
- blink::WebString::FromASCII(entries[i]->base_name);
- }
- callbacks->OnSuccess(std::move(web_entries));
- }
- },
- std::move(callbacks)));
-}
-
-void FileSystemDispatcher::DidOpenFileSystem(int request_id,
- const std::string& name,
- const GURL& root,
- base::File::Error error_code) {
- if (error_code == base::File::Error::FILE_OK) {
- CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
- DCHECK(dispatcher);
- dispatcher->DidOpenFileSystem(name, root);
- dispatchers_.Remove(request_id);
- } else {
- DidFail(request_id, error_code);
- }
-}
-
-void FileSystemDispatcher::DidResolveURL(int request_id,
- blink::mojom::FileSystemInfoPtr info,
- const base::FilePath& file_path,
- bool is_directory,
- base::File::Error error_code) {
- if (error_code == base::File::Error::FILE_OK) {
- DCHECK(info->root_url.is_valid());
- CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
- DCHECK(dispatcher);
- dispatcher->DidResolveURL(mojo::ConvertTo<storage::FileSystemInfo>(info),
- file_path, is_directory);
- dispatchers_.Remove(request_id);
- } else {
- DidFail(request_id, error_code);
- }
-}
-
-void FileSystemDispatcher::DidFinish(int request_id,
- base::File::Error error_code) {
- if (error_code == base::File::Error::FILE_OK) {
- CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
- DCHECK(dispatcher);
- dispatcher->DidSucceed();
- dispatchers_.Remove(request_id);
- } else {
- DidFail(request_id, error_code);
- }
-}
-
-void FileSystemDispatcher::DidReadMetadata(int request_id,
- const base::File::Info& file_info,
- base::File::Error error_code) {
- if (error_code == base::File::FILE_OK) {
- CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
- DCHECK(dispatcher);
- dispatcher->DidReadMetadata(file_info);
- dispatchers_.Remove(request_id);
- } else {
- DidFail(request_id, error_code);
- }
-}
-
-void FileSystemDispatcher::DidCreateSnapshotFile(
- int request_id,
- const base::File::Info& file_info,
- const base::FilePath& platform_path,
- base::File::Error error_code,
- blink::mojom::ReceivedSnapshotListenerPtr listener) {
- base::Optional<blink::mojom::ReceivedSnapshotListenerPtr> opt_listener;
- if (listener)
- opt_listener = std::move(listener);
- if (error_code == base::File::FILE_OK) {
- CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
- DCHECK(dispatcher);
- dispatcher->DidCreateSnapshotFile(file_info, platform_path,
- std::move(opt_listener), request_id);
- dispatchers_.Remove(request_id);
- } else {
- DidFail(request_id, error_code);
- }
-}
-
-void FileSystemDispatcher::DidReadDirectory(
- int request_id,
- std::vector<filesystem::mojom::DirectoryEntryPtr> entries,
- bool has_more) {
- CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
- DCHECK(dispatcher);
- std::vector<filesystem::mojom::DirectoryEntry> entries_copy;
- for (const auto& entry : entries) {
- entries_copy.push_back(*entry);
- }
- dispatcher->DidReadDirectory(std::move(entries_copy), has_more);
- if (!has_more)
- dispatchers_.Remove(request_id);
-}
-
-void FileSystemDispatcher::DidFail(int request_id,
- base::File::Error error_code) {
- CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
- DCHECK(dispatcher);
- dispatcher->DidFail(error_code);
- dispatchers_.Remove(request_id);
-}
-
-void FileSystemDispatcher::DidWrite(int request_id,
- int64_t bytes,
- bool complete) {
- CallbackDispatcher* dispatcher = dispatchers_.Lookup(request_id);
- DCHECK(dispatcher);
- dispatcher->DidWrite(bytes, complete);
- if (complete) {
- dispatchers_.Remove(request_id);
- RemoveOperationPtr(request_id);
- }
-}
-
-void FileSystemDispatcher::DidTruncate(int request_id,
- base::File::Error error_code) {
- // If |error_code| is ABORT, it means the operation was cancelled,
- // so we let DidCancel clean up the interface pointer.
- if (error_code != base::File::FILE_ERROR_ABORT)
- RemoveOperationPtr(request_id);
- DidFinish(request_id, error_code);
-}
-
-void FileSystemDispatcher::DidCancel(int request_id,
- int cancelled_request_id,
- base::File::Error error_code) {
- if (error_code == base::File::FILE_OK)
- RemoveOperationPtr(cancelled_request_id);
- DidFinish(request_id, error_code);
-}
-
-void FileSystemDispatcher::FileSystemOperationListenerImpl::ResultsRetrieved(
- std::vector<filesystem::mojom::DirectoryEntryPtr> entries,
- bool has_more) {
- dispatcher_->DidReadDirectory(request_id_, std::move(entries), has_more);
-}
-
-void FileSystemDispatcher::FileSystemOperationListenerImpl::ErrorOccurred(
- base::File::Error error_code) {
- dispatcher_->DidFail(request_id_, error_code);
-}
-
-void FileSystemDispatcher::FileSystemOperationListenerImpl::DidWrite(
- int64_t byte_count,
- bool complete) {
- dispatcher_->DidWrite(request_id_, byte_count, complete);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/fileapi/file_system_dispatcher.h b/chromium/content/renderer/fileapi/file_system_dispatcher.h
deleted file mode 100644
index ff90f64008d..00000000000
--- a/chromium/content/renderer/fileapi/file_system_dispatcher.h
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_
-#define CONTENT_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/callback_forward.h"
-#include "base/containers/id_map.h"
-#include "base/macros.h"
-#include "base/process/process.h"
-#include "components/services/filesystem/public/interfaces/types.mojom.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_platform_file.h"
-#include "mojo/public/cpp/bindings/strong_binding_set.h"
-#include "storage/common/fileapi/file_system_types.h"
-#include "storage/common/quota/quota_limit_type.h"
-#include "third_party/blink/public/mojom/filesystem/file_system.mojom.h"
-#include "third_party/blink/public/platform/web_callbacks.h"
-#include "third_party/blink/public/platform/web_file_system.h"
-#include "third_party/blink/public/platform/web_url.h"
-
-namespace base {
-class FilePath;
-}
-
-namespace storage {
-struct FileSystemInfo;
-}
-
-class GURL;
-
-namespace content {
-class FileSystemOperationListenerImpl;
-
-// Dispatches and sends file system related messages sent to/from a child
-// process from/to the main browser process. There is an instance held by
-// each WebFileSystemImpl and WebFileWriterImpl object.
-class FileSystemDispatcher {
- public:
- typedef base::Callback<void(base::File::Error error)> StatusCallback;
- typedef base::Callback<void(const base::File::Info& file_info)>
- MetadataCallback;
- typedef base::Callback<void(
- const base::File::Info& file_info,
- const base::FilePath& platform_path,
- base::Optional<blink::mojom::ReceivedSnapshotListenerPtr> opt_listener,
- int request_id)>
- CreateSnapshotFileCallback;
-
- typedef base::Callback<void(
- const std::vector<filesystem::mojom::DirectoryEntry>& entries,
- bool has_more)>
- ReadDirectoryCallback;
- typedef base::Callback<void(const std::string& name, const GURL& root)>
- OpenFileSystemCallback;
- typedef base::Callback<void(const storage::FileSystemInfo& info,
- const base::FilePath& file_path,
- bool is_directory)>
- ResolveURLCallback;
-
- typedef base::Callback<void(int64_t bytes, bool complete)> WriteCallback;
- typedef base::Callback<void(base::PlatformFile file,
- int file_open_id,
- storage::QuotaLimitType quota_policy)>
- OpenFileCallback;
-
- explicit FileSystemDispatcher(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
- ~FileSystemDispatcher();
-
- void OpenFileSystem(const GURL& origin_url,
- storage::FileSystemType type,
- const OpenFileSystemCallback& success_callback,
- const StatusCallback& error_callback);
- void OpenFileSystemSync(const GURL& origin_url,
- storage::FileSystemType type,
- const OpenFileSystemCallback& success_callback,
- const StatusCallback& error_callback);
-
- void ResolveURL(const GURL& filesystem_url,
- const ResolveURLCallback& success_callback,
- const StatusCallback& error_callback);
- void ResolveURLSync(const GURL& filesystem_url,
- const ResolveURLCallback& success_callback,
- const StatusCallback& error_callback);
-
- void Move(const GURL& src_path,
- const GURL& dest_path,
- const StatusCallback& callback);
- void MoveSync(const GURL& src_path,
- const GURL& dest_path,
- const StatusCallback& callback);
-
- void Copy(const GURL& src_path,
- const GURL& dest_path,
- const StatusCallback& callback);
- void CopySync(const GURL& src_path,
- const GURL& dest_path,
- const StatusCallback& callback);
-
- void Remove(const GURL& path, bool recursive, const StatusCallback& callback);
- void RemoveSync(const GURL& path,
- bool recursive,
- const StatusCallback& callback);
-
- void ReadMetadata(const GURL& path,
- const MetadataCallback& success_callback,
- const StatusCallback& error_callback);
- void ReadMetadataSync(const GURL& path,
- const MetadataCallback& success_callback,
- const StatusCallback& error_callback);
-
- void CreateFile(const GURL& path,
- bool exclusive,
- const StatusCallback& callback);
- void CreateFileSync(const GURL& path,
- bool exclusive,
- const StatusCallback& callback);
-
- void CreateDirectory(const GURL& path,
- bool exclusive,
- bool recursive,
- const StatusCallback& callback);
- void CreateDirectorySync(const GURL& path,
- bool exclusive,
- bool recursive,
- const StatusCallback& callback);
-
- void Exists(const GURL& path,
- bool for_directory,
- const StatusCallback& callback);
- void ExistsSync(const GURL& path,
- bool for_directory,
- const StatusCallback& callback);
-
- void ReadDirectory(const GURL& path,
- const ReadDirectoryCallback& success_callback,
- const StatusCallback& error_callback);
- void ReadDirectorySync(const GURL& path,
- const ReadDirectoryCallback& success_callback,
- const StatusCallback& error_callback);
-
- void Truncate(const GURL& path,
- int64_t offset,
- int* request_id_out,
- const StatusCallback& callback);
- void TruncateSync(const GURL& path,
- int64_t offset,
- const StatusCallback& callback);
-
- void Write(const GURL& path,
- const std::string& blob_id,
- int64_t offset,
- int* request_id_out,
- const WriteCallback& success_callback,
- const StatusCallback& error_callback);
- void WriteSync(const GURL& path,
- const std::string& blob_id,
- int64_t offset,
- const WriteCallback& success_callback,
- const StatusCallback& error_callback);
-
- void Cancel(int request_id_to_cancel, const StatusCallback& callback);
- void TouchFile(const GURL& file_path,
- const base::Time& last_access_time,
- const base::Time& last_modified_time,
- const StatusCallback& callback);
-
- void CreateSnapshotFile(const GURL& file_path,
- const CreateSnapshotFileCallback& success_callback,
- const StatusCallback& error_callback);
- void CreateSnapshotFileSync(
- const GURL& file_path,
- const CreateSnapshotFileCallback& success_callback,
- const StatusCallback& error_callback);
-
- using CreateFileWriterCallbacks =
- blink::WebFileSystem::CreateFileWriterCallbacks;
- void CreateFileWriter(const GURL& file_path,
- std::unique_ptr<CreateFileWriterCallbacks> callbacks);
-
- using ChooseEntryCallbacks = blink::WebFileSystem::ChooseEntryCallbacks;
- void ChooseEntry(int render_frame_id,
- std::unique_ptr<ChooseEntryCallbacks> callbacks);
-
- private:
- class CallbackDispatcher;
- class FileSystemOperationListenerImpl;
-
- void DidOpenFileSystem(int request_id,
- const std::string& name,
- const GURL& root,
- base::File::Error error_code);
- void DidResolveURL(int request_id,
- blink::mojom::FileSystemInfoPtr info,
- const base::FilePath& file_path,
- bool is_directory,
- base::File::Error error_code);
- void DidFinish(int request_id, base::File::Error error_code);
- void DidReadMetadata(int request_id,
- const base::File::Info& file_info,
- base::File::Error error);
- void DidCreateSnapshotFile(
- int request_id,
- const base::File::Info& file_info,
- const base::FilePath& platform_path,
- base::File::Error error_code,
- blink::mojom::ReceivedSnapshotListenerPtr listener);
- void DidReadDirectory(
- int request_id,
- std::vector<filesystem::mojom::DirectoryEntryPtr> entries,
- bool has_more);
- void DidFail(int request_id, base::File::Error error_code);
- void DidWrite(int request_id, int64_t bytes, bool complete);
- void DidTruncate(int request_id, base::File::Error error_code);
- void DidCancel(int request_id,
- int cancelled_request_id,
- base::File::Error error_code);
-
- void RemoveOperationPtr(int request_id) {
- DCHECK(cancellable_operations_.find(request_id) !=
- cancellable_operations_.end());
- cancellable_operations_.erase(request_id);
- }
-
- blink::mojom::FileSystemManager& GetFileSystemManager();
-
- blink::mojom::FileSystemManagerPtr file_system_manager_ptr_;
-
- base::IDMap<std::unique_ptr<CallbackDispatcher>> dispatchers_;
-
- mojo::StrongBindingSet<blink::mojom::FileSystemOperationListener>
- op_listeners_;
-
- using OperationsMap =
- std::unordered_map<int, blink::mojom::FileSystemCancellableOperationPtr>;
- OperationsMap cancellable_operations_;
-
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(FileSystemDispatcher);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_
diff --git a/chromium/content/renderer/fileapi/webfilesystem_impl.cc b/chromium/content/renderer/fileapi/webfilesystem_impl.cc
deleted file mode 100644
index b58fac0c441..00000000000
--- a/chromium/content/renderer/fileapi/webfilesystem_impl.cc
+++ /dev/null
@@ -1,483 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/fileapi/webfilesystem_impl.h"
-
-#include <stddef.h>
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread_local.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "components/services/filesystem/public/interfaces/types.mojom.h"
-#include "content/public/renderer/render_frame.h"
-#include "content/renderer/file_info_util.h"
-#include "content/renderer/fileapi/file_system_dispatcher.h"
-#include "content/renderer/fileapi/webfilewriter_impl.h"
-#include "content/renderer/render_thread_impl.h"
-#include "storage/common/fileapi/file_system_util.h"
-#include "third_party/blink/public/platform/file_path_conversion.h"
-#include "third_party/blink/public/platform/web_file_info.h"
-#include "third_party/blink/public/platform/web_file_system_callbacks.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_url.h"
-#include "third_party/blink/public/web/web_local_frame.h"
-#include "url/gurl.h"
-
-using blink::WebFileInfo;
-using blink::WebFileSystemCallbacks;
-using blink::WebFileSystemEntry;
-using blink::WebString;
-using blink::WebURL;
-using blink::WebVector;
-
-namespace content {
-
-namespace {
-
-base::LazyInstance<base::ThreadLocalPointer<WebFileSystemImpl>>::Leaky
- g_webfilesystem_tls = LAZY_INSTANCE_INITIALIZER;
-
-enum CallbacksUnregisterMode {
- UNREGISTER_CALLBACKS,
- DO_NOT_UNREGISTER_CALLBACKS,
-};
-
-template <typename Method, typename Params>
-void CallDispatcher(const WebFileSystemCallbacks& callbacks,
- Method async_method,
- Method sync_method,
- FileSystemDispatcher* dispatcher,
- Params&& params) {
- if (callbacks.ShouldBlockUntilCompletion())
- DispatchToMethod(dispatcher, sync_method, params);
- else
- DispatchToMethod(dispatcher, async_method, params);
-}
-
-// Bridging functions that convert the arguments into Blink objects
-// (e.g. WebFileInfo, WebString, WebVector<WebFileSystemEntry>)
-// and call WebFileSystemCallbacks's methods.
-void DidSucceed(WebFileSystemCallbacks* callbacks) {
- callbacks->DidSucceed();
-}
-
-void DidReadMetadata(const base::File::Info& file_info,
- WebFileSystemCallbacks* callbacks) {
- WebFileInfo web_file_info;
- FileInfoToWebFileInfo(file_info, &web_file_info);
- callbacks->DidReadMetadata(web_file_info);
-}
-
-void DidReadDirectory(
- const std::vector<filesystem::mojom::DirectoryEntry>& entries,
- bool has_more,
- WebFileSystemCallbacks* callbacks) {
- WebVector<WebFileSystemEntry> file_system_entries(entries.size());
- for (size_t i = 0; i < entries.size(); ++i) {
- file_system_entries[i].name =
- blink::FilePathToWebString(base::FilePath(entries[i].name));
- file_system_entries[i].is_directory =
- entries[i].type == filesystem::mojom::FsFileType::DIRECTORY;
- }
- callbacks->DidReadDirectory(file_system_entries, has_more);
-}
-
-void DidOpenFileSystem(const std::string& name,
- const GURL& root,
- WebFileSystemCallbacks* callbacks) {
- callbacks->DidOpenFileSystem(blink::WebString::FromUTF8(name), root);
-}
-
-void DidResolveURL(const std::string& name,
- const GURL& root_url,
- storage::FileSystemType mount_type,
- const base::FilePath& file_path,
- bool is_directory,
- WebFileSystemCallbacks* callbacks) {
- callbacks->DidResolveURL(blink::WebString::FromUTF8(name), root_url,
- static_cast<blink::WebFileSystemType>(mount_type),
- blink::FilePathToWebString(file_path), is_directory);
-}
-
-void DidFail(base::File::Error error, WebFileSystemCallbacks* callbacks) {
- callbacks->DidFail(storage::FileErrorToWebFileError(error));
-}
-
-void RunCallbacks(int callbacks_id,
- base::OnceCallback<void(WebFileSystemCallbacks*)> callback,
- CallbacksUnregisterMode callbacks_unregister_mode) {
- WebFileSystemImpl* filesystem =
- WebFileSystemImpl::ThreadSpecificInstance(nullptr);
- if (!filesystem)
- return;
- WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id);
- if (callbacks_unregister_mode == UNREGISTER_CALLBACKS)
- filesystem->UnregisterCallbacks(callbacks_id);
- std::move(callback).Run(&callbacks);
-}
-
-//-----------------------------------------------------------------------------
-// Callback adapters.
-
-void OpenFileSystemCallbackAdapter(int callbacks_id,
- const std::string& name,
- const GURL& root) {
- RunCallbacks(callbacks_id, base::BindOnce(&DidOpenFileSystem, name, root),
- UNREGISTER_CALLBACKS);
-}
-
-void ResolveURLCallbackAdapter(int callbacks_id,
- const storage::FileSystemInfo& info,
- const base::FilePath& file_path,
- bool is_directory) {
- base::FilePath normalized_path(
- storage::VirtualPath::GetNormalizedFilePath(file_path));
- RunCallbacks(callbacks_id,
- base::BindOnce(&DidResolveURL, info.name, info.root_url,
- info.mount_type, normalized_path, is_directory),
- UNREGISTER_CALLBACKS);
-}
-
-void StatusCallbackAdapter(int callbacks_id, base::File::Error error) {
- if (error == base::File::FILE_OK) {
- RunCallbacks(callbacks_id, base::BindOnce(&DidSucceed),
- UNREGISTER_CALLBACKS);
- } else {
- RunCallbacks(callbacks_id, base::BindOnce(&DidFail, error),
- UNREGISTER_CALLBACKS);
- }
-}
-
-void ReadMetadataCallbackAdapter(int callbacks_id,
- const base::File::Info& file_info) {
- RunCallbacks(callbacks_id, base::BindOnce(&DidReadMetadata, file_info),
- UNREGISTER_CALLBACKS);
-}
-
-void ReadDirectoryCallbackAdapter(
- int callbacks_id,
- const std::vector<filesystem::mojom::DirectoryEntry>& entries,
- bool has_more) {
- RunCallbacks(callbacks_id,
- base::BindOnce(&DidReadDirectory, entries, has_more),
- has_more ? DO_NOT_UNREGISTER_CALLBACKS : UNREGISTER_CALLBACKS);
-}
-
-void DidCreateFileWriter(int callbacks_id,
- const GURL& path,
- blink::WebFileWriterClient* client,
- base::SingleThreadTaskRunner* main_thread_task_runner,
- const base::File::Info& file_info) {
- WebFileSystemImpl* filesystem =
- WebFileSystemImpl::ThreadSpecificInstance(nullptr);
- if (!filesystem)
- return;
-
- WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id);
- filesystem->UnregisterCallbacks(callbacks_id);
-
- if (file_info.is_directory || file_info.size < 0) {
- callbacks.DidFail(blink::kWebFileErrorInvalidState);
- return;
- }
- WebFileWriterImpl::Type type = callbacks.ShouldBlockUntilCompletion()
- ? WebFileWriterImpl::TYPE_SYNC
- : WebFileWriterImpl::TYPE_ASYNC;
- callbacks.DidCreateFileWriter(
- new WebFileWriterImpl(path, client, type, main_thread_task_runner),
- file_info.size);
-}
-
-void CreateFileWriterCallbackAdapter(
- int callbacks_id,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
- const GURL& path,
- blink::WebFileWriterClient* client,
- const base::File::Info& file_info) {
- DidCreateFileWriter(callbacks_id, path, client, main_thread_task_runner.get(),
- file_info);
-}
-
-void DidCreateSnapshotFile(
- int callbacks_id,
- const base::File::Info& file_info,
- const base::FilePath& platform_path,
- base::Optional<blink::mojom::ReceivedSnapshotListenerPtr> opt_listener,
- int request_id) {
- WebFileSystemImpl* filesystem =
- WebFileSystemImpl::ThreadSpecificInstance(nullptr);
- if (!filesystem)
- return;
-
- WebFileSystemCallbacks callbacks = filesystem->GetCallbacks(callbacks_id);
- filesystem->UnregisterCallbacks(callbacks_id);
-
- WebFileInfo web_file_info;
- FileInfoToWebFileInfo(file_info, &web_file_info);
- web_file_info.platform_path = blink::FilePathToWebString(platform_path);
- callbacks.DidCreateSnapshotFile(web_file_info);
-
- // TODO(michaeln,kinuko): Use ThreadSafeSender when Blob becomes
- // non-bridge model.
- if (opt_listener) {
- opt_listener.value()->DidReceiveSnapshotFile();
- }
-}
-
-void CreateSnapshotFileCallbackAdapter(
- int callbacks_id,
- const base::File::Info& file_info,
- const base::FilePath& platform_path,
- base::Optional<blink::mojom::ReceivedSnapshotListenerPtr> opt_listener,
- int request_id) {
- DidCreateSnapshotFile(callbacks_id, file_info, platform_path,
- std::move(opt_listener), request_id);
-}
-
-} // namespace
-
-//-----------------------------------------------------------------------------
-// WebFileSystemImpl
-
-WebFileSystemImpl* WebFileSystemImpl::ThreadSpecificInstance(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) {
- if (g_webfilesystem_tls.Pointer()->Get() || !main_thread_task_runner)
- return g_webfilesystem_tls.Pointer()->Get();
- WebFileSystemImpl* filesystem =
- new WebFileSystemImpl(std::move(main_thread_task_runner));
- if (WorkerThread::GetCurrentId())
- WorkerThread::AddObserver(filesystem);
- return filesystem;
-}
-
-void WebFileSystemImpl::DeleteThreadSpecificInstance() {
- DCHECK(!WorkerThread::GetCurrentId());
- if (g_webfilesystem_tls.Pointer()->Get())
- delete g_webfilesystem_tls.Pointer()->Get();
-}
-
-WebFileSystemImpl::WebFileSystemImpl(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
- : main_thread_task_runner_(main_thread_task_runner),
- next_callbacks_id_(1),
- file_system_dispatcher_(std::move(main_thread_task_runner)) {
- g_webfilesystem_tls.Pointer()->Set(this);
-}
-
-WebFileSystemImpl::~WebFileSystemImpl() {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- g_webfilesystem_tls.Pointer()->Set(nullptr);
-}
-
-void WebFileSystemImpl::WillStopCurrentWorkerThread() {
- delete this;
-}
-
-void WebFileSystemImpl::OpenFileSystem(const blink::WebURL& storage_partition,
- blink::WebFileSystemType type,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(
- callbacks, &FileSystemDispatcher::OpenFileSystem,
- &FileSystemDispatcher::OpenFileSystemSync, &file_system_dispatcher_,
- std::make_tuple(
- GURL(storage_partition), static_cast<storage::FileSystemType>(type),
- base::BindRepeating(&OpenFileSystemCallbackAdapter, callbacks_id),
- base::BindRepeating(&StatusCallbackAdapter, callbacks_id)));
-}
-
-void WebFileSystemImpl::ResolveURL(const blink::WebURL& filesystem_url,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(
- callbacks, &FileSystemDispatcher::ResolveURL,
- &FileSystemDispatcher::ResolveURLSync, &file_system_dispatcher_,
- std::make_tuple(
- GURL(filesystem_url),
- base::BindRepeating(&ResolveURLCallbackAdapter, callbacks_id),
- base::BindRepeating(&StatusCallbackAdapter, callbacks_id)));
-}
-
-void WebFileSystemImpl::Move(const blink::WebURL& src_path,
- const blink::WebURL& dest_path,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(callbacks, &FileSystemDispatcher::Move,
- &FileSystemDispatcher::MoveSync, &file_system_dispatcher_,
- std::make_tuple(GURL(src_path), GURL(dest_path),
- base::BindRepeating(&StatusCallbackAdapter,
- callbacks_id)));
-}
-
-void WebFileSystemImpl::Copy(const blink::WebURL& src_path,
- const blink::WebURL& dest_path,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(callbacks, &FileSystemDispatcher::Copy,
- &FileSystemDispatcher::CopySync, &file_system_dispatcher_,
- std::make_tuple(GURL(src_path), GURL(dest_path),
- base::BindRepeating(&StatusCallbackAdapter,
- callbacks_id)));
-}
-
-void WebFileSystemImpl::Remove(const blink::WebURL& path,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(callbacks, &FileSystemDispatcher::Remove,
- &FileSystemDispatcher::RemoveSync, &file_system_dispatcher_,
- std::make_tuple(GURL(path), /*recursive=*/false,
- base::BindRepeating(&StatusCallbackAdapter,
- callbacks_id)));
-}
-
-void WebFileSystemImpl::RemoveRecursively(const blink::WebURL& path,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(callbacks, &FileSystemDispatcher::Remove,
- &FileSystemDispatcher::RemoveSync, &file_system_dispatcher_,
- std::make_tuple(GURL(path), /*recursive=*/true,
- base::BindRepeating(&StatusCallbackAdapter,
- callbacks_id)));
-}
-
-void WebFileSystemImpl::ReadMetadata(const blink::WebURL& path,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(
- callbacks, &FileSystemDispatcher::ReadMetadata,
- &FileSystemDispatcher::ReadMetadataSync, &file_system_dispatcher_,
- std::make_tuple(
- GURL(path),
- base::BindRepeating(&ReadMetadataCallbackAdapter, callbacks_id),
- base::BindRepeating(&StatusCallbackAdapter, callbacks_id)));
-}
-
-void WebFileSystemImpl::CreateFile(const blink::WebURL& path,
- bool exclusive,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(
- callbacks, &FileSystemDispatcher::CreateFile,
- &FileSystemDispatcher::CreateFileSync, &file_system_dispatcher_,
- std::make_tuple(
- GURL(path), exclusive,
- base::BindRepeating(&StatusCallbackAdapter, callbacks_id)));
-}
-
-void WebFileSystemImpl::CreateDirectory(const blink::WebURL& path,
- bool exclusive,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(
- callbacks, &FileSystemDispatcher::CreateDirectory,
- &FileSystemDispatcher::CreateDirectorySync, &file_system_dispatcher_,
- std::make_tuple(
- GURL(path), exclusive, /*recursive=*/false,
- base::BindRepeating(&StatusCallbackAdapter, callbacks_id)));
-}
-
-void WebFileSystemImpl::FileExists(const blink::WebURL& path,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(callbacks, &FileSystemDispatcher::Exists,
- &FileSystemDispatcher::ExistsSync, &file_system_dispatcher_,
- std::make_tuple(GURL(path), /*directory=*/false,
- base::BindRepeating(&StatusCallbackAdapter,
- callbacks_id)));
-}
-
-void WebFileSystemImpl::DirectoryExists(const blink::WebURL& path,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(callbacks, &FileSystemDispatcher::Exists,
- &FileSystemDispatcher::ExistsSync, &file_system_dispatcher_,
- std::make_tuple(GURL(path), /*directory=*/true,
- base::BindRepeating(&StatusCallbackAdapter,
- callbacks_id)));
-}
-
-int WebFileSystemImpl::ReadDirectory(const blink::WebURL& path,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(
- callbacks, &FileSystemDispatcher::ReadDirectory,
- &FileSystemDispatcher::ReadDirectorySync, &file_system_dispatcher_,
- std::make_tuple(
- GURL(path),
- base::BindRepeating(&ReadDirectoryCallbackAdapter, callbacks_id),
- base::BindRepeating(&StatusCallbackAdapter, callbacks_id)));
- return callbacks_id;
-}
-
-void WebFileSystemImpl::CreateFileWriter(const WebURL& path,
- blink::WebFileWriterClient* client,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(
- callbacks, &FileSystemDispatcher::ReadMetadata,
- &FileSystemDispatcher::ReadMetadataSync, &file_system_dispatcher_,
- std::make_tuple(
- GURL(path),
- base::BindRepeating(&CreateFileWriterCallbackAdapter, callbacks_id,
- main_thread_task_runner_, GURL(path), client),
- base::BindRepeating(&StatusCallbackAdapter, callbacks_id)));
-}
-
-void WebFileSystemImpl::CreateFileWriter(
- const blink::WebURL& path,
- std::unique_ptr<CreateFileWriterCallbacks> callbacks) {
- file_system_dispatcher_.CreateFileWriter(path, std::move(callbacks));
-}
-
-void WebFileSystemImpl::CreateSnapshotFileAndReadMetadata(
- const blink::WebURL& path,
- WebFileSystemCallbacks callbacks) {
- int callbacks_id = RegisterCallbacks(callbacks);
- CallDispatcher(
- callbacks, &FileSystemDispatcher::CreateSnapshotFile,
- &FileSystemDispatcher::CreateSnapshotFileSync, &file_system_dispatcher_,
- std::make_tuple(
- GURL(path),
- base::BindRepeating(&CreateSnapshotFileCallbackAdapter, callbacks_id),
- base::BindRepeating(&StatusCallbackAdapter, callbacks_id)));
-}
-
-void WebFileSystemImpl::ChooseEntry(
- blink::WebFrame* frame,
- std::unique_ptr<ChooseEntryCallbacks> callbacks) {
- file_system_dispatcher_.ChooseEntry(
- RenderFrame::GetRoutingIdForWebFrame(frame), std::move(callbacks));
-}
-
-int WebFileSystemImpl::RegisterCallbacks(
- const WebFileSystemCallbacks& callbacks) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- int id = next_callbacks_id_++;
- callbacks_[id] = callbacks;
- return id;
-}
-
-WebFileSystemCallbacks WebFileSystemImpl::GetCallbacks(int callbacks_id) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- CallbacksMap::iterator found = callbacks_.find(callbacks_id);
- DCHECK(found != callbacks_.end());
- return found->second;
-}
-
-void WebFileSystemImpl::UnregisterCallbacks(int callbacks_id) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- CallbacksMap::iterator found = callbacks_.find(callbacks_id);
- DCHECK(found != callbacks_.end());
- callbacks_.erase(found);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/fileapi/webfilesystem_impl.h b/chromium/content/renderer/fileapi/webfilesystem_impl.h
deleted file mode 100644
index eeb7145f71c..00000000000
--- a/chromium/content/renderer/fileapi/webfilesystem_impl.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_
-#define CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_
-
-#include <map>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/threading/thread_checker.h"
-#include "content/public/renderer/worker_thread.h"
-#include "content/renderer/fileapi/file_system_dispatcher.h"
-#include "third_party/blink/public/platform/web_file_system.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace blink {
-class WebURL;
-class WebFileWriterClient;
-}
-
-namespace content {
-
-class WebFileSystemImpl : public blink::WebFileSystem,
- public WorkerThread::Observer {
- public:
- // Returns thread-specific instance. If non-null |main_thread_loop|
- // is given and no thread-specific instance has been created it may
- // create a new instance.
- static WebFileSystemImpl* ThreadSpecificInstance(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
-
- // Deletes thread-specific instance (if exists). For workers it deletes
- // itself in WillStopCurrentWorkerThread(), but for an instance created on the
- // main thread this method must be called.
- static void DeleteThreadSpecificInstance();
-
- explicit WebFileSystemImpl(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
- ~WebFileSystemImpl() override;
-
- // WorkerThread::Observer implementation.
- void WillStopCurrentWorkerThread() override;
-
- // WebFileSystem implementation.
- void OpenFileSystem(const blink::WebURL& storage_partition,
- const blink::WebFileSystemType type,
- blink::WebFileSystemCallbacks) override;
- void ResolveURL(const blink::WebURL& filesystem_url,
- blink::WebFileSystemCallbacks) override;
- void Move(const blink::WebURL& src_path,
- const blink::WebURL& dest_path,
- blink::WebFileSystemCallbacks) override;
- void Copy(const blink::WebURL& src_path,
- const blink::WebURL& dest_path,
- blink::WebFileSystemCallbacks) override;
- void Remove(const blink::WebURL& path,
- blink::WebFileSystemCallbacks) override;
- void RemoveRecursively(const blink::WebURL& path,
- blink::WebFileSystemCallbacks) override;
- void ReadMetadata(const blink::WebURL& path,
- blink::WebFileSystemCallbacks) override;
- void CreateFile(const blink::WebURL& path,
- bool exclusive,
- blink::WebFileSystemCallbacks) override;
- void CreateDirectory(const blink::WebURL& path,
- bool exclusive,
- blink::WebFileSystemCallbacks) override;
- void FileExists(const blink::WebURL& path,
- blink::WebFileSystemCallbacks) override;
- void DirectoryExists(const blink::WebURL& path,
- blink::WebFileSystemCallbacks) override;
- int ReadDirectory(const blink::WebURL& path,
- blink::WebFileSystemCallbacks) override;
- void CreateFileWriter(const blink::WebURL& path,
- blink::WebFileWriterClient*,
- blink::WebFileSystemCallbacks) override;
- void CreateFileWriter(
- const blink::WebURL& path,
- std::unique_ptr<CreateFileWriterCallbacks> callbacks) override;
- void CreateSnapshotFileAndReadMetadata(
- const blink::WebURL& path,
- blink::WebFileSystemCallbacks) override;
-
- void ChooseEntry(blink::WebFrame* frame,
- std::unique_ptr<ChooseEntryCallbacks>) override;
-
- int RegisterCallbacks(const blink::WebFileSystemCallbacks& callbacks);
- blink::WebFileSystemCallbacks GetCallbacks(int callbacks_id);
- void UnregisterCallbacks(int callbacks_id);
-
- private:
- typedef std::map<int, blink::WebFileSystemCallbacks> CallbacksMap;
-
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
-
- CallbacksMap callbacks_;
- int next_callbacks_id_;
- FileSystemDispatcher file_system_dispatcher_;
-
- // Thread-affine per use of TLS in impl.
- THREAD_CHECKER(thread_checker_);
-
- DISALLOW_COPY_AND_ASSIGN(WebFileSystemImpl);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_
diff --git a/chromium/content/renderer/fileapi/webfilewriter_base.cc b/chromium/content/renderer/fileapi/webfilewriter_base.cc
deleted file mode 100644
index edce76d8e37..00000000000
--- a/chromium/content/renderer/fileapi/webfilewriter_base.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/fileapi/webfilewriter_base.h"
-
-#include "base/logging.h"
-#include "storage/common/fileapi/file_system_util.h"
-#include "third_party/blink/public/platform/web_file_error.h"
-#include "third_party/blink/public/platform/web_file_writer_client.h"
-#include "third_party/blink/public/platform/web_url.h"
-
-using storage::FileErrorToWebFileError;
-
-namespace content {
-
-WebFileWriterBase::WebFileWriterBase(const GURL& path,
- blink::WebFileWriterClient* client)
- : path_(path),
- client_(client),
- operation_(kOperationNone),
- cancel_state_(kCancelNotInProgress) {}
-
-WebFileWriterBase::~WebFileWriterBase() {}
-
-void WebFileWriterBase::Truncate(long long length) {
- DCHECK(kOperationNone == operation_);
- DCHECK(kCancelNotInProgress == cancel_state_);
- operation_ = kOperationTruncate;
- DoTruncate(path_, length);
-}
-
-void WebFileWriterBase::Write(long long position, const blink::WebString& id) {
- DCHECK_EQ(kOperationNone, operation_);
- DCHECK_EQ(kCancelNotInProgress, cancel_state_);
- operation_ = kOperationWrite;
- DoWrite(path_, id.Utf8(), position);
-}
-
-// When we cancel a write/truncate, we always get back the result of the write
-// before the result of the cancel, no matter what happens.
-// So we'll get back either
-// success [of the write/truncate, in a DidWrite(XXX, true)/DidSucceed() call]
-// followed by failure [of the cancel]; or
-// failure [of the write, either from cancel or other reasons] followed by
-// the result of the cancel.
-// In the write case, there could also be queued up non-terminal DidWrite calls
-// before any of that comes back, but there will always be a terminal write
-// response [success or failure] after them, followed by the cancel result, so
-// we can ignore non-terminal write responses, take the terminal write success
-// or the first failure as the last write response, then know that the next
-// thing to come back is the cancel response. We only notify the
-// AsyncFileWriterClient when it's all over.
-void WebFileWriterBase::Cancel() {
- // Check for the cancel passing the previous operation's return in-flight.
- if (kOperationWrite != operation_ && kOperationTruncate != operation_)
- return;
- if (kCancelNotInProgress != cancel_state_)
- return;
- cancel_state_ = kCancelSent;
- DoCancel();
-}
-
-void WebFileWriterBase::DidFinish(base::File::Error error_code) {
- if (error_code == base::File::FILE_OK)
- DidSucceed();
- else
- DidFail(error_code);
-}
-
-void WebFileWriterBase::DidWrite(int64_t bytes, bool complete) {
- DCHECK(kOperationWrite == operation_);
- switch (cancel_state_) {
- case kCancelNotInProgress:
- if (complete)
- operation_ = kOperationNone;
- client_->DidWrite(bytes, complete);
- break;
- case kCancelSent:
- // This is the success call of the write, which we'll eat, even though
- // it succeeded before the cancel got there. We accepted the cancel call,
- // so the write will eventually return an error.
- if (complete)
- cancel_state_ = kCancelReceivedWriteResponse;
- break;
- case kCancelReceivedWriteResponse:
- default:
- NOTREACHED();
- }
-}
-
-void WebFileWriterBase::DidSucceed() {
- // Write never gets a DidSucceed call, so this is either a cancel or truncate
- // response.
- switch (cancel_state_) {
- case kCancelNotInProgress:
- // A truncate succeeded, with no complications.
- DCHECK(kOperationTruncate == operation_);
- operation_ = kOperationNone;
- client_->DidTruncate();
- break;
- case kCancelSent:
- DCHECK(kOperationTruncate == operation_);
- // This is the success call of the truncate, which we'll eat, even though
- // it succeeded before the cancel got there. We accepted the cancel call,
- // so the truncate will eventually return an error.
- cancel_state_ = kCancelReceivedWriteResponse;
- break;
- case kCancelReceivedWriteResponse:
- // This is the success of the cancel operation.
- FinishCancel();
- break;
- default:
- NOTREACHED();
- }
-}
-
-void WebFileWriterBase::DidFail(base::File::Error error_code) {
- DCHECK(kOperationNone != operation_);
- switch (cancel_state_) {
- case kCancelNotInProgress:
- // A write or truncate failed.
- operation_ = kOperationNone;
- client_->DidFail(FileErrorToWebFileError(error_code));
- break;
- case kCancelSent:
- // This is the failure of a write or truncate; the next message should be
- // the result of the cancel. We don't assume that it'll be a success, as
- // the write/truncate could have failed for other reasons.
- cancel_state_ = kCancelReceivedWriteResponse;
- break;
- case kCancelReceivedWriteResponse:
- // The cancel reported failure, meaning that the write or truncate
- // finished before the cancel got there. But we suppressed the
- // write/truncate's response, and will now report that it was cancelled.
- FinishCancel();
- break;
- default:
- NOTREACHED();
- }
-}
-
-void WebFileWriterBase::FinishCancel() {
- DCHECK(kCancelReceivedWriteResponse == cancel_state_);
- DCHECK(kOperationNone != operation_);
- cancel_state_ = kCancelNotInProgress;
- operation_ = kOperationNone;
- client_->DidFail(blink::kWebFileErrorAbort);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/fileapi/webfilewriter_base.h b/chromium/content/renderer/fileapi/webfilewriter_base.h
deleted file mode 100644
index 4c28e91e297..00000000000
--- a/chromium/content/renderer/fileapi/webfilewriter_base.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_BASE_H_
-#define CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_BASE_H_
-
-#include <stdint.h>
-
-#include "base/files/file.h"
-#include "content/common/content_export.h"
-#include "third_party/blink/public/platform/web_file_writer.h"
-#include "url/gurl.h"
-
-namespace blink {
-class WebFileWriterClient;
-}
-
-namespace content {
-
-class CONTENT_EXPORT WebFileWriterBase : public blink::WebFileWriter {
- public:
- WebFileWriterBase(const GURL& path, blink::WebFileWriterClient* client);
- ~WebFileWriterBase() override;
-
- // WebFileWriter implementation
- void Truncate(long long length) override;
- void Write(long long position, const blink::WebString& id) override;
- void Cancel() override;
-
- protected:
- // This calls DidSucceed() or DidFail() based on the value of |error_code|.
- void DidFinish(base::File::Error error_code);
-
- void DidWrite(int64_t bytes, bool complete);
- void DidSucceed();
- void DidFail(base::File::Error error_code);
-
- // Derived classes must provide these methods to asynchronously perform
- // the requested operation, and they must call the appropiate DidSomething
- // method upon completion and as progress is made in the Write case.
- virtual void DoTruncate(const GURL& path, int64_t offset) = 0;
- virtual void DoWrite(const GURL& path,
- const std::string& blob_id,
- int64_t offset) = 0;
- virtual void DoCancel() = 0;
-
- private:
- enum OperationType {
- kOperationNone,
- kOperationWrite,
- kOperationTruncate
- };
-
- enum CancelState {
- kCancelNotInProgress,
- kCancelSent,
- kCancelReceivedWriteResponse,
- };
-
- void FinishCancel();
-
- GURL path_;
- blink::WebFileWriterClient* client_;
- OperationType operation_;
- CancelState cancel_state_;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_BASE_H_
diff --git a/chromium/content/renderer/fileapi/webfilewriter_base_unittest.cc b/chromium/content/renderer/fileapi/webfilewriter_base_unittest.cc
deleted file mode 100644
index 58bd5aaa08f..00000000000
--- a/chromium/content/renderer/fileapi/webfilewriter_base_unittest.cc
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/fileapi/webfilewriter_base.h"
-
-#include <stdint.h>
-
-#include <memory>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/strings/utf_string_conversions.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_file_error.h"
-#include "third_party/blink/public/platform/web_file_writer_client.h"
-#include "third_party/blink/public/platform/web_url.h"
-#include "url/gurl.h"
-
-namespace content {
-
-namespace {
-
-// We use particular offsets to trigger particular behaviors
-// in the TestableFileWriter.
-const int kNoOffset = -1;
-const int kBasicFileTruncate_Offset = 1;
-const int kErrorFileTruncate_Offset = 2;
-const int kCancelFileTruncate_Offset = 3;
-const int kCancelFailedTruncate_Offset = 4;
-const int kBasicFileWrite_Offset = 1;
-const int kErrorFileWrite_Offset = 2;
-const int kMultiFileWrite_Offset = 3;
-const int kCancelFileWriteBeforeCompletion_Offset = 4;
-const int kCancelFileWriteAfterCompletion_Offset = 5;
-
-GURL mock_path_as_gurl() {
- return GURL("MockPath");
-}
-
-} // namespace
-
-class TestableFileWriter : public WebFileWriterBase {
- public:
- explicit TestableFileWriter(blink::WebFileWriterClient* client)
- : WebFileWriterBase(mock_path_as_gurl(), client) {
- reset();
- }
-
- void reset() {
- received_truncate_ = false;
- received_truncate_path_ = GURL();
- received_truncate_offset_ = kNoOffset;
- received_write_ = false;
- received_write_path_ = GURL();
- received_write_offset_ = kNoOffset;
- received_write_blob_uuid_ = std::string();
- received_cancel_ = false;
- }
-
- bool received_truncate_;
- GURL received_truncate_path_;
- int64_t received_truncate_offset_;
- bool received_write_;
- GURL received_write_path_;
- std::string received_write_blob_uuid_;
- int64_t received_write_offset_;
- bool received_cancel_;
-
- protected:
- void DoTruncate(const GURL& path, int64_t offset) override {
- received_truncate_ = true;
- received_truncate_path_ = path;
- received_truncate_offset_ = offset;
-
- if (offset == kBasicFileTruncate_Offset) {
- DidSucceed();
- } else if (offset == kErrorFileTruncate_Offset) {
- DidFail(base::File::FILE_ERROR_NOT_FOUND);
- } else if (offset == kCancelFileTruncate_Offset) {
- Cancel();
- DidSucceed(); // truncate completion
- DidSucceed(); // cancel completion
- } else if (offset == kCancelFailedTruncate_Offset) {
- Cancel();
- DidFail(base::File::FILE_ERROR_NOT_FOUND); // truncate completion
- DidSucceed(); // cancel completion
- } else {
- FAIL();
- }
- }
-
- void DoWrite(const GURL& path,
- const std::string& blob_uuid,
- int64_t offset) override {
- received_write_ = true;
- received_write_path_ = path;
- received_write_offset_ = offset;
- received_write_blob_uuid_ = blob_uuid;
-
- if (offset == kBasicFileWrite_Offset) {
- DidWrite(1, true);
- } else if (offset == kErrorFileWrite_Offset) {
- DidFail(base::File::FILE_ERROR_NOT_FOUND);
- } else if (offset == kMultiFileWrite_Offset) {
- DidWrite(1, false);
- DidWrite(1, false);
- DidWrite(1, true);
- } else if (offset == kCancelFileWriteBeforeCompletion_Offset) {
- DidWrite(1, false);
- Cancel();
- DidWrite(1, false);
- DidWrite(1, false);
- DidFail(base::File::FILE_ERROR_FAILED); // write completion
- DidSucceed(); // cancel completion
- } else if (offset == kCancelFileWriteAfterCompletion_Offset) {
- DidWrite(1, false);
- Cancel();
- DidWrite(1, false);
- DidWrite(1, false);
- DidWrite(1, true); // write completion
- DidFail(base::File::FILE_ERROR_FAILED); // cancel completion
- } else {
- FAIL();
- }
- }
-
- void DoCancel() override { received_cancel_ = true; }
-};
-
-class FileWriterTest : public testing::Test,
- public blink::WebFileWriterClient {
- public:
- FileWriterTest() {
- reset();
- }
-
- blink::WebFileWriter* writer() {
- return testable_writer_.get();
- }
-
- // WebFileWriterClient overrides
- void DidWrite(long long bytes, bool complete) override {
- EXPECT_FALSE(received_did_write_complete_);
- ++received_did_write_count_;
- received_did_write_bytes_total_ += bytes;
- if (complete)
- received_did_write_complete_ = true;
-
- if (delete_in_client_callback_)
- testable_writer_.reset(nullptr);
- }
-
- void DidTruncate() override {
- EXPECT_FALSE(received_did_truncate_);
- received_did_truncate_ = true;
- if (delete_in_client_callback_)
- testable_writer_.reset(nullptr);
- }
-
- void DidFail(blink::WebFileError error) override {
- EXPECT_FALSE(received_did_fail_);
- received_did_fail_ = true;
- fail_error_received_ = error;
- if (delete_in_client_callback_)
- testable_writer_.reset(nullptr);
- }
-
- protected:
- void reset() {
- testable_writer_.reset(new TestableFileWriter(this));
- delete_in_client_callback_ = false;
- received_did_write_count_ = 0;
- received_did_write_bytes_total_ = 0;
- received_did_write_complete_ = false;
- received_did_truncate_ = false;
- received_did_fail_ = false;
- fail_error_received_ = static_cast<blink::WebFileError>(0);
- }
-
- std::unique_ptr<TestableFileWriter> testable_writer_;
- bool delete_in_client_callback_;
-
- // Observed WebFileWriterClient artifacts.
- int received_did_write_count_;
- long long received_did_write_bytes_total_;
- bool received_did_write_complete_;
- bool received_did_truncate_;
- bool received_did_fail_;
- blink::WebFileError fail_error_received_;
-
- DISALLOW_COPY_AND_ASSIGN(FileWriterTest);
-};
-
-TEST_F(FileWriterTest, BasicFileWrite) {
- // Call the webkit facing api.
- const std::string kBlobId("1234");
- writer()->Write(kBasicFileWrite_Offset, blink::WebString::FromUTF8(kBlobId));
-
- // Check that the derived class gets called correctly.
- EXPECT_TRUE(testable_writer_->received_write_);
- EXPECT_EQ(testable_writer_->received_write_path_,
- mock_path_as_gurl());
- EXPECT_EQ(kBasicFileWrite_Offset,
- testable_writer_->received_write_offset_);
- EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
- EXPECT_FALSE(testable_writer_->received_truncate_);
- EXPECT_FALSE(testable_writer_->received_cancel_);
-
- // Check that the client gets called correctly.
- EXPECT_EQ(1, received_did_write_count_);
- EXPECT_TRUE(received_did_write_complete_);
- EXPECT_EQ(1, received_did_write_bytes_total_);
- EXPECT_FALSE(received_did_truncate_);
- EXPECT_FALSE(received_did_fail_);
-}
-
-TEST_F(FileWriterTest, BasicFileTruncate) {
- // Call the webkit facing api.
- writer()->Truncate(kBasicFileTruncate_Offset);
-
- // Check that the derived class gets called correctly.
- EXPECT_TRUE(testable_writer_->received_truncate_);
- EXPECT_EQ(mock_path_as_gurl(),
- testable_writer_->received_truncate_path_);
- EXPECT_EQ(kBasicFileTruncate_Offset,
- testable_writer_->received_truncate_offset_);
- EXPECT_FALSE(testable_writer_->received_write_);
- EXPECT_FALSE(testable_writer_->received_cancel_);
-
- // Check that the client gets called correctly.
- EXPECT_TRUE(received_did_truncate_);
- EXPECT_EQ(0, received_did_write_count_);
- EXPECT_FALSE(received_did_fail_);
-}
-
-TEST_F(FileWriterTest, ErrorFileWrite) {
- // Call the webkit facing api.
- const std::string kBlobId("1234");
- writer()->Write(kErrorFileWrite_Offset, blink::WebString::FromUTF8(kBlobId));
-
- // Check that the derived class gets called correctly.
- EXPECT_TRUE(testable_writer_->received_write_);
- EXPECT_EQ(testable_writer_->received_write_path_,
- mock_path_as_gurl());
- EXPECT_EQ(kErrorFileWrite_Offset,
- testable_writer_->received_write_offset_);
- EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
- EXPECT_FALSE(testable_writer_->received_truncate_);
- EXPECT_FALSE(testable_writer_->received_cancel_);
-
- // Check that the client gets called correctly.
- EXPECT_TRUE(received_did_fail_);
- EXPECT_EQ(blink::kWebFileErrorNotFound, fail_error_received_);
- EXPECT_EQ(0, received_did_write_count_);
- EXPECT_FALSE(received_did_truncate_);
-}
-
-TEST_F(FileWriterTest, ErrorFileTruncate) {
- // Call the webkit facing api.
- writer()->Truncate(kErrorFileTruncate_Offset);
-
- // Check that the derived class gets called correctly.
- EXPECT_TRUE(testable_writer_->received_truncate_);
- EXPECT_EQ(mock_path_as_gurl(),
- testable_writer_->received_truncate_path_);
- EXPECT_EQ(kErrorFileTruncate_Offset,
- testable_writer_->received_truncate_offset_);
- EXPECT_FALSE(testable_writer_->received_write_);
- EXPECT_FALSE(testable_writer_->received_cancel_);
-
- // Check that the client gets called correctly.
- EXPECT_TRUE(received_did_fail_);
- EXPECT_EQ(blink::kWebFileErrorNotFound, fail_error_received_);
- EXPECT_FALSE(received_did_truncate_);
- EXPECT_EQ(0, received_did_write_count_);
-}
-
-TEST_F(FileWriterTest, MultiFileWrite) {
- // Call the webkit facing api.
- const std::string kBlobId("1234");
- writer()->Write(kMultiFileWrite_Offset, blink::WebString::FromUTF8(kBlobId));
-
- // Check that the derived class gets called correctly.
- EXPECT_TRUE(testable_writer_->received_write_);
- EXPECT_EQ(testable_writer_->received_write_path_,
- mock_path_as_gurl());
- EXPECT_EQ(kMultiFileWrite_Offset,
- testable_writer_->received_write_offset_);
- EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
- EXPECT_FALSE(testable_writer_->received_truncate_);
- EXPECT_FALSE(testable_writer_->received_cancel_);
-
- // Check that the client gets called correctly.
- EXPECT_EQ(3, received_did_write_count_);
- EXPECT_TRUE(received_did_write_complete_);
- EXPECT_EQ(3, received_did_write_bytes_total_);
- EXPECT_FALSE(received_did_truncate_);
- EXPECT_FALSE(received_did_fail_);
-}
-
-TEST_F(FileWriterTest, CancelFileWriteBeforeCompletion) {
- // Call the webkit facing api.
- const std::string kBlobId("1234");
- writer()->Write(kCancelFileWriteBeforeCompletion_Offset,
- blink::WebString::FromUTF8(kBlobId));
-
- // Check that the derived class gets called correctly.
- EXPECT_TRUE(testable_writer_->received_write_);
- EXPECT_EQ(testable_writer_->received_write_path_,
- mock_path_as_gurl());
- EXPECT_EQ(kCancelFileWriteBeforeCompletion_Offset,
- testable_writer_->received_write_offset_);
- EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
- EXPECT_TRUE(testable_writer_->received_cancel_);
- EXPECT_FALSE(testable_writer_->received_truncate_);
-
- // Check that the client gets called correctly.
- EXPECT_TRUE(received_did_fail_);
- EXPECT_EQ(blink::kWebFileErrorAbort, fail_error_received_);
- EXPECT_EQ(1, received_did_write_count_);
- EXPECT_FALSE(received_did_write_complete_);
- EXPECT_EQ(1, received_did_write_bytes_total_);
- EXPECT_FALSE(received_did_truncate_);
-}
-
-TEST_F(FileWriterTest, CancelFileWriteAfterCompletion) {
- // Call the webkit facing api.
- const std::string kBlobId("1234");
- writer()->Write(kCancelFileWriteAfterCompletion_Offset,
- blink::WebString::FromUTF8(kBlobId));
-
- // Check that the derived class gets called correctly.
- EXPECT_TRUE(testable_writer_->received_write_);
- EXPECT_EQ(testable_writer_->received_write_path_,
- mock_path_as_gurl());
- EXPECT_EQ(kCancelFileWriteAfterCompletion_Offset,
- testable_writer_->received_write_offset_);
- EXPECT_EQ(kBlobId, testable_writer_->received_write_blob_uuid_);
- EXPECT_TRUE(testable_writer_->received_cancel_);
- EXPECT_FALSE(testable_writer_->received_truncate_);
-
- // Check that the client gets called correctly.
- EXPECT_TRUE(received_did_fail_);
- EXPECT_EQ(blink::kWebFileErrorAbort, fail_error_received_);
- EXPECT_EQ(1, received_did_write_count_);
- EXPECT_FALSE(received_did_write_complete_);
- EXPECT_EQ(1, received_did_write_bytes_total_);
- EXPECT_FALSE(received_did_truncate_);
-}
-
-TEST_F(FileWriterTest, CancelFileTruncate) {
- // Call the webkit facing api.
- writer()->Truncate(kCancelFileTruncate_Offset);
-
- // Check that the derived class gets called correctly.
- EXPECT_TRUE(testable_writer_->received_truncate_);
- EXPECT_EQ(mock_path_as_gurl(),
- testable_writer_->received_truncate_path_);
- EXPECT_EQ(kCancelFileTruncate_Offset,
- testable_writer_->received_truncate_offset_);
- EXPECT_TRUE(testable_writer_->received_cancel_);
- EXPECT_FALSE(testable_writer_->received_write_);
-
- // Check that the client gets called correctly.
- EXPECT_TRUE(received_did_fail_);
- EXPECT_EQ(blink::kWebFileErrorAbort, fail_error_received_);
- EXPECT_FALSE(received_did_truncate_);
- EXPECT_EQ(0, received_did_write_count_);
-}
-
-TEST_F(FileWriterTest, CancelFailedTruncate) {
- // Call the webkit facing api.
- writer()->Truncate(kCancelFailedTruncate_Offset);
-
- // Check that the derived class gets called correctly.
- EXPECT_TRUE(testable_writer_->received_truncate_);
- EXPECT_EQ(mock_path_as_gurl(),
- testable_writer_->received_truncate_path_);
- EXPECT_EQ(kCancelFailedTruncate_Offset,
- testable_writer_->received_truncate_offset_);
- EXPECT_TRUE(testable_writer_->received_cancel_);
- EXPECT_FALSE(testable_writer_->received_write_);
-
- // Check that the client gets called correctly.
- EXPECT_TRUE(received_did_fail_);
- EXPECT_EQ(blink::kWebFileErrorAbort, fail_error_received_);
- EXPECT_FALSE(received_did_truncate_);
- EXPECT_EQ(0, received_did_write_count_);
-}
-
-TEST_F(FileWriterTest, DeleteInCompletionCallbacks) {
- const std::string kBlobId("1234");
- delete_in_client_callback_ = true;
- writer()->Write(kBasicFileWrite_Offset, blink::WebString::FromUTF8(kBlobId));
- EXPECT_FALSE(testable_writer_.get());
-
- reset();
- delete_in_client_callback_ = true;
- writer()->Truncate(kBasicFileTruncate_Offset);
- EXPECT_FALSE(testable_writer_.get());
-
- reset();
- delete_in_client_callback_ = true;
- writer()->Write(kErrorFileWrite_Offset, blink::WebString::FromUTF8(kBlobId));
- EXPECT_FALSE(testable_writer_.get());
-
- reset();
- delete_in_client_callback_ = true;
- writer()->Truncate(kErrorFileTruncate_Offset);
- EXPECT_FALSE(testable_writer_.get());
-
- // Not crashing counts as passing.
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/fileapi/webfilewriter_impl.cc b/chromium/content/renderer/fileapi/webfilewriter_impl.cc
deleted file mode 100644
index 9502920bd98..00000000000
--- a/chromium/content/renderer/fileapi/webfilewriter_impl.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/fileapi/webfilewriter_impl.h"
-
-#include "base/bind.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/public/renderer/worker_thread.h"
-#include "content/renderer/fileapi/file_system_dispatcher.h"
-#include "content/renderer/render_thread_impl.h"
-
-namespace content {
-
-typedef FileSystemDispatcher::StatusCallback StatusCallback;
-typedef FileSystemDispatcher::WriteCallback WriteCallback;
-
-WebFileWriterImpl::WebFileWriterImpl(
- const GURL& path,
- blink::WebFileWriterClient* client,
- Type type,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
- : WebFileWriterBase(path, client),
- request_id_(0),
- type_(type),
- file_system_dispatcher_(std::make_unique<FileSystemDispatcher>(
- std::move(main_thread_task_runner))) {}
-
-WebFileWriterImpl::~WebFileWriterImpl() {}
-
-void WebFileWriterImpl::DoTruncate(const GURL& path, int64_t offset) {
- if (type_ == TYPE_SYNC) {
- file_system_dispatcher_->TruncateSync(
- path, offset,
- base::Bind(&WebFileWriterImpl::DidFinish, base::Unretained(this)));
- } else {
- file_system_dispatcher_->Truncate(
- path, offset, &request_id_,
- base::Bind(&WebFileWriterImpl::DidFinish, base::Unretained(this)));
- }
-}
-
-void WebFileWriterImpl::DoWrite(const GURL& path,
- const std::string& blob_id,
- int64_t offset) {
- if (type_ == TYPE_SYNC) {
- file_system_dispatcher_->WriteSync(
- path, blob_id, offset,
- base::Bind(&WebFileWriterImpl::DidWrite, base::Unretained(this)),
- base::Bind(&WebFileWriterImpl::DidFinish, base::Unretained(this)));
- } else {
- file_system_dispatcher_->Write(
- path, blob_id, offset, &request_id_,
- base::Bind(&WebFileWriterImpl::DidWrite, base::Unretained(this)),
- base::Bind(&WebFileWriterImpl::DidFinish, base::Unretained(this)));
- }
-}
-
-void WebFileWriterImpl::DoCancel() {
- DCHECK_EQ(type_, TYPE_ASYNC);
- file_system_dispatcher_->Cancel(
- request_id_,
- base::Bind(&WebFileWriterImpl::DidFinish, base::Unretained(this)));
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/fileapi/webfilewriter_impl.h b/chromium/content/renderer/fileapi/webfilewriter_impl.h
deleted file mode 100644
index cddc24df921..00000000000
--- a/chromium/content/renderer/fileapi/webfilewriter_impl.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_IMPL_H_
-#define CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_IMPL_H_
-
-#include <stdint.h>
-
-#include <string>
-
-#include "base/callback_forward.h"
-#include "content/renderer/fileapi/webfilewriter_base.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace content {
-
-class FileSystemDispatcher;
-
-// An implementation of WebFileWriter for use in chrome renderers and workers.
-class WebFileWriterImpl : public WebFileWriterBase {
- public:
- enum Type {
- TYPE_SYNC,
- TYPE_ASYNC,
- };
-
- WebFileWriterImpl(
- const GURL& path,
- blink::WebFileWriterClient* client,
- Type type,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
- ~WebFileWriterImpl() override;
-
- protected:
- // WebFileWriterBase overrides
- void DoTruncate(const GURL& path, int64_t offset) override;
- void DoWrite(const GURL& path,
- const std::string& blob_id,
- int64_t offset) override;
- void DoCancel() override;
-
- private:
- int request_id_;
- Type type_;
- std::unique_ptr<FileSystemDispatcher> file_system_dispatcher_;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_FILEAPI_WEBFILEWRITER_IMPL_H_
diff --git a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
index bef6372a97b..65237cd8103 100644
--- a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -21,6 +21,7 @@
#include "cc/layers/layer.h"
#include "cc/paint/skia_paint_canvas.h"
#include "cc/trees/layer_tree_host.h"
+#include "content/common/input/actions_parser.h"
#include "content/common/input/synthetic_gesture_params.h"
#include "content/common/input/synthetic_pinch_gesture_params.h"
#include "content/common/input/synthetic_pointer_action_list_params.h"
@@ -32,7 +33,6 @@
#include "content/public/renderer/chrome_object_extensions_utils.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/v8_value_converter.h"
-#include "content/renderer/gpu/actions_parser.h"
#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
@@ -54,6 +54,7 @@
#include "third_party/skia/include/core/SkGraphics.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
+#include "third_party/skia/include/docs/SkXPSDocument.h"
// Note that headers in third_party/skia/src are fragile. This is
// an experimental, fragile, and diagnostic-only document type.
#include "third_party/skia/src/utils/SkMultiPictureDocument.h"
@@ -64,7 +65,7 @@
// XpsObjectModel.h indirectly includes <wincrypt.h> which is
// incompatible with Chromium's OpenSSL. By including wincrypt_shim.h
// first, problems are avoided.
-#include "crypto/wincrypt_shim.h"
+#include "base/win/wincrypt_shim.h"
#include <XpsObjectModel.h>
#include <objbase.h>
@@ -290,7 +291,8 @@ bool BeginSmoothScroll(GpuBenchmarkingContext* context,
float start_y,
float fling_velocity,
bool precise_scrolling_deltas,
- bool scroll_by_page) {
+ bool scroll_by_page,
+ bool cursor_visible) {
gfx::Rect rect = context->render_view_impl()->GetWidget()->ViewRect();
rect -= rect.OffsetFromOrigin();
if (!rect.Contains(start_x, start_y)) {
@@ -308,7 +310,7 @@ bool BeginSmoothScroll(GpuBenchmarkingContext* context,
mouseMove.SetPositionInWidget(start_x, start_y);
context->web_view()->HandleInputEvent(
blink::WebCoalescedInputEvent(mouseMove));
- context->web_view()->SetCursorVisibilityState(true);
+ context->web_view()->SetCursorVisibilityState(cursor_visible);
}
scoped_refptr<CallbackAndContext> callback_and_context =
@@ -456,8 +458,10 @@ static void PrintDocumentTofile(v8::Isolate* isolate,
if (!base::PathIsWritable(path.DirName())) {
std::string msg("Path is not writable: ");
msg.append(path.DirName().MaybeAsASCII());
- isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
- isolate, msg.c_str(), v8::String::kNormalString, msg.length())));
+ isolate->ThrowException(v8::Exception::Error(
+ v8::String::NewFromUtf8(isolate, msg.c_str(),
+ v8::NewStringType::kNormal, msg.length())
+ .ToLocalChecked()));
return;
}
SkFILEWStream wStream(path.MaybeAsASCII().c_str());
@@ -487,7 +491,7 @@ static sk_sp<SkDocument> MakeXPSDocument(SkWStream* s) {
LOG(ERROR) << "CoCreateInstance(CLSID_XpsOMObjectFactory, ...) failed:"
<< logging::SystemErrorCodeToString(hr);
}
- return SkDocument::MakeXPS(s, factory.Get());
+ return SkXPS::MakeDocument(s, factory.Get());
}
#endif
} // namespace
@@ -606,8 +610,10 @@ void GpuBenchmarking::PrintPagesToXPS(v8::Isolate* isolate,
PrintDocumentTofile(isolate, filename, &MakeXPSDocument);
#else
std::string msg("PrintPagesToXPS is unsupported.");
- isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
- isolate, msg.c_str(), v8::String::kNormalString, msg.length())));
+ isolate->ThrowException(v8::Exception::Error(
+ v8::String::NewFromUtf8(isolate, msg.c_str(), v8::NewStringType::kNormal,
+ msg.length())
+ .ToLocalChecked()));
#endif
}
@@ -626,8 +632,10 @@ void GpuBenchmarking::PrintToSkPicture(v8::Isolate* isolate,
!base::PathIsWritable(dirpath)) {
std::string msg("Path is not writable: ");
msg.append(dirpath.MaybeAsASCII());
- isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(
- isolate, msg.c_str(), v8::String::kNormalString, msg.length())));
+ isolate->ThrowException(v8::Exception::Error(
+ v8::String::NewFromUtf8(isolate, msg.c_str(),
+ v8::NewStringType::kNormal, msg.length())
+ .ToLocalChecked()));
return;
}
@@ -662,6 +670,7 @@ bool GpuBenchmarking::SmoothScrollBy(gin::Arguments* args) {
float speed_in_pixels_s = 800;
bool precise_scrolling_deltas = true;
bool scroll_by_page = false;
+ bool cursor_visible = true;
if (!GetOptionalArg(args, &pixels_to_scroll) ||
!GetOptionalArg(args, &callback) || !GetOptionalArg(args, &start_x) ||
@@ -670,7 +679,8 @@ bool GpuBenchmarking::SmoothScrollBy(gin::Arguments* args) {
!GetOptionalArg(args, &direction) ||
!GetOptionalArg(args, &speed_in_pixels_s) ||
!GetOptionalArg(args, &precise_scrolling_deltas) ||
- !GetOptionalArg(args, &scroll_by_page)) {
+ !GetOptionalArg(args, &scroll_by_page) ||
+ !GetOptionalArg(args, &cursor_visible)) {
return false;
}
@@ -682,10 +692,10 @@ bool GpuBenchmarking::SmoothScrollBy(gin::Arguments* args) {
gesture_source_type == SyntheticGestureParams::MOUSE_INPUT);
EnsureRemoteInterface();
- return BeginSmoothScroll(&context, args, input_injector_, pixels_to_scroll,
- callback, gesture_source_type, direction,
- speed_in_pixels_s, true, start_x, start_y, 0,
- precise_scrolling_deltas, scroll_by_page);
+ return BeginSmoothScroll(
+ &context, args, input_injector_, pixels_to_scroll, callback,
+ gesture_source_type, direction, speed_in_pixels_s, true, start_x, start_y,
+ 0, precise_scrolling_deltas, scroll_by_page, cursor_visible);
}
bool GpuBenchmarking::SmoothDrag(gin::Arguments* args) {
@@ -751,11 +761,11 @@ bool GpuBenchmarking::Swipe(gin::Arguments* args) {
fling_velocity = 1000;
EnsureRemoteInterface();
- return BeginSmoothScroll(&context, args, input_injector_, -pixels_to_scroll,
- callback, gesture_source_type, direction,
- speed_in_pixels_s, false, start_x, start_y,
- fling_velocity, true /* precise_scrolling_deltas */,
- false /* scroll_by_page */);
+ return BeginSmoothScroll(
+ &context, args, input_injector_, -pixels_to_scroll, callback,
+ gesture_source_type, direction, speed_in_pixels_s, false, start_x,
+ start_y, fling_velocity, true /* precise_scrolling_deltas */,
+ false /* scroll_by_page */, true /* cursor_visible */);
}
bool GpuBenchmarking::ScrollBounce(gin::Arguments* args) {
diff --git a/chromium/content/renderer/gpu/layer_tree_view.cc b/chromium/content/renderer/gpu/layer_tree_view.cc
index 7b8ae60acba..c8433165482 100644
--- a/chromium/content/renderer/gpu/layer_tree_view.cc
+++ b/chromium/content/renderer/gpu/layer_tree_view.cc
@@ -191,10 +191,11 @@ void LayerTreeView::Initialize(
}
if (!is_threaded) {
// Single-threaded layout tests, and unit tests.
- layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded(this, &params);
- } else {
layer_tree_host_ =
- cc::LayerTreeHost::CreateThreaded(compositor_thread_, &params);
+ cc::LayerTreeHost::CreateSingleThreaded(this, std::move(params));
+ } else {
+ layer_tree_host_ = cc::LayerTreeHost::CreateThreaded(compositor_thread_,
+ std::move(params));
}
}
@@ -478,12 +479,9 @@ void LayerTreeView::CompositeAndReadbackAsync(
}
}
-void LayerTreeView::SynchronouslyCompositeNoRasterForTesting() {
- SynchronouslyComposite(false /* raster */, nullptr /* swap_promise */);
-}
-
-void LayerTreeView::CompositeWithRasterForTesting() {
- SynchronouslyComposite(true /* raster */, nullptr /* swap_promise */);
+void LayerTreeView::UpdateAllLifecyclePhasesAndCompositeForTesting(
+ bool do_raster) {
+ SynchronouslyComposite(do_raster, nullptr /* swap_promise */);
}
void LayerTreeView::SynchronouslyComposite(
@@ -498,8 +496,7 @@ void LayerTreeView::SynchronouslyComposite(
// frame, but the compositor does not support this. In this case, we only
// run blink's lifecycle updates.
delegate_->BeginMainFrame(base::TimeTicks::Now());
- delegate_->UpdateVisualState(
- cc::LayerTreeHostClient::VisualStateUpdate::kAll);
+ delegate_->UpdateVisualState();
return;
}
@@ -516,8 +513,8 @@ void LayerTreeView::SynchronouslyComposite(
layer_tree_host_->Composite(base::TimeTicks::Now(), raster);
}
-void LayerTreeView::SetDeferCommits(bool defer_commits) {
- layer_tree_host_->SetDeferCommits(defer_commits);
+std::unique_ptr<cc::ScopedDeferCommits> LayerTreeView::DeferCommits() {
+ return layer_tree_host_->DeferCommits();
}
int LayerTreeView::LayerTreeId() const {
@@ -611,19 +608,13 @@ void LayerTreeView::BeginMainFrameNotExpectedUntil(base::TimeTicks time) {
web_main_thread_scheduler_->BeginMainFrameNotExpectedUntil(time);
}
-void LayerTreeView::UpdateLayerTreeHost(VisualStateUpdate requested_update) {
- delegate_->UpdateVisualState(requested_update);
+void LayerTreeView::UpdateLayerTreeHost() {
+ delegate_->UpdateVisualState();
}
-void LayerTreeView::ApplyViewportDeltas(
- const gfx::Vector2dF& inner_delta,
- const gfx::Vector2dF& outer_delta,
- const gfx::Vector2dF& elastic_overscroll_delta,
- float page_scale,
- float top_controls_delta) {
- delegate_->ApplyViewportDeltas(inner_delta, outer_delta,
- elastic_overscroll_delta, page_scale,
- top_controls_delta);
+void LayerTreeView::ApplyViewportChanges(
+ const cc::ApplyViewportChangesArgs& args) {
+ delegate_->ApplyViewportChanges(args);
}
void LayerTreeView::RecordWheelAndTouchScrollingCount(
@@ -669,10 +660,6 @@ void LayerTreeView::DidCommitAndDrawFrame() {
delegate_->DidCommitAndDrawCompositorFrame();
}
-void LayerTreeView::DidReceiveCompositorFrameAck() {
- delegate_->DidReceiveCompositorFrameAck();
-}
-
void LayerTreeView::DidCompletePageScaleAnimation() {
delegate_->DidCompletePageScaleAnimation();
}
@@ -693,6 +680,10 @@ void LayerTreeView::DidPresentCompositorFrame(
}
}
+void LayerTreeView::RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) {
+ delegate_->RecordEndOfFrameMetrics(frame_begin_time);
+}
+
void LayerTreeView::RequestScheduleAnimation() {
delegate_->RequestScheduleAnimation();
}
diff --git a/chromium/content/renderer/gpu/layer_tree_view.h b/chromium/content/renderer/gpu/layer_tree_view.h
index 09dbf800511..daa30344d7e 100644
--- a/chromium/content/renderer/gpu/layer_tree_view.h
+++ b/chromium/content/renderer/gpu/layer_tree_view.h
@@ -40,6 +40,7 @@ class LayerTreeSettings;
class RenderFrameMetadataObserver;
class TaskGraphRunner;
class UkmRecorderFactory;
+class ScopedDeferCommits;
} // namespace cc
namespace gfx {
@@ -136,9 +137,11 @@ class CONTENT_EXPORT LayerTreeView
void LayoutAndPaintAsync(base::OnceClosure callback) override;
void CompositeAndReadbackAsync(
base::OnceCallback<void(const SkBitmap&)> callback) override;
- void SynchronouslyCompositeNoRasterForTesting() override;
- void CompositeWithRasterForTesting() override;
- void SetDeferCommits(bool defer_commits) override;
+ // Synchronously performs the complete set of document lifecycle phases,
+ // including updates to the compositor state, optionally including
+ // rasterization.
+ void UpdateAllLifecyclePhasesAndCompositeForTesting(bool do_raster) override;
+ std::unique_ptr<cc::ScopedDeferCommits> DeferCommits() override;
void RegisterViewportLayers(const ViewportLayers& viewport_layers) override;
void ClearViewportLayers() override;
void RegisterSelection(const cc::LayerSelection& selection) override;
@@ -177,12 +180,8 @@ class CONTENT_EXPORT LayerTreeView
void BeginMainFrame(const viz::BeginFrameArgs& args) override;
void BeginMainFrameNotExpectedSoon() override;
void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override;
- void UpdateLayerTreeHost(VisualStateUpdate requested_update) override;
- void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
- const gfx::Vector2dF& outer_delta,
- const gfx::Vector2dF& elastic_overscroll_delta,
- float page_scale,
- float top_controls_delta) override;
+ void UpdateLayerTreeHost() override;
+ void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) override;
void RecordWheelAndTouchScrollingCount(bool has_scrolled_by_wheel,
bool has_scrolled_by_touch) override;
void RequestNewLayerTreeFrameSink() override;
@@ -191,11 +190,12 @@ class CONTENT_EXPORT LayerTreeView
void WillCommit() override;
void DidCommit() override;
void DidCommitAndDrawFrame() override;
- void DidReceiveCompositorFrameAck() override;
+ void DidReceiveCompositorFrameAck() override {}
void DidCompletePageScaleAnimation() override;
void DidPresentCompositorFrame(
uint32_t frame_token,
const gfx::PresentationFeedback& feedback) override;
+ void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override;
// cc::LayerTreeHostSingleThreadClient implementation.
void RequestScheduleAnimation() override;
diff --git a/chromium/content/renderer/gpu/layer_tree_view_delegate.h b/chromium/content/renderer/gpu/layer_tree_view_delegate.h
index 51ab69aed61..68d11d612ab 100644
--- a/chromium/content/renderer/gpu/layer_tree_view_delegate.h
+++ b/chromium/content/renderer/gpu/layer_tree_view_delegate.h
@@ -17,10 +17,6 @@ class LayerTreeFrameSink;
class SwapPromise;
} // namespace cc
-namespace gfx {
-class Vector2dF;
-}
-
namespace viz {
class CopyOutputRequest;
}
@@ -36,12 +32,8 @@ class LayerTreeViewDelegate {
// Report viewport related properties during a commit from the compositor
// thread.
- virtual void ApplyViewportDeltas(
- const gfx::Vector2dF& inner_delta,
- const gfx::Vector2dF& outer_delta,
- const gfx::Vector2dF& elastic_overscroll_delta,
- float page_scale,
- float top_controls_delta) = 0;
+ virtual void ApplyViewportChanges(
+ const cc::ApplyViewportChangesArgs& args) = 0;
// Record use count of wheel/touch sources for scrolling on the compositor
// thread.
@@ -65,9 +57,11 @@ class LayerTreeViewDelegate {
// Called by the compositor when page scale animation completed.
virtual void DidCompletePageScaleAnimation() = 0;
- // Notifies that the last submitted CompositorFrame has been processed and
- // will be displayed.
- virtual void DidReceiveCompositorFrameAck() = 0;
+ // Requests that a UMA and UKM metric be recorded for the total frame time.
+ // Call this as soon as the total frame time becomes known for a given frame.
+ // For example, ProxyMain::BeginMainFrame calls it immediately before aborting
+ // or committing a frame (at the same time Tracing measurements are taken).
+ virtual void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) = 0;
// Indicates whether the LayerTreeView is about to close.
virtual bool IsClosing() const = 0;
@@ -78,8 +72,7 @@ class LayerTreeViewDelegate {
// Requests a visual frame-based update to the state of the delegate if there
// an update available.
- using VisualStateUpdate = cc::LayerTreeHostClient::VisualStateUpdate;
- virtual void UpdateVisualState(VisualStateUpdate requested_update) = 0;
+ virtual void UpdateVisualState() = 0;
// Indicates that the compositor is about to begin a frame. This is primarily
// to signal to flow control mechanisms that a frame is beginning, not to
diff --git a/chromium/content/renderer/gpu/layer_tree_view_unittest.cc b/chromium/content/renderer/gpu/layer_tree_view_unittest.cc
index abc55297718..2b48efd88bd 100644
--- a/chromium/content/renderer/gpu/layer_tree_view_unittest.cc
+++ b/chromium/content/renderer/gpu/layer_tree_view_unittest.cc
@@ -8,9 +8,9 @@
#include "base/location.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "cc/test/fake_layer_tree_frame_sink.h"
@@ -253,7 +253,7 @@ class LayerTreeViewWithFrameSinkTrackingTest : public testing::Test {
}
protected:
- base::MessageLoop ye_olde_message_loope_;
+ base::test::ScopedTaskEnvironment task_environment_;
cc::TestTaskGraphRunner test_task_graph_runner_;
blink::scheduler::FakeRendererScheduler fake_renderer_scheduler_;
FakeLayerTreeViewDelegate layer_tree_view_delegate_;
@@ -328,7 +328,7 @@ TEST(LayerTreeViewTest, VisibilityTest) {
// Test that LayerTreeView does not retry FrameSink request while
// invisible.
- base::MessageLoop message_loop;
+ base::test::ScopedTaskEnvironment task_environment;
cc::TestTaskGraphRunner test_task_graph_runner;
blink::scheduler::FakeRendererScheduler fake_renderer_scheduler;
diff --git a/chromium/content/renderer/gpu/queue_message_swap_promise.cc b/chromium/content/renderer/gpu/queue_message_swap_promise.cc
index b9a07865124..280bde5f952 100644
--- a/chromium/content/renderer/gpu/queue_message_swap_promise.cc
+++ b/chromium/content/renderer/gpu/queue_message_swap_promise.cc
@@ -7,7 +7,7 @@
#include <memory>
#include "base/command_line.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_thread.h"
#include "content/renderer/gpu/frame_swap_message_queue.h"
@@ -62,7 +62,7 @@ void QueueMessageSwapPromise::WillSwap(viz::CompositorFrameMetadata* metadata) {
FrameSwapMessageQueue::TransferMessages(&messages, &messages_to_send);
if (!messages_to_send.empty()) {
metadata->send_frame_token_to_embedder = true;
- message_sender_->Send(new ViewHostMsg_FrameSwapMessages(
+ message_sender_->Send(new WidgetHostMsg_FrameSwapMessages(
message_queue_->routing_id(), metadata->frame_token,
messages_to_send));
}
diff --git a/chromium/content/renderer/gpu/queue_message_swap_promise_unittest.cc b/chromium/content/renderer/gpu/queue_message_swap_promise_unittest.cc
index 551cef8b5b0..45b1308cff7 100644
--- a/chromium/content/renderer/gpu/queue_message_swap_promise_unittest.cc
+++ b/chromium/content/renderer/gpu/queue_message_swap_promise_unittest.cc
@@ -14,7 +14,7 @@
#include "base/test/scoped_task_environment.h"
#include "cc/trees/swap_promise.h"
#include "content/common/render_frame_metadata.mojom.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/renderer/gpu/frame_swap_message_queue.h"
#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/render_widget.h"
@@ -31,9 +31,9 @@ class TestSyncMessageFilter : public IPC::SyncMessageFilter {
TestSyncMessageFilter() : IPC::SyncMessageFilter(nullptr) {}
bool Send(IPC::Message* message) override {
- if (message->type() == ViewHostMsg_FrameSwapMessages::ID) {
- ViewHostMsg_FrameSwapMessages::Param param;
- ViewHostMsg_FrameSwapMessages::Read(message, &param);
+ if (message->type() == WidgetHostMsg_FrameSwapMessages::ID) {
+ WidgetHostMsg_FrameSwapMessages::Param param;
+ WidgetHostMsg_FrameSwapMessages::Read(message, &param);
std::vector<IPC::Message> messages = std::get<1>(param);
last_swap_messages_.clear();
for (const IPC::Message& message : messages) {
diff --git a/chromium/content/renderer/idle_user_detector.cc b/chromium/content/renderer/idle_user_detector.cc
deleted file mode 100644
index a33ea38de41..00000000000
--- a/chromium/content/renderer/idle_user_detector.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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 "content/renderer/idle_user_detector.h"
-
-#include "base/logging.h"
-#include "content/common/input_messages.h"
-#include "content/public/renderer/content_renderer_client.h"
-#include "content/renderer/render_thread_impl.h"
-
-namespace content {
-
-IdleUserDetector::IdleUserDetector() = default;
-
-IdleUserDetector::~IdleUserDetector() = default;
-
-void IdleUserDetector::ActivityDetected() {
- if (GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) {
- RenderThreadImpl* render_thread = RenderThreadImpl::current();
- if (render_thread != nullptr) {
- render_thread->PostponeIdleNotification();
- }
- }
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/idle_user_detector.h b/chromium/content/renderer/idle_user_detector.h
deleted file mode 100644
index ead8dcc49dc..00000000000
--- a/chromium/content/renderer/idle_user_detector.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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 CONTENT_RENDERER_IDLE_USER_DETECTOR_H_
-#define CONTENT_RENDERER_IDLE_USER_DETECTOR_H_
-
-#include "base/macros.h"
-
-namespace content {
-
-// Class which observes user input events and postpones
-// idle notifications if the user is active.
-class IdleUserDetector {
- public:
- IdleUserDetector();
- ~IdleUserDetector();
-
- void ActivityDetected();
-
- private:
-
- DISALLOW_COPY_AND_ASSIGN(IdleUserDetector);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_IDLE_USER_DETECTOR_H_
diff --git a/chromium/content/renderer/image_downloader/image_downloader_base.cc b/chromium/content/renderer/image_downloader/image_downloader_base.cc
index cd2b1388ddf..f5eab2c1e92 100644
--- a/chromium/content/renderer/image_downloader/image_downloader_base.cc
+++ b/chromium/content/renderer/image_downloader/image_downloader_base.cc
@@ -14,7 +14,7 @@
#include "content/public/renderer/render_thread.h"
#include "content/renderer/fetchers/multi_resolution_image_resource_fetcher.h"
#include "net/base/data_url.h"
-#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "ui/gfx/favicon_size.h"
@@ -89,8 +89,8 @@ void ImageDownloaderBase::FetchImage(const GURL& image_url,
image_fetchers_.push_back(
std::make_unique<MultiResolutionImageResourceFetcher>(
image_url, frame, 0,
- is_favicon ? WebURLRequest::kRequestContextFavicon
- : WebURLRequest::kRequestContextImage,
+ is_favicon ? blink::mojom::RequestContextType::FAVICON
+ : blink::mojom::RequestContextType::IMAGE,
bypass_cache ? blink::mojom::FetchCacheMode::kBypassCache
: blink::mojom::FetchCacheMode::kDefault,
base::BindOnce(&ImageDownloaderBase::DidFetchImage,
diff --git a/chromium/content/renderer/image_downloader/image_downloader_impl.cc b/chromium/content/renderer/image_downloader/image_downloader_impl.cc
index f20ad653cf1..164406abf57 100644
--- a/chromium/content/renderer/image_downloader/image_downloader_impl.cc
+++ b/chromium/content/renderer/image_downloader/image_downloader_impl.cc
@@ -54,8 +54,7 @@ void FilterAndResizeImagesForMaximalSize(
uint32_t min_image_size = std::numeric_limits<uint32_t>::max();
// Filter the images by |max_image_size|, and also identify the smallest image
// in case all the images are bigger than |max_image_size|.
- for (std::vector<SkBitmap>::const_iterator it = unfiltered.begin();
- it != unfiltered.end(); ++it) {
+ for (auto it = unfiltered.begin(); it != unfiltered.end(); ++it) {
const SkBitmap& image = *it;
uint32_t current_size = std::max(it->width(), it->height());
if (current_size < min_image_size) {
diff --git a/chromium/content/renderer/indexed_db/webidbdatabase_impl.cc b/chromium/content/renderer/indexed_db/webidbdatabase_impl.cc
index aea8e1840cd..ae5449220cc 100644
--- a/chromium/content/renderer/indexed_db/webidbdatabase_impl.cc
+++ b/chromium/content/renderer/indexed_db/webidbdatabase_impl.cc
@@ -48,16 +48,14 @@ namespace content {
namespace {
std::vector<IndexedDBIndexKeys> ConvertWebIndexKeys(
- const WebVector<long long>& index_ids,
- const WebVector<WebIDBDatabase::WebIndexKeys>& index_keys) {
- DCHECK_EQ(index_ids.size(), index_keys.size());
+ const WebVector<blink::WebIDBIndexKeys>& index_keys) {
std::vector<IndexedDBIndexKeys> result;
- result.reserve(index_ids.size());
- for (size_t i = 0, len = index_ids.size(); i < len; ++i) {
- result.emplace_back(index_ids[i], std::vector<IndexedDBKey>());
+ result.reserve(index_keys.size());
+ for (size_t i = 0, len = index_keys.size(); i < len; ++i) {
+ result.emplace_back(index_keys[i].first, std::vector<IndexedDBKey>());
std::vector<IndexedDBKey>& result_keys = result.back().second;
- result_keys.reserve(index_keys[i].size());
- for (const WebIDBKey& index_key : index_keys[i])
+ result_keys.reserve(index_keys[i].second.size());
+ for (const WebIDBKey& index_key : index_keys[i].second)
result_keys.emplace_back(IndexedDBKeyBuilder::Build(index_key.View()));
}
return result;
@@ -165,15 +163,15 @@ void WebIDBDatabaseImpl::GetAll(long long transaction_id,
max_count, GetCallbacksProxy(std::move(callbacks_impl)));
}
-void WebIDBDatabaseImpl::Put(long long transaction_id,
- long long object_store_id,
- const blink::WebData& value,
- const WebVector<WebBlobInfo>& web_blob_info,
- WebIDBKeyView web_primary_key,
- blink::WebIDBPutMode put_mode,
- WebIDBCallbacks* callbacks,
- const WebVector<long long>& index_ids,
- WebVector<WebIndexKeys> index_keys) {
+void WebIDBDatabaseImpl::Put(
+ long long transaction_id,
+ long long object_store_id,
+ const blink::WebData& value,
+ const WebVector<WebBlobInfo>& web_blob_info,
+ WebIDBKeyView web_primary_key,
+ blink::WebIDBPutMode put_mode,
+ WebIDBCallbacks* callbacks,
+ const WebVector<blink::WebIDBIndexKeys>& index_keys) {
IndexedDBKey key = IndexedDBKeyBuilder::Build(web_primary_key);
if (value.size() + key.size_estimate() > max_put_value_size_) {
@@ -219,7 +217,7 @@ void WebIDBDatabaseImpl::Put(long long transaction_id,
auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), transaction_id, nullptr);
database_->Put(transaction_id, object_store_id, std::move(mojo_value), key,
- put_mode, ConvertWebIndexKeys(index_ids, index_keys),
+ put_mode, ConvertWebIndexKeys(index_keys),
GetCallbacksProxy(std::move(callbacks_impl)));
}
@@ -227,11 +225,10 @@ void WebIDBDatabaseImpl::SetIndexKeys(
long long transaction_id,
long long object_store_id,
WebIDBKeyView primary_key,
- const WebVector<long long>& index_ids,
- const WebVector<WebIndexKeys>& index_keys) {
+ const WebVector<blink::WebIDBIndexKeys>& index_keys) {
database_->SetIndexKeys(transaction_id, object_store_id,
IndexedDBKeyBuilder::Build(primary_key),
- ConvertWebIndexKeys(index_ids, index_keys));
+ ConvertWebIndexKeys(index_keys));
}
void WebIDBDatabaseImpl::SetIndexesReady(
diff --git a/chromium/content/renderer/indexed_db/webidbdatabase_impl.h b/chromium/content/renderer/indexed_db/webidbdatabase_impl.h
index 95fed9c766a..e33154d4c53 100644
--- a/chromium/content/renderer/indexed_db/webidbdatabase_impl.h
+++ b/chromium/content/renderer/indexed_db/webidbdatabase_impl.h
@@ -80,13 +80,11 @@ class CONTENT_EXPORT WebIDBDatabaseImpl : public blink::WebIDBDatabase {
blink::WebIDBKeyView primary_key,
blink::WebIDBPutMode,
blink::WebIDBCallbacks*,
- const blink::WebVector<long long>& index_ids,
- blink::WebVector<WebIndexKeys>) override;
+ const blink::WebVector<blink::WebIDBIndexKeys>&) override;
void SetIndexKeys(long long transaction_id,
long long object_store_id,
blink::WebIDBKeyView primary_key,
- const blink::WebVector<long long>& index_ids,
- const blink::WebVector<WebIndexKeys>&) override;
+ const blink::WebVector<blink::WebIDBIndexKeys>&) override;
void SetIndexesReady(long long transaction_id,
long long object_store_id,
const blink::WebVector<long long>& index_ids) override;
diff --git a/chromium/content/renderer/indexed_db/webidbdatabase_impl_unittest.cc b/chromium/content/renderer/indexed_db/webidbdatabase_impl_unittest.cc
index be6629f1f76..39bc0f26e3f 100644
--- a/chromium/content/renderer/indexed_db/webidbdatabase_impl_unittest.cc
+++ b/chromium/content/renderer/indexed_db/webidbdatabase_impl_unittest.cc
@@ -65,8 +65,7 @@ TEST_F(WebIDBDatabaseImplTest, ValueSizeTest) {
const WebIDBKey idb_key = WebIDBKey::CreateNumber(0);
database_impl.Put(transaction_id, object_store_id, value, web_blob_info,
idb_key.View(), blink::kWebIDBPutModeAddOrUpdate,
- &callbacks, WebVector<long long>(),
- WebVector<WebVector<WebIDBKey>>());
+ &callbacks, WebVector<blink::WebIDBIndexKeys>());
}
TEST_F(WebIDBDatabaseImplTest, KeyAndValueSizeTest) {
@@ -91,7 +90,7 @@ TEST_F(WebIDBDatabaseImplTest, KeyAndValueSizeTest) {
database_impl.max_put_value_size_ = kMaxValueSizeForTesting;
database_impl.Put(transaction_id, object_store_id, value, web_blob_info,
key.View(), blink::kWebIDBPutModeAddOrUpdate, &callbacks,
- WebVector<long long>(), WebVector<WebVector<WebIDBKey>>());
+ WebVector<blink::WebIDBIndexKeys>());
}
} // namespace content
diff --git a/chromium/content/renderer/input/OWNERS b/chromium/content/renderer/input/OWNERS
index 5becb59f9da..4b3d57a7073 100644
--- a/chromium/content/renderer/input/OWNERS
+++ b/chromium/content/renderer/input/OWNERS
@@ -1,5 +1,6 @@
dtapuska@chromium.org
tdresser@chromium.org
+nzolghadr@chromium.org
# TEAM: input-dev@chromium.org
# COMPONENT: Blink>Input
diff --git a/chromium/content/renderer/input/frame_input_handler_impl.cc b/chromium/content/renderer/input/frame_input_handler_impl.cc
index 175e4aaaf34..b2f1c689f12 100644
--- a/chromium/content/renderer/input/frame_input_handler_impl.cc
+++ b/chromium/content/renderer/input/frame_input_handler_impl.cc
@@ -58,11 +58,11 @@ void FrameInputHandlerImpl::CreateMojoService(
new FrameInputHandlerImpl(render_frame, std::move(request));
}
-void FrameInputHandlerImpl::RunOnMainThread(const base::Closure& closure) {
+void FrameInputHandlerImpl::RunOnMainThread(base::OnceClosure closure) {
if (input_event_queue_) {
- input_event_queue_->QueueClosure(closure);
+ input_event_queue_->QueueClosure(std::move(closure));
} else {
- closure.Run();
+ std::move(closure).Run();
}
}
@@ -287,6 +287,49 @@ void FrameInputHandlerImpl::SelectRange(const gfx::Point& base,
window_widget->ConvertWindowPointToViewport(extent));
}
+#if defined(OS_ANDROID)
+void FrameInputHandlerImpl::SelectWordAroundCaret(
+ SelectWordAroundCaretCallback callback) {
+ if (!main_thread_task_runner_->BelongsToCurrentThread()) {
+ RunOnMainThread(
+ base::BindOnce(&FrameInputHandlerImpl::SelectWordAroundCaret,
+ weak_this_, std::move(callback)));
+ return;
+ }
+
+ bool did_select = false;
+ int start_adjust = 0;
+ int end_adjust = 0;
+ if (render_frame_) {
+ blink::WebLocalFrame* frame = render_frame_->GetWebFrame();
+ blink::WebRange initial_range = frame->SelectionRange();
+ render_frame_->GetRenderWidget()->SetHandlingInputEvent(true);
+ if (!initial_range.IsNull())
+ did_select = frame->SelectWordAroundCaret();
+ if (did_select) {
+ blink::WebRange adjusted_range = frame->SelectionRange();
+ DCHECK(!adjusted_range.IsNull());
+ start_adjust = adjusted_range.StartOffset() - initial_range.StartOffset();
+ end_adjust = adjusted_range.EndOffset() - initial_range.EndOffset();
+ }
+ render_frame_->GetRenderWidget()->SetHandlingInputEvent(false);
+ }
+
+ // If the mojom channel is registered with compositor thread, we have to run
+ // the callback on compositor thread. Otherwise run it on main thread. Mojom
+ // requires the callback runs on the same thread.
+ if (RenderThreadImpl::current() &&
+ RenderThreadImpl::current()->compositor_task_runner() &&
+ input_event_queue_) {
+ RenderThreadImpl::current()->compositor_task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), did_select, start_adjust,
+ end_adjust));
+ } else {
+ std::move(callback).Run(did_select, start_adjust, end_adjust);
+ }
+}
+#endif // defined(OS_ANDROID)
+
void FrameInputHandlerImpl::AdjustSelectionByCharacterOffset(
int32_t start,
int32_t end,
diff --git a/chromium/content/renderer/input/frame_input_handler_impl.h b/chromium/content/renderer/input/frame_input_handler_impl.h
index 794229f0f1e..8155c1ab26a 100644
--- a/chromium/content/renderer/input/frame_input_handler_impl.h
+++ b/chromium/content/renderer/input/frame_input_handler_impl.h
@@ -6,6 +6,7 @@
#define CONTENT_RENDERER_INPUT_FRAME_INPUT_HANDLER_IMPL_H_
#include "base/memory/ref_counted.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/common/input/input_handler.mojom.h"
#include "content/renderer/render_frame_impl.h"
@@ -66,6 +67,9 @@ class CONTENT_EXPORT FrameInputHandlerImpl : public mojom::FrameInputHandler {
void SelectAll() override;
void CollapseSelection() override;
void SelectRange(const gfx::Point& base, const gfx::Point& extent) override;
+#if defined(OS_ANDROID)
+ void SelectWordAroundCaret(SelectWordAroundCaretCallback callback) override;
+#endif // defined(OS_ANDROID)
void AdjustSelectionByCharacterOffset(
int32_t start,
int32_t end,
@@ -96,7 +100,7 @@ class CONTENT_EXPORT FrameInputHandlerImpl : public mojom::FrameInputHandler {
FrameInputHandlerImpl(base::WeakPtr<RenderFrameImpl> render_frame,
mojom::FrameInputHandlerRequest request);
- void RunOnMainThread(const base::Closure& closure);
+ void RunOnMainThread(base::OnceClosure closure);
void BindNow(mojom::FrameInputHandlerRequest request);
void ExecuteCommandOnMainThread(const std::string& command,
UpdateState state);
diff --git a/chromium/content/renderer/input/input_target_client_impl.cc b/chromium/content/renderer/input/input_target_client_impl.cc
index b8ee18d5fe4..d97b46ab422 100644
--- a/chromium/content/renderer/input/input_target_client_impl.cc
+++ b/chromium/content/renderer/input/input_target_client_impl.cc
@@ -19,11 +19,18 @@ InputTargetClientImpl::~InputTargetClientImpl() {}
void InputTargetClientImpl::BindToRequest(
viz::mojom::InputTargetClientRequest request) {
DCHECK(!binding_.is_bound());
- binding_.Bind(std::move(request));
+ binding_.Bind(std::move(request), render_frame_->GetTaskRunner(
+ blink::TaskType::kInternalDefault));
}
void InputTargetClientImpl::FrameSinkIdAt(const gfx::Point& point,
+ const uint64_t trace_id,
FrameSinkIdAtCallback callback) {
+ TRACE_EVENT_WITH_FLOW1("viz,benchmark", "Event.Pipeline",
+ TRACE_ID_GLOBAL(trace_id),
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+ "step", "FrameSinkIdAt");
+
gfx::PointF local_point;
viz::FrameSinkId id = render_frame_->GetRenderWidget()->GetFrameSinkIdAtPoint(
point, &local_point);
diff --git a/chromium/content/renderer/input/input_target_client_impl.h b/chromium/content/renderer/input/input_target_client_impl.h
index fce58322701..7dc3c94bbe4 100644
--- a/chromium/content/renderer/input/input_target_client_impl.h
+++ b/chromium/content/renderer/input/input_target_client_impl.h
@@ -22,6 +22,7 @@ class InputTargetClientImpl : public viz::mojom::InputTargetClient {
// viz::mojom::InputTargetClient:
void FrameSinkIdAt(const gfx::Point& point,
+ const uint64_t trace_id,
FrameSinkIdAtCallback callback) override;
private:
diff --git a/chromium/content/renderer/input/main_thread_event_queue_unittest.cc b/chromium/content/renderer/input/main_thread_event_queue_unittest.cc
index 670672eb0f1..ecd6777a7e5 100644
--- a/chromium/content/renderer/input/main_thread_event_queue_unittest.cc
+++ b/chromium/content/renderer/input/main_thread_event_queue_unittest.cc
@@ -140,7 +140,6 @@ class HandledEventCallbackTracker {
private:
std::vector<ReceivedCallback> callbacks_received_;
- std::vector<ui::LatencyInfo> latency_info_received_;
base::WeakPtr<HandledEventCallbackTracker> weak_this_;
base::WeakPtrFactory<HandledEventCallbackTracker> weak_ptr_factory_;
};
diff --git a/chromium/content/renderer/internal_document_state_data.cc b/chromium/content/renderer/internal_document_state_data.cc
index 2360f2144b3..6750e0ebe6b 100644
--- a/chromium/content/renderer/internal_document_state_data.cc
+++ b/chromium/content/renderer/internal_document_state_data.cc
@@ -6,6 +6,7 @@
#include "base/memory/ptr_util.h"
#include "content/public/renderer/document_state.h"
+#include "content/renderer/navigation_state.h"
#include "third_party/blink/public/web/web_document_loader.h"
namespace content {
@@ -48,4 +49,18 @@ InternalDocumentStateData* InternalDocumentStateData::FromDocumentState(
InternalDocumentStateData::~InternalDocumentStateData() {
}
+void InternalDocumentStateData::CopyFrom(InternalDocumentStateData* other) {
+ http_status_code_ = other->http_status_code_;
+ is_overriding_user_agent_ = other->is_overriding_user_agent_;
+ must_reset_scroll_and_scale_state_ =
+ other->must_reset_scroll_and_scale_state_;
+ cache_policy_override_set_ = other->cache_policy_override_set_;
+ cache_policy_override_ = other->cache_policy_override_;
+}
+
+void InternalDocumentStateData::set_navigation_state(
+ std::unique_ptr<NavigationState> navigation_state) {
+ navigation_state_ = std::move(navigation_state);
+}
+
} // namespace content
diff --git a/chromium/content/renderer/internal_document_state_data.h b/chromium/content/renderer/internal_document_state_data.h
index 1705e537a65..edfdd6ffad1 100644
--- a/chromium/content/renderer/internal_document_state_data.h
+++ b/chromium/content/renderer/internal_document_state_data.h
@@ -10,7 +10,7 @@
#include "base/macros.h"
#include "base/supports_user_data.h"
-#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "url/gurl.h"
namespace blink {
@@ -20,6 +20,7 @@ class WebDocumentLoader;
namespace content {
class DocumentState;
+class NavigationState;
// Stores internal state per WebDocumentLoader.
class InternalDocumentStateData : public base::SupportsUserData::Data {
@@ -31,20 +32,13 @@ class InternalDocumentStateData : public base::SupportsUserData::Data {
blink::WebDocumentLoader* document_loader);
static InternalDocumentStateData* FromDocumentState(DocumentState* ds);
+ void CopyFrom(InternalDocumentStateData* other);
+
int http_status_code() const { return http_status_code_; }
void set_http_status_code(int http_status_code) {
http_status_code_ = http_status_code;
}
- const GURL& searchable_form_url() const { return searchable_form_url_; }
- void set_searchable_form_url(const GURL& url) { searchable_form_url_ = url; }
- const std::string& searchable_form_encoding() const {
- return searchable_form_encoding_;
- }
- void set_searchable_form_encoding(const std::string& encoding) {
- searchable_form_encoding_ = encoding;
- }
-
// True if the user agent was overridden for this page.
bool is_overriding_user_agent() const { return is_overriding_user_agent_; }
void set_is_overriding_user_agent(bool state) {
@@ -78,14 +72,16 @@ class InternalDocumentStateData : public base::SupportsUserData::Data {
return cache_policy_override_set_;
}
+ NavigationState* navigation_state() { return navigation_state_.get(); }
+ void set_navigation_state(std::unique_ptr<NavigationState> navigation_state);
+
private:
int http_status_code_;
- GURL searchable_form_url_;
- std::string searchable_form_encoding_;
bool is_overriding_user_agent_;
bool must_reset_scroll_and_scale_state_;
bool cache_policy_override_set_;
blink::mojom::FetchCacheMode cache_policy_override_;
+ std::unique_ptr<NavigationState> navigation_state_;
DISALLOW_COPY_AND_ASSIGN(InternalDocumentStateData);
};
diff --git a/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc b/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc
index 4e66f652480..0847553956c 100644
--- a/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc
+++ b/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc
@@ -4,7 +4,13 @@
#include "content/renderer/loader/child_url_loader_factory_bundle.h"
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
#include "base/logging.h"
+#include "content/public/common/resource_type.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "url/gurl.h"
#include "url/url_constants.h"
@@ -89,26 +95,44 @@ class URLLoaderRelay : public network::mojom::URLLoaderClient,
network::mojom::URLLoaderClientPtr client_sink_;
};
+template <typename TKey>
+static std::map<TKey, network::mojom::URLLoaderFactoryPtrInfo>
+PassInterfacePtrMapToPtrInfoMap(
+ std::map<TKey, network::mojom::URLLoaderFactoryPtr> input) {
+ std::map<TKey, network::mojom::URLLoaderFactoryPtrInfo> output;
+ for (auto& it : input) {
+ const TKey& key = it.first;
+ network::mojom::URLLoaderFactoryPtr& factory = it.second;
+ output.emplace(key, factory.PassInterface());
+ }
+ return output;
+}
+
} // namespace
ChildURLLoaderFactoryBundleInfo::ChildURLLoaderFactoryBundleInfo() = default;
ChildURLLoaderFactoryBundleInfo::ChildURLLoaderFactoryBundleInfo(
std::unique_ptr<URLLoaderFactoryBundleInfo> base_info)
- : URLLoaderFactoryBundleInfo(std::move(base_info->default_factory_info()),
- std::move(base_info->factories_info()),
- base_info->bypass_redirect_checks()) {}
+ : URLLoaderFactoryBundleInfo(
+ std::move(base_info->default_factory_info()),
+ std::move(base_info->scheme_specific_factory_infos()),
+ std::move(base_info->initiator_specific_factory_infos()),
+ base_info->bypass_redirect_checks()) {}
ChildURLLoaderFactoryBundleInfo::ChildURLLoaderFactoryBundleInfo(
network::mojom::URLLoaderFactoryPtrInfo default_factory_info,
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>
- factories_info,
+ SchemeMap scheme_specific_factory_infos,
+ OriginMap initiator_specific_factory_infos,
PossiblyAssociatedURLLoaderFactoryPtrInfo direct_network_factory_info,
+ network::mojom::URLLoaderFactoryPtrInfo prefetch_loader_factory_info,
bool bypass_redirect_checks)
: URLLoaderFactoryBundleInfo(std::move(default_factory_info),
- std::move(factories_info),
+ std::move(scheme_specific_factory_infos),
+ std::move(initiator_specific_factory_infos),
bypass_redirect_checks),
- direct_network_factory_info_(std::move(direct_network_factory_info)) {}
+ direct_network_factory_info_(std::move(direct_network_factory_info)),
+ prefetch_loader_factory_info_(std::move(prefetch_loader_factory_info)) {}
ChildURLLoaderFactoryBundleInfo::~ChildURLLoaderFactoryBundleInfo() = default;
@@ -116,8 +140,13 @@ scoped_refptr<network::SharedURLLoaderFactory>
ChildURLLoaderFactoryBundleInfo::CreateFactory() {
auto other = std::make_unique<ChildURLLoaderFactoryBundleInfo>();
other->default_factory_info_ = std::move(default_factory_info_);
- other->factories_info_ = std::move(factories_info_);
+ other->scheme_specific_factory_infos_ =
+ std::move(scheme_specific_factory_infos_);
+ other->initiator_specific_factory_infos_ =
+ std::move(initiator_specific_factory_infos_);
other->direct_network_factory_info_ = std::move(direct_network_factory_info_);
+ other->prefetch_loader_factory_info_ =
+ std::move(prefetch_loader_factory_info_);
other->bypass_redirect_checks_ = bypass_redirect_checks_;
return base::MakeRefCounted<ChildURLLoaderFactoryBundle>(std::move(other));
@@ -139,14 +168,12 @@ ChildURLLoaderFactoryBundle::ChildURLLoaderFactoryBundle(
ChildURLLoaderFactoryBundle::~ChildURLLoaderFactoryBundle() = default;
-network::mojom::URLLoaderFactory* ChildURLLoaderFactoryBundle::GetFactoryForURL(
- const GURL& url) {
- auto it = factories_.find(url.scheme());
- if (it != factories_.end())
- return it->second.get();
-
- if (default_factory_)
- return default_factory_.get();
+network::mojom::URLLoaderFactory* ChildURLLoaderFactoryBundle::GetFactory(
+ const network::ResourceRequest& request) {
+ network::mojom::URLLoaderFactory* base_result =
+ URLLoaderFactoryBundle::GetFactory(request);
+ if (base_result)
+ return base_result;
InitDirectNetworkFactoryIfNecessary();
DCHECK(direct_network_factory_);
@@ -179,11 +206,22 @@ void ChildURLLoaderFactoryBundle::CreateLoaderAndStart(
return;
}
- network::mojom::URLLoaderFactory* factory_ptr = GetFactoryForURL(request.url);
+ // Use |prefetch_loader_factory_| for prefetch requests to send the requests
+ // to the PrefetchURLLoaderService in the browser process and triger the
+ // special prefetch handling.
+ // TODO(horo): Move this routing logic to network service, when we will have
+ // the special prefetch handling in network service.
+ if ((request.resource_type == RESOURCE_TYPE_PREFETCH) &&
+ prefetch_loader_factory_) {
+ prefetch_loader_factory_->CreateLoaderAndStart(
+ std::move(loader), routing_id, request_id, options, request,
+ std::move(client), traffic_annotation);
+ return;
+ }
- factory_ptr->CreateLoaderAndStart(std::move(loader), routing_id, request_id,
- options, request, std::move(client),
- traffic_annotation);
+ URLLoaderFactoryBundle::CreateLoaderAndStart(
+ std::move(loader), routing_id, request_id, options, request,
+ std::move(client), traffic_annotation);
}
std::unique_ptr<network::SharedURLLoaderFactoryInfo>
@@ -204,6 +242,10 @@ void ChildURLLoaderFactoryBundle::Update(
direct_network_factory_.Bind(
std::move(info->direct_network_factory_info()));
}
+ if (info->prefetch_loader_factory_info()) {
+ prefetch_loader_factory_.Bind(
+ std::move(info->prefetch_loader_factory_info()));
+ }
URLLoaderFactoryBundle::Update(std::move(info));
if (subresource_overrides) {
@@ -213,6 +255,11 @@ void ChildURLLoaderFactoryBundle::Update(
}
}
+void ChildURLLoaderFactoryBundle::SetPrefetchLoaderFactory(
+ network::mojom::URLLoaderFactoryPtr prefetch_loader_factory) {
+ prefetch_loader_factory_ = std::move(prefetch_loader_factory);
+}
+
bool ChildURLLoaderFactoryBundle::IsHostChildURLLoaderFactoryBundle() const {
return false;
}
@@ -236,25 +283,27 @@ ChildURLLoaderFactoryBundle::CloneInternal(bool include_default) {
if (include_default && default_factory_)
default_factory_->Clone(mojo::MakeRequest(&default_factory_info));
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo> factories_info;
- for (auto& factory : factories_) {
- network::mojom::URLLoaderFactoryPtrInfo factory_info;
- factory.second->Clone(mojo::MakeRequest(&factory_info));
- factories_info.emplace(factory.first, std::move(factory_info));
- }
-
network::mojom::URLLoaderFactoryPtrInfo direct_network_factory_info;
if (direct_network_factory_) {
direct_network_factory_->Clone(
mojo::MakeRequest(&direct_network_factory_info));
}
+ network::mojom::URLLoaderFactoryPtrInfo prefetch_loader_factory_info;
+ if (prefetch_loader_factory_) {
+ prefetch_loader_factory_->Clone(
+ mojo::MakeRequest(&prefetch_loader_factory_info));
+ }
+
// Currently there is no need to override subresources from workers,
// therefore |subresource_overrides| are not shared with the clones.
return std::make_unique<ChildURLLoaderFactoryBundleInfo>(
- std::move(default_factory_info), std::move(factories_info),
- std::move(direct_network_factory_info), bypass_redirect_checks_);
+ std::move(default_factory_info),
+ ClonePtrMapToPtrInfoMap(scheme_specific_factories_),
+ ClonePtrMapToPtrInfoMap(initiator_specific_factories_),
+ std::move(direct_network_factory_info),
+ std::move(prefetch_loader_factory_info), bypass_redirect_checks_);
}
std::unique_ptr<ChildURLLoaderFactoryBundleInfo>
@@ -265,20 +314,23 @@ ChildURLLoaderFactoryBundle::PassInterface() {
if (default_factory_)
default_factory_info = default_factory_.PassInterface();
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo> factories_info;
- for (auto& factory : factories_) {
- factories_info.emplace(factory.first, factory.second.PassInterface());
- }
-
PossiblyAssociatedInterfacePtrInfo<network::mojom::URLLoaderFactory>
direct_network_factory_info;
if (direct_network_factory_) {
direct_network_factory_info = direct_network_factory_.PassInterface();
}
+ network::mojom::URLLoaderFactoryPtrInfo prefetch_loader_factory_info;
+ if (prefetch_loader_factory_) {
+ prefetch_loader_factory_info = prefetch_loader_factory_.PassInterface();
+ }
+
return std::make_unique<ChildURLLoaderFactoryBundleInfo>(
- std::move(default_factory_info), std::move(factories_info),
- std::move(direct_network_factory_info), bypass_redirect_checks_);
+ std::move(default_factory_info),
+ PassInterfacePtrMapToPtrInfoMap(std::move(scheme_specific_factories_)),
+ PassInterfacePtrMapToPtrInfoMap(std::move(initiator_specific_factories_)),
+ std::move(direct_network_factory_info),
+ std::move(prefetch_loader_factory_info), bypass_redirect_checks_);
}
} // namespace content
diff --git a/chromium/content/renderer/loader/child_url_loader_factory_bundle.h b/chromium/content/renderer/loader/child_url_loader_factory_bundle.h
index 0ba0c4950a3..a6b429299c7 100644
--- a/chromium/content/renderer/loader/child_url_loader_factory_bundle.h
+++ b/chromium/content/renderer/loader/child_url_loader_factory_bundle.h
@@ -5,7 +5,12 @@
#ifndef CONTENT_RENDERER_LOADER_CHILD_URL_LOADER_FACTORY_BUNDLE_H_
#define CONTENT_RENDERER_LOADER_CHILD_URL_LOADER_FACTORY_BUNDLE_H_
+#include <map>
+#include <memory>
+#include <vector>
+
#include "base/callback.h"
+#include "base/optional.h"
#include "content/common/content_export.h"
#include "content/common/possibly_associated_interface_ptr.h"
#include "content/common/url_loader_factory_bundle.h"
@@ -16,6 +21,12 @@ namespace content {
// Holds the internal state of a ChildURLLoaderFactoryBundle in a form that is
// safe to pass across sequences.
+// |prefetch_loader_factory_info| is used only by the frames who may send
+// prefetch requests by <link rel="prefetch"> tags. The loader factory allows
+// prefetch loading to be done by the browser process (therefore less memory
+// pressure), and also adds special handling for Signed Exchanges (SXG) when the
+// flag is enabled. TODO(crbug/803776): deprecate this once SXG specific code is
+// moved into Network Service unless we see huge memory benefit for doing this.
class CONTENT_EXPORT ChildURLLoaderFactoryBundleInfo
: public URLLoaderFactoryBundleInfo {
public:
@@ -27,21 +38,26 @@ class CONTENT_EXPORT ChildURLLoaderFactoryBundleInfo
std::unique_ptr<URLLoaderFactoryBundleInfo> base_info);
ChildURLLoaderFactoryBundleInfo(
network::mojom::URLLoaderFactoryPtrInfo default_factory_info,
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>
- factories_info,
+ SchemeMap scheme_specific_factory_infos,
+ OriginMap initiator_specific_factory_infos,
PossiblyAssociatedURLLoaderFactoryPtrInfo direct_network_factory_info,
+ network::mojom::URLLoaderFactoryPtrInfo prefetch_loader_factory_info,
bool bypass_redirect_checks);
~ChildURLLoaderFactoryBundleInfo() override;
PossiblyAssociatedURLLoaderFactoryPtrInfo& direct_network_factory_info() {
return direct_network_factory_info_;
}
+ network::mojom::URLLoaderFactoryPtrInfo& prefetch_loader_factory_info() {
+ return prefetch_loader_factory_info_;
+ }
protected:
// URLLoaderFactoryBundleInfo overrides.
scoped_refptr<network::SharedURLLoaderFactory> CreateFactory() override;
PossiblyAssociatedURLLoaderFactoryPtrInfo direct_network_factory_info_;
+ network::mojom::URLLoaderFactoryPtrInfo prefetch_loader_factory_info_;
DISALLOW_COPY_AND_ASSIGN(ChildURLLoaderFactoryBundleInfo);
};
@@ -70,8 +86,6 @@ class CONTENT_EXPORT ChildURLLoaderFactoryBundle
PossiblyAssociatedFactoryGetterCallback direct_network_factory_getter);
// URLLoaderFactoryBundle overrides.
- network::mojom::URLLoaderFactory* GetFactoryForURL(const GURL& url) override;
-
void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader,
int32_t routing_id,
int32_t request_id,
@@ -80,7 +94,6 @@ class CONTENT_EXPORT ChildURLLoaderFactoryBundle
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag&
traffic_annotation) override;
-
std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override;
// Returns an info that omits this bundle's default factory, if any. This is
@@ -93,12 +106,18 @@ class CONTENT_EXPORT ChildURLLoaderFactoryBundle
void Update(std::unique_ptr<ChildURLLoaderFactoryBundleInfo> info,
base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
subresource_overrides);
+ void SetPrefetchLoaderFactory(
+ network::mojom::URLLoaderFactoryPtr prefetch_loader_factory);
virtual bool IsHostChildURLLoaderFactoryBundle() const;
protected:
~ChildURLLoaderFactoryBundle() override;
+ // URLLoaderFactoryBundle overrides.
+ network::mojom::URLLoaderFactory* GetFactory(
+ const network::ResourceRequest& request) override;
+
private:
void InitDirectNetworkFactoryIfNecessary();
std::unique_ptr<network::SharedURLLoaderFactoryInfo> CloneInternal(
@@ -106,6 +125,7 @@ class CONTENT_EXPORT ChildURLLoaderFactoryBundle
PossiblyAssociatedFactoryGetterCallback direct_network_factory_getter_;
PossiblyAssociatedURLLoaderFactoryPtr direct_network_factory_;
+ network::mojom::URLLoaderFactoryPtr prefetch_loader_factory_;
std::map<GURL, mojom::TransferrableURLLoaderPtr> subresource_overrides_;
};
diff --git a/chromium/content/renderer/loader/code_cache_loader_impl.cc b/chromium/content/renderer/loader/code_cache_loader_impl.cc
index 0fbbeac5e1b..edc4e117dfd 100644
--- a/chromium/content/renderer/loader/code_cache_loader_impl.cc
+++ b/chromium/content/renderer/loader/code_cache_loader_impl.cc
@@ -45,10 +45,11 @@ void CodeCacheLoaderImpl::FetchFromCodeCacheSynchronously(
// It is Ok to pass |fetch_code_cache_event| with base::Unretained. Since
// this thread is stalled, the fetch_code_cache_event will be kept alive.
task_runner->PostTask(
- FROM_HERE,
- base::BindOnce(&CodeCacheLoaderImpl::FetchFromCodeCacheImpl,
- weak_ptr_factory_.GetWeakPtr(), url, std::move(callback),
- base::Unretained(&fetch_code_cache_event)));
+ FROM_HERE, base::BindOnce(&CodeCacheLoaderImpl::FetchFromCodeCacheImpl,
+ weak_ptr_factory_.GetWeakPtr(),
+ blink::mojom::CodeCacheType::kJavascript, url,
+ std::move(callback),
+ base::Unretained(&fetch_code_cache_event)));
// Wait for the fetch from code cache to finish.
fetch_code_cache_event.Wait();
@@ -58,12 +59,15 @@ void CodeCacheLoaderImpl::FetchFromCodeCacheSynchronously(
*data_out = data_for_sync_load_;
}
-void CodeCacheLoaderImpl::FetchFromCodeCache(const GURL& url,
- FetchCodeCacheCallback callback) {
- FetchFromCodeCacheImpl(url, std::move(callback), nullptr);
+void CodeCacheLoaderImpl::FetchFromCodeCache(
+ blink::mojom::CodeCacheType cache_type,
+ const GURL& url,
+ FetchCodeCacheCallback callback) {
+ FetchFromCodeCacheImpl(cache_type, url, std::move(callback), nullptr);
}
void CodeCacheLoaderImpl::FetchFromCodeCacheImpl(
+ blink::mojom::CodeCacheType cache_type,
const GURL& gurl,
FetchCodeCacheCallback callback,
base::WaitableEvent* fetch_event) {
@@ -71,9 +75,10 @@ void CodeCacheLoaderImpl::FetchFromCodeCacheImpl(
// fetch_event, because the thread is stalled and it will keep the fetch_event
// alive.
blink::Platform::Current()->FetchCachedCode(
- gurl, base::BindOnce(&CodeCacheLoaderImpl::OnReceiveCachedCode,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback),
- fetch_event));
+ cache_type, gurl,
+ base::BindOnce(&CodeCacheLoaderImpl::OnReceiveCachedCode,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+ fetch_event));
}
void CodeCacheLoaderImpl::OnReceiveCachedCode(
diff --git a/chromium/content/renderer/loader/code_cache_loader_impl.h b/chromium/content/renderer/loader/code_cache_loader_impl.h
index 99c9d156e18..fc4084b616d 100644
--- a/chromium/content/renderer/loader/code_cache_loader_impl.h
+++ b/chromium/content/renderer/loader/code_cache_loader_impl.h
@@ -22,16 +22,18 @@ class CodeCacheLoaderImpl : public blink::CodeCacheLoader {
// Fetches code cache corresponding to |url| and returns response in
// |response_time_out| and |data_out|. |response_time_out| and |data_out|
- // cannot be nullptrs.
+ // cannot be nullptrs. This only fetches from the Javascript cache.
void FetchFromCodeCacheSynchronously(const GURL& url,
base::Time* response_time_out,
std::vector<uint8_t>* data_out) override;
- void FetchFromCodeCache(const GURL& url,
+ void FetchFromCodeCache(blink::mojom::CodeCacheType cache_type,
+ const GURL& url,
FetchCodeCacheCallback callback) override;
private:
- void FetchFromCodeCacheImpl(const GURL& url,
+ void FetchFromCodeCacheImpl(blink::mojom::CodeCacheType cache_type,
+ const GURL& url,
FetchCodeCacheCallback callback,
base::WaitableEvent* event);
diff --git a/chromium/content/renderer/loader/request_extra_data.h b/chromium/content/renderer/loader/request_extra_data.h
index 2239ee9443d..caafb0083c8 100644
--- a/chromium/content/renderer/loader/request_extra_data.h
+++ b/chromium/content/renderer/loader/request_extra_data.h
@@ -73,12 +73,6 @@ class CONTENT_EXPORT RequestExtraData : public blink::WebURLRequest::ExtraData {
void set_custom_user_agent(const blink::WebString& custom_user_agent) {
custom_user_agent_ = custom_user_agent;
}
- const blink::WebString& requested_with() const {
- return requested_with_;
- }
- void set_requested_with(const blink::WebString& requested_with) {
- requested_with_ = requested_with;
- }
// PlzNavigate: |navigation_response_override| is used to override certain
// parameters of navigation requests.
@@ -173,7 +167,6 @@ class CONTENT_EXPORT RequestExtraData : public blink::WebURLRequest::ExtraData {
int service_worker_provider_id_;
bool originated_from_service_worker_;
blink::WebString custom_user_agent_;
- blink::WebString requested_with_;
std::unique_ptr<NavigationResponseOverrideParameters>
navigation_response_override_;
// TODO(arthursonzogni): Move most of the |navigation_response_override_|
diff --git a/chromium/content/renderer/loader/resource_dispatcher.cc b/chromium/content/renderer/loader/resource_dispatcher.cc
index f07e67896b5..dd7f440dd97 100644
--- a/chromium/content/renderer/loader/resource_dispatcher.cc
+++ b/chromium/content/renderer/loader/resource_dispatcher.cc
@@ -196,6 +196,26 @@ void NotifyResourceTransferSizeUpdate(
render_frame->DidReceiveTransferSizeUpdate(request_id, transfer_size_diff);
}
+#if defined(OS_ANDROID)
+void NotifyUpdateUserGestureCarryoverInfo(int render_frame_id) {
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ RenderThreadImpl::DeprecatedGetMainTaskRunner();
+ if (!task_runner->BelongsToCurrentThread()) {
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(NotifyUpdateUserGestureCarryoverInfo, render_frame_id));
+ return;
+ }
+
+ RenderFrameImpl* render_frame =
+ RenderFrameImpl::FromRoutingID(render_frame_id);
+ if (!render_frame)
+ return;
+
+ render_frame->GetFrameHost()->UpdateUserGestureCarryoverInfo();
+}
+#endif
+
// Returns true if the headers indicate that this resource should always be
// revalidated or not cached.
bool AlwaysAccessNetwork(
@@ -261,7 +281,7 @@ ResourceDispatcher::~ResourceDispatcher() {
ResourceDispatcher::PendingRequestInfo*
ResourceDispatcher::GetPendingRequestInfo(int request_id) {
- PendingRequestMap::iterator it = pending_requests_.find(request_id);
+ auto it = pending_requests_.find(request_id);
if (it == pending_requests_.end())
return nullptr;
return it->second.get();
@@ -495,6 +515,7 @@ void ResourceDispatcher::OnRequestComplete(
}
network::URLLoaderCompletionStatus renderer_status(status);
+ // TODO(toyoshim): Consider to convert status.cors_preflight_timing_info here.
if (status.completion_time.is_null()) {
// No completion timestamp is provided, leave it as is.
} else if (request_info->remote_request_start.is_null() ||
@@ -528,7 +549,7 @@ void ResourceDispatcher::OnRequestComplete(
bool ResourceDispatcher::RemovePendingRequest(
int request_id,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- PendingRequestMap::iterator it = pending_requests_.find(request_id);
+ auto it = pending_requests_.find(request_id);
if (it == pending_requests_.end())
return false;
@@ -559,7 +580,7 @@ bool ResourceDispatcher::RemovePendingRequest(
void ResourceDispatcher::Cancel(
int request_id,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- PendingRequestMap::iterator it = pending_requests_.find(request_id);
+ auto it = pending_requests_.find(request_id);
if (it == pending_requests_.end()) {
DLOG(ERROR) << "unknown request";
return;
@@ -716,6 +737,13 @@ int ResourceDispatcher::StartAsync(
base::OnceClosure* continue_navigation_function) {
CheckSchemeForReferrerPolicy(*request);
+#if defined(OS_ANDROID)
+ if (request->resource_type != RESOURCE_TYPE_MAIN_FRAME &&
+ request->has_user_gesture) {
+ NotifyUpdateUserGestureCarryoverInfo(request->render_frame_id);
+ }
+#endif
+
bool override_url_loader =
!!response_override_params &&
!!response_override_params->url_loader_client_endpoints;
@@ -735,10 +763,23 @@ int ResourceDispatcher::StartAsync(
request_id, this, loading_task_runner,
true /* bypass_redirect_checks */, request->url);
- DCHECK(continue_navigation_function);
- *continue_navigation_function =
- base::BindOnce(&ResourceDispatcher::ContinueForNavigation,
- weak_factory_.GetWeakPtr(), request_id);
+ if (request->resource_type == RESOURCE_TYPE_SHARED_WORKER) {
+ // For shared workers, immediately post a task for continuing loading
+ // because shared workers don't have the concept of the navigation commit
+ // and |continue_navigation_function| is never called.
+ // TODO(nhiroki): Unify this case with the navigation case for code
+ // health.
+ loading_task_runner->PostTask(
+ FROM_HERE, base::BindOnce(&ResourceDispatcher::ContinueForNavigation,
+ weak_factory_.GetWeakPtr(), request_id));
+ } else {
+ // For navigations, |continue_navigation_function| is called after the
+ // navigation commit.
+ DCHECK(continue_navigation_function);
+ *continue_navigation_function =
+ base::BindOnce(&ResourceDispatcher::ContinueForNavigation,
+ weak_factory_.GetWeakPtr(), request_id);
+ }
return request_id;
}
@@ -752,7 +793,8 @@ int ResourceDispatcher::StartAsync(
uint32_t options = network::mojom::kURLLoadOptionNone;
// TODO(jam): use this flag for ResourceDispatcherHost code path once
// MojoLoading is the only IPC code path.
- if (request->fetch_request_context_type != REQUEST_CONTEXT_TYPE_FETCH) {
+ if (request->fetch_request_context_type !=
+ static_cast<int>(blink::mojom::RequestContextType::FETCH)) {
// MIME sniffing should be disabled for a request initiated by fetch().
options |= network::mojom::kURLLoadOptionSniffMimeType;
if (blink::ServiceWorkerUtils::IsServicificationEnabled())
diff --git a/chromium/content/renderer/loader/resource_dispatcher_unittest.cc b/chromium/content/renderer/loader/resource_dispatcher_unittest.cc
index 186292fb0ba..a129c4d568b 100644
--- a/chromium/content/renderer/loader/resource_dispatcher_unittest.cc
+++ b/chromium/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -15,10 +15,10 @@
#include "base/macros.h"
#include "base/memory/shared_memory.h"
-#include "base/message_loop/message_loop.h"
#include "base/process/process_handle.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
+#include "base/test/scoped_task_environment.h"
#include "content/common/appcache_interfaces.h"
#include "content/public/common/content_features.h"
#include "content/public/renderer/fixed_received_data.h"
@@ -130,7 +130,7 @@ class ResourceDispatcherTest : public testing::Test,
std::vector<std::pair<network::mojom::URLLoaderRequest,
network::mojom::URLLoaderClientPtr>>
loader_and_clients_;
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
std::unique_ptr<ResourceDispatcher> dispatcher_;
};
diff --git a/chromium/content/renderer/loader/shared_memory_data_consumer_handle_unittest.cc b/chromium/content/renderer/loader/shared_memory_data_consumer_handle_unittest.cc
index 777deb6c681..77f7542b151 100644
--- a/chromium/content/renderer/loader/shared_memory_data_consumer_handle_unittest.cc
+++ b/chromium/content/renderer/loader/shared_memory_data_consumer_handle_unittest.cc
@@ -15,11 +15,11 @@
#include "base/callback.h"
#include "base/location.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_split.h"
#include "base/task_runner.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/public/renderer/fixed_received_data.h"
@@ -129,11 +129,12 @@ class ThreadedSharedMemoryDataConsumerHandleTest : public ::testing::Test {
class ReadDataOperation final {
public:
typedef WebDataConsumerHandle::Result Result;
- ReadDataOperation(std::unique_ptr<SharedMemoryDataConsumerHandle> handle,
- base::MessageLoop* main_message_loop,
- const base::Closure& on_done)
+ ReadDataOperation(
+ std::unique_ptr<SharedMemoryDataConsumerHandle> handle,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
+ const base::Closure& on_done)
: handle_(std::move(handle)),
- main_message_loop_(main_message_loop),
+ main_thread_task_runner_(main_thread_task_runner),
on_done_(on_done) {}
const std::string& result() const { return result_; }
@@ -169,14 +170,14 @@ class ThreadedSharedMemoryDataConsumerHandleTest : public ::testing::Test {
// The operation is done.
reader_.reset();
- main_message_loop_->task_runner()->PostTask(FROM_HERE, on_done_);
+ main_thread_task_runner_->PostTask(FROM_HERE, on_done_);
}
private:
std::unique_ptr<SharedMemoryDataConsumerHandle> handle_;
std::unique_ptr<WebDataConsumerHandle::Reader> reader_;
std::unique_ptr<WebDataConsumerHandle::Client> client_;
- base::MessageLoop* main_message_loop_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
base::Closure on_done_;
std::string result_;
};
@@ -189,7 +190,7 @@ class ThreadedSharedMemoryDataConsumerHandleTest : public ::testing::Test {
StrictMock<MockClient> client_;
std::unique_ptr<SharedMemoryDataConsumerHandle> handle_;
std::unique_ptr<Writer> writer_;
- base::MessageLoop loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
};
class SharedMemoryDataConsumerHandleTest
@@ -205,7 +206,7 @@ class SharedMemoryDataConsumerHandleTest
StrictMock<MockClient> client_;
std::unique_ptr<SharedMemoryDataConsumerHandle> handle_;
std::unique_ptr<Writer> writer_;
- base::MessageLoop loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
};
void RunPostedTasks() {
@@ -923,7 +924,7 @@ TEST_P(SharedMemoryDataConsumerHandleTest, RecursiveErrorNotification) {
}
TEST(SharedMemoryDataConsumerHandleBackpressureTest, Read) {
- base::MessageLoop loop;
+ base::test::ScopedTaskEnvironment task_environment;
char buffer[20];
Result result;
size_t size;
@@ -969,7 +970,7 @@ TEST(SharedMemoryDataConsumerHandleBackpressureTest, Read) {
}
TEST(SharedMemoryDataConsumerHandleBackpressureTest, CloseAndReset) {
- base::MessageLoop loop;
+ base::test::ScopedTaskEnvironment task_environment;
char buffer[20];
Result result;
size_t size;
@@ -1017,7 +1018,7 @@ TEST(SharedMemoryDataConsumerHandleBackpressureTest, CloseAndReset) {
}
TEST(SharedMemoryDataConsumerHandleWithoutBackpressureTest, AddData) {
- base::MessageLoop loop;
+ base::test::ScopedTaskEnvironment task_environment;
std::unique_ptr<Writer> writer;
auto handle = std::make_unique<SharedMemoryDataConsumerHandle>(
kDoNotApplyBackpressure, &writer);
@@ -1043,7 +1044,8 @@ TEST(SharedMemoryDataConsumerHandleWithoutBackpressureTest, AddData) {
TEST_F(ThreadedSharedMemoryDataConsumerHandleTest, Read) {
base::RunLoop run_loop;
auto operation = std::make_unique<ReadDataOperation>(
- std::move(handle_), &loop_, run_loop.QuitClosure());
+ std::move(handle_), base::ThreadTaskRunnerHandle::Get(),
+ run_loop.QuitClosure());
scoped_refptr<Logger> logger(new Logger);
base::Thread t("DataConsumerHandle test thread");
diff --git a/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.cc b/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.cc
index 22997f9d413..243eb38d8fa 100644
--- a/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.cc
+++ b/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.cc
@@ -4,6 +4,8 @@
#include "content/renderer/loader/tracked_child_url_loader_factory_bundle.h"
+#include <utility>
+
#include "content/public/renderer/render_thread.h"
namespace content {
@@ -13,15 +15,19 @@ TrackedChildURLLoaderFactoryBundleInfo::
TrackedChildURLLoaderFactoryBundleInfo::TrackedChildURLLoaderFactoryBundleInfo(
network::mojom::URLLoaderFactoryPtrInfo default_factory_info,
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>
- factories_info,
+ SchemeMap scheme_specific_factory_infos,
+ OriginMap initiator_specific_factory_infos,
PossiblyAssociatedURLLoaderFactoryPtrInfo direct_network_factory_info,
+ network::mojom::URLLoaderFactoryPtrInfo prefetch_loader_factory_info,
std::unique_ptr<HostPtrAndTaskRunner> main_thread_host_bundle,
bool bypass_redirect_checks)
- : ChildURLLoaderFactoryBundleInfo(std::move(default_factory_info),
- std::move(factories_info),
- std::move(direct_network_factory_info),
- bypass_redirect_checks),
+ : ChildURLLoaderFactoryBundleInfo(
+ std::move(default_factory_info),
+ std::move(scheme_specific_factory_infos),
+ std::move(initiator_specific_factory_infos),
+ std::move(direct_network_factory_info),
+ std::move(prefetch_loader_factory_info),
+ bypass_redirect_checks),
main_thread_host_bundle_(std::move(main_thread_host_bundle)) {}
TrackedChildURLLoaderFactoryBundleInfo::
@@ -31,8 +37,13 @@ scoped_refptr<network::SharedURLLoaderFactory>
TrackedChildURLLoaderFactoryBundleInfo::CreateFactory() {
auto other = std::make_unique<TrackedChildURLLoaderFactoryBundleInfo>();
other->default_factory_info_ = std::move(default_factory_info_);
- other->factories_info_ = std::move(factories_info_);
+ other->scheme_specific_factory_infos_ =
+ std::move(scheme_specific_factory_infos_);
+ other->initiator_specific_factory_infos_ =
+ std::move(initiator_specific_factory_infos_);
other->direct_network_factory_info_ = std::move(direct_network_factory_info_);
+ other->prefetch_loader_factory_info_ =
+ std::move(prefetch_loader_factory_info_);
other->main_thread_host_bundle_ = std::move(main_thread_host_bundle_);
other->bypass_redirect_checks_ = bypass_redirect_checks_;
@@ -52,7 +63,7 @@ TrackedChildURLLoaderFactoryBundle::TrackedChildURLLoaderFactoryBundle(
TrackedChildURLLoaderFactoryBundle::~TrackedChildURLLoaderFactoryBundle() {
RemoveObserverOnMainThread();
-};
+}
std::unique_ptr<network::SharedURLLoaderFactoryInfo>
TrackedChildURLLoaderFactoryBundle::Clone() {
@@ -66,16 +77,17 @@ TrackedChildURLLoaderFactoryBundle::Clone() {
return std::make_unique<TrackedChildURLLoaderFactoryBundleInfo>(
std::move(info->default_factory_info()),
- std::move(info->factories_info()),
+ std::move(info->scheme_specific_factory_infos()),
+ std::move(info->initiator_specific_factory_infos()),
std::move(info->direct_network_factory_info()),
+ std::move(info->prefetch_loader_factory_info()),
std::move(main_thread_host_bundle_clone), info->bypass_redirect_checks());
}
void TrackedChildURLLoaderFactoryBundle::AddObserverOnMainThread() {
DCHECK(main_thread_host_bundle_);
- // TODO(chongz): Change this to a DCHECK once all call sites have a
- // SequencedTaskRunnerHandle.
+ // Required by |SequencedTaskRunnerHandle::Get()| below.
if (!base::SequencedTaskRunnerHandle::IsSet())
return;
@@ -129,8 +141,10 @@ HostChildURLLoaderFactoryBundle::Clone() {
return std::make_unique<TrackedChildURLLoaderFactoryBundleInfo>(
std::move(info->default_factory_info()),
- std::move(info->factories_info()),
+ std::move(info->scheme_specific_factory_infos()),
+ std::move(info->initiator_specific_factory_infos()),
std::move(info->direct_network_factory_info()),
+ std::move(info->prefetch_loader_factory_info()),
std::move(main_thread_host_bundle_clone), info->bypass_redirect_checks());
}
@@ -146,8 +160,10 @@ HostChildURLLoaderFactoryBundle::CloneWithoutDefaultFactory() {
return std::make_unique<TrackedChildURLLoaderFactoryBundleInfo>(
std::move(info->default_factory_info()),
- std::move(info->factories_info()),
+ std::move(info->scheme_specific_factory_infos()),
+ std::move(info->initiator_specific_factory_infos()),
std::move(info->direct_network_factory_info()),
+ std::move(info->prefetch_loader_factory_info()),
std::move(main_thread_host_bundle_clone), info->bypass_redirect_checks());
}
diff --git a/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.h b/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.h
index 0b183ec2180..1322ee93925 100644
--- a/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.h
+++ b/chromium/content/renderer/loader/tracked_child_url_loader_factory_bundle.h
@@ -5,6 +5,10 @@
#ifndef CONTENT_RENDERER_LOADER_TRACKED_CHILD_URL_LOADER_FACTORY_BUNDLE_H_
#define CONTENT_RENDERER_LOADER_TRACKED_CHILD_URL_LOADER_FACTORY_BUNDLE_H_
+#include <memory>
+#include <unordered_map>
+#include <utility>
+
#include "base/sequenced_task_runner.h"
#include "content/common/content_export.h"
#include "content/renderer/loader/child_url_loader_factory_bundle.h"
@@ -25,9 +29,10 @@ class CONTENT_EXPORT TrackedChildURLLoaderFactoryBundleInfo
TrackedChildURLLoaderFactoryBundleInfo();
TrackedChildURLLoaderFactoryBundleInfo(
network::mojom::URLLoaderFactoryPtrInfo default_factory_info,
- std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>
- factories_info,
+ SchemeMap scheme_specific_factory_infos,
+ OriginMap initiator_specific_factory_infos,
PossiblyAssociatedURLLoaderFactoryPtrInfo direct_network_factory_info,
+ network::mojom::URLLoaderFactoryPtrInfo prefetch_loader_factory_info,
std::unique_ptr<HostPtrAndTaskRunner> main_thread_host_bundle,
bool bypass_redirect_checks);
~TrackedChildURLLoaderFactoryBundleInfo() override;
@@ -120,8 +125,8 @@ class CONTENT_EXPORT HostChildURLLoaderFactoryBundle
bool IsHostChildURLLoaderFactoryBundle() const override;
// Update this bundle with |info|, and post cloned |info| to tracked bundles.
- // TODO(chongz): We should also update |direct_network_factory_| together with
- // the |URLLoaderFactoryBundleInfo| we got from browser.
+ // Note: We don't need to worry about |direct_network_factory_| since it's
+ // only used by |RendererBlinkPlatformImpl| and doesn't rely on this codepath.
void UpdateThisAndAllClones(std::unique_ptr<URLLoaderFactoryBundleInfo> info);
private:
diff --git a/chromium/content/renderer/loader/url_loader_client_impl.cc b/chromium/content/renderer/loader/url_loader_client_impl.cc
index bf813ff292a..f9d55782cdc 100644
--- a/chromium/content/renderer/loader/url_loader_client_impl.cc
+++ b/chromium/content/renderer/loader/url_loader_client_impl.cc
@@ -289,7 +289,7 @@ void URLLoaderClientImpl::OnReceiveCachedMetadata(
}
void URLLoaderClientImpl::OnTransferSizeUpdated(int32_t transfer_size_diff) {
- if (is_deferred_) {
+ if (NeedsStoringMessage()) {
accumulated_transfer_size_diff_during_deferred_ += transfer_size_diff;
} else {
resource_dispatcher_->OnTransferSizeUpdated(request_id_,
@@ -311,7 +311,7 @@ void URLLoaderClientImpl::OnStartLoadingResponseBody(
body_consumer_ = new URLResponseBodyConsumer(
request_id_, resource_dispatcher_, std::move(body), task_runner_);
- if (is_deferred_) {
+ if (NeedsStoringMessage()) {
body_consumer_->SetDefersLoading();
return;
}
diff --git a/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc b/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc
index 2fc2884de80..42a3691bad7 100644
--- a/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc
+++ b/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc
@@ -5,9 +5,8 @@
#include "content/renderer/loader/url_loader_client_impl.h"
#include <vector>
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
-#include "content/public/common/request_context_type.h"
+#include "base/test/scoped_task_environment.h"
#include "content/renderer/loader/navigation_response_override_parameters.h"
#include "content/renderer/loader/resource_dispatcher.h"
#include "content/renderer/loader/test_request_peer.h"
@@ -18,6 +17,7 @@
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
namespace content {
@@ -30,7 +30,8 @@ class URLLoaderClientImplTest : public ::testing::Test,
// Set request context type to fetch so that ResourceDispatcher doesn't
// install MimeSniffingThrottle, which makes URLLoaderThrottleLoader
// defer the request.
- request->fetch_request_context_type = REQUEST_CONTEXT_TYPE_FETCH;
+ request->fetch_request_context_type =
+ static_cast<int>(blink::mojom::RequestContextType::FETCH);
request_id_ = dispatcher_->StartAsync(
std::move(request), 0,
blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
@@ -75,7 +76,7 @@ class URLLoaderClientImplTest : public ::testing::Test,
return options;
}
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
std::unique_ptr<ResourceDispatcher> dispatcher_;
TestRequestPeer::Context request_peer_context_;
int request_id_ = 0;
diff --git a/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc b/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc
index fb32f809835..36b002badde 100644
--- a/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc
+++ b/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc
@@ -7,9 +7,9 @@
#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/test/scoped_task_environment.h"
#include "content/public/renderer/request_peer.h"
#include "content/renderer/loader/navigation_response_override_parameters.h"
#include "content/renderer/loader/request_extra_data.h"
@@ -154,7 +154,8 @@ class URLResponseBodyConsumerTest : public ::testing::Test {
blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
TRAFFIC_ANNOTATION_FOR_TESTS, false,
false /* pass_response_pipe_to_peer */,
- std::make_unique<TestRequestPeer>(context, message_loop_.task_runner()),
+ std::make_unique<TestRequestPeer>(context,
+ base::ThreadTaskRunnerHandle::Get()),
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&factory_),
std::vector<std::unique_ptr<URLLoaderThrottle>>(),
@@ -168,7 +169,7 @@ class URLResponseBodyConsumerTest : public ::testing::Test {
run_loop.Run();
}
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
NoopURLLoaderFactory factory_;
std::unique_ptr<ResourceDispatcher> dispatcher_;
static const MojoWriteDataFlags kNone = MOJO_WRITE_DATA_FLAG_NONE;
@@ -182,7 +183,7 @@ TEST_F(URLResponseBodyConsumerTest, ReceiveData) {
scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer(
request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle),
- message_loop_.task_runner()));
+ base::ThreadTaskRunnerHandle::Get()));
consumer->ArmOrNotify();
mojo::ScopedDataPipeProducerHandle writer =
@@ -207,7 +208,7 @@ TEST_F(URLResponseBodyConsumerTest, OnCompleteThenClose) {
scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer(
request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle),
- message_loop_.task_runner()));
+ base::ThreadTaskRunnerHandle::Get()));
consumer->ArmOrNotify();
consumer->OnComplete(network::URLLoaderCompletionStatus());
@@ -242,7 +243,7 @@ TEST_F(URLResponseBodyConsumerTest, OnCompleteThenCloseWithAsyncRelease) {
scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer(
request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle),
- message_loop_.task_runner()));
+ base::ThreadTaskRunnerHandle::Get()));
consumer->ArmOrNotify();
consumer->OnComplete(network::URLLoaderCompletionStatus());
@@ -274,7 +275,7 @@ TEST_F(URLResponseBodyConsumerTest, CloseThenOnComplete) {
scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer(
request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle),
- message_loop_.task_runner()));
+ base::ThreadTaskRunnerHandle::Get()));
consumer->ArmOrNotify();
network::URLLoaderCompletionStatus status;
@@ -317,7 +318,7 @@ TEST_F(URLResponseBodyConsumerTest, TooBigChunkShouldBeSplit) {
scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer(
request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle),
- message_loop_.task_runner()));
+ base::ThreadTaskRunnerHandle::Get()));
consumer->ArmOrNotify();
Run(&context);
diff --git a/chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc b/chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc
index 8e4f0a216a5..da0eb4f749e 100644
--- a/chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc
+++ b/chromium/content/renderer/loader/web_data_consumer_handle_impl_unittest.cc
@@ -14,10 +14,10 @@
#include "base/bind.h"
#include "base/location.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "mojo/public/cpp/system/data_pipe.h"
@@ -62,11 +62,12 @@ class ClientImpl final : public WebDataConsumerHandle::Client {
class ReadDataOperation : public ReadDataOperationBase {
public:
typedef WebDataConsumerHandle::Result Result;
- ReadDataOperation(mojo::ScopedDataPipeConsumerHandle handle,
- base::MessageLoop* main_message_loop,
- const base::Closure& on_done)
+ ReadDataOperation(
+ mojo::ScopedDataPipeConsumerHandle handle,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
+ const base::Closure& on_done)
: handle_(new WebDataConsumerHandleImpl(std::move(handle))),
- main_message_loop_(main_message_loop),
+ main_thread_task_runner_(main_thread_task_runner),
on_done_(on_done) {}
const std::string& result() const { return result_; }
@@ -107,14 +108,14 @@ class ReadDataOperation : public ReadDataOperationBase {
// The operation is done.
reader_.reset();
- main_message_loop_->task_runner()->PostTask(FROM_HERE, on_done_);
+ main_thread_task_runner_->PostTask(FROM_HERE, on_done_);
}
private:
std::unique_ptr<WebDataConsumerHandleImpl> handle_;
std::unique_ptr<WebDataConsumerHandle::Reader> reader_;
std::unique_ptr<WebDataConsumerHandle::Client> client_;
- base::MessageLoop* main_message_loop_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
base::Closure on_done_;
std::string result_;
};
@@ -122,11 +123,12 @@ class ReadDataOperation : public ReadDataOperationBase {
class TwoPhaseReadDataOperation : public ReadDataOperationBase {
public:
typedef WebDataConsumerHandle::Result Result;
- TwoPhaseReadDataOperation(mojo::ScopedDataPipeConsumerHandle handle,
- base::MessageLoop* main_message_loop,
- const base::Closure& on_done)
+ TwoPhaseReadDataOperation(
+ mojo::ScopedDataPipeConsumerHandle handle,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner,
+ const base::Closure& on_done)
: handle_(new WebDataConsumerHandleImpl(std::move(handle))),
- main_message_loop_(main_message_loop),
+ main_thread_task_runner_(main_thread_task_runner),
on_done_(on_done) {}
const std::string& result() const { return result_; }
@@ -160,7 +162,7 @@ class TwoPhaseReadDataOperation : public ReadDataOperationBase {
if (rv != kOk) {
// Something is wrong.
result_ = "error";
- main_message_loop_->task_runner()->PostTask(FROM_HERE, on_done_);
+ main_thread_task_runner_->PostTask(FROM_HERE, on_done_);
return;
}
}
@@ -177,14 +179,14 @@ class TwoPhaseReadDataOperation : public ReadDataOperationBase {
// The operation is done.
reader_.reset();
- main_message_loop_->task_runner()->PostTask(FROM_HERE, on_done_);
+ main_thread_task_runner_->PostTask(FROM_HERE, on_done_);
}
private:
std::unique_ptr<WebDataConsumerHandleImpl> handle_;
std::unique_ptr<WebDataConsumerHandle::Reader> reader_;
std::unique_ptr<WebDataConsumerHandle::Client> client_;
- base::MessageLoop* main_message_loop_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
base::Closure on_done_;
std::string result_;
};
@@ -236,7 +238,7 @@ class WebDataConsumerHandleImplTest : public ::testing::Test {
return expected;
}
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
mojo::ScopedDataPipeProducerHandle producer_;
mojo::ScopedDataPipeConsumerHandle consumer_;
@@ -245,7 +247,8 @@ class WebDataConsumerHandleImplTest : public ::testing::Test {
TEST_F(WebDataConsumerHandleImplTest, ReadData) {
base::RunLoop run_loop;
auto operation = std::make_unique<ReadDataOperation>(
- std::move(consumer_), &message_loop_, run_loop.QuitClosure());
+ std::move(consumer_), base::ThreadTaskRunnerHandle::Get(),
+ run_loop.QuitClosure());
base::Thread t("DataConsumerHandle test thread");
ASSERT_TRUE(t.Start());
@@ -266,7 +269,8 @@ TEST_F(WebDataConsumerHandleImplTest, ReadData) {
TEST_F(WebDataConsumerHandleImplTest, TwoPhaseReadData) {
base::RunLoop run_loop;
auto operation = std::make_unique<TwoPhaseReadDataOperation>(
- std::move(consumer_), &message_loop_, run_loop.QuitClosure());
+ std::move(consumer_), base::ThreadTaskRunnerHandle::Get(),
+ run_loop.QuitClosure());
base::Thread t("DataConsumerHandle test thread");
ASSERT_TRUE(t.Start());
diff --git a/chromium/content/renderer/loader/web_url_loader_impl.cc b/chromium/content/renderer/loader/web_url_loader_impl.cc
index 5d63b5a8728..2cc5fe42d5f 100644
--- a/chromium/content/renderer/loader/web_url_loader_impl.cc
+++ b/chromium/content/renderer/loader/web_url_loader_impl.cc
@@ -24,7 +24,6 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/child/child_thread_impl.h"
-#include "content/child/scoped_child_process_reference.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_features.h"
@@ -102,18 +101,6 @@ constexpr char kImageAcceptHeader[] = "image/webp,image/apng,image/*,*/*;q=0.8";
using HeadersVector = network::HttpRawRequestResponseInfo::HeadersVector;
-class KeepAliveHandleWithChildProcessReference {
- public:
- explicit KeepAliveHandleWithChildProcessReference(
- mojom::KeepAliveHandlePtr ptr)
- : keep_alive_handle_(std::move(ptr)) {}
- ~KeepAliveHandleWithChildProcessReference() {}
-
- private:
- mojom::KeepAliveHandlePtr keep_alive_handle_;
- ScopedChildProcessReference reference_;
-};
-
// TODO(estark): Figure out a way for the embedder to provide the
// security style for a resource. Ideally, the logic for assigning
// per-resource security styles should live in the same place as the
@@ -463,7 +450,7 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context> {
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
std::unique_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_;
std::unique_ptr<SharedMemoryDataConsumerHandle::Writer> body_stream_writer_;
- std::unique_ptr<KeepAliveHandleWithChildProcessReference> keep_alive_handle_;
+ mojom::KeepAliveHandlePtr keep_alive_handle_;
enum DeferState {NOT_DEFERRING, SHOULD_DEFER, DEFERRED_DATA};
DeferState defers_loading_;
int request_id_;
@@ -542,11 +529,7 @@ WebURLLoaderImpl::Context::Context(
resource_dispatcher_(resource_dispatcher),
task_runner_handle_(std::move(task_runner_handle)),
task_runner_(task_runner_handle_->GetTaskRunner()),
- keep_alive_handle_(
- keep_alive_handle_ptr
- ? std::make_unique<KeepAliveHandleWithChildProcessReference>(
- std::move(keep_alive_handle_ptr))
- : nullptr),
+ keep_alive_handle_(std::move(keep_alive_handle_ptr)),
defers_loading_(NOT_DEFERRING),
request_id_(-1),
url_loader_factory_(std::move(url_loader_factory)) {
@@ -661,10 +644,18 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
resource_request->url = url_;
resource_request->site_for_cookies = request.SiteForCookies();
resource_request->upgrade_if_insecure = request.UpgradeIfInsecure();
- resource_request->request_initiator =
- request.RequestorOrigin().IsNull()
- ? base::Optional<url::Origin>()
- : base::Optional<url::Origin>(request.RequestorOrigin());
+ resource_request->is_revalidating = request.IsRevalidating();
+ if (!request.RequestorOrigin().IsNull()) {
+ if (request.RequestorOrigin().ToString() == "null") {
+ // "file:" origin is treated like an opaque unique origin when
+ // allow-file-access-from-files is not specified. Such origin is not
+ // opaque (i.e., IsOpaque() returns false) but still serializes to
+ // "null".
+ resource_request->request_initiator = url::Origin();
+ } else {
+ resource_request->request_initiator = request.RequestorOrigin();
+ }
+ }
resource_request->referrer = referrer_url;
resource_request->referrer_policy =
@@ -685,6 +676,8 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
resource_request->headers.SetHeaderIfMissing(network::kAcceptHeader,
network::kDefaultAcceptHeader);
}
+ resource_request->requested_with =
+ WebString(request.GetRequestedWith()).Utf8();
if (resource_request->resource_type == RESOURCE_TYPE_PREFETCH ||
resource_request->resource_type == RESOURCE_TYPE_FAVICON) {
@@ -710,7 +703,7 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
resource_request->fetch_integrity =
GetFetchIntegrityForWebURLRequest(request);
resource_request->fetch_request_context_type =
- GetRequestContextTypeForWebURLRequest(request);
+ static_cast<int>(GetRequestContextTypeForWebURLRequest(request));
resource_request->fetch_frame_type = request.GetFrameType();
resource_request->request_body =
@@ -721,7 +714,7 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
resource_request->enable_upload_progress = request.ReportUploadProgress();
GURL gurl(url_);
if (request.GetRequestContext() ==
- WebURLRequest::kRequestContextXMLHttpRequest &&
+ blink::mojom::RequestContextType::XML_HTTP_REQUEST &&
(gurl.has_username() || gurl.has_password())) {
resource_request->do_not_prompt_for_login = true;
}
@@ -732,13 +725,14 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
static_cast<int>(request.GetPreviewsState());
resource_request->throttling_profile_id = request.GetDevToolsToken();
+ if (base::UnguessableToken window_id = request.GetFetchWindowId())
+ resource_request->fetch_window_id = base::make_optional(window_id);
+
// The network request has already been made by the browser. The renderer
// should bind the URLLoaderClientEndpoints stored in |response_override| to
// an implementation of a URLLoaderClient to get the response body.
if (response_override) {
DCHECK(!sync_load_response);
- DCHECK_NE(network::mojom::RequestContextFrameType::kNone,
- request.GetFrameType());
}
RequestExtraData empty_extra_data;
@@ -987,7 +981,8 @@ void WebURLLoaderImpl::Context::OnCompletedRequest(
} else {
client_->DidFinishLoading(status.completion_time, total_transfer_size,
encoded_body_size, status.decoded_body_length,
- status.should_report_corb_blocking);
+ status.should_report_corb_blocking,
+ status.cors_preflight_timing_info);
}
}
}
@@ -1032,7 +1027,7 @@ bool WebURLLoaderImpl::Context::CanHandleDataURLRequestLocally(
// Data url requests from object tags may need to be intercepted as streams
// and so need to be sent to the browser.
- if (request.GetRequestContext() == WebURLRequest::kRequestContextObject)
+ if (request.GetRequestContext() == blink::mojom::RequestContextType::OBJECT)
return false;
// Optimize for the case where we can handle a data URL locally. We must
@@ -1223,6 +1218,9 @@ void WebURLLoaderImpl::PopulateURLResponse(
WebString::FromUTF8(info.alpn_negotiated_protocol));
response->SetConnectionInfo(info.connection_info);
response->SetAsyncRevalidationRequested(info.async_revalidation_requested);
+ response->SetRequestId(request_id);
+ response->SetIsSignedExchangeInnerResponse(
+ info.is_signed_exchange_inner_response);
SetSecurityStyleAndDetails(url, info, response, report_security_info);
@@ -1233,7 +1231,6 @@ void WebURLLoaderImpl::PopulateURLResponse(
extra_data->set_was_alternate_protocol_available(
info.was_alternate_protocol_available);
extra_data->set_effective_connection_type(info.effective_connection_type);
- extra_data->set_request_id(request_id);
// If there's no received headers end time, don't set load timing. This is
// the case for non-HTTP requests, requests that don't go over the wire, and
@@ -1260,20 +1257,17 @@ void WebURLLoaderImpl::PopulateURLResponse(
info.raw_request_response_info->response_headers_text));
const HeadersVector& request_headers =
info.raw_request_response_info->request_headers;
- for (HeadersVector::const_iterator it = request_headers.begin();
- it != request_headers.end(); ++it) {
+ for (auto it = request_headers.begin(); it != request_headers.end(); ++it) {
load_info.AddRequestHeader(WebString::FromLatin1(it->first),
WebString::FromLatin1(it->second));
}
const HeadersVector& response_headers =
info.raw_request_response_info->response_headers;
- for (HeadersVector::const_iterator it = response_headers.begin();
- it != response_headers.end(); ++it) {
+ for (auto it = response_headers.begin(); it != response_headers.end();
+ ++it) {
load_info.AddResponseHeader(WebString::FromLatin1(it->first),
WebString::FromLatin1(it->second));
}
- load_info.SetNPNNegotiatedProtocol(
- WebString::FromLatin1(info.alpn_negotiated_protocol));
response->SetHTTPLoadInfo(load_info);
}
@@ -1388,36 +1382,36 @@ net::NetworkTrafficAnnotationTag
WebURLLoaderImpl::Context::GetTrafficAnnotationTag(
const blink::WebURLRequest& request) {
switch (request.GetRequestContext()) {
- case WebURLRequest::kRequestContextUnspecified:
- case WebURLRequest::kRequestContextAudio:
- case WebURLRequest::kRequestContextBeacon:
- case WebURLRequest::kRequestContextCSPReport:
- case WebURLRequest::kRequestContextDownload:
- case WebURLRequest::kRequestContextEventSource:
- case WebURLRequest::kRequestContextFetch:
- case WebURLRequest::kRequestContextFont:
- case WebURLRequest::kRequestContextForm:
- case WebURLRequest::kRequestContextFrame:
- case WebURLRequest::kRequestContextHyperlink:
- case WebURLRequest::kRequestContextIframe:
- case WebURLRequest::kRequestContextImage:
- case WebURLRequest::kRequestContextImageSet:
- case WebURLRequest::kRequestContextImport:
- case WebURLRequest::kRequestContextInternal:
- case WebURLRequest::kRequestContextLocation:
- case WebURLRequest::kRequestContextManifest:
- case WebURLRequest::kRequestContextPing:
- case WebURLRequest::kRequestContextPrefetch:
- case WebURLRequest::kRequestContextScript:
- case WebURLRequest::kRequestContextServiceWorker:
- case WebURLRequest::kRequestContextSharedWorker:
- case WebURLRequest::kRequestContextSubresource:
- case WebURLRequest::kRequestContextStyle:
- case WebURLRequest::kRequestContextTrack:
- case WebURLRequest::kRequestContextVideo:
- case WebURLRequest::kRequestContextWorker:
- case WebURLRequest::kRequestContextXMLHttpRequest:
- case WebURLRequest::kRequestContextXSLT:
+ case blink::mojom::RequestContextType::UNSPECIFIED:
+ case blink::mojom::RequestContextType::AUDIO:
+ case blink::mojom::RequestContextType::BEACON:
+ case blink::mojom::RequestContextType::CSP_REPORT:
+ case blink::mojom::RequestContextType::DOWNLOAD:
+ case blink::mojom::RequestContextType::EVENT_SOURCE:
+ case blink::mojom::RequestContextType::FETCH:
+ case blink::mojom::RequestContextType::FONT:
+ case blink::mojom::RequestContextType::FORM:
+ case blink::mojom::RequestContextType::FRAME:
+ case blink::mojom::RequestContextType::HYPERLINK:
+ case blink::mojom::RequestContextType::IFRAME:
+ case blink::mojom::RequestContextType::IMAGE:
+ case blink::mojom::RequestContextType::IMAGE_SET:
+ case blink::mojom::RequestContextType::IMPORT:
+ case blink::mojom::RequestContextType::INTERNAL:
+ case blink::mojom::RequestContextType::LOCATION:
+ case blink::mojom::RequestContextType::MANIFEST:
+ case blink::mojom::RequestContextType::PING:
+ case blink::mojom::RequestContextType::PREFETCH:
+ case blink::mojom::RequestContextType::SCRIPT:
+ case blink::mojom::RequestContextType::SERVICE_WORKER:
+ case blink::mojom::RequestContextType::SHARED_WORKER:
+ case blink::mojom::RequestContextType::SUBRESOURCE:
+ case blink::mojom::RequestContextType::STYLE:
+ case blink::mojom::RequestContextType::TRACK:
+ case blink::mojom::RequestContextType::VIDEO:
+ case blink::mojom::RequestContextType::WORKER:
+ case blink::mojom::RequestContextType::XML_HTTP_REQUEST:
+ case blink::mojom::RequestContextType::XSLT:
return net::DefineNetworkTrafficAnnotation("blink_resource_loader", R"(
semantics {
sender: "Blink Resource Loader"
@@ -1439,9 +1433,9 @@ WebURLLoaderImpl::Context::GetTrafficAnnotationTag(
"to load any webpage."
})");
- case WebURLRequest::kRequestContextEmbed:
- case WebURLRequest::kRequestContextObject:
- case WebURLRequest::kRequestContextPlugin:
+ case blink::mojom::RequestContextType::EMBED:
+ case blink::mojom::RequestContextType::OBJECT:
+ case blink::mojom::RequestContextType::PLUGIN:
return net::DefineNetworkTrafficAnnotation(
"blink_extension_resource_loader", R"(
semantics {
@@ -1470,7 +1464,7 @@ WebURLLoaderImpl::Context::GetTrafficAnnotationTag(
}
})");
- case WebURLRequest::kRequestContextFavicon:
+ case blink::mojom::RequestContextType::FAVICON:
return net::DefineNetworkTrafficAnnotation("favicon_loader", R"(
semantics {
sender: "Blink Resource Loader"
diff --git a/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc b/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc
index 282e275354b..d9a336e1c2d 100644
--- a/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc
+++ b/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -13,9 +13,9 @@
#include "base/command_line.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/test/scoped_task_environment.h"
#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
#include "content/public/common/content_switches.h"
@@ -240,11 +240,13 @@ class TestWebURLLoaderClient : public blink::WebURLLoaderClient {
loader_.reset();
}
- void DidFinishLoading(base::TimeTicks finishTime,
- int64_t totalEncodedDataLength,
- int64_t totalEncodedBodyLength,
- int64_t totalDecodedBodyLength,
- bool should_report_corb_blocking) override {
+ void DidFinishLoading(
+ base::TimeTicks finishTime,
+ int64_t totalEncodedDataLength,
+ int64_t totalEncodedBodyLength,
+ int64_t totalDecodedBodyLength,
+ bool should_report_corb_blocking,
+ const std::vector<network::cors::PreflightTimingInfo>&) override {
EXPECT_TRUE(loader_);
EXPECT_TRUE(did_receive_response_);
EXPECT_FALSE(did_finish_);
@@ -314,7 +316,7 @@ class WebURLLoaderImplTest : public testing::Test {
void DoStartAsyncRequest() {
blink::WebURLRequest request{GURL(kTestURL)};
- request.SetRequestContext(blink::WebURLRequest::kRequestContextInternal);
+ request.SetRequestContext(blink::mojom::RequestContextType::INTERNAL);
client()->loader()->LoadAsynchronously(request, client());
ASSERT_TRUE(peer());
}
@@ -322,7 +324,7 @@ class WebURLLoaderImplTest : public testing::Test {
void DoStartAsyncRequestWithPriority(
blink::WebURLRequest::Priority priority) {
blink::WebURLRequest request{GURL(kTestURL)};
- request.SetRequestContext(blink::WebURLRequest::kRequestContextInternal);
+ request.SetRequestContext(blink::mojom::RequestContextType::INTERNAL);
request.SetPriority(priority);
client()->loader()->LoadAsynchronously(request, client());
ASSERT_TRUE(peer());
@@ -408,10 +410,9 @@ class WebURLLoaderImplTest : public testing::Test {
TestWebURLLoaderClient* client() { return client_.get(); }
TestResourceDispatcher* dispatcher() { return &dispatcher_; }
RequestPeer* peer() { return dispatcher()->peer(); }
- base::MessageLoop* message_loop() { return &message_loop_; }
private:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
TestResourceDispatcher dispatcher_;
std::unique_ptr<TestWebURLLoaderClient> client_;
};
@@ -640,7 +641,7 @@ TEST_F(WebURLLoaderImplTest, BrowserSideNavigationCommit) {
const std::string kMimeType = "text/html";
blink::WebURLRequest request(kNavigationURL);
request.SetFrameType(network::mojom::RequestContextFrameType::kTopLevel);
- request.SetRequestContext(blink::WebURLRequest::kRequestContextFrame);
+ request.SetRequestContext(blink::mojom::RequestContextType::FRAME);
std::unique_ptr<NavigationResponseOverrideParameters> response_override(
new NavigationResponseOverrideParameters());
response_override->response.mime_type = kMimeType;
@@ -778,7 +779,7 @@ TEST_F(WebURLLoaderImplTest, SyncLengths) {
const int kEncodedDataLength = 130;
const GURL url(kTestURL);
blink::WebURLRequest request(url);
- request.SetRequestContext(blink::WebURLRequest::kRequestContextInternal);
+ request.SetRequestContext(blink::mojom::RequestContextType::INTERNAL);
// Prepare a mock response
SyncLoadResponse sync_load_response;
diff --git a/chromium/content/renderer/loader/web_url_request_util.cc b/chromium/content/renderer/loader/web_url_request_util.cc
index a7c47640c90..6197434ad49 100644
--- a/chromium/content/renderer/loader/web_url_request_util.cc
+++ b/chromium/content/renderer/loader/web_url_request_util.cc
@@ -27,14 +27,13 @@
#include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/interface_provider.h"
-#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_http_body.h"
#include "third_party/blink/public/platform/web_http_header_visitor.h"
#include "third_party/blink/public/platform/web_mixed_content.h"
#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_thread.h"
using blink::mojom::FetchCacheMode;
using blink::WebData;
@@ -109,95 +108,95 @@ class HeaderFlattener : public blink::WebHTTPHeaderVisitor {
} // namespace
-ResourceType WebURLRequestContextToResourceType(
- WebURLRequest::RequestContext request_context) {
+ResourceType RequestContextToResourceType(
+ blink::mojom::RequestContextType request_context) {
switch (request_context) {
// CSP report
- case WebURLRequest::kRequestContextCSPReport:
+ case blink::mojom::RequestContextType::CSP_REPORT:
return RESOURCE_TYPE_CSP_REPORT;
// Favicon
- case WebURLRequest::kRequestContextFavicon:
+ case blink::mojom::RequestContextType::FAVICON:
return RESOURCE_TYPE_FAVICON;
// Font
- case WebURLRequest::kRequestContextFont:
+ case blink::mojom::RequestContextType::FONT:
return RESOURCE_TYPE_FONT_RESOURCE;
// Image
- case WebURLRequest::kRequestContextImage:
- case WebURLRequest::kRequestContextImageSet:
+ case blink::mojom::RequestContextType::IMAGE:
+ case blink::mojom::RequestContextType::IMAGE_SET:
return RESOURCE_TYPE_IMAGE;
// Media
- case WebURLRequest::kRequestContextAudio:
- case WebURLRequest::kRequestContextVideo:
+ case blink::mojom::RequestContextType::AUDIO:
+ case blink::mojom::RequestContextType::VIDEO:
return RESOURCE_TYPE_MEDIA;
// Object
- case WebURLRequest::kRequestContextEmbed:
- case WebURLRequest::kRequestContextObject:
+ case blink::mojom::RequestContextType::EMBED:
+ case blink::mojom::RequestContextType::OBJECT:
return RESOURCE_TYPE_OBJECT;
// Ping
- case WebURLRequest::kRequestContextBeacon:
- case WebURLRequest::kRequestContextPing:
+ case blink::mojom::RequestContextType::BEACON:
+ case blink::mojom::RequestContextType::PING:
return RESOURCE_TYPE_PING;
// Subresource of plugins
- case WebURLRequest::kRequestContextPlugin:
+ case blink::mojom::RequestContextType::PLUGIN:
return RESOURCE_TYPE_PLUGIN_RESOURCE;
// Prefetch
- case WebURLRequest::kRequestContextPrefetch:
+ case blink::mojom::RequestContextType::PREFETCH:
return RESOURCE_TYPE_PREFETCH;
// Script
- case WebURLRequest::kRequestContextImport:
- case WebURLRequest::kRequestContextScript:
+ case blink::mojom::RequestContextType::IMPORT:
+ case blink::mojom::RequestContextType::SCRIPT:
return RESOURCE_TYPE_SCRIPT;
// Style
- case WebURLRequest::kRequestContextXSLT:
- case WebURLRequest::kRequestContextStyle:
+ case blink::mojom::RequestContextType::XSLT:
+ case blink::mojom::RequestContextType::STYLE:
return RESOURCE_TYPE_STYLESHEET;
// Subresource
- case WebURLRequest::kRequestContextDownload:
- case WebURLRequest::kRequestContextManifest:
- case WebURLRequest::kRequestContextSubresource:
+ case blink::mojom::RequestContextType::DOWNLOAD:
+ case blink::mojom::RequestContextType::MANIFEST:
+ case blink::mojom::RequestContextType::SUBRESOURCE:
return RESOURCE_TYPE_SUB_RESOURCE;
// TextTrack
- case WebURLRequest::kRequestContextTrack:
+ case blink::mojom::RequestContextType::TRACK:
return RESOURCE_TYPE_MEDIA;
// Workers
- case WebURLRequest::kRequestContextServiceWorker:
+ case blink::mojom::RequestContextType::SERVICE_WORKER:
return RESOURCE_TYPE_SERVICE_WORKER;
- case WebURLRequest::kRequestContextSharedWorker:
+ case blink::mojom::RequestContextType::SHARED_WORKER:
return RESOURCE_TYPE_SHARED_WORKER;
- case WebURLRequest::kRequestContextWorker:
+ case blink::mojom::RequestContextType::WORKER:
return RESOURCE_TYPE_WORKER;
// Unspecified
- case WebURLRequest::kRequestContextInternal:
- case WebURLRequest::kRequestContextUnspecified:
+ case blink::mojom::RequestContextType::INTERNAL:
+ case blink::mojom::RequestContextType::UNSPECIFIED:
return RESOURCE_TYPE_SUB_RESOURCE;
// XHR
- case WebURLRequest::kRequestContextEventSource:
- case WebURLRequest::kRequestContextFetch:
- case WebURLRequest::kRequestContextXMLHttpRequest:
+ case blink::mojom::RequestContextType::EVENT_SOURCE:
+ case blink::mojom::RequestContextType::FETCH:
+ case blink::mojom::RequestContextType::XML_HTTP_REQUEST:
return RESOURCE_TYPE_XHR;
// These should be handled by the FrameType checks at the top of the
// function.
- case WebURLRequest::kRequestContextForm:
- case WebURLRequest::kRequestContextHyperlink:
- case WebURLRequest::kRequestContextLocation:
- case WebURLRequest::kRequestContextFrame:
- case WebURLRequest::kRequestContextIframe:
+ case blink::mojom::RequestContextType::FORM:
+ case blink::mojom::RequestContextType::HYPERLINK:
+ case blink::mojom::RequestContextType::LOCATION:
+ case blink::mojom::RequestContextType::FRAME:
+ case blink::mojom::RequestContextType::IFRAME:
NOTREACHED();
return RESOURCE_TYPE_SUB_RESOURCE;
@@ -208,15 +207,16 @@ ResourceType WebURLRequestContextToResourceType(
}
ResourceType WebURLRequestToResourceType(const WebURLRequest& request) {
- WebURLRequest::RequestContext request_context = request.GetRequestContext();
+ blink::mojom::RequestContextType request_context =
+ request.GetRequestContext();
if (request.GetFrameType() !=
network::mojom::RequestContextFrameType::kNone) {
- DCHECK(request_context == WebURLRequest::kRequestContextForm ||
- request_context == WebURLRequest::kRequestContextFrame ||
- request_context == WebURLRequest::kRequestContextHyperlink ||
- request_context == WebURLRequest::kRequestContextIframe ||
- request_context == WebURLRequest::kRequestContextInternal ||
- request_context == WebURLRequest::kRequestContextLocation);
+ DCHECK(request_context == blink::mojom::RequestContextType::FORM ||
+ request_context == blink::mojom::RequestContextType::FRAME ||
+ request_context == blink::mojom::RequestContextType::HYPERLINK ||
+ request_context == blink::mojom::RequestContextType::IFRAME ||
+ request_context == blink::mojom::RequestContextType::INTERNAL ||
+ request_context == blink::mojom::RequestContextType::LOCATION);
if (request.GetFrameType() ==
network::mojom::RequestContextFrameType::kTopLevel ||
request.GetFrameType() ==
@@ -229,7 +229,7 @@ ResourceType WebURLRequestToResourceType(const WebURLRequest& request) {
NOTREACHED();
return RESOURCE_TYPE_SUB_RESOURCE;
}
- return WebURLRequestContextToResourceType(request_context);
+ return RequestContextToResourceType(request_context);
}
net::HttpRequestHeaders GetWebURLRequestHeaders(
@@ -283,7 +283,7 @@ int GetLoadFlagsForWebURLRequest(const WebURLRequest& request) {
load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA;
}
- if (request.GetRequestContext() == WebURLRequest::kRequestContextPrefetch)
+ if (request.GetRequestContext() == blink::mojom::RequestContextType::PREFETCH)
load_flags |= net::LOAD_PREFETCH;
if (request.GetExtraData()) {
@@ -456,78 +456,10 @@ std::string GetFetchIntegrityForWebURLRequest(const WebURLRequest& request) {
return request.GetFetchIntegrity().Utf8();
}
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_UNSPECIFIED,
- WebURLRequest::kRequestContextUnspecified);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_AUDIO,
- WebURLRequest::kRequestContextAudio);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_BEACON,
- WebURLRequest::kRequestContextBeacon);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_CSP_REPORT,
- WebURLRequest::kRequestContextCSPReport);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_DOWNLOAD,
- WebURLRequest::kRequestContextDownload);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_EMBED,
- WebURLRequest::kRequestContextEmbed);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_EVENT_SOURCE,
- WebURLRequest::kRequestContextEventSource);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_FAVICON,
- WebURLRequest::kRequestContextFavicon);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_FETCH,
- WebURLRequest::kRequestContextFetch);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_FONT,
- WebURLRequest::kRequestContextFont);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_FORM,
- WebURLRequest::kRequestContextForm);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_FRAME,
- WebURLRequest::kRequestContextFrame);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_HYPERLINK,
- WebURLRequest::kRequestContextHyperlink);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_IFRAME,
- WebURLRequest::kRequestContextIframe);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_IMAGE,
- WebURLRequest::kRequestContextImage);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_IMAGE_SET,
- WebURLRequest::kRequestContextImageSet);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_IMPORT,
- WebURLRequest::kRequestContextImport);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_INTERNAL,
- WebURLRequest::kRequestContextInternal);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_LOCATION,
- WebURLRequest::kRequestContextLocation);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_MANIFEST,
- WebURLRequest::kRequestContextManifest);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_OBJECT,
- WebURLRequest::kRequestContextObject);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_PING,
- WebURLRequest::kRequestContextPing);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_PLUGIN,
- WebURLRequest::kRequestContextPlugin);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_PREFETCH,
- WebURLRequest::kRequestContextPrefetch);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_SCRIPT,
- WebURLRequest::kRequestContextScript);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_SERVICE_WORKER,
- WebURLRequest::kRequestContextServiceWorker);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_SHARED_WORKER,
- WebURLRequest::kRequestContextSharedWorker);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_SUBRESOURCE,
- WebURLRequest::kRequestContextSubresource);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_STYLE,
- WebURLRequest::kRequestContextStyle);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_TRACK,
- WebURLRequest::kRequestContextTrack);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_VIDEO,
- WebURLRequest::kRequestContextVideo);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_WORKER,
- WebURLRequest::kRequestContextWorker);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_XML_HTTP_REQUEST,
- WebURLRequest::kRequestContextXMLHttpRequest);
-STATIC_ASSERT_ENUM(REQUEST_CONTEXT_TYPE_XSLT,
- WebURLRequest::kRequestContextXSLT);
-
-RequestContextType GetRequestContextTypeForWebURLRequest(
+blink::mojom::RequestContextType GetRequestContextTypeForWebURLRequest(
const WebURLRequest& request) {
- return static_cast<RequestContextType>(request.GetRequestContext());
+ return static_cast<blink::mojom::RequestContextType>(
+ request.GetRequestContext());
}
blink::WebMixedContentContextType GetMixedContentContextTypeForWebURLRequest(
diff --git a/chromium/content/renderer/loader/web_url_request_util.h b/chromium/content/renderer/loader/web_url_request_util.h
index bc85bb64d15..de7df077361 100644
--- a/chromium/content/renderer/loader/web_url_request_util.h
+++ b/chromium/content/renderer/loader/web_url_request_util.h
@@ -8,12 +8,12 @@
#include <string>
#include "content/common/content_export.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "net/http/http_request_headers.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/web_mixed_content_context_type.h"
#include "third_party/blink/public/platform/web_url_request.h"
@@ -23,8 +23,8 @@ class WebHTTPBody;
namespace content {
-ResourceType WebURLRequestContextToResourceType(
- blink::WebURLRequest::RequestContext request_context);
+ResourceType RequestContextToResourceType(
+ blink::mojom::RequestContextType request_context);
CONTENT_EXPORT ResourceType WebURLRequestToResourceType(
const blink::WebURLRequest& request);
@@ -68,7 +68,7 @@ scoped_refptr<network::ResourceRequestBody> GetRequestBodyForWebURLRequest(
// type.
std::string GetFetchIntegrityForWebURLRequest(
const blink::WebURLRequest& request);
-RequestContextType GetRequestContextTypeForWebURLRequest(
+blink::mojom::RequestContextType GetRequestContextTypeForWebURLRequest(
const blink::WebURLRequest& request);
blink::WebMixedContentContextType GetMixedContentContextTypeForWebURLRequest(
const blink::WebURLRequest& request);
diff --git a/chromium/content/renderer/loader/web_worker_fetch_context_impl.cc b/chromium/content/renderer/loader/web_worker_fetch_context_impl.cc
index 61e6dbb61eb..fc03ca1589f 100644
--- a/chromium/content/renderer/loader/web_worker_fetch_context_impl.cc
+++ b/chromium/content/renderer/loader/web_worker_fetch_context_impl.cc
@@ -41,8 +41,8 @@ WebWorkerFetchContextImpl::RewriteURLFunction g_rewrite_url = nullptr;
namespace {
-// Runs on IO thread.
-void CreateSubresourceLoaderFactoryForWorker(
+// Runs on a background thread created in ResetServiceWorkerURLLoaderFactory().
+void CreateServiceWorkerSubresourceLoaderFactory(
mojom::ServiceWorkerContainerHostPtrInfo container_host_info,
const std::string& client_id,
std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory,
@@ -201,7 +201,7 @@ WebWorkerFetchContextImpl::CloneForNestedWorker() {
mojom::ServiceWorkerContainerHostPtrInfo host_ptr_info;
if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
- service_worker_container_host_->CloneForWorker(
+ service_worker_container_host_->CloneContainerHost(
mojo::MakeRequest(&host_ptr_info));
}
@@ -449,7 +449,7 @@ void WebWorkerFetchContextImpl::ResetServiceWorkerURLLoaderFactory() {
network::mojom::URLLoaderFactoryPtr service_worker_url_loader_factory;
mojom::ServiceWorkerContainerHostPtrInfo host_ptr_info;
- service_worker_container_host_->CloneForWorker(
+ service_worker_container_host_->CloneContainerHost(
mojo::MakeRequest(&host_ptr_info));
// To avoid potential dead-lock while synchronous loading, create the
// SubresourceLoaderFactory on a background thread.
@@ -458,8 +458,8 @@ void WebWorkerFetchContextImpl::ResetServiceWorkerURLLoaderFactory() {
task_runner->PostTask(
FROM_HERE,
base::BindOnce(
- &CreateSubresourceLoaderFactoryForWorker, std::move(host_ptr_info),
- client_id_, fallback_factory_->Clone(),
+ &CreateServiceWorkerSubresourceLoaderFactory,
+ std::move(host_ptr_info), client_id_, fallback_factory_->Clone(),
mojo::MakeRequest(&service_worker_url_loader_factory), task_runner));
web_loader_factory_->SetServiceWorkerURLLoaderFactory(
std::move(service_worker_url_loader_factory));
diff --git a/chromium/content/renderer/loader/weburlresponse_extradata_impl.h b/chromium/content/renderer/loader/weburlresponse_extradata_impl.h
index 9b26d307ac1..aa5e687481a 100644
--- a/chromium/content/renderer/loader/weburlresponse_extradata_impl.h
+++ b/chromium/content/renderer/loader/weburlresponse_extradata_impl.h
@@ -62,17 +62,12 @@ class CONTENT_EXPORT WebURLResponseExtraDataImpl
effective_connection_type_ = effective_connection_type;
}
- // Request ID generated by the renderer.
- int request_id() const { return request_id_; }
- void set_request_id(int request_id) { request_id_ = request_id; }
-
private:
bool is_ftp_directory_listing_;
bool was_fetched_via_spdy_;
bool was_alpn_negotiated_;
bool was_alternate_protocol_available_;
net::EffectiveConnectionType effective_connection_type_;
- int request_id_;
DISALLOW_COPY_AND_ASSIGN(WebURLResponseExtraDataImpl);
};
diff --git a/chromium/content/renderer/manifest/manifest_manager.cc b/chromium/content/renderer/manifest/manifest_manager.cc
index 9e83891ab48..c7928619694 100644
--- a/chromium/content/renderer/manifest/manifest_manager.cc
+++ b/chromium/content/renderer/manifest/manifest_manager.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/no_destructor.h"
#include "base/strings/nullable_string16.h"
#include "content/public/renderer/render_frame.h"
#include "content/renderer/fetchers/manifest_fetcher.h"
@@ -95,9 +96,8 @@ void ManifestManager::DidChangeManifest() {
manifest_debug_info_ = nullptr;
}
-void ManifestManager::DidCommitProvisionalLoad(
- bool is_new_navigation,
- bool is_same_document_navigation) {
+void ManifestManager::DidCommitProvisionalLoad(bool is_same_document_navigation,
+ ui::PageTransition transition) {
if (is_same_document_navigation)
return;
@@ -131,8 +131,8 @@ void ManifestManager::FetchManifest() {
}
static const std::string& GetMessagePrefix() {
- CR_DEFINE_STATIC_LOCAL(std::string, message_prefix, ("Manifest: "));
- return message_prefix;
+ static base::NoDestructor<std::string> message_prefix("Manifest: ");
+ return *message_prefix;
}
void ManifestManager::OnManifestFetchComplete(
diff --git a/chromium/content/renderer/manifest/manifest_manager.h b/chromium/content/renderer/manifest/manifest_manager.h
index 67d2d374607..5836e416818 100644
--- a/chromium/content/renderer/manifest/manifest_manager.h
+++ b/chromium/content/renderer/manifest/manifest_manager.h
@@ -42,8 +42,8 @@ class ManifestManager : public RenderFrameObserver,
// RenderFrameObserver implementation.
void DidChangeManifest() override;
- void DidCommitProvisionalLoad(bool is_new_navigation,
- bool is_same_document_navigation) override;
+ void DidCommitProvisionalLoad(bool is_same_document_navigation,
+ ui::PageTransition transition) override;
void BindToRequest(blink::mojom::ManifestManagerRequest request);
diff --git a/chromium/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc b/chromium/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc
index cefb2a3c533..57aa595588c 100644
--- a/chromium/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc
+++ b/chromium/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc
@@ -8,8 +8,8 @@
#include <utility>
#include <vector>
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "media/audio/audio_output_ipc.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -99,7 +99,7 @@ class AudioOutputIPCFactoryTest : public testing::Test {
TEST_F(AudioOutputIPCFactoryTest, CallFactoryFromIOThread) {
// This test makes sure that AudioOutputIPCFactory correctly binds the
// RendererAudioOutputStreamFactoryPtr to the IO thread.
- base::MessageLoop message_loop;
+ base::test::ScopedTaskEnvironment task_environment;
base::RunLoop run_loop;
auto io_thread = MakeIOThread();
@@ -137,7 +137,7 @@ TEST_F(AudioOutputIPCFactoryTest, CallFactoryFromIOThread) {
TEST_F(AudioOutputIPCFactoryTest, SeveralFactories) {
// This test simulates having several frames being created and destructed.
- base::MessageLoop message_loop;
+ base::test::ScopedTaskEnvironment task_environment;
auto io_thread = MakeIOThread();
const int n_factories = 5;
@@ -197,7 +197,7 @@ TEST_F(AudioOutputIPCFactoryTest, SeveralFactories) {
TEST_F(AudioOutputIPCFactoryTest, RegisterDeregisterBackToBack_Deregisters) {
// This test makes sure that calling Register... followed by Deregister...
// correctly sequences the registration before the deregistration.
- base::MessageLoop message_loop;
+ base::test::ScopedTaskEnvironment task_environment;
auto io_thread = MakeIOThread();
FakeRemoteFactory remote_factory;
diff --git a/chromium/content/renderer/media/audio/audio_renderer_mixer_manager.cc b/chromium/content/renderer/media/audio/audio_renderer_mixer_manager.cc
index b457f7ce47c..a3211106c08 100644
--- a/chromium/content/renderer/media/audio/audio_renderer_mixer_manager.cc
+++ b/chromium/content/renderer/media/audio/audio_renderer_mixer_manager.cc
@@ -187,7 +187,7 @@ media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
latency_map_.to_ulong());
}
- AudioRendererMixerMap::iterator it = mixers_.find(key);
+ auto it = mixers_.find(key);
if (it != mixers_.end()) {
if (device_status)
*device_status = media::OUTPUT_DEVICE_STATUS_OK;
@@ -223,7 +223,7 @@ media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
void AudioRendererMixerManager::ReturnMixer(media::AudioRendererMixer* mixer) {
base::AutoLock auto_lock(mixers_lock_);
- AudioRendererMixerMap::iterator it = std::find_if(
+ auto it = std::find_if(
mixers_.begin(), mixers_.end(),
[mixer](const std::pair<MixerKey, AudioRendererMixerReference>& val) {
return val.second.mixer == mixer;
diff --git a/chromium/content/renderer/media/audio/audio_renderer_sink_cache_impl.cc b/chromium/content/renderer/media/audio/audio_renderer_sink_cache_impl.cc
index 9a89887847d..f8197151f61 100644
--- a/chromium/content/renderer/media/audio/audio_renderer_sink_cache_impl.cc
+++ b/chromium/content/renderer/media/audio/audio_renderer_sink_cache_impl.cc
@@ -12,6 +12,7 @@
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "base/stl_util.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
@@ -35,8 +36,8 @@ class AudioRendererSinkCacheImpl::FrameObserver : public RenderFrameObserver {
private:
// content::RenderFrameObserver implementation:
- void DidCommitProvisionalLoad(bool is_new_navigation,
- bool is_same_document_navigation) override {
+ void DidCommitProvisionalLoad(bool is_same_document_navigation,
+ ui::PageTransition transition) override {
if (!is_same_document_navigation)
DropFrameCache();
}
@@ -337,16 +338,13 @@ void AudioRendererSinkCacheImpl::CacheOrStopUnusedSink(
void AudioRendererSinkCacheImpl::DropSinksForFrame(int source_render_frame_id) {
base::AutoLock auto_lock(cache_lock_);
- cache_.erase(std::remove_if(cache_.begin(), cache_.end(),
- [source_render_frame_id](const CacheEntry& val) {
- if (val.source_render_frame_id ==
- source_render_frame_id) {
- val.sink->Stop();
- return true;
- }
- return false;
- }),
- cache_.end());
+ base::EraseIf(cache_, [source_render_frame_id](const CacheEntry& val) {
+ if (val.source_render_frame_id == source_render_frame_id) {
+ val.sink->Stop();
+ return true;
+ }
+ return false;
+ });
}
int AudioRendererSinkCacheImpl::GetCacheSizeForTesting() {
diff --git a/chromium/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc b/chromium/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc
index a45f6367412..f01899b682d 100644
--- a/chromium/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc
+++ b/chromium/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc
@@ -9,10 +9,10 @@
#include <string>
#include <utility>
-#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/test/gtest_util.h"
+#include "base/test/scoped_task_environment.h"
#include "media/audio/audio_device_description.h"
#include "media/base/audio_parameters.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -132,7 +132,8 @@ void AssociateOutputForAec(const base::UnguessableToken& stream_id,
} // namespace
TEST(MojoAudioInputIPC, OnStreamCreated_Propagates) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
FakeStreamCreator creator(&stream, false);
@@ -152,7 +153,8 @@ TEST(MojoAudioInputIPC, OnStreamCreated_Propagates) {
}
TEST(MojoAudioInputIPC, FactoryDisconnected_SendsError) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
StrictMock<MockDelegate> delegate;
const std::unique_ptr<media::AudioInputIPC> ipc =
@@ -176,7 +178,8 @@ TEST(MojoAudioInputIPC, FactoryDisconnected_SendsError) {
}
TEST(MojoAudioInputIPC, OnStreamCreated_PropagatesInitiallyMuted) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
FakeStreamCreator creator(&stream, true);
@@ -196,7 +199,8 @@ TEST(MojoAudioInputIPC, OnStreamCreated_PropagatesInitiallyMuted) {
}
TEST(MojoAudioInputIPC, IsReusable) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
FakeStreamCreator creator(&stream, false);
@@ -221,7 +225,8 @@ TEST(MojoAudioInputIPC, IsReusable) {
}
TEST(MojoAudioInputIPC, IsReusableAfterError) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
FakeStreamCreator creator(&stream, false);
@@ -251,7 +256,8 @@ TEST(MojoAudioInputIPC, IsReusableAfterError) {
}
TEST(MojoAudioInputIPC, Record_Records) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
FakeStreamCreator creator(&stream, false);
@@ -274,7 +280,8 @@ TEST(MojoAudioInputIPC, Record_Records) {
}
TEST(MojoAudioInputIPC, SetVolume_SetsVolume) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
FakeStreamCreator creator(&stream, false);
@@ -297,7 +304,8 @@ TEST(MojoAudioInputIPC, SetVolume_SetsVolume) {
}
TEST(MojoAudioInputIPC, SetOutputDeviceForAec_AssociatesInputAndOutputForAec) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
FakeStreamCreator creator(&stream, false);
diff --git a/chromium/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc b/chromium/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc
index 1f8f1e3dac6..2276ded5883 100644
--- a/chromium/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc
+++ b/chromium/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc
@@ -9,10 +9,10 @@
#include <string>
#include <utility>
-#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/test/gtest_util.h"
+#include "base/test/scoped_task_environment.h"
#include "media/audio/audio_device_description.h"
#include "media/base/audio_parameters.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -200,7 +200,8 @@ class MockDelegate : public media::AudioOutputIPCDelegate {
} // namespace
TEST(MojoAudioOutputIPC, AuthorizeWithoutFactory_CallsAuthorizedWithError) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
StrictMock<MockDelegate> delegate;
std::unique_ptr<media::AudioOutputIPC> ipc =
@@ -221,7 +222,8 @@ TEST(MojoAudioOutputIPC, AuthorizeWithoutFactory_CallsAuthorizedWithError) {
TEST(MojoAudioOutputIPC,
CreateWithoutAuthorizationWithoutFactory_CallsAuthorizedWithError) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
StrictMock<MockDelegate> delegate;
std::unique_ptr<media::AudioOutputIPC> ipc =
@@ -238,7 +240,8 @@ TEST(MojoAudioOutputIPC,
}
TEST(MojoAudioOutputIPC, DeviceAuthorized_Propagates) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockDelegate> delegate;
@@ -261,7 +264,8 @@ TEST(MojoAudioOutputIPC, DeviceAuthorized_Propagates) {
}
TEST(MojoAudioOutputIPC, OnDeviceCreated_Propagates) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
@@ -288,7 +292,8 @@ TEST(MojoAudioOutputIPC, OnDeviceCreated_Propagates) {
TEST(MojoAudioOutputIPC,
CreateWithoutAuthorization_RequestsAuthorizationFirst) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
@@ -315,7 +320,8 @@ TEST(MojoAudioOutputIPC,
}
TEST(MojoAudioOutputIPC, IsReusable) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
@@ -346,7 +352,8 @@ TEST(MojoAudioOutputIPC, IsReusable) {
}
TEST(MojoAudioOutputIPC, IsReusableAfterError) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
@@ -399,7 +406,8 @@ TEST(MojoAudioOutputIPC, IsReusableAfterError) {
}
TEST(MojoAudioOutputIPC, DeviceNotAuthorized_Propagates) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockDelegate> delegate;
@@ -430,7 +438,8 @@ TEST(MojoAudioOutputIPC,
// The authorization IPC message might be aborted by the remote end
// disconnecting. In this case, the MojoAudioOutputIPC object must still
// send a notification to unblock the AudioOutputIPCDelegate.
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockDelegate> delegate;
@@ -460,7 +469,8 @@ TEST(MojoAudioOutputIPC,
// This test makes sure that the MojoAudioOutputIPC doesn't callback for
// authorization when the factory disconnects if it already got a callback
// for authorization.
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
stream_factory.PrepareProviderForAuthorization(
kSessionId, kDeviceId, std::make_unique<TestStreamProvider>(nullptr));
@@ -486,7 +496,8 @@ TEST(MojoAudioOutputIPC,
}
TEST(MojoAudioOutputIPC, AuthorizeNoClose_DCHECKs) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockDelegate> delegate;
@@ -506,7 +517,8 @@ TEST(MojoAudioOutputIPC, AuthorizeNoClose_DCHECKs) {
}
TEST(MojoAudioOutputIPC, CreateNoClose_DCHECKs) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockDelegate> delegate;
StrictMock<MockStream> stream;
@@ -528,7 +540,8 @@ TEST(MojoAudioOutputIPC, CreateNoClose_DCHECKs) {
}
TEST(MojoAudioOutputIPC, Play_Plays) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
@@ -556,7 +569,8 @@ TEST(MojoAudioOutputIPC, Play_Plays) {
}
TEST(MojoAudioOutputIPC, Pause_Pauses) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
@@ -584,7 +598,8 @@ TEST(MojoAudioOutputIPC, Pause_Pauses) {
}
TEST(MojoAudioOutputIPC, SetVolume_SetsVolume) {
- base::MessageLoopForIO message_loop;
+ base::test::ScopedTaskEnvironment task_environment(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO);
TestRemoteFactory stream_factory;
StrictMock<MockStream> stream;
StrictMock<MockDelegate> delegate;
diff --git a/chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
index 902db29ef01..83ed0ba87ee 100644
--- a/chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
+++ b/chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -8,6 +8,7 @@
#include <GLES2/gl2ext.h>
#include "base/bind.h"
+#include "base/feature_list.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/unguessable_token.h"
@@ -23,9 +24,13 @@
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
+#include "media/base/media_switches.h"
+#include "media/filters/gpu_video_decoder.h"
#include "media/gpu/gpu_video_accelerator_util.h"
#include "media/gpu/ipc/client/gpu_video_decode_accelerator_host.h"
#include "media/gpu/ipc/common/media_messages.h"
+#include "media/mojo/buildflags.h"
+#include "media/mojo/clients/mojo_video_decoder.h"
#include "media/mojo/clients/mojo_video_encode_accelerator.h"
#include "media/video/video_decode_accelerator.h"
#include "media/video/video_encode_accelerator.h"
@@ -61,14 +66,15 @@ GpuVideoAcceleratorFactoriesImpl::Create(
bool enable_video_gpu_memory_buffers,
bool enable_media_stream_gpu_memory_buffers,
bool enable_video_accelerator,
- media::mojom::VideoEncodeAcceleratorProviderPtrInfo unbound_vea_provider) {
+ media::mojom::InterfaceFactoryPtrInfo interface_factory_info,
+ media::mojom::VideoEncodeAcceleratorProviderPtrInfo vea_provider_info) {
RecordContextProviderPhaseUmaEnum(
ContextProviderPhase::CONTEXT_PROVIDER_ACQUIRED);
return base::WrapUnique(new GpuVideoAcceleratorFactoriesImpl(
std::move(gpu_channel_host), main_thread_task_runner, task_runner,
context_provider, enable_video_gpu_memory_buffers,
enable_media_stream_gpu_memory_buffers, enable_video_accelerator,
- std::move(unbound_vea_provider)));
+ std::move(interface_factory_info), std::move(vea_provider_info)));
}
GpuVideoAcceleratorFactoriesImpl::GpuVideoAcceleratorFactoriesImpl(
@@ -79,7 +85,8 @@ GpuVideoAcceleratorFactoriesImpl::GpuVideoAcceleratorFactoriesImpl(
bool enable_video_gpu_memory_buffers,
bool enable_media_stream_gpu_memory_buffers,
bool enable_video_accelerator,
- media::mojom::VideoEncodeAcceleratorProviderPtrInfo unbound_vea_provider)
+ media::mojom::InterfaceFactoryPtrInfo interface_factory_info,
+ media::mojom::VideoEncodeAcceleratorProviderPtrInfo vea_provider_info)
: main_thread_task_runner_(main_thread_task_runner),
task_runner_(task_runner),
gpu_channel_host_(std::move(gpu_channel_host)),
@@ -94,25 +101,45 @@ GpuVideoAcceleratorFactoriesImpl::GpuVideoAcceleratorFactoriesImpl(
DCHECK(main_thread_task_runner_);
DCHECK(gpu_channel_host_);
- task_runner->PostTask(
- FROM_HERE,
- base::BindOnce(&GpuVideoAcceleratorFactoriesImpl::BindContextToTaskRunner,
- base::Unretained(this)));
-
task_runner_->PostTask(
FROM_HERE,
- base::BindOnce(&GpuVideoAcceleratorFactoriesImpl::
- BindVideoEncodeAcceleratorProviderOnTaskRunner,
- base::Unretained(this), std::move(unbound_vea_provider)));
+ base::BindOnce(&GpuVideoAcceleratorFactoriesImpl::BindOnTaskRunner,
+ base::Unretained(this), std::move(interface_factory_info),
+ std::move(vea_provider_info)));
}
GpuVideoAcceleratorFactoriesImpl::~GpuVideoAcceleratorFactoriesImpl() {}
-void GpuVideoAcceleratorFactoriesImpl::BindContextToTaskRunner() {
+void GpuVideoAcceleratorFactoriesImpl::BindOnTaskRunner(
+ media::mojom::InterfaceFactoryPtrInfo interface_factory_info,
+ media::mojom::VideoEncodeAcceleratorProviderPtrInfo vea_provider_info) {
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(context_provider_);
- if (context_provider_->BindToCurrentThread() != gpu::ContextResult::kSuccess)
+
+ interface_factory_.Bind(std::move(interface_factory_info));
+ vea_provider_.Bind(std::move(vea_provider_info));
+
+ if (context_provider_->BindToCurrentThread() !=
+ gpu::ContextResult::kSuccess) {
SetContextProviderLost();
+ return;
+ }
+
+#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
+ if (base::FeatureList::IsEnabled(media::kMojoVideoDecoder)) {
+ interface_factory_->CreateVideoDecoder(mojo::MakeRequest(&video_decoder_));
+ video_decoder_->GetSupportedConfigs(base::BindOnce(
+ &GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs,
+ base::Unretained(this)));
+ }
+#endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
+}
+
+void GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs(
+ std::vector<media::mojom::SupportedVideoDecoderConfigPtr>
+ supported_configs) {
+ supported_decoder_configs_ = std::move(supported_configs);
+ video_decoder_.reset();
}
bool GpuVideoAcceleratorFactoriesImpl::CheckContextLost() {
@@ -162,6 +189,55 @@ int32_t GpuVideoAcceleratorFactoriesImpl::GetCommandBufferRouteId() {
return context_provider_->GetCommandBufferProxy()->route_id();
}
+bool GpuVideoAcceleratorFactoriesImpl::IsDecoderConfigSupported(
+ const media::VideoDecoderConfig& config) {
+ // If GetSupportedConfigs() has not completed (or was never started), report
+ // that all configs are supported. Clients will find out that configs are not
+ // supported when VideoDecoder::Initialize() fails.
+ if (!supported_decoder_configs_)
+ return true;
+
+ for (const media::mojom::SupportedVideoDecoderConfigPtr& supported :
+ *supported_decoder_configs_) {
+ if (config.profile() >= supported->profile_min &&
+ config.profile() <= supported->profile_max &&
+ config.coded_size().width() >= supported->coded_size_min.width() &&
+ config.coded_size().width() <= supported->coded_size_max.width() &&
+ config.coded_size().height() >= supported->coded_size_min.height() &&
+ config.coded_size().height() <= supported->coded_size_max.height() &&
+ (config.is_encrypted() ? supported->allow_encrypted
+ : !supported->require_encrypted)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+std::unique_ptr<media::VideoDecoder>
+GpuVideoAcceleratorFactoriesImpl::CreateVideoDecoder(
+ media::MediaLog* media_log,
+ const media::RequestOverlayInfoCB& request_overlay_info_cb,
+ const gfx::ColorSpace& target_color_space) {
+ DCHECK(video_accelerator_enabled_);
+ DCHECK(task_runner_->BelongsToCurrentThread());
+ DCHECK(interface_factory_.is_bound());
+ if (CheckContextLost())
+ return nullptr;
+
+#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
+ if (base::FeatureList::IsEnabled(media::kMojoVideoDecoder)) {
+ media::mojom::VideoDecoderPtr video_decoder;
+ interface_factory_->CreateVideoDecoder(mojo::MakeRequest(&video_decoder));
+ return std::make_unique<media::MojoVideoDecoder>(
+ task_runner_, this, media_log, std::move(video_decoder),
+ request_overlay_info_cb, target_color_space);
+ }
+#endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
+
+ return std::make_unique<media::GpuVideoDecoder>(
+ this, request_overlay_info_cb, target_color_space, media_log);
+}
+
std::unique_ptr<media::VideoDecodeAccelerator>
GpuVideoAcceleratorFactoriesImpl::CreateVideoDecodeAccelerator() {
DCHECK(video_accelerator_enabled_);
@@ -415,15 +491,6 @@ bool GpuVideoAcceleratorFactoriesImpl::CheckContextProviderLostOnMainThread() {
return context_provider_lost_;
}
-void GpuVideoAcceleratorFactoriesImpl::
- BindVideoEncodeAcceleratorProviderOnTaskRunner(
- media::mojom::VideoEncodeAcceleratorProviderPtrInfo
- unbound_vea_provider) {
- DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(!vea_provider_.is_bound());
- vea_provider_.Bind(std::move(unbound_vea_provider), task_runner_);
-}
-
void GpuVideoAcceleratorFactoriesImpl::SetContextProviderLost() {
DCHECK(task_runner_->BelongsToCurrentThread());
diff --git a/chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h b/chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h
index 19894023019..c8718cd7478 100644
--- a/chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h
+++ b/chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h
@@ -14,11 +14,14 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
#include "base/unguessable_token.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/content_export.h"
+#include "media/mojo/interfaces/interface_factory.mojom.h"
+#include "media/mojo/interfaces/video_decoder.mojom.h"
#include "media/mojo/interfaces/video_encode_accelerator.mojom.h"
#include "media/video/gpu_video_accelerator_factories.h"
#include "ui/gfx/geometry/size.h"
@@ -30,7 +33,7 @@ class GpuMemoryBufferManager;
namespace ui {
class ContextProviderCommandBuffer;
-}
+} // namespace ui
namespace content {
@@ -58,12 +61,19 @@ class CONTENT_EXPORT GpuVideoAcceleratorFactoriesImpl
bool enable_video_gpu_memory_buffers,
bool enable_media_stream_gpu_memory_buffers,
bool enable_video_accelerator,
- media::mojom::VideoEncodeAcceleratorProviderPtrInfo unbound_vea_provider);
+ media::mojom::InterfaceFactoryPtrInfo interface_factory_info,
+ media::mojom::VideoEncodeAcceleratorProviderPtrInfo vea_provider_info);
// media::GpuVideoAcceleratorFactories implementation.
bool IsGpuVideoAcceleratorEnabled() override;
base::UnguessableToken GetChannelToken() override;
int32_t GetCommandBufferRouteId() override;
+ std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
+ media::MediaLog* media_log,
+ const media::RequestOverlayInfoCB& request_overlay_info_cb,
+ const gfx::ColorSpace& target_color_space) override;
+ bool IsDecoderConfigSupported(
+ const media::VideoDecoderConfig& config) override;
std::unique_ptr<media::VideoDecodeAccelerator> CreateVideoDecodeAccelerator()
override;
std::unique_ptr<media::VideoEncodeAccelerator> CreateVideoEncodeAccelerator()
@@ -96,7 +106,6 @@ class CONTENT_EXPORT GpuVideoAcceleratorFactoriesImpl
// Called on the media thread. Returns the GLES2Interface unless the
// ContextProvider has been lost, in which case it returns null.
gpu::gles2::GLES2Interface* ContextGL() override;
- void BindContextToTaskRunner();
// Called on the media thread. Verifies if the ContextProvider is lost and
// notifies the main thread of loss if it has occured, which can be seen later
// from CheckContextProviderLost().
@@ -136,14 +145,20 @@ class CONTENT_EXPORT GpuVideoAcceleratorFactoriesImpl
bool enable_gpu_memory_buffer_video_frames_for_video,
bool enable_gpu_memory_buffer_video_frames_for_media_stream,
bool enable_video_accelerator,
- media::mojom::VideoEncodeAcceleratorProviderPtrInfo unbound_vea_provider);
+ media::mojom::InterfaceFactoryPtrInfo interface_factory_info,
+ media::mojom::VideoEncodeAcceleratorProviderPtrInfo vea_provider_info);
- void BindVideoEncodeAcceleratorProviderOnTaskRunner(
- media::mojom::VideoEncodeAcceleratorProviderPtrInfo unbound_vea_provider);
+ void BindOnTaskRunner(
+ media::mojom::InterfaceFactoryPtrInfo interface_factory_info,
+ media::mojom::VideoEncodeAcceleratorProviderPtrInfo vea_provider_info);
void SetContextProviderLost();
void SetContextProviderLostOnMainThread();
+ void OnSupportedDecoderConfigs(
+ std::vector<media::mojom::SupportedVideoDecoderConfigPtr>
+ supported_configs);
+
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
const scoped_refptr<gpu::GpuChannelHost> gpu_channel_host_;
@@ -170,8 +185,14 @@ class CONTENT_EXPORT GpuVideoAcceleratorFactoriesImpl
gpu::GpuMemoryBufferManager* const gpu_memory_buffer_manager_;
+ media::mojom::InterfaceFactoryPtr interface_factory_;
media::mojom::VideoEncodeAcceleratorProviderPtr vea_provider_;
+ // SupportedDecoderConfigs state.
+ mojo::InterfacePtr<media::mojom::VideoDecoder> video_decoder_;
+ base::Optional<std::vector<media::mojom::SupportedVideoDecoderConfigPtr>>
+ supported_decoder_configs_;
+
// For sending requests to allocate shared memory in the Browser process.
scoped_refptr<ThreadSafeSender> thread_safe_sender_;
diff --git a/chromium/content/renderer/media/media_factory.cc b/chromium/content/renderer/media/media_factory.cc
index 97aacde6a45..fd3b83488a9 100644
--- a/chromium/content/renderer/media/media_factory.cc
+++ b/chromium/content/renderer/media/media_factory.cc
@@ -13,6 +13,7 @@
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/buildflag.h"
+#include "cc/trees/layer_tree_settings.h"
#include "content/public/common/content_client.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/media/audio/audio_device_factory.h"
@@ -115,7 +116,7 @@ void PostContextProviderToCallback(
blink::WebSubmitterConfigurationCallback cb) {
auto* rti = content::RenderThreadImpl::current();
auto context_provider = rti->GetVideoFrameCompositorContextProvider(
- unwanted_context_provider);
+ std::move(unwanted_context_provider));
std::move(cb).Run(!rti->IsGpuCompositingDisabled(),
std::move(context_provider));
},
@@ -128,7 +129,7 @@ void PostContextProviderToCallback(
namespace content {
// static
-media::WebMediaPlayerParams::SurfaceLayerMode
+blink::WebMediaPlayer::SurfaceLayerMode
MediaFactory::GetVideoSurfaceLayerMode() {
// LayoutTests do not support SurfaceLayer by default at the moment.
// See https://crbug.com/838128
@@ -136,33 +137,19 @@ MediaFactory::GetVideoSurfaceLayerMode() {
content::RenderThreadImpl::current();
if (render_thread && render_thread->layout_test_mode() &&
!render_thread->LayoutTestModeUsesDisplayCompositorPixelDump()) {
- return media::WebMediaPlayerParams::SurfaceLayerMode::kNever;
+ return blink::WebMediaPlayer::SurfaceLayerMode::kNever;
}
if (features::IsMultiProcessMash())
- return media::WebMediaPlayerParams::SurfaceLayerMode::kNever;
+ return blink::WebMediaPlayer::SurfaceLayerMode::kNever;
if (base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideo))
- return media::WebMediaPlayerParams::SurfaceLayerMode::kAlways;
+ return blink::WebMediaPlayer::SurfaceLayerMode::kAlways;
if (base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideoPIP))
- return media::WebMediaPlayerParams::SurfaceLayerMode::kOnDemand;
+ return blink::WebMediaPlayer::SurfaceLayerMode::kOnDemand;
- return media::WebMediaPlayerParams::SurfaceLayerMode::kNever;
-}
-
-bool MediaFactory::VideoSurfaceLayerEnabledForMS() {
- // LayoutTests do not support SurfaceLayer by default at the moment.
- // See https://crbug.com/838128
- content::RenderThreadImpl* render_thread =
- content::RenderThreadImpl::current();
- if (render_thread && render_thread->layout_test_mode() &&
- !render_thread->LayoutTestModeUsesDisplayCompositorPixelDump()) {
- return false;
- }
-
- return base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideoMS) &&
- !features::IsMultiProcessMash();
+ return blink::WebMediaPlayer::SurfaceLayerMode::kNever;
}
MediaFactory::MediaFactory(
@@ -202,15 +189,59 @@ bool UseMediaPlayerRenderer(const GURL& url) {
return true;
}
- // Indicates if the Android MediaPlayer should be used instead of WMPI.
- if (GetContentClient()->renderer()->ShouldUseMediaPlayerForURL(url))
- return true;
-
// Otherwise, use the default renderer.
return false;
}
#endif // defined(OS_ANDROID)
+std::unique_ptr<blink::WebVideoFrameSubmitter> MediaFactory::CreateSubmitter(
+ scoped_refptr<base::SingleThreadTaskRunner>*
+ video_frame_compositor_task_runner,
+ const cc::LayerTreeSettings& settings) {
+ blink::WebMediaPlayer::SurfaceLayerMode use_surface_layer_for_video =
+ GetVideoSurfaceLayerMode();
+ content::RenderThreadImpl* render_thread =
+ content::RenderThreadImpl::current();
+ *video_frame_compositor_task_runner = nullptr;
+
+ if (!render_thread)
+ return nullptr;
+
+ bool use_sync_primitives = false;
+ if (use_surface_layer_for_video ==
+ blink::WebMediaPlayer::SurfaceLayerMode::kAlways) {
+ // Run the compositor / frame submitter on its own thread.
+ *video_frame_compositor_task_runner =
+ render_thread->CreateVideoFrameCompositorTaskRunner();
+ // We must use sync primitives on this thread.
+ use_sync_primitives = true;
+ } else {
+ // Run on the cc thread, even if we may switch to SurfaceLayer mode later
+ // if we're in kOnDemand mode. We do this to avoid switching threads when
+ // switching to SurfaceLayer.
+ *video_frame_compositor_task_runner =
+ render_thread->compositor_task_runner()
+ ? render_thread->compositor_task_runner()
+ : render_frame_->GetTaskRunner(
+ blink::TaskType::kInternalMediaRealTime);
+ }
+
+ std::unique_ptr<blink::WebVideoFrameSubmitter> submitter;
+
+ if (use_surface_layer_for_video !=
+ blink::WebMediaPlayer::SurfaceLayerMode::kNever) {
+ submitter = blink::WebVideoFrameSubmitter::Create(
+ base::BindRepeating(
+ &PostContextProviderToCallback,
+ RenderThreadImpl::current()->GetCompositorMainThreadTaskRunner()),
+ settings, use_sync_primitives);
+ }
+
+ DCHECK(*video_frame_compositor_task_runner);
+
+ return submitter;
+}
+
blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
const blink::WebMediaPlayerSource& source,
blink::WebMediaPlayerClient* client,
@@ -225,8 +256,8 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
blink::WebMediaStream web_stream =
GetWebMediaStreamFromWebMediaPlayerSource(source);
if (!web_stream.IsNull())
- return CreateWebMediaPlayerForMediaStream(client, sink_id, security_origin,
- web_frame, layer_tree_view);
+ return CreateWebMediaPlayerForMediaStream(
+ client, sink_id, security_origin, web_frame, layer_tree_view, settings);
// If |source| was not a MediaStream, it must be a URL.
// TODO(guidou): Fix this when support for other srcObject types is added.
@@ -254,15 +285,6 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
webkit_preferences.embedded_media_experience_enabled;
#endif // defined(OS_ANDROID)
- // Enable background optimizations based on field trial for src= content, but
- // always enable for MSE content. See http://crbug.com/709302.
- base::TimeDelta max_keyframe_distance_to_disable_background_video =
- base::TimeDelta::FromMilliseconds(base::GetFieldTrialParamByFeatureAsInt(
- media::kBackgroundVideoTrackOptimization, "max_keyframe_distance_ms",
- 0));
- base::TimeDelta max_keyframe_distance_to_disable_background_video_mse =
- base::TimeDelta::FromSeconds(5);
-
// When memory pressure based garbage collection is enabled for MSE, the
// |enable_instant_source_buffer_gc| flag controls whether the GC is done
// immediately on memory pressure notification or during the next SourceBuffer
@@ -302,36 +324,8 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
scoped_refptr<base::SingleThreadTaskRunner>
video_frame_compositor_task_runner;
- std::unique_ptr<blink::WebVideoFrameSubmitter> submitter;
- media::WebMediaPlayerParams::SurfaceLayerMode use_surface_layer_for_video =
- GetVideoSurfaceLayerMode();
- bool use_sync_primitives = false;
- if (use_surface_layer_for_video ==
- media::WebMediaPlayerParams::SurfaceLayerMode::kAlways) {
- // Run the compositor / frame submitter on its own thread.
- video_frame_compositor_task_runner =
- render_thread->CreateVideoFrameCompositorTaskRunner();
- // We must use sync primitives on this thread.
- use_sync_primitives = true;
- } else {
- // Run on the cc thread, even if we may switch to SurfaceLayer mode later
- // if we're in kOnDemand mode. We do this to avoid switching threads when
- // switching to SurfaceLayer.
- video_frame_compositor_task_runner =
- render_thread->compositor_task_runner()
- ? render_thread->compositor_task_runner()
- : render_frame_->GetTaskRunner(
- blink::TaskType::kInternalMediaRealTime);
- }
-
- if (use_surface_layer_for_video !=
- media::WebMediaPlayerParams::SurfaceLayerMode::kNever) {
- submitter = blink::WebVideoFrameSubmitter::Create(
- base::BindRepeating(
- &PostContextProviderToCallback,
- RenderThreadImpl::current()->GetCompositorMainThreadTaskRunner()),
- settings, use_sync_primitives);
- }
+ std::unique_ptr<blink::WebVideoFrameSubmitter> submitter =
+ CreateSubmitter(&video_frame_compositor_task_runner, settings);
DCHECK(layer_tree_view);
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner =
@@ -358,14 +352,12 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
base::Bind(&v8::Isolate::AdjustAmountOfExternalAllocatedMemory,
base::Unretained(blink::MainThreadIsolate())),
initial_cdm, request_routing_token_cb_, media_observer,
- max_keyframe_distance_to_disable_background_video,
- max_keyframe_distance_to_disable_background_video_mse,
enable_instant_source_buffer_gc, embedded_media_experience_enabled,
std::move(metrics_provider),
base::BindOnce(&blink::WebSurfaceLayerBridge::Create,
layer_tree_view),
RenderThreadImpl::current()->SharedMainThreadContextProvider(),
- use_surface_layer_for_video));
+ GetVideoSurfaceLayerMode()));
std::unique_ptr<media::VideoFrameCompositor> vfc =
std::make_unique<media::VideoFrameCompositor>(
@@ -533,7 +525,8 @@ blink::WebMediaPlayer* MediaFactory::CreateWebMediaPlayerForMediaStream(
const blink::WebString& sink_id,
const blink::WebSecurityOrigin& security_origin,
blink::WebLocalFrame* frame,
- blink::WebLayerTreeView* layer_tree_view) {
+ blink::WebLayerTreeView* layer_tree_view,
+ const cc::LayerTreeSettings& settings) {
RenderThreadImpl* const render_thread = RenderThreadImpl::current();
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner =
@@ -542,6 +535,11 @@ blink::WebMediaPlayer* MediaFactory::CreateWebMediaPlayerForMediaStream(
compositor_task_runner =
render_frame_->GetTaskRunner(blink::TaskType::kInternalMediaRealTime);
+ scoped_refptr<base::SingleThreadTaskRunner>
+ video_frame_compositor_task_runner;
+ std::unique_ptr<blink::WebVideoFrameSubmitter> submitter =
+ CreateSubmitter(&video_frame_compositor_task_runner, settings);
+
DCHECK(layer_tree_view);
return new WebMediaPlayerMS(
frame, client, GetWebMediaPlayerDelegate(),
@@ -549,11 +547,12 @@ blink::WebMediaPlayer* MediaFactory::CreateWebMediaPlayerForMediaStream(
url::Origin(security_origin).GetURL(),
render_frame_->GetTaskRunner(blink::TaskType::kInternalMedia)),
CreateMediaStreamRendererFactory(), render_thread->GetIOTaskRunner(),
- compositor_task_runner, render_thread->GetMediaThreadTaskRunner(),
+ video_frame_compositor_task_runner,
+ render_thread->GetMediaThreadTaskRunner(),
render_thread->GetWorkerTaskRunner(), render_thread->GetGpuFactories(),
sink_id,
base::BindOnce(&blink::WebSurfaceLayerBridge::Create, layer_tree_view),
- VideoSurfaceLayerEnabledForMS());
+ std::move(submitter), GetVideoSurfaceLayerMode());
}
media::RendererWebMediaPlayerDelegate*
diff --git a/chromium/content/renderer/media/media_factory.h b/chromium/content/renderer/media/media_factory.h
index 730c283e3fe..7293d2dd6de 100644
--- a/chromium/content/renderer/media/media_factory.h
+++ b/chromium/content/renderer/media/media_factory.h
@@ -73,8 +73,7 @@ class RendererMediaPlayerManager;
class MediaFactory {
public:
// Helper function returning whether VideoSurfaceLayer should be enabled.
- static media::WebMediaPlayerParams::SurfaceLayerMode
- GetVideoSurfaceLayerMode();
+ static blink::WebMediaPlayer::SurfaceLayerMode GetVideoSurfaceLayerMode();
// Helper function returning whether VideoSurfaceLayer should be enabled for
// MediaStreams.
@@ -92,6 +91,13 @@ class MediaFactory {
// interface provider is bound.
void SetupMojo();
+ // Creates the VideoFrameSubmitter and its task_runner based on the current
+ // SurfaceLayerMode;
+ std::unique_ptr<blink::WebVideoFrameSubmitter> CreateSubmitter(
+ scoped_refptr<base::SingleThreadTaskRunner>*
+ video_frame_compositor_task_runner,
+ const cc::LayerTreeSettings& settings);
+
// Creates a new WebMediaPlayer for the given |source| (either a stream or
// URL). All pointers other than |initial_cdm| are required to be non-null.
// The created player serves and is directed by the |client| (e.g.
@@ -129,7 +135,8 @@ class MediaFactory {
const blink::WebString& sink_id,
const blink::WebSecurityOrigin& security_origin,
blink::WebLocalFrame* frame,
- blink::WebLayerTreeView* layer_tree_view);
+ blink::WebLayerTreeView* layer_tree_view,
+ const cc::LayerTreeSettings& settings);
// Returns the media delegate for WebMediaPlayer usage. If
// |media_player_delegate_| is NULL, one is created.
diff --git a/chromium/content/renderer/media/media_permission_dispatcher.cc b/chromium/content/renderer/media/media_permission_dispatcher.cc
index b22e0987284..96f057c5f6a 100644
--- a/chromium/content/renderer/media/media_permission_dispatcher.cc
+++ b/chromium/content/renderer/media/media_permission_dispatcher.cc
@@ -43,15 +43,12 @@ blink::mojom::PermissionDescriptorPtr MediaPermissionTypeToPermissionDescriptor(
namespace content {
MediaPermissionDispatcher::MediaPermissionDispatcher(
- const ConnectToServiceCB& connect_to_service_cb,
- const IsEncryptedMediaEnabledCB& is_encrypted_media_enabled_cb)
- : connect_to_service_cb_(connect_to_service_cb),
- is_encrypted_media_enabled_cb_(is_encrypted_media_enabled_cb),
- task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ RenderFrameImpl* render_frame)
+ : task_runner_(base::ThreadTaskRunnerHandle::Get()),
next_request_id_(0),
+ render_frame_(render_frame),
weak_factory_(this) {
- DCHECK(!connect_to_service_cb_.is_null());
- DCHECK(!is_encrypted_media_enabled_cb_.is_null());
+ DCHECK(render_frame_);
weak_ptr_ = weak_factory_.GetWeakPtr();
}
@@ -108,13 +105,14 @@ void MediaPermissionDispatcher::RequestPermission(
GetPermissionService()->RequestPermission(
MediaPermissionTypeToPermissionDescriptor(type),
- blink::WebUserGestureIndicator::IsProcessingUserGesture(),
+ blink::WebUserGestureIndicator::IsProcessingUserGesture(
+ render_frame_->GetWebFrame()),
base::BindOnce(&MediaPermissionDispatcher::OnPermissionStatus, weak_ptr_,
request_id));
}
bool MediaPermissionDispatcher::IsEncryptedMediaEnabled() {
- return is_encrypted_media_enabled_cb_.Run();
+ return render_frame_->GetRendererPreferences().enable_encrypted_media;
}
uint32_t MediaPermissionDispatcher::RegisterCallback(
@@ -131,7 +129,8 @@ uint32_t MediaPermissionDispatcher::RegisterCallback(
blink::mojom::PermissionService*
MediaPermissionDispatcher::GetPermissionService() {
if (!permission_service_) {
- connect_to_service_cb_.Run(mojo::MakeRequest(&permission_service_));
+ render_frame_->GetRemoteInterfaces()->GetInterface(
+ mojo::MakeRequest(&permission_service_));
permission_service_.set_connection_error_handler(base::BindOnce(
&MediaPermissionDispatcher::OnConnectionError, base::Unretained(this)));
}
@@ -145,7 +144,7 @@ void MediaPermissionDispatcher::OnPermissionStatus(
DVLOG(2) << __func__ << ": (" << request_id << ", " << status << ")";
DCHECK(task_runner_->RunsTasksInCurrentSequence());
- RequestMap::iterator iter = requests_.find(request_id);
+ auto iter = requests_.find(request_id);
DCHECK(iter != requests_.end()) << "Request not found.";
PermissionStatusCB permission_status_cb = iter->second;
diff --git a/chromium/content/renderer/media/media_permission_dispatcher.h b/chromium/content/renderer/media/media_permission_dispatcher.h
index 5660721131c..f1ad13382bc 100644
--- a/chromium/content/renderer/media/media_permission_dispatcher.h
+++ b/chromium/content/renderer/media/media_permission_dispatcher.h
@@ -14,6 +14,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
+#include "content/renderer/render_frame_impl.h"
#include "media/base/media_permission.h"
#include "third_party/blink/public/platform/modules/permissions/permission.mojom.h"
@@ -26,13 +27,7 @@ namespace content {
// MediaPermission implementation using content PermissionService.
class CONTENT_EXPORT MediaPermissionDispatcher : public media::MediaPermission {
public:
- using ConnectToServiceCB = base::RepeatingCallback<void(
- mojo::InterfaceRequest<blink::mojom::PermissionService>)>;
- using IsEncryptedMediaEnabledCB = base::RepeatingCallback<bool()>;
-
- MediaPermissionDispatcher(
- const ConnectToServiceCB& connect_to_service_cb,
- const IsEncryptedMediaEnabledCB& is_encrypted_media_enabled_cb);
+ explicit MediaPermissionDispatcher(RenderFrameImpl* render_frame);
~MediaPermissionDispatcher() override;
// Called when the frame owning this MediaPermissionDispatcher is navigated.
@@ -66,13 +61,16 @@ class CONTENT_EXPORT MediaPermissionDispatcher : public media::MediaPermission {
// Callback for |permission_service_| connection errors.
void OnConnectionError();
- ConnectToServiceCB connect_to_service_cb_;
- IsEncryptedMediaEnabledCB is_encrypted_media_enabled_cb_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
uint32_t next_request_id_;
RequestMap requests_;
blink::mojom::PermissionServicePtr permission_service_;
+ // The |RenderFrameImpl| that owns this MediaPermissionDispatcher. It's okay
+ // to hold a raw pointer here because the lifetime of this object is bounded
+ // by the render frame's life (the latter holds a unique pointer to this).
+ RenderFrameImpl* const render_frame_;
+
// Used to safely post MediaPermission calls for execution on |task_runner_|.
base::WeakPtr<MediaPermissionDispatcher> weak_ptr_;
diff --git a/chromium/content/renderer/media/midi/midi_message_filter.cc b/chromium/content/renderer/media/midi/midi_message_filter.cc
index b96e36e822a..bb485d61d10 100644
--- a/chromium/content/renderer/media/midi/midi_message_filter.cc
+++ b/chromium/content/renderer/media/midi/midi_message_filter.cc
@@ -57,9 +57,8 @@ void MidiMessageFilter::RemoveClient(blink::WebMIDIAccessorClient* client) {
<< "RemoveClient call was not ballanced with AddClient call";
DCHECK(main_task_runner_->BelongsToCurrentThread());
clients_.erase(client);
- ClientsQueue::iterator it = std::find(clients_waiting_session_queue_.begin(),
- clients_waiting_session_queue_.end(),
- client);
+ auto it = std::find(clients_waiting_session_queue_.begin(),
+ clients_waiting_session_queue_.end(), client);
if (it != clients_waiting_session_queue_.end())
clients_waiting_session_queue_.erase(it);
if (clients_.empty() && clients_waiting_session_queue_.empty()) {
diff --git a/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter.cc b/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter.cc
deleted file mode 100644
index d768c2954da..00000000000
--- a/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright (c) 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 "content/renderer/media/pepper/pepper_to_video_track_adapter.h"
-
-#include <string>
-
-#include "base/base64.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/rand_util.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/trace_event/trace_event.h"
-#include "content/renderer/media/stream/media_stream_registry_interface.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
-#include "content/renderer/pepper/ppb_image_data_impl.h"
-#include "content/renderer/render_thread_impl.h"
-#include "media/base/video_frame_pool.h"
-#include "media/capture/video_capture_types.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_url.h"
-#include "third_party/blink/public/web/web_media_stream_registry.h"
-#include "third_party/libyuv/include/libyuv/convert.h"
-#include "url/gurl.h"
-
-namespace content {
-
-// PpFrameWriter implements MediaStreamVideoSource and can therefore provide
-// video frames to MediaStreamVideoTracks. It also implements
-// FrameWriterInterface, which will be used by Pepper plugins (notably the
-// Effects plugin) to inject the processed frame.
-class PpFrameWriter : public MediaStreamVideoSource,
- public FrameWriterInterface,
- public base::SupportsWeakPtr<PpFrameWriter> {
- public:
- PpFrameWriter();
- ~PpFrameWriter() override;
-
- // FrameWriterInterface implementation.
- // This method will be called by the Pepper host from render thread.
- void PutFrame(PPB_ImageData_Impl* image_data, int64_t time_stamp_ns) override;
-
- protected:
- // MediaStreamVideoSource implementation.
- void StartSourceImpl(
- const VideoCaptureDeliverFrameCB& frame_callback) override;
- void StopSourceImpl() override;
-
- private:
- media::VideoFramePool frame_pool_;
-
- class FrameWriterDelegate;
- scoped_refptr<FrameWriterDelegate> delegate_;
-
- DISALLOW_COPY_AND_ASSIGN(PpFrameWriter);
-};
-
-class PpFrameWriter::FrameWriterDelegate
- : public base::RefCountedThreadSafe<FrameWriterDelegate> {
- public:
- FrameWriterDelegate(
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
- const VideoCaptureDeliverFrameCB& new_frame_callback);
-
- void DeliverFrame(const scoped_refptr<media::VideoFrame>& frame);
- private:
- friend class base::RefCountedThreadSafe<FrameWriterDelegate>;
- virtual ~FrameWriterDelegate();
-
- void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame);
-
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
- VideoCaptureDeliverFrameCB new_frame_callback_;
-};
-
-PpFrameWriter::FrameWriterDelegate::FrameWriterDelegate(
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
- const VideoCaptureDeliverFrameCB& new_frame_callback)
- : io_task_runner_(io_task_runner), new_frame_callback_(new_frame_callback) {
-}
-
-PpFrameWriter::FrameWriterDelegate::~FrameWriterDelegate() {
-}
-
-void PpFrameWriter::FrameWriterDelegate::DeliverFrame(
- const scoped_refptr<media::VideoFrame>& frame) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&FrameWriterDelegate::DeliverFrameOnIO, this, frame));
-}
-
-void PpFrameWriter::FrameWriterDelegate::DeliverFrameOnIO(
- const scoped_refptr<media::VideoFrame>& frame) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- // The local time when this frame is generated is unknown so give a null
- // value to |estimated_capture_time|.
- new_frame_callback_.Run(frame, base::TimeTicks());
-}
-
-PpFrameWriter::PpFrameWriter() {
- DVLOG(3) << "PpFrameWriter ctor";
-}
-
-PpFrameWriter::~PpFrameWriter() {
- DVLOG(3) << "PpFrameWriter dtor";
-}
-
-void PpFrameWriter::StartSourceImpl(
- const VideoCaptureDeliverFrameCB& frame_callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(!delegate_.get());
- DVLOG(3) << "PpFrameWriter::StartSourceImpl()";
- delegate_ = new FrameWriterDelegate(io_task_runner(), frame_callback);
- OnStartDone(MEDIA_DEVICE_OK);
-}
-
-void PpFrameWriter::StopSourceImpl() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-}
-
-// Note: PutFrame must copy or process image_data directly in this function,
-// because it may be overwritten as soon as we return from this function.
-void PpFrameWriter::PutFrame(PPB_ImageData_Impl* image_data,
- int64_t time_stamp_ns) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- TRACE_EVENT0("media", "PpFrameWriter::PutFrame");
- DVLOG(3) << "PpFrameWriter::PutFrame()";
-
- if (!image_data) {
- LOG(ERROR) << "PpFrameWriter::PutFrame - Called with NULL image_data.";
- return;
- }
- ImageDataAutoMapper mapper(image_data);
- if (!mapper.is_valid()) {
- LOG(ERROR) << "PpFrameWriter::PutFrame - "
- << "The image could not be mapped and is unusable.";
- return;
- }
- SkBitmap bitmap(image_data->GetMappedBitmap());
- if (bitmap.empty()) {
- LOG(ERROR) << "PpFrameWriter::PutFrame - "
- << "The image_data's mapped bitmap failed.";
- return;
- }
-
- const uint8_t* src_data = static_cast<uint8_t*>(bitmap.getPixels());
- const int src_stride = static_cast<int>(bitmap.rowBytes());
- const int width = bitmap.width();
- const int height = bitmap.height();
-
- // We only support PP_IMAGEDATAFORMAT_BGRA_PREMUL at the moment.
- DCHECK(image_data->format() == PP_IMAGEDATAFORMAT_BGRA_PREMUL);
-
- const gfx::Size frame_size(width, height);
-
- if (state() != MediaStreamVideoSource::STARTED)
- return;
-
- const base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds(
- time_stamp_ns / base::Time::kNanosecondsPerMicrosecond);
-
- scoped_refptr<media::VideoFrame> new_frame =
- frame_pool_.CreateFrame(media::PIXEL_FORMAT_I420, frame_size,
- gfx::Rect(frame_size), frame_size, timestamp);
-
- libyuv::ARGBToI420(src_data,
- src_stride,
- new_frame->data(media::VideoFrame::kYPlane),
- new_frame->stride(media::VideoFrame::kYPlane),
- new_frame->data(media::VideoFrame::kUPlane),
- new_frame->stride(media::VideoFrame::kUPlane),
- new_frame->data(media::VideoFrame::kVPlane),
- new_frame->stride(media::VideoFrame::kVPlane),
- width,
- height);
-
- delegate_->DeliverFrame(new_frame);
-}
-
-// PpFrameWriterProxy is a helper class to make sure the user won't use
-// PpFrameWriter after it is released (IOW its owner - WebMediaStreamSource -
-// is released).
-class PpFrameWriterProxy : public FrameWriterInterface {
- public:
- explicit PpFrameWriterProxy(const base::WeakPtr<PpFrameWriter>& writer)
- : writer_(writer) {
- DCHECK(writer_);
- }
-
- ~PpFrameWriterProxy() override {}
-
- void PutFrame(PPB_ImageData_Impl* image_data,
- int64_t time_stamp_ns) override {
- writer_->PutFrame(image_data, time_stamp_ns);
- }
-
- private:
- base::WeakPtr<PpFrameWriter> writer_;
-
- DISALLOW_COPY_AND_ASSIGN(PpFrameWriterProxy);
-};
-
-bool PepperToVideoTrackAdapter::Open(MediaStreamRegistryInterface* registry,
- const std::string& url,
- FrameWriterInterface** frame_writer) {
- DVLOG(3) << "PepperToVideoTrackAdapter::Open";
- blink::WebMediaStream stream;
- if (registry) {
- stream = registry->GetMediaStream(url);
- } else {
- stream =
- blink::WebMediaStreamRegistry::LookupMediaStreamDescriptor(GURL(url));
- }
- if (stream.IsNull()) {
- LOG(ERROR) << "PepperToVideoTrackAdapter::Open - invalid url: " << url;
- return false;
- }
-
- // Create a new native video track and add it to |stream|.
- std::string track_id;
- // According to spec, a media stream source's id should be unique per
- // application. There's no easy way to strictly achieve that. The id
- // generated with this method should be unique for most of the cases but
- // theoretically it's possible we can get an id that's duplicated with the
- // existing sources.
- base::Base64Encode(base::RandBytesAsString(64), &track_id);
-
- PpFrameWriter* writer = new PpFrameWriter();
-
- // Create a new webkit video track.
- blink::WebMediaStreamSource webkit_source;
- blink::WebMediaStreamSource::Type type =
- blink::WebMediaStreamSource::kTypeVideo;
- blink::WebString webkit_track_id = blink::WebString::FromUTF8(track_id);
- webkit_source.Initialize(webkit_track_id, type, webkit_track_id,
- false /* remote */);
- webkit_source.SetExtraData(writer);
-
- bool track_enabled = true;
- stream.AddTrack(MediaStreamVideoTrack::CreateVideoTrack(
- writer, MediaStreamVideoSource::ConstraintsCallback(), track_enabled));
-
- *frame_writer = new PpFrameWriterProxy(writer->AsWeakPtr());
- return true;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter.h b/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter.h
deleted file mode 100644
index 618fc41ebcd..00000000000
--- a/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 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 CONTENT_RENDERER_MEDIA_PEPPER_PEPPER_TO_VIDEO_TRACK_ADAPTER_H_
-#define CONTENT_RENDERER_MEDIA_PEPPER_PEPPER_TO_VIDEO_TRACK_ADAPTER_H_
-
-#include <stdint.h>
-
-#include <string>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-class MediaStreamRegistryInterface;
-class PPB_ImageData_Impl;
-
-// Interface used by a Pepper plugin to output frames to a video track.
-class CONTENT_EXPORT FrameWriterInterface {
- public:
- // The ownership of the |image_data| doesn't transfer. So the implementation
- // of this interface should make a copy of the |image_data| before return.
- virtual void PutFrame(PPB_ImageData_Impl* image_data,
- int64_t time_stamp_ns) = 0;
- virtual ~FrameWriterInterface() {}
-};
-
-// PepperToVideoTrackAdapter is a glue class between the content MediaStream and
-// the effects pepper plugin host.
-class CONTENT_EXPORT PepperToVideoTrackAdapter {
- public:
- // Instantiates and adds a new video track to the MediaStream specified by
- // |url|. Returns a handler for delivering frames to the new video track as
- // |frame_writer|.
- // If |registry| is NULL the global blink::WebMediaStreamRegistry will be
- // used to look up the media stream.
- // The caller of the function takes the ownership of |frame_writer|.
- // Returns true on success and false on failure.
- static bool Open(MediaStreamRegistryInterface* registry,
- const std::string& url,
- FrameWriterInterface** frame_writer);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(PepperToVideoTrackAdapter);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_PEPPER_PEPPER_TO_VIDEO_TRACK_ADAPTER_H_
diff --git a/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc b/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc
deleted file mode 100644
index ce350d3026f..00000000000
--- a/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) 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 <string>
-
-#include "base/run_loop.h"
-#include "content/child/child_process.h"
-#include "content/public/test/mock_render_thread.h"
-#include "content/renderer/media/pepper/pepper_to_video_track_adapter.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
-#include "content/renderer/media/stream/mock_media_stream_registry.h"
-#include "content/renderer/media/stream/mock_media_stream_video_sink.h"
-#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
-#include "content/renderer/pepper/ppb_image_data_impl.h"
-#include "content/test/ppapi_unittest.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/web/web_heap.h"
-
-using ::testing::_;
-
-namespace content {
-
-ACTION_P(RunClosure, closure) {
- closure.Run();
-}
-
-static const std::string kTestStreamUrl = "stream_url";
-static const std::string kUnknownStreamUrl = "unknown_stream_url";
-
-class PepperToVideoTrackAdapterTest : public PpapiUnittest {
- public:
- PepperToVideoTrackAdapterTest() : registry_(new MockMediaStreamRegistry()) {
- registry_->Init(kTestStreamUrl);
- }
-
- void TearDown() override {
- registry_.reset();
- blink::WebHeap::CollectAllGarbageForTesting();
- PpapiUnittest::TearDown();
- }
-
- protected:
- // A ChildProcess is needed to fool the Tracks and Sources into believing they
- // are on the right threads. The ScopedTaskEnvironment provided by
- // PpapiUnittest prevents the ChildProcess from leaking a TaskScheduler.
- const ChildProcess child_process_;
- const MockRenderThread render_thread_;
- std::unique_ptr<MockMediaStreamRegistry> registry_;
-};
-
-TEST_F(PepperToVideoTrackAdapterTest, Open) {
- // |frame_writer| is a proxy and is owned by whoever call Open.
- FrameWriterInterface* frame_writer = nullptr;
- // Unknow url will return false.
- EXPECT_FALSE(PepperToVideoTrackAdapter::Open(registry_.get(),
- kUnknownStreamUrl, &frame_writer));
- EXPECT_TRUE(PepperToVideoTrackAdapter::Open(registry_.get(),
- kTestStreamUrl, &frame_writer));
- delete frame_writer;
-}
-
-TEST_F(PepperToVideoTrackAdapterTest, PutFrame) {
- FrameWriterInterface* frame_writer = nullptr;
- EXPECT_TRUE(PepperToVideoTrackAdapter::Open(registry_.get(),
- kTestStreamUrl, &frame_writer));
- ASSERT_TRUE(frame_writer);
-
- // Verify the video track has been added.
- const blink::WebMediaStream test_stream = registry_->test_stream();
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
- test_stream.VideoTracks();
- ASSERT_EQ(1u, video_tracks.size());
-
- // Verify the native video track has been added.
- MediaStreamVideoTrack* native_track =
- MediaStreamVideoTrack::GetVideoTrack(video_tracks[0]);
- ASSERT_TRUE(native_track != nullptr);
-
- MockMediaStreamVideoSink sink;
- native_track->AddSink(&sink, sink.GetDeliverFrameCB(), false);
- scoped_refptr<PPB_ImageData_Impl> image(new PPB_ImageData_Impl(
- instance()->pp_instance(), PPB_ImageData_Impl::ForTest()));
- image->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, 640, 360, true);
- {
- base::RunLoop run_loop;
- base::Closure quit_closure = run_loop.QuitClosure();
-
- EXPECT_CALL(sink, OnVideoFrame())
- .WillOnce(RunClosure(std::move(quit_closure)));
- frame_writer->PutFrame(image.get(), 10);
- run_loop.Run();
- // Run all pending tasks to let the the test clean up before the test ends.
- // This is due to that
- // FrameWriterDelegate::FrameWriterDelegate::DeliverFrame use
- // PostTaskAndReply to the IO thread and expects the reply to process
- // on the main render thread to clean up its resources. However, the
- // QuitClosure above ends before that.
- base::RunLoop().RunUntilIdle();
- }
- EXPECT_EQ(1, sink.number_of_frames());
- native_track->RemoveSink(&sink);
-
- // The |frame_writer| is a proxy and is owned by whoever call Open.
- delete frame_writer;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.cc b/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.cc
deleted file mode 100644
index a87b792ff77..00000000000
--- a/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 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 "content/renderer/media/pepper/video_track_to_pepper_adapter.h"
-
-#include <string>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/synchronization/lock.h"
-#include "base/trace_event/trace_event.h"
-#include "content/public/renderer/media_stream_video_sink.h"
-#include "content/renderer/media/stream/media_stream_registry_interface.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/capture/video_capture_types.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_url.h"
-#include "third_party/blink/public/web/web_media_stream_registry.h"
-#include "url/gurl.h"
-
-namespace content {
-
-// PpFrameReceiver implements MediaStreamVideoSink so that it can be attached
-// to video track to receive captured frames.
-// It can be attached to a FrameReaderInterface to output the received frame.
-class PpFrameReceiver : public MediaStreamVideoSink {
- public:
- PpFrameReceiver(blink::WebMediaStreamTrack track)
- : track_(track), reader_(nullptr), weak_factory_(this) {}
-
- ~PpFrameReceiver() override {}
-
- void SetReader(FrameReaderInterface* reader) {
- DCHECK((reader_ && !reader) || (!reader_ && reader))
- << " |reader| = " << reader << ", |reader_| = " << reader_;
- if (reader) {
- MediaStreamVideoSink::ConnectToTrack(
- track_,
- media::BindToCurrentLoop(base::Bind(&PpFrameReceiver::OnVideoFrame,
- weak_factory_.GetWeakPtr())),
- false);
- } else {
- MediaStreamVideoSink::DisconnectFromTrack();
- weak_factory_.InvalidateWeakPtrs();
- }
- reader_ = reader;
- }
-
- void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame,
- base::TimeTicks estimated_capture_time) {
- TRACE_EVENT0("media", "PpFrameReceiver::OnVideoFrame");
- if (reader_)
- reader_->GotFrame(frame);
- }
-
- private:
- const blink::WebMediaStreamTrack track_;
- FrameReaderInterface* reader_;
- base::WeakPtrFactory<PpFrameReceiver> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(PpFrameReceiver);
-};
-
-VideoTrackToPepperAdapter::VideoTrackToPepperAdapter(
- MediaStreamRegistryInterface* registry)
- : registry_(registry) {}
-
-VideoTrackToPepperAdapter::~VideoTrackToPepperAdapter() {
- for (const auto& reader_and_receiver : reader_to_receiver_)
- delete reader_and_receiver.second;
-}
-
-bool VideoTrackToPepperAdapter::Open(const std::string& url,
- FrameReaderInterface* reader) {
- DCHECK(thread_checker_.CalledOnValidThread());
- const blink::WebMediaStreamTrack& track = GetFirstVideoTrack(url);
- if (track.IsNull())
- return false;
- reader_to_receiver_[reader] = new SourceInfo(track, reader);
- return true;
-}
-
-bool VideoTrackToPepperAdapter::Close(FrameReaderInterface* reader) {
- DCHECK(thread_checker_. CalledOnValidThread());
- SourceInfoMap::iterator it = reader_to_receiver_.find(reader);
- if (it == reader_to_receiver_.end())
- return false;
- delete it->second;
- reader_to_receiver_.erase(it);
- return true;
-}
-
-blink::WebMediaStreamTrack VideoTrackToPepperAdapter::GetFirstVideoTrack(
- const std::string& url) {
- DCHECK(thread_checker_.CalledOnValidThread());
- const blink::WebMediaStream stream =
- registry_ ? registry_->GetMediaStream(url)
- : blink::WebMediaStreamRegistry::LookupMediaStreamDescriptor(
- GURL(url));
-
- if (stream.IsNull()) {
- LOG(ERROR) << "GetFirstVideoSource - invalid url: " << url;
- return blink::WebMediaStreamTrack();
- }
-
- // Get the first video track from the stream.
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
- stream.VideoTracks();
- if (video_tracks.IsEmpty()) {
- LOG(ERROR) << "GetFirstVideoSource - no video tracks. url: " << url;
- return blink::WebMediaStreamTrack();
- }
-
- return video_tracks[0];
-}
-
-void VideoTrackToPepperAdapter::DeliverFrameForTesting(
- FrameReaderInterface* reader,
- const scoped_refptr<media::VideoFrame>& frame) {
- SourceInfoMap::const_iterator it = reader_to_receiver_.find(reader);
- if (it == reader_to_receiver_.end())
- return;
- PpFrameReceiver* receiver = it->second->receiver_.get();
- receiver->OnVideoFrame(frame, base::TimeTicks());
-}
-
-VideoTrackToPepperAdapter::SourceInfo::SourceInfo(
- const blink::WebMediaStreamTrack& blink_track,
- FrameReaderInterface* reader)
- : receiver_(new PpFrameReceiver(blink_track)) {
- receiver_->SetReader(reader);
-}
-
-VideoTrackToPepperAdapter::SourceInfo::~SourceInfo() {
- receiver_->SetReader(nullptr);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.h b/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.h
deleted file mode 100644
index 732ec6225f2..00000000000
--- a/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 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 CONTENT_RENDERER_MEDIA_VIDEO_VIDEO_TRACK_TO_PEPPER_ADAPTER_H_
-#define CONTENT_RENDERER_MEDIA_VIDEO_VIDEO_TRACK_TO_PEPPER_ADAPTER_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/threading/thread_checker.h"
-#include "content/common/content_export.h"
-#include "media/base/video_frame.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-
-namespace content {
-
-class MediaStreamRegistryInterface;
-class PpFrameReceiver;
-
-// Interface used by a Pepper plugin to get captured frames from a video track.
-class CONTENT_EXPORT FrameReaderInterface {
- public:
- // Got a new captured frame.
- virtual void GotFrame(const scoped_refptr<media::VideoFrame>& frame) = 0;
-
- protected:
- virtual ~FrameReaderInterface() {}
-};
-
-// VideoTrackToPepperAdapter is a glue class between MediaStreamVideoTrack and a
-// Pepper plugin host.
-class CONTENT_EXPORT VideoTrackToPepperAdapter {
- public:
- // |registry| is used to look up the media stream by url. If a NULL |registry|
- // is given, the global blink::WebMediaStreamRegistry will be used.
- explicit VideoTrackToPepperAdapter(MediaStreamRegistryInterface* registry);
- virtual ~VideoTrackToPepperAdapter();
- // Connects to the first video track in the MediaStream specified by |url| and
- // the received frames will be delivered via |reader|.
- // Returns true on success and false on failure.
- bool Open(const std::string& url, FrameReaderInterface* reader);
- // Closes |reader|'s connection with the video track, i.e. stops receiving
- // frames from the video track.
- // Returns true on success and false on failure.
- bool Close(FrameReaderInterface* reader);
-
- private:
- friend class VideoTrackToPepperAdapterTest;
-
- struct SourceInfo {
- SourceInfo(const blink::WebMediaStreamTrack& blink_track,
- FrameReaderInterface* reader);
- ~SourceInfo();
-
- std::unique_ptr<PpFrameReceiver> receiver_;
- };
-
- typedef std::map<FrameReaderInterface*, SourceInfo*> SourceInfoMap;
-
- blink::WebMediaStreamTrack GetFirstVideoTrack(const std::string& url);
-
- // Deliver VideoFrame to the MediaStreamVideoSink associated with
- // |reader|. For testing only.
- void DeliverFrameForTesting(FrameReaderInterface* reader,
- const scoped_refptr<media::VideoFrame>& frame);
-
- MediaStreamRegistryInterface* const registry_;
- SourceInfoMap reader_to_receiver_;
-
- base::ThreadChecker thread_checker_;
-
- DISALLOW_COPY_AND_ASSIGN(VideoTrackToPepperAdapter);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_VIDEO_VIDEO_TRACK_TO_PEPPER_ADAPTER_H_
diff --git a/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter_unittest.cc b/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter_unittest.cc
deleted file mode 100644
index 2edaed60628..00000000000
--- a/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter_unittest.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 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 <string>
-
-#include "base/test/scoped_task_environment.h"
-#include "content/child/child_process.h"
-#include "content/renderer/media/pepper/video_track_to_pepper_adapter.h"
-#include "content/renderer/media/stream/mock_media_stream_registry.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/web/web_heap.h"
-
-namespace content {
-
-static const std::string kTestStreamUrl = "stream_url";
-static const std::string kTestVideoTrackId = "video_track_id";
-static const std::string kUnknownStreamUrl = "unknown_stream_url";
-
-class VideoTrackToPepperAdapterTest : public ::testing::Test,
- public FrameReaderInterface {
- public:
- VideoTrackToPepperAdapterTest() : registry_(new MockMediaStreamRegistry()) {
- handler_.reset(new VideoTrackToPepperAdapter(registry_.get()));
- registry_->Init(kTestStreamUrl);
- registry_->AddVideoTrack(kTestVideoTrackId);
- EXPECT_FALSE(handler_->GetFirstVideoTrack(kTestStreamUrl).IsNull());
- }
-
- MOCK_METHOD1(GotFrame, void(const scoped_refptr<media::VideoFrame>&));
-
- void TearDown() override {
- registry_.reset();
- handler_.reset();
- blink::WebHeap::CollectAllGarbageForTesting();
- }
-
- void DeliverFrameForTesting(const scoped_refptr<media::VideoFrame>& frame) {
- handler_->DeliverFrameForTesting(this, frame);
- }
-
- protected:
- // A ChildProcess is needed to fool the Tracks and Sources below into
- // believing they are on the right threads. A ScopedTaskEnvironment must be
- // instantiated before ChildProcess to prevent it from leaking a
- // TaskScheduler.
- const base::test::ScopedTaskEnvironment scoped_task_environment_;
- const ChildProcess child_process_;
- std::unique_ptr<VideoTrackToPepperAdapter> handler_;
- std::unique_ptr<MockMediaStreamRegistry> registry_;
-};
-
-// Open |handler_| and send a VideoFrame to be received at the other side.
-TEST_F(VideoTrackToPepperAdapterTest, OpenClose) {
- // Unknow url will return false.
- EXPECT_FALSE(handler_->Open(kUnknownStreamUrl, this));
- EXPECT_TRUE(handler_->Open(kTestStreamUrl, this));
-
- const base::TimeDelta ts = base::TimeDelta::FromMilliseconds(789012);
- const scoped_refptr<media::VideoFrame> captured_frame =
- media::VideoFrame::CreateBlackFrame(gfx::Size(640, 360));
- captured_frame->set_timestamp(ts);
-
- EXPECT_CALL(*this, GotFrame(captured_frame));
- DeliverFrameForTesting(captured_frame);
-
- EXPECT_FALSE(handler_->Close(nullptr));
- EXPECT_TRUE(handler_->Close(this));
-}
-
-TEST_F(VideoTrackToPepperAdapterTest, OpenWithoutClose) {
- EXPECT_TRUE(handler_->Open(kTestStreamUrl, this));
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/render_media_log_unittest.cc b/chromium/content/renderer/media/render_media_log_unittest.cc
index 9f5d15d5daa..ae362c89776 100644
--- a/chromium/content/renderer/media/render_media_log_unittest.cc
+++ b/chromium/content/renderer/media/render_media_log_unittest.cc
@@ -5,7 +5,7 @@
#include <tuple>
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/test_mock_time_task_runner.h"
#include "content/common/view_messages.h"
@@ -57,7 +57,7 @@ class RenderMediaLogTest : public testing::Test {
}
private:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
MockRenderThread render_thread_;
base::SimpleTestTickClock tick_clock_;
RenderMediaLog log_;
diff --git a/chromium/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc b/chromium/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc
index 6da7d4f72ea..8cb93d6ecbe 100644
--- a/chromium/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc
+++ b/chromium/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc
@@ -5,8 +5,8 @@
#include "content/renderer/media/renderer_webaudiodevice_impl.h"
#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
+#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "content/renderer/media/audio/audio_device_factory.h"
#include "media/base/audio_capturer_source.h"
@@ -68,7 +68,8 @@ class RendererWebAudioDeviceImplTest
void SetupDevice(blink::WebAudioLatencyHint latencyHint) {
webaudio_device_.reset(new RendererWebAudioDeviceImplUnderTest(
media::CHANNEL_LAYOUT_MONO, 1, latencyHint, this, 0));
- webaudio_device_->SetMediaTaskRunnerForTesting(message_loop_.task_runner());
+ webaudio_device_->SetMediaTaskRunnerForTesting(
+ task_environment_.GetMainThreadTaskRunner());
}
void SetupDevice(media::ChannelLayout layout, int channels) {
@@ -77,7 +78,8 @@ class RendererWebAudioDeviceImplTest
blink::WebAudioLatencyHint(
blink::WebAudioLatencyHint::kCategoryInteractive),
this, 0));
- webaudio_device_->SetMediaTaskRunnerForTesting(message_loop_.task_runner());
+ webaudio_device_->SetMediaTaskRunnerForTesting(
+ task_environment_.GetMainThreadTaskRunner());
}
MOCK_METHOD2(CreateAudioCapturerSource,
@@ -114,7 +116,7 @@ class RendererWebAudioDeviceImplTest
void TearDown() override { webaudio_device_.reset(); }
std::unique_ptr<RendererWebAudioDeviceImpl> webaudio_device_;
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
};
TEST_F(RendererWebAudioDeviceImplTest, ChannelLayout) {
diff --git a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
index 1080b18e7c5..249e16b8641 100644
--- a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
+++ b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
@@ -127,12 +127,14 @@ void RendererWebMediaPlayerDelegate::DidPictureInPictureModeStart(
int delegate_id,
const viz::SurfaceId& surface_id,
const gfx::Size& natural_size,
- blink::WebMediaPlayer::PipWindowOpenedCallback callback) {
+ blink::WebMediaPlayer::PipWindowOpenedCallback callback,
+ bool show_play_pause_button) {
int request_id = next_picture_in_picture_callback_id_++;
enter_picture_in_picture_callback_map_.insert(
std::make_pair(request_id, std::move(callback)));
Send(new MediaPlayerDelegateHostMsg_OnPictureInPictureModeStarted(
- routing_id(), delegate_id, surface_id, natural_size, request_id));
+ routing_id(), delegate_id, surface_id, natural_size, request_id,
+ show_play_pause_button));
}
void RendererWebMediaPlayerDelegate::DidPictureInPictureModeEnd(
@@ -155,9 +157,11 @@ void RendererWebMediaPlayerDelegate::DidSetPictureInPictureCustomControls(
void RendererWebMediaPlayerDelegate::DidPictureInPictureSurfaceChange(
int delegate_id,
const viz::SurfaceId& surface_id,
- const gfx::Size& natural_size) {
+ const gfx::Size& natural_size,
+ bool show_play_pause_button) {
Send(new MediaPlayerDelegateHostMsg_OnPictureInPictureSurfaceChanged(
- routing_id(), delegate_id, surface_id, natural_size));
+ routing_id(), delegate_id, surface_id, natural_size,
+ show_play_pause_button));
}
void RendererWebMediaPlayerDelegate::
diff --git a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
index cb3e715174d..7fd65bb2a0b 100644
--- a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
+++ b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -69,14 +69,16 @@ class CONTENT_EXPORT RendererWebMediaPlayerDelegate
int delegate_id,
const viz::SurfaceId&,
const gfx::Size&,
- blink::WebMediaPlayer::PipWindowOpenedCallback) override;
+ blink::WebMediaPlayer::PipWindowOpenedCallback,
+ bool show_play_pause_button) override;
void DidPictureInPictureModeEnd(int delegate_id, base::OnceClosure) override;
void DidSetPictureInPictureCustomControls(
int delegate_id,
const std::vector<blink::PictureInPictureControlInfo>& controls) override;
void DidPictureInPictureSurfaceChange(int delegate_id,
const viz::SurfaceId&,
- const gfx::Size&) override;
+ const gfx::Size&,
+ bool show_play_pause_button) override;
void RegisterPictureInPictureWindowResizeCallback(
int player_id,
blink::WebMediaPlayer::PipWindowResizedCallback) override;
diff --git a/chromium/content/renderer/media/stream/aec_dump_message_filter.cc b/chromium/content/renderer/media/stream/aec_dump_message_filter.cc
index 5c1312e963b..bb1f4296661 100644
--- a/chromium/content/renderer/media/stream/aec_dump_message_filter.cc
+++ b/chromium/content/renderer/media/stream/aec_dump_message_filter.cc
@@ -148,7 +148,7 @@ void AecDumpMessageFilter::DoEnableAecDump(
int id,
IPC::PlatformFileForTransit file_handle) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- DelegateMap::iterator it = delegates_.find(id);
+ auto it = delegates_.find(id);
if (it != delegates_.end()) {
it->second->OnAecDumpFile(file_handle);
} else {
@@ -161,16 +161,14 @@ void AecDumpMessageFilter::DoEnableAecDump(
void AecDumpMessageFilter::DoDisableAecDump() {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- for (DelegateMap::iterator it = delegates_.begin();
- it != delegates_.end(); ++it) {
+ for (auto it = delegates_.begin(); it != delegates_.end(); ++it) {
it->second->OnDisableAecDump();
}
}
void AecDumpMessageFilter::DoChannelClosingOnDelegates() {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- for (DelegateMap::iterator it = delegates_.begin();
- it != delegates_.end(); ++it) {
+ for (auto it = delegates_.begin(); it != delegates_.end(); ++it) {
it->second->OnIpcClosing();
}
delegates_.clear();
@@ -179,8 +177,7 @@ void AecDumpMessageFilter::DoChannelClosingOnDelegates() {
int AecDumpMessageFilter::GetIdForDelegate(
AecDumpMessageFilter::AecDumpDelegate* delegate) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- for (DelegateMap::iterator it = delegates_.begin();
- it != delegates_.end(); ++it) {
+ for (auto it = delegates_.begin(); it != delegates_.end(); ++it) {
if (it->second == delegate)
return it->first;
}
diff --git a/chromium/content/renderer/media/stream/apply_constraints_processor.cc b/chromium/content/renderer/media/stream/apply_constraints_processor.cc
index 874d3bd98b3..9d791cb6b84 100644
--- a/chromium/content/renderer/media/stream/apply_constraints_processor.cc
+++ b/chromium/content/renderer/media/stream/apply_constraints_processor.cc
@@ -256,8 +256,6 @@ VideoCaptureSettings ApplyConstraintsProcessor::SelectVideoSettings(
DCHECK(video_source_->GetCurrentCaptureParams());
VideoDeviceCaptureCapabilities video_capabilities;
- video_capabilities.power_line_capabilities.push_back(
- video_source_->GetCurrentCaptureParams()->power_line_frequency);
video_capabilities.noise_reduction_capabilities.push_back(
GetCurrentVideoTrack()->noise_reduction());
video_capabilities.device_capabilities.push_back(
diff --git a/chromium/content/renderer/media/stream/local_media_stream_audio_source.cc b/chromium/content/renderer/media/stream/local_media_stream_audio_source.cc
index 6b826e25c95..58a617f5072 100644
--- a/chromium/content/renderer/media/stream/local_media_stream_audio_source.cc
+++ b/chromium/content/renderer/media/stream/local_media_stream_audio_source.cc
@@ -4,12 +4,27 @@
#include "content/renderer/media/stream/local_media_stream_audio_source.h"
+#include "build/build_config.h"
#include "content/renderer/media/audio/audio_device_factory.h"
#include "content/renderer/media/webrtc_logging.h"
#include "content/renderer/render_frame_impl.h"
namespace content {
+// TODO(crbug.com/638081): Like in ProcessedLocalAudioSource::GetBufferSize(),
+// we should re-evaluate whether Android needs special treatment here. Or,
+// perhaps we should just DCHECK_GT(device...frames_per_buffer, 0)?
+#if defined(OS_ANDROID)
+static constexpr int kFallbackAudioLatencyMs = 20;
+#else
+static constexpr int kFallbackAudioLatencyMs = 10;
+#endif
+
+static_assert(kFallbackAudioLatencyMs >= 0,
+ "Audio latency has to be non-negative.");
+static_assert(kFallbackAudioLatencyMs <= kMaxAudioLatencyMs,
+ "Audio latency can cause overflow.");
+
LocalMediaStreamAudioSource::LocalMediaStreamAudioSource(
int consumer_render_frame_id,
const MediaStreamDevice& device,
@@ -27,15 +42,8 @@ LocalMediaStreamAudioSource::LocalMediaStreamAudioSource(
// If the device buffer size was not provided, use a default.
int frames_per_buffer = device.input.frames_per_buffer();
if (frames_per_buffer <= 0) {
-// TODO(miu): Like in ProcessedLocalAudioSource::GetBufferSize(), we should
-// re-evaluate whether Android needs special treatment here. Or, perhaps we
-// should just DCHECK_GT(device...frames_per_buffer, 0)?
-// http://crbug.com/638081
-#if defined(OS_ANDROID)
- frames_per_buffer = device.input.sample_rate() / 50; // 20 ms
-#else
- frames_per_buffer = device.input.sample_rate() / 100; // 10 ms
-#endif
+ frames_per_buffer =
+ (device.input.sample_rate() * kFallbackAudioLatencyMs) / 1000;
}
SetFormat(media::AudioParameters(
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_processor.cc b/chromium/content/renderer/media/stream/media_stream_audio_processor.cc
index 40af27f948d..c9a3b8ba93c 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_processor.cc
+++ b/chromium/content/renderer/media/stream/media_stream_audio_processor.cc
@@ -22,7 +22,9 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
+#include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/media/webrtc/webrtc_audio_device_impl.h"
#include "media/base/audio_converter.h"
#include "media/base/audio_fifo.h"
@@ -30,6 +32,8 @@
#include "media/base/channel_layout.h"
#include "media/webrtc/echo_information.h"
#include "media/webrtc/webrtc_switches.h"
+#include "third_party/webrtc/api/audio/echo_canceller3_config.h"
+#include "third_party/webrtc/api/audio/echo_canceller3_config_json.h"
#include "third_party/webrtc/api/audio/echo_canceller3_factory.h"
#include "third_party/webrtc/api/mediaconstraintsinterface.h"
#include "third_party/webrtc/modules/audio_processing/include/audio_processing_statistics.h"
@@ -44,7 +48,8 @@ namespace {
using webrtc::AudioProcessing;
using webrtc::NoiseSuppression;
-const int kAudioProcessingNumberOfChannels = 1;
+constexpr int kAudioProcessingNumberOfChannels = 1;
+constexpr int kBuffersPerSecond = 100; // 10 ms per buffer.
AudioProcessing::ChannelLayout MapLayout(media::ChannelLayout media_layout) {
switch (media_layout) {
@@ -272,6 +277,7 @@ MediaStreamAudioProcessor::MediaStreamAudioProcessor(
const AudioProcessingProperties& properties,
WebRtcPlayoutDataSource* playout_data_source)
: render_delay_ms_(0),
+ audio_delay_stats_reporter_(kBuffersPerSecond),
playout_data_source_(playout_data_source),
main_thread_runner_(base::ThreadTaskRunnerHandle::Get()),
audio_mirroring_(false),
@@ -471,11 +477,6 @@ void MediaStreamAudioProcessor::OnPlayoutData(media::AudioBus* audio_bus,
int sample_rate,
int audio_delay_milliseconds) {
DCHECK(render_thread_checker_.CalledOnValidThread());
-#if defined(OS_ANDROID)
- DCHECK(!audio_processing_->echo_cancellation()->is_enabled());
-#else
- DCHECK(!audio_processing_->echo_control_mobile()->is_enabled());
-#endif
DCHECK_GE(audio_bus->channels(), 1);
DCHECK_LE(audio_bus->channels(), 2);
int frames_per_10_ms = sample_rate / 100;
@@ -603,11 +604,22 @@ void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
if (properties.echo_cancellation_type ==
EchoCancellationType::kEchoCancellationAec3) {
webrtc::EchoCanceller3Config aec3_config;
- aec3_config.ep_strength.bounded_erl =
+ base::Optional<std::string> audio_processing_platform_config_json =
+ GetContentClient()
+ ->renderer()
+ ->WebRTCPlatformSpecificAudioProcessingConfiguration();
+ if (audio_processing_platform_config_json) {
+ aec3_config = webrtc::Aec3ConfigFromJsonString(
+ *audio_processing_platform_config_json);
+ bool config_parameters_already_valid =
+ webrtc::EchoCanceller3Config::Validate(&aec3_config);
+ RTC_DCHECK(config_parameters_already_valid);
+ }
+ aec3_config.ep_strength.bounded_erl |=
base::FeatureList::IsEnabled(features::kWebRtcAecBoundedErlSetup);
- aec3_config.echo_removal_control.has_clock_drift =
+ aec3_config.echo_removal_control.has_clock_drift |=
base::FeatureList::IsEnabled(features::kWebRtcAecClockDriftSetup);
- aec3_config.echo_audibility.use_stationary_properties =
+ aec3_config.echo_audibility.use_stationary_properties |=
base::FeatureList::IsEnabled(features::kWebRtcAecNoiseTransparency);
ap_builder.SetEchoControlFactory(
@@ -665,19 +677,13 @@ void MediaStreamAudioProcessor::InitializeCaptureFifo(
DCHECK(input_format.IsValid());
input_format_ = input_format;
- // TODO(ajm): For now, we assume fixed parameters for the output when audio
- // processing is enabled, to match the previous behavior. We should either
- // use the input parameters (in which case, audio processing will convert
- // at output) or ideally, have a backchannel from the sink to know what
- // format it would prefer.
-#if defined(OS_ANDROID)
- int audio_processing_sample_rate = AudioProcessing::kSampleRate16kHz;
-#else
- int audio_processing_sample_rate = AudioProcessing::kSampleRate48kHz;
-#endif
- const int output_sample_rate = audio_processing_ ?
- audio_processing_sample_rate :
- input_format.sample_rate();
+ // TODO(crbug/881275): For now, we assume fixed parameters for the output when
+ // audio processing is enabled, to match the previous behavior. We should
+ // either use the input parameters (in which case, audio processing will
+ // convert at output) or ideally, have a backchannel from the sink to know
+ // what format it would prefer.
+ const int output_sample_rate = audio_processing_ ? kAudioProcessingSampleRate
+ : input_format.sample_rate();
media::ChannelLayout output_channel_layout = audio_processing_ ?
media::GuessChannelLayout(kAudioProcessingNumberOfChannels) :
input_format.channel_layout();
@@ -751,13 +757,16 @@ int MediaStreamAudioProcessor::ProcessData(const float* const* process_ptrs,
"capture_delay_ms", capture_delay_ms, "render_delay_ms",
render_delay_ms);
- int total_delay_ms = capture_delay_ms + render_delay_ms;
+ const int total_delay_ms = capture_delay_ms + render_delay_ms;
if (total_delay_ms > 300 && large_delay_log_count_ < 10) {
LOG(WARNING) << "Large audio delay, capture delay: " << capture_delay_ms
<< "ms; render delay: " << render_delay_ms << "ms";
++large_delay_log_count_;
}
+ audio_delay_stats_reporter_.ReportDelay(
+ capture_delay, base::TimeDelta::FromMilliseconds(render_delay_ms));
+
webrtc::AudioProcessing* ap = audio_processing_.get();
ap->set_stream_delay_ms(total_delay_ms);
@@ -798,7 +807,8 @@ int MediaStreamAudioProcessor::ProcessData(const float* const* process_ptrs,
void MediaStreamAudioProcessor::UpdateAecStats() {
DCHECK(main_thread_runner_->BelongsToCurrentThread());
if (echo_information_)
- echo_information_->UpdateAecStats(audio_processing_->echo_cancellation());
+ echo_information_->UpdateAecStats(
+ audio_processing_->GetStatistics(true /* has_remote_tracks */));
}
} // namespace content
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_processor.h b/chromium/content/renderer/media/stream/media_stream_audio_processor.h
index edf302f3460..f105c489239 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_processor.h
+++ b/chromium/content/renderer/media/stream/media_stream_audio_processor.h
@@ -23,6 +23,7 @@
#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
#include "content/renderer/media/webrtc/webrtc_audio_device_impl.h"
#include "media/base/audio_converter.h"
+#include "media/webrtc/audio_delay_stats_reporter.h"
#include "third_party/webrtc/api/mediastreaminterface.h"
#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h"
#include "third_party/webrtc/rtc_base/task_queue.h"
@@ -164,6 +165,9 @@ class CONTENT_EXPORT MediaStreamAudioProcessor
// both the capture audio thread and the render audio thread.
base::subtle::Atomic32 render_delay_ms_;
+ // For reporting audio delay stats.
+ media::AudioDelayStatsReporter audio_delay_stats_reporter_;
+
// Low-priority task queue for doing AEC dump recordings. It has to
// out-live audio_processing_ and be created/destroyed from the same
// thread.
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_processor_options.cc b/chromium/content/renderer/media/stream/media_stream_audio_processor_options.cc
index eceaaee43d2..e6b525b05bb 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_processor_options.cc
+++ b/chromium/content/renderer/media/stream/media_stream_audio_processor_options.cc
@@ -91,25 +91,11 @@ AudioProcessingProperties::ToAudioProcessingSettings() const {
}
void EnableEchoCancellation(AudioProcessing* audio_processing) {
- // TODO(bugs.webrtc.org/9535): Remove double-booking AEC toggle when the
- // config applies (from 2018-08-16).
webrtc::AudioProcessing::Config apm_config = audio_processing->GetConfig();
apm_config.echo_canceller.enabled = true;
#if defined(OS_ANDROID)
- // Mobile devices are using AECM.
- CHECK_EQ(0, audio_processing->echo_control_mobile()->set_routing_mode(
- webrtc::EchoControlMobile::kSpeakerphone));
- CHECK_EQ(0, audio_processing->echo_control_mobile()->Enable(true));
apm_config.echo_canceller.mobile_mode = true;
#else
- int err = audio_processing->echo_cancellation()->set_suppression_level(
- webrtc::EchoCancellation::kHighSuppression);
-
- // Enable the metrics for AEC.
- err |= audio_processing->echo_cancellation()->enable_metrics(true);
- err |= audio_processing->echo_cancellation()->enable_delay_logging(true);
- err |= audio_processing->echo_cancellation()->Enable(true);
- CHECK_EQ(err, 0);
apm_config.echo_canceller.mobile_mode = false;
#endif
audio_processing->ApplyConfig(apm_config);
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_processor_options.h b/chromium/content/renderer/media/stream/media_stream_audio_processor_options.h
index c730fab589e..f6d64874b3e 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_processor_options.h
+++ b/chromium/content/renderer/media/stream/media_stream_audio_processor_options.h
@@ -11,6 +11,7 @@
#include "base/files/file.h"
#include "base/macros.h"
#include "base/threading/thread_checker.h"
+#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/common/media_stream_request.h"
#include "media/audio/audio_processing.h"
@@ -31,6 +32,13 @@ namespace content {
using webrtc::AudioProcessing;
+static constexpr int kAudioProcessingSampleRate =
+#if defined(OS_ANDROID)
+ AudioProcessing::kSampleRate16kHz;
+#else
+ AudioProcessing::kSampleRate48kHz;
+#endif
+
// Simple struct with audio-processing properties.
struct CONTENT_EXPORT AudioProcessingProperties {
enum class EchoCancellationType {
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_processor_unittest.cc b/chromium/content/renderer/media/stream/media_stream_audio_processor_unittest.cc
index 19dff280a73..a36eac22e4b 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_processor_unittest.cc
+++ b/chromium/content/renderer/media/stream/media_stream_audio_processor_unittest.cc
@@ -44,11 +44,6 @@ namespace content {
namespace {
-#if defined(ANDROID)
-const int kAudioProcessingSampleRate = 16000;
-#else
-const int kAudioProcessingSampleRate = 48000;
-#endif
const int kAudioProcessingNumberOfChannel = 1;
// The number of packers used for testing.
@@ -122,13 +117,7 @@ class MediaStreamAudioProcessorTest : public ::testing::Test {
// |audio_processor| does nothing when the audio processing is off in
// the processor.
webrtc::AudioProcessing* ap = audio_processor->audio_processing_.get();
-#if defined(OS_ANDROID)
- const bool is_aec_enabled = ap && ap->echo_control_mobile()->is_enabled();
- // AEC should be turned off for mobiles.
- DCHECK(!ap || !ap->echo_cancellation()->is_enabled());
-#else
- const bool is_aec_enabled = ap && ap->echo_cancellation()->is_enabled();
-#endif
+ const bool is_aec_enabled = ap && ap->GetConfig().echo_canceller.enabled;
if (is_aec_enabled) {
if (params.channels() > kMaxNumberOfPlayoutDataChannels) {
for (int i = 0; i < kMaxNumberOfPlayoutDataChannels; ++i) {
@@ -164,24 +153,19 @@ class MediaStreamAudioProcessorTest : public ::testing::Test {
void VerifyDefaultComponents(MediaStreamAudioProcessor* audio_processor) {
webrtc::AudioProcessing* audio_processing =
audio_processor->audio_processing_.get();
+ const webrtc::AudioProcessing::Config config =
+ audio_processing->GetConfig();
+ EXPECT_TRUE(config.echo_canceller.enabled);
#if defined(OS_ANDROID)
- EXPECT_TRUE(audio_processing->echo_control_mobile()->is_enabled());
- EXPECT_TRUE(audio_processing->echo_control_mobile()->routing_mode() ==
- webrtc::EchoControlMobile::kSpeakerphone);
- EXPECT_FALSE(audio_processing->echo_cancellation()->is_enabled());
+ EXPECT_TRUE(config.echo_canceller.mobile_mode);
#else
- EXPECT_TRUE(audio_processing->echo_cancellation()->is_enabled());
- EXPECT_TRUE(audio_processing->echo_cancellation()->suppression_level() ==
- webrtc::EchoCancellation::kHighSuppression);
- EXPECT_TRUE(audio_processing->echo_cancellation()->are_metrics_enabled());
- EXPECT_TRUE(
- audio_processing->echo_cancellation()->is_delay_logging_enabled());
+ EXPECT_FALSE(config.echo_canceller.mobile_mode);
#endif
+ EXPECT_TRUE(config.high_pass_filter.enabled);
EXPECT_TRUE(audio_processing->noise_suppression()->is_enabled());
EXPECT_TRUE(audio_processing->noise_suppression()->level() ==
webrtc::NoiseSuppression::kHigh);
- EXPECT_TRUE(audio_processing->high_pass_filter()->is_enabled());
EXPECT_TRUE(audio_processing->gain_control()->is_enabled());
#if defined(OS_ANDROID)
EXPECT_TRUE(audio_processing->gain_control()->mode() ==
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_source.h b/chromium/content/renderer/media/stream/media_stream_audio_source.h
index cc55c329096..dfcbfcc7e62 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_source.h
+++ b/chromium/content/renderer/media/stream/media_stream_audio_source.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_AUDIO_SOURCE_H_
#define CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_AUDIO_SOURCE_H_
+#include <limits>
#include <memory>
#include <string>
@@ -14,6 +15,7 @@
#include "content/common/content_export.h"
#include "content/renderer/media/stream/media_stream_audio_deliverer.h"
#include "content/renderer/media/stream/media_stream_source.h"
+#include "media/base/limits.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
@@ -23,6 +25,15 @@ class SingleThreadTaskRunner;
namespace content {
+// Define a max limit on the latency equivalent to 5 seconds. This limit is
+// meant to avoid overflows when deriving buffersize or sample rate from the
+// latency.
+static constexpr int kMaxAudioLatencyMs = 5000;
+
+static_assert(std::numeric_limits<int>::max() / media::limits::kMaxSampleRate >
+ kMaxAudioLatencyMs,
+ "The maxium audio latency can cause overflow.");
+
class MediaStreamAudioTrack;
// Represents a source of audio, and manages the delivery of audio data between
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_unittest.cc b/chromium/content/renderer/media/stream/media_stream_audio_unittest.cc
index abddd1deed5..4c881a02674 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_unittest.cc
+++ b/chromium/content/renderer/media/stream/media_stream_audio_unittest.cc
@@ -5,9 +5,9 @@
#include <stdint.h>
#include "base/atomicops.h"
-#include "base/message_loop/message_loop.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_task_environment.h"
#include "base/test/test_timeouts.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_checker.h"
@@ -267,7 +267,7 @@ class MediaStreamAudioTest : public ::testing::Test {
blink::WebMediaStreamSource blink_audio_source_;
blink::WebMediaStreamTrack blink_audio_track_;
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
};
// Tests that a simple source-->track-->sink connection and audio data flow
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util.cc
index d4111ac35b1..5708faed1f7 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util.cc
@@ -152,14 +152,12 @@ AudioCaptureSettings::AudioCaptureSettings(const char* failed_constraint_name)
AudioCaptureSettings::AudioCaptureSettings(
std::string device_id,
- const media::AudioParameters& audio_parameters,
bool enable_hotword,
bool disable_local_echo,
bool enable_automatic_output_device_selection,
const AudioProcessingProperties& audio_processing_properties)
: failed_constraint_name_(nullptr),
device_id_(std::move(device_id)),
- audio_parameters_(audio_parameters),
hotword_enabled_(enable_hotword),
disable_local_echo_(disable_local_echo),
render_to_associated_sink_(enable_automatic_output_device_selection),
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util.h b/chromium/content/renderer/media/stream/media_stream_constraints_util.h
index fd2267d2086..4bcbf1068d6 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util.h
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util.h
@@ -36,8 +36,8 @@ class NumericRangeSet;
// The following fields are used to control MediaStreamVideoSource objects:
// * device_id: used for device selection and obtained from the deviceId
// * capture_params: used to initialize video capture. Its values are obtained
-// from the width, height, aspectRatio, frame_rate, googPowerLineFrequency,
-// and googNoiseReduction constraints.
+// from the width, height, aspectRatio, frame_rate, and googNoiseReduction
+// constraints.
// The following fields are used to control MediaStreamVideoTrack objects:
// * track_adapter_settings: All track objects use a VideoTrackAdapter object
// that may perform cropping and frame-rate adjustment. This field contains
@@ -104,10 +104,6 @@ class CONTENT_EXPORT VideoCaptureSettings {
DCHECK(HasValue());
return capture_params_.resolution_change_policy;
}
- media::PowerLineFrequency PowerLineFrequency() const {
- DCHECK(HasValue());
- return capture_params_.power_line_frequency;
- }
// Other accessors.
const char* failed_constraint_name() const { return failed_constraint_name_; }
@@ -186,7 +182,6 @@ class CONTENT_EXPORT AudioCaptureSettings {
// Creates an object with the given values.
explicit AudioCaptureSettings(
std::string device_id,
- const media::AudioParameters& audio_parameters,
bool enable_hotword,
bool disable_local_echo,
bool enable_automatic_output_device_selection,
@@ -204,11 +199,6 @@ class CONTENT_EXPORT AudioCaptureSettings {
DCHECK(HasValue());
return device_id_;
}
- // This field is meaningless in content capture.
- const media::AudioParameters& device_parameters() const {
- DCHECK(HasValue());
- return audio_parameters_;
- }
bool hotword_enabled() const {
DCHECK(HasValue());
return hotword_enabled_;
@@ -229,7 +219,6 @@ class CONTENT_EXPORT AudioCaptureSettings {
private:
const char* failed_constraint_name_;
std::string device_id_;
- media::AudioParameters audio_parameters_;
bool hotword_enabled_;
bool disable_local_echo_;
bool render_to_associated_sink_;
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.cc
index ac494175f9c..735fda4877f 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.cc
@@ -400,9 +400,9 @@ class SingleDeviceCandidateSet {
basic_constraint_set, is_device_capture,
should_disable_hardware_noise_suppression);
- return AudioCaptureSettings(
- std::move(device_id), parameters_, hotword_enabled, disable_local_echo,
- render_to_associated_sink, audio_processing_properties);
+ return AudioCaptureSettings(std::move(device_id), hotword_enabled,
+ disable_local_echo, render_to_associated_sink,
+ audio_processing_properties);
}
private:
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
index bce1de0a82c..934644c3811 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
@@ -9,7 +9,7 @@
#include <string>
#include <utility>
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "content/renderer/media/stream/local_media_stream_audio_source.h"
#include "content/renderer/media/stream/media_stream_audio_source.h"
#include "content/renderer/media/stream/media_stream_source.h"
@@ -343,12 +343,6 @@ class MediaStreamConstraintsUtilAudioTest
void CheckDevice(const AudioDeviceCaptureCapability& expected_device,
const AudioCaptureSettings& result) {
EXPECT_EQ(expected_device.DeviceID(), result.device_id());
- EXPECT_EQ(expected_device.Parameters().sample_rate(),
- result.device_parameters().sample_rate());
- EXPECT_EQ(expected_device.Parameters().channels(),
- result.device_parameters().channels());
- EXPECT_EQ(expected_device.Parameters().effects(),
- result.device_parameters().effects());
}
void CheckDeviceDefaults(const AudioCaptureSettings& result) {
@@ -473,7 +467,7 @@ class MediaStreamConstraintsUtilAudioTest
private:
// Required for tests involving a MediaStreamAudioSource.
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
MockPeerConnectionDependencyFactory pc_factory_;
};
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.cc
index 0062de4435e..8be1cee6042 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.cc
@@ -14,6 +14,7 @@
#include "content/renderer/media/stream/media_stream_constraints_util_sets.h"
#include "content/renderer/media/stream/media_stream_video_source.h"
#include "media/base/limits.h"
+#include "media/mojo/interfaces/display_media_information.mojom.h"
#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -26,8 +27,8 @@ using DoubleRangeSet = media_constraints::NumericRangeSet<double>;
// Number of default settings to be used as final tie-breaking criteria for
// settings that are equally good at satisfying constraints:
-// device ID, power-line frequency, noise reduction, resolution and frame rate.
-const int kNumDefaultDistanceEntries = 5;
+// device ID, noise reduction, resolution and frame rate.
+const int kNumDefaultDistanceEntries = 4;
// The minimum aspect ratio to be supported by sources.
const double kMinSourceAspectRatio = 0.05;
@@ -53,21 +54,16 @@ struct Candidate {
const std::string& group_id,
const media::VideoCaptureFormat& format,
media::VideoFacingMode facing_mode,
- media::PowerLineFrequency power_line_frequency,
const base::Optional<bool>& noise_reduction)
: device_id_(device_id),
group_id_(group_id),
format_(format),
facing_mode_(facing_mode),
- power_line_frequency_(power_line_frequency),
noise_reduction_(noise_reduction) {}
// These accessor-like methods transform types to what Blink constraint
// classes expect.
blink::WebString GetFacingMode() const { return ToWebString(facing_mode_); }
- long GetPowerLineFrequency() const {
- return static_cast<long>(power_line_frequency_);
- }
blink::WebString GetDeviceId() const {
return blink::WebString::FromASCII(device_id_.data());
}
@@ -83,9 +79,6 @@ struct Candidate {
const std::string& device_id() const { return device_id_; }
const std::string& group_id() const { return group_id_; }
media::VideoFacingMode facing_mode() const { return facing_mode_; }
- media::PowerLineFrequency power_line_frequency() const {
- return power_line_frequency_;
- }
const base::Optional<bool>& noise_reduction() const {
return noise_reduction_;
}
@@ -95,7 +88,6 @@ struct Candidate {
std::string group_id_;
media::VideoCaptureFormat format_;
media::VideoFacingMode facing_mode_;
- media::PowerLineFrequency power_line_frequency_;
base::Optional<bool> noise_reduction_;
};
@@ -184,7 +176,6 @@ VideoCaptureSettings ComputeVideoDeviceCaptureSettings(
const blink::WebMediaTrackConstraintSet& basic_constraint_set) {
media::VideoCaptureParams capture_params;
capture_params.requested_format = candidate.format();
- capture_params.power_line_frequency = candidate.power_line_frequency();
auto track_adapter_settings = SelectVideoTrackAdapterSettings(
basic_constraint_set, constrained_format.constrained_resolution(),
constrained_format.constrained_frame_rate(),
@@ -408,32 +399,6 @@ double AspectRatioConstraintSourceDistance(
return 0.0;
}
-// Returns a custom distance function suitable for the googPowerLineFrequency
-// constraint, given a |constraint| and a candidate value |source_value|.
-// The distance is HUGE_VAL if |source_value| cannot satisfy |constraint|.
-// Otherwise, the distance is zero.
-double PowerLineFrequencyConstraintSourceDistance(
- const blink::LongConstraint& constraint,
- media::PowerLineFrequency source_value,
- const char** failed_constraint_name) {
- bool constraint_has_min = ConstraintHasMin(constraint);
- bool constraint_has_max = ConstraintHasMax(constraint);
- long constraint_min = constraint_has_min ? ConstraintMin(constraint) : -1L;
- long constraint_max = constraint_has_max ? ConstraintMax(constraint) : -1L;
- long source_value_long = static_cast<long>(source_value);
-
- if ((constraint_has_max && source_value_long > constraint_max) ||
- (constraint_has_min && source_value_long < constraint_min) ||
- (constraint_has_min && constraint_has_max &&
- constraint_min > constraint_max)) {
- if (failed_constraint_name)
- *failed_constraint_name = constraint.GetName();
- return HUGE_VAL;
- }
-
- return 0.0;
-}
-
// Returns a custom distance function suitable for the googNoiseReduction
// constraint, given a |constraint| and a candidate value |value|.
// The distance is HUGE_VAL if |candidate_value| cannot satisfy |constraint|.
@@ -519,9 +484,6 @@ double CandidateSourceDistance(
failed_constraint_name) +
FormatSourceDistance(candidate.format(), constrained_format,
constraint_set, failed_constraint_name) +
- PowerLineFrequencyConstraintSourceDistance(
- constraint_set.goog_power_line_frequency,
- candidate.power_line_frequency(), failed_constraint_name) +
NoiseReductionConstraintSourceDistance(
constraint_set.goog_noise_reduction, candidate.noise_reduction(),
failed_constraint_name);
@@ -626,23 +588,6 @@ double FrameRateConstraintNativeFitnessDistance(
}
// Returns the fitness distance between |value| and |constraint| for the
-// googPowerLineFrequency constraint.
-// Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
-double PowerLineFrequencyConstraintFitnessDistance(
- long value,
- const blink::LongConstraint& constraint) {
- if (!constraint.HasIdeal())
- return 0.0;
-
- // This constraint is of type long, but it behaves as an enum. Thus, values
- // equal to ideal have fitness 0.0 and any other values have fitness 1.0.
- if (value == constraint.Ideal())
- return 0.0;
-
- return 1.0;
-}
-
-// Returns the fitness distance between |value| and |constraint| for the
// googNoiseReduction constraint.
// Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance.
double NoiseReductionConstraintFitnessDistance(
@@ -678,9 +623,6 @@ double CandidateFitnessDistance(
constraint_set.facing_mode);
fitness += StringConstraintFitnessDistance(candidate.GetVideoKind(),
constraint_set.video_kind);
- fitness += PowerLineFrequencyConstraintFitnessDistance(
- candidate.GetPowerLineFrequency(),
- constraint_set.goog_power_line_frequency);
fitness += NoiseReductionConstraintFitnessDistance(
candidate.noise_reduction(), constraint_set.goog_noise_reduction);
// No need to pass minimum value to compute fitness for range-based
@@ -740,14 +682,6 @@ void AppendDistanceFromDefault(
}
}
- // Prefer default power-line frequency.
- double power_line_frequency_distance =
- candidate.power_line_frequency() ==
- media::PowerLineFrequency::FREQUENCY_DEFAULT
- ? 0.0
- : HUGE_VAL;
- distance_vector->push_back(power_line_frequency_distance);
-
// Prefer not having a specific noise-reduction value and let the lower-layers
// implementation choose a noise-reduction strategy.
double noise_reduction_distance =
@@ -793,6 +727,33 @@ blink::WebMediaStreamTrack::FacingMode ToWebFacingMode(
}
}
+blink::WebMediaStreamTrack::DisplayCaptureSurfaceType ToWebDisplaySurface(
+ media::mojom::DisplayCaptureSurfaceType display_surface) {
+ switch (display_surface) {
+ case media::mojom::DisplayCaptureSurfaceType::MONITOR:
+ return blink::WebMediaStreamTrack::DisplayCaptureSurfaceType::kMonitor;
+ case media::mojom::DisplayCaptureSurfaceType::WINDOW:
+ return blink::WebMediaStreamTrack::DisplayCaptureSurfaceType::kWindow;
+ case media::mojom::DisplayCaptureSurfaceType::APPLICATION:
+ return blink::WebMediaStreamTrack::DisplayCaptureSurfaceType::
+ kApplication;
+ case media::mojom::DisplayCaptureSurfaceType::BROWSER:
+ return blink::WebMediaStreamTrack::DisplayCaptureSurfaceType::kBrowser;
+ }
+}
+
+blink::WebMediaStreamTrack::CursorCaptureType ToWebCursorCaptureType(
+ media::mojom::CursorCaptureType cursor) {
+ switch (cursor) {
+ case media::mojom::CursorCaptureType::NEVER:
+ return blink::WebMediaStreamTrack::CursorCaptureType::kNever;
+ case media::mojom::CursorCaptureType::ALWAYS:
+ return blink::WebMediaStreamTrack::CursorCaptureType::kAlways;
+ case media::mojom::CursorCaptureType::MOTION:
+ return blink::WebMediaStreamTrack::CursorCaptureType::kMotion;
+ }
+}
+
VideoDeviceCaptureCapabilities::VideoDeviceCaptureCapabilities() = default;
VideoDeviceCaptureCapabilities::VideoDeviceCaptureCapabilities(
VideoDeviceCaptureCapabilities&& other) = default;
@@ -849,75 +810,63 @@ VideoCaptureSettings SelectSettingsVideoDeviceCapture(
if (!constrained_format.ApplyConstraintSet(constraints.Basic()))
continue;
- for (auto& power_line_frequency : capabilities.power_line_capabilities) {
- double basic_power_line_frequency_distance =
- PowerLineFrequencyConstraintSourceDistance(
- constraints.Basic().goog_power_line_frequency,
- power_line_frequency, &failed_constraint_name);
- if (!std::isfinite(basic_power_line_frequency_distance))
+ for (auto& noise_reduction : capabilities.noise_reduction_capabilities) {
+ double basic_noise_reduction_distance =
+ NoiseReductionConstraintSourceDistance(
+ constraints.Basic().goog_noise_reduction, noise_reduction,
+ &failed_constraint_name);
+ if (!std::isfinite(basic_noise_reduction_distance))
continue;
- for (auto& noise_reduction :
- capabilities.noise_reduction_capabilities) {
- double basic_noise_reduction_distance =
- NoiseReductionConstraintSourceDistance(
- constraints.Basic().goog_noise_reduction, noise_reduction,
- &failed_constraint_name);
- if (!std::isfinite(basic_noise_reduction_distance))
- continue;
-
- // The candidate satisfies the basic constraint set.
- double candidate_basic_custom_distance =
- basic_device_distance + basic_format_distance +
- basic_power_line_frequency_distance +
- basic_noise_reduction_distance;
- DCHECK(std::isfinite(candidate_basic_custom_distance));
-
- // Temporary vector to save custom distances for advanced constraints.
- // Custom distances must be added to the candidate distance vector
- // after all the spec-mandated values.
- DistanceVector advanced_custom_distance_vector;
- Candidate candidate(device->device_id, device->group_id, format,
- device->facing_mode, power_line_frequency,
- noise_reduction);
- DistanceVector candidate_distance_vector;
- // First criteria for valid candidates is satisfaction of advanced
- // constraint sets.
- for (const auto& advanced_set : constraints.Advanced()) {
- double custom_distance = CandidateSourceDistance(
- candidate, constrained_format, advanced_set, nullptr);
- if (!constrained_format.ApplyConstraintSet(advanced_set))
- custom_distance = HUGE_VAL;
- advanced_custom_distance_vector.push_back(custom_distance);
- double spec_distance = std::isfinite(custom_distance) ? 0 : 1;
- candidate_distance_vector.push_back(spec_distance);
- }
-
- // Second criterion is fitness distance.
- candidate_distance_vector.push_back(CandidateFitnessDistance(
- candidate, constrained_format, constraints.Basic()));
-
- // Third criteria are custom distances to constraint sets.
- candidate_distance_vector.push_back(candidate_basic_custom_distance);
- std::copy(advanced_custom_distance_vector.begin(),
- advanced_custom_distance_vector.end(),
- std::back_inserter(candidate_distance_vector));
-
- // Fourth criteria is native fitness distance.
- candidate_distance_vector.push_back(CandidateNativeFitnessDistance(
- constrained_format, constraints.Basic()));
-
- // Final criteria are custom distances to default settings.
- AppendDistanceFromDefault(candidate, capabilities, default_width,
- default_height, default_frame_rate,
- &candidate_distance_vector);
-
- DCHECK_EQ(best_distance.size(), candidate_distance_vector.size());
- if (candidate_distance_vector < best_distance) {
- best_distance = candidate_distance_vector;
- result = ComputeVideoDeviceCaptureSettings(
- candidate, constrained_format, constraints.Basic());
- }
+ // The candidate satisfies the basic constraint set.
+ double candidate_basic_custom_distance = basic_device_distance +
+ basic_format_distance +
+ basic_noise_reduction_distance;
+ DCHECK(std::isfinite(candidate_basic_custom_distance));
+
+ // Temporary vector to save custom distances for advanced constraints.
+ // Custom distances must be added to the candidate distance vector
+ // after all the spec-mandated values.
+ DistanceVector advanced_custom_distance_vector;
+ Candidate candidate(device->device_id, device->group_id, format,
+ device->facing_mode, noise_reduction);
+ DistanceVector candidate_distance_vector;
+ // First criteria for valid candidates is satisfaction of advanced
+ // constraint sets.
+ for (const auto& advanced_set : constraints.Advanced()) {
+ double custom_distance = CandidateSourceDistance(
+ candidate, constrained_format, advanced_set, nullptr);
+ if (!constrained_format.ApplyConstraintSet(advanced_set))
+ custom_distance = HUGE_VAL;
+ advanced_custom_distance_vector.push_back(custom_distance);
+ double spec_distance = std::isfinite(custom_distance) ? 0 : 1;
+ candidate_distance_vector.push_back(spec_distance);
+ }
+
+ // Second criterion is fitness distance.
+ candidate_distance_vector.push_back(CandidateFitnessDistance(
+ candidate, constrained_format, constraints.Basic()));
+
+ // Third criteria are custom distances to constraint sets.
+ candidate_distance_vector.push_back(candidate_basic_custom_distance);
+ std::copy(advanced_custom_distance_vector.begin(),
+ advanced_custom_distance_vector.end(),
+ std::back_inserter(candidate_distance_vector));
+
+ // Fourth criteria is native fitness distance.
+ candidate_distance_vector.push_back(CandidateNativeFitnessDistance(
+ constrained_format, constraints.Basic()));
+
+ // Final criteria are custom distances to default settings.
+ AppendDistanceFromDefault(candidate, capabilities, default_width,
+ default_height, default_frame_rate,
+ &candidate_distance_vector);
+
+ DCHECK_EQ(best_distance.size(), candidate_distance_vector.size());
+ if (candidate_distance_vector < best_distance) {
+ best_distance = candidate_distance_vector;
+ result = ComputeVideoDeviceCaptureSettings(
+ candidate, constrained_format, constraints.Basic());
}
}
}
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.h b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.h
index cfd1e96908c..4466828ab51 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.h
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.h
@@ -17,17 +17,23 @@
namespace blink {
class WebString;
class WebMediaConstraints;
-}
+} // namespace blink
namespace content {
// Calculates and returns videoKind value for |format|.
// See https://w3c.github.io/mediacapture-depth.
-blink::WebString CONTENT_EXPORT
-GetVideoKindForFormat(const media::VideoCaptureFormat& format);
+CONTENT_EXPORT blink::WebString GetVideoKindForFormat(
+ const media::VideoCaptureFormat& format);
-blink::WebMediaStreamTrack::FacingMode CONTENT_EXPORT
-ToWebFacingMode(media::VideoFacingMode video_facing);
+CONTENT_EXPORT blink::WebMediaStreamTrack::FacingMode ToWebFacingMode(
+ media::VideoFacingMode video_facing);
+
+CONTENT_EXPORT blink::WebMediaStreamTrack::DisplayCaptureSurfaceType
+ToWebDisplaySurface(media::mojom::DisplayCaptureSurfaceType display_surface);
+
+CONTENT_EXPORT blink::WebMediaStreamTrack::CursorCaptureType
+ToWebCursorCaptureType(media::mojom::CursorCaptureType cursor);
struct CONTENT_EXPORT VideoDeviceCaptureCapabilities {
VideoDeviceCaptureCapabilities();
@@ -39,7 +45,6 @@ struct CONTENT_EXPORT VideoDeviceCaptureCapabilities {
// Each field is independent of each other.
std::vector<blink::mojom::VideoInputDeviceCapabilitiesPtr>
device_capabilities;
- std::vector<media::PowerLineFrequency> power_line_capabilities;
std::vector<base::Optional<bool>> noise_reduction_capabilities;
};
@@ -100,9 +105,9 @@ struct CONTENT_EXPORT VideoDeviceCaptureCapabilities {
// ideal value and thus has worse fitness according to step 2, even if C3's
// native fitness is better than C1's and C2's.
// 5. C1 is better than C2 if its settings are closer to certain default
-// settings that include the device ID, power-line frequency, noise
-// reduction, resolution, and frame rate, in that order. Note that there is
-// no default facing mode or aspect ratio.
+// settings that include the device ID, noise reduction, resolution,
+// and frame rate, in that order. Note that there is no default facing mode
+// or aspect ratio.
// This function uses the SelectVideoTrackAdapterSettings function to compute
// some track-specific settings. These are available in the returned value via
// the track_adapter_settings() accessor. For more details about the algorithm
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc
index 8a9a13eb380..cb17ff92126 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc
@@ -171,12 +171,6 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test {
};
capabilities_.device_capabilities.push_back(std::move(device));
- capabilities_.power_line_capabilities = {
- media::PowerLineFrequency::FREQUENCY_DEFAULT,
- media::PowerLineFrequency::FREQUENCY_50HZ,
- media::PowerLineFrequency::FREQUENCY_60HZ,
- };
-
capabilities_.noise_reduction_capabilities = {
base::Optional<bool>(), base::Optional<bool>(true),
base::Optional<bool>(false),
@@ -222,8 +216,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, Unconstrained) {
EXPECT_EQ(default_device_->device_id, result.device_id());
EXPECT_EQ(*default_closest_format_, result.Format());
// Should select default settings for other constraints.
- EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
- result.PowerLineFrequency());
EXPECT_EQ(base::Optional<bool>(), result.noise_reduction());
}
@@ -387,30 +379,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, OverconstrainedOnFrameRate) {
}
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
- OverconstrainedOnPowerLineFrequency) {
- constraint_factory_.Reset();
- constraint_factory_.basic().goog_power_line_frequency.SetExact(123467890);
- auto result = SelectSettings();
- EXPECT_FALSE(result.HasValue());
- EXPECT_EQ(constraint_factory_.basic().goog_power_line_frequency.GetName(),
- result.failed_constraint_name());
-
- constraint_factory_.Reset();
- constraint_factory_.basic().goog_power_line_frequency.SetMin(123467890);
- result = SelectSettings();
- EXPECT_FALSE(result.HasValue());
- EXPECT_EQ(constraint_factory_.basic().goog_power_line_frequency.GetName(),
- result.failed_constraint_name());
-
- constraint_factory_.Reset();
- constraint_factory_.basic().goog_power_line_frequency.SetMax(-1);
- result = SelectSettings();
- EXPECT_FALSE(result.HasValue());
- EXPECT_EQ(constraint_factory_.basic().goog_power_line_frequency.GetName(),
- result.failed_constraint_name());
-}
-
-TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
OverconstrainedOnNoiseReduction) {
// Simulate a system that does not support noise reduction.
// Manually adding device capabilities because VideoDeviceCaptureCapabilities
@@ -425,7 +393,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
media::PIXEL_FORMAT_I420),
};
capabilities.device_capabilities.push_back(std::move(device));
- capabilities.power_line_capabilities = capabilities_.power_line_capabilities;
capabilities.noise_reduction_capabilities = {base::Optional<bool>(false)};
constraint_factory_.Reset();
@@ -447,8 +414,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryDeviceID) {
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(default_device_->device_id, result.device_id());
EXPECT_EQ(*default_closest_format_, result.Format());
- EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
- result.PowerLineFrequency());
CheckTrackAdapterSettingsEqualsFormat(result);
constraint_factory_.basic().device_id.SetExact(
@@ -456,8 +421,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryDeviceID) {
result = SelectSettings();
EXPECT_EQ(low_res_device_->device_id, result.device_id());
EXPECT_EQ(*low_res_closest_format_, result.Format());
- EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
- result.PowerLineFrequency());
CheckTrackAdapterSettingsEqualsFormat(result);
constraint_factory_.basic().device_id.SetExact(
@@ -465,8 +428,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryDeviceID) {
result = SelectSettings();
EXPECT_EQ(high_res_device_->device_id, result.device_id());
EXPECT_EQ(*high_res_closest_format_, result.Format());
- EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
- result.PowerLineFrequency());
CheckTrackAdapterSettingsEqualsFormat(result);
}
@@ -478,8 +439,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryGroupID) {
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(default_device_->device_id, result.device_id());
EXPECT_EQ(*default_closest_format_, result.Format());
- EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
- result.PowerLineFrequency());
CheckTrackAdapterSettingsEqualsFormat(result);
constraint_factory_.basic().group_id.SetExact(
@@ -487,8 +446,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryGroupID) {
result = SelectSettings();
EXPECT_EQ(low_res_device_->device_id, result.device_id());
EXPECT_EQ(*low_res_closest_format_, result.Format());
- EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
- result.PowerLineFrequency());
CheckTrackAdapterSettingsEqualsFormat(result);
constraint_factory_.basic().group_id.SetExact(
@@ -496,8 +453,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryGroupID) {
result = SelectSettings();
EXPECT_EQ(high_res_device_->device_id, result.device_id());
EXPECT_EQ(*high_res_closest_format_, result.Format());
- EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
- result.PowerLineFrequency());
CheckTrackAdapterSettingsEqualsFormat(result);
}
@@ -513,8 +468,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFacingMode) {
EXPECT_EQ(media::MEDIA_VIDEO_FACING_ENVIRONMENT,
low_res_device_->facing_mode);
EXPECT_EQ(*low_res_closest_format_, result.Format());
- EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
- result.PowerLineFrequency());
CheckTrackAdapterSettingsEqualsFormat(result);
constraint_factory_.basic().facing_mode.SetExact(
@@ -526,8 +479,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryFacingMode) {
EXPECT_EQ(high_res_device_->device_id, result.device_id());
EXPECT_EQ(media::MEDIA_VIDEO_FACING_USER, high_res_device_->facing_mode);
EXPECT_EQ(*high_res_closest_format_, result.Format());
- EXPECT_EQ(media::PowerLineFrequency::FREQUENCY_DEFAULT,
- result.PowerLineFrequency());
CheckTrackAdapterSettingsEqualsFormat(result);
}
@@ -549,25 +500,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryVideoKind) {
CheckTrackAdapterSettingsEqualsFormat(result);
}
-TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryPowerLineFrequency) {
- constraint_factory_.Reset();
- const media::PowerLineFrequency kPowerLineFrequencies[] = {
- media::PowerLineFrequency::FREQUENCY_50HZ,
- media::PowerLineFrequency::FREQUENCY_60HZ};
- for (auto power_line_frequency : kPowerLineFrequencies) {
- constraint_factory_.basic().goog_power_line_frequency.SetExact(
- static_cast<long>(power_line_frequency));
- auto result = SelectSettings();
- EXPECT_TRUE(result.HasValue());
- EXPECT_EQ(power_line_frequency, result.PowerLineFrequency());
- // The default device and settings closest to the default should be
- // selected.
- EXPECT_EQ(default_device_->device_id, result.device_id());
- EXPECT_EQ(*default_closest_format_, result.Format());
- CheckTrackAdapterSettingsEqualsFormat(result);
- }
-}
-
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryNoiseReduction) {
constraint_factory_.Reset();
const bool kNoiseReductionValues[] = {true, false};
@@ -2276,39 +2208,6 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
}
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
- AdvancedContradictoryPowerLineFrequency) {
- {
- constraint_factory_.Reset();
- blink::WebMediaTrackConstraintSet& advanced1 =
- constraint_factory_.AddAdvanced();
- advanced1.width.SetMin(640);
- advanced1.height.SetMin(480);
- advanced1.goog_power_line_frequency.SetExact(50);
- blink::WebMediaTrackConstraintSet& advanced2 =
- constraint_factory_.AddAdvanced();
- advanced2.width.SetMin(1920);
- advanced2.height.SetMin(1080);
- advanced2.goog_power_line_frequency.SetExact(60);
- auto result = SelectSettings();
- EXPECT_TRUE(result.HasValue());
- // The second advanced set cannot be satisfied because it contradicts the
- // first set. The default device supports the first set and should be
- // selected.
- EXPECT_EQ(default_device_->device_id, result.device_id());
- EXPECT_LE(640, result.Width());
- EXPECT_LE(480, result.Height());
- EXPECT_EQ(50, static_cast<int>(result.PowerLineFrequency()));
- EXPECT_EQ(result.Width(), result.track_adapter_settings().max_width);
- EXPECT_EQ(result.Height(), result.track_adapter_settings().max_height);
- EXPECT_EQ(640.0 / result.Height(),
- result.track_adapter_settings().min_aspect_ratio);
- EXPECT_EQ(result.Width() / 480.0,
- result.track_adapter_settings().max_aspect_ratio);
- CheckTrackAdapterSettingsEqualsFrameRate(result);
- }
-}
-
-TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
AdvancedContradictoryAspectRatioWidth) {
{
constraint_factory_.Reset();
diff --git a/chromium/content/renderer/media/stream/media_stream_device_observer.cc b/chromium/content/renderer/media/stream/media_stream_device_observer.cc
index 80a3e5df962..df23fbe6299 100644
--- a/chromium/content/renderer/media/stream/media_stream_device_observer.cc
+++ b/chromium/content/renderer/media/stream/media_stream_device_observer.cc
@@ -22,8 +22,8 @@ namespace {
bool RemoveStreamDeviceFromArray(const MediaStreamDevice& device,
MediaStreamDevices* devices) {
- for (MediaStreamDevices::iterator device_it = devices->begin();
- device_it != devices->end(); ++device_it) {
+ for (auto device_it = devices->begin(); device_it != devices->end();
+ ++device_it) {
if (device_it->IsSameDevice(device)) {
devices->erase(device_it);
return true;
diff --git a/chromium/content/renderer/media/stream/media_stream_video_source.cc b/chromium/content/renderer/media/stream/media_stream_video_source.cc
index 9ea6162be88..0550fb2209c 100644
--- a/chromium/content/renderer/media/stream/media_stream_video_source.cc
+++ b/chromium/content/renderer/media/stream/media_stream_video_source.cc
@@ -15,7 +15,6 @@
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/sequenced_task_runner_handle.h"
-#include "base/trace_event/trace_event.h"
#include "content/child/child_process.h"
#include "content/public/common/content_features.h"
#include "content/renderer/media/stream/media_stream_constraints_util_video_device.h"
@@ -86,8 +85,7 @@ void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track,
base::OnceClosure callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
{
- std::vector<MediaStreamVideoTrack*>::iterator it =
- std::find(tracks_.begin(), tracks_.end(), video_track);
+ auto it = std::find(tracks_.begin(), tracks_.end(), video_track);
DCHECK(it != tracks_.end());
tracks_.erase(it);
}
@@ -126,7 +124,7 @@ void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track,
// stopping a source with StopSource() can have side effects that affect
// sources created after that StopSource() call, but before the actual
// stop takes place. See http://crbug.com/778039.
- StopForRestart(base::BindOnce(&MediaStreamVideoSource::DidRemoveLastTrack,
+ StopForRestart(base::BindOnce(&MediaStreamVideoSource::DidStopSource,
weak_factory_.GetWeakPtr(),
std::move(callback)));
if (state_ == STOPPING_FOR_RESTART || state_ == STOPPED_FOR_RESTART) {
@@ -139,7 +137,7 @@ void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track,
FinalizeStopSource();
} else {
// If the source does not support restarting, call StopSource()
- // to ensure stop on this task. DidRemoveLastTrack() will be called on
+ // to ensure stop on this task. DidStopSource() will be called on
// another task even if the source does not support restarting, as
// StopForRestart() always posts a task to run its callback.
StopSource();
@@ -152,11 +150,10 @@ void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track,
}
}
-void MediaStreamVideoSource::DidRemoveLastTrack(base::OnceClosure callback,
- RestartResult result) {
+void MediaStreamVideoSource::DidStopSource(base::OnceClosure callback,
+ RestartResult result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(callback);
- DCHECK(tracks_.empty());
DCHECK_EQ(Owner().GetReadyState(),
blink::WebMediaStreamSource::kReadyStateEnded);
if (result == RestartResult::IS_STOPPED) {
diff --git a/chromium/content/renderer/media/stream/media_stream_video_source.h b/chromium/content/renderer/media/stream/media_stream_video_source.h
index 4ef327f92f5..82da3b1f3c2 100644
--- a/chromium/content/renderer/media/stream/media_stream_video_source.h
+++ b/chromium/content/renderer/media/stream/media_stream_video_source.h
@@ -256,7 +256,7 @@ class CONTENT_EXPORT MediaStreamVideoSource : public MediaStreamSource {
void StartFrameMonitoring();
void UpdateTrackSettings(MediaStreamVideoTrack* track,
const VideoTrackAdapterSettings& adapter_settings);
- void DidRemoveLastTrack(base::OnceClosure callback, RestartResult result);
+ void DidStopSource(base::OnceClosure callback, RestartResult result);
State state_;
diff --git a/chromium/content/renderer/media/stream/media_stream_video_source_unittest.cc b/chromium/content/renderer/media/stream/media_stream_video_source_unittest.cc
index ebbbf191ad5..ff1c5663c7c 100644
--- a/chromium/content/renderer/media/stream/media_stream_video_source_unittest.cc
+++ b/chromium/content/renderer/media/stream/media_stream_video_source_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <string>
+#include <utility>
#include <vector>
#include "base/bind.h"
@@ -58,15 +59,15 @@ class MediaStreamVideoSourceTest : public ::testing::Test {
media::PIXEL_FORMAT_I420));
formats.push_back(media::VideoCaptureFormat(gfx::Size(320, 240), 30,
media::PIXEL_FORMAT_I420));
- webkit_source_.Initialize(blink::WebString::FromASCII("dummy_source_id"),
- blink::WebMediaStreamSource::kTypeVideo,
- blink::WebString::FromASCII("dummy_source_name"),
- false /* remote */);
- webkit_source_.SetExtraData(mock_source_);
+ web_source_.Initialize(blink::WebString::FromASCII("dummy_source_id"),
+ blink::WebMediaStreamSource::kTypeVideo,
+ blink::WebString::FromASCII("dummy_source_name"),
+ false /* remote */);
+ web_source_.SetExtraData(mock_source_);
}
void TearDown() override {
- webkit_source_.Reset();
+ web_source_.Reset();
blink::WebHeap::CollectAllGarbageForTesting();
}
@@ -75,7 +76,7 @@ class MediaStreamVideoSourceTest : public ::testing::Test {
protected:
MediaStreamVideoSource* source() { return mock_source_; }
- // Create a track that's associated with |webkit_source_|.
+ // Create a track that's associated with |web_source_|.
blink::WebMediaStreamTrack CreateTrack(const std::string& id) {
bool enabled = true;
return MediaStreamVideoTrack::CreateVideoTrack(
@@ -131,7 +132,7 @@ class MediaStreamVideoSourceTest : public ::testing::Test {
MockMediaStreamVideoSource* mock_source() { return mock_source_; }
- const blink::WebMediaStreamSource& webkit_source() { return webkit_source_; }
+ const blink::WebMediaStreamSource& web_source() { return web_source_; }
void TestSourceCropFrame(int capture_width,
int capture_height,
@@ -238,7 +239,7 @@ class MediaStreamVideoSourceTest : public ::testing::Test {
void OnConstraintsApplied(MediaStreamSource* source,
MediaStreamRequestResult result,
const blink::WebString& result_name) {
- ASSERT_EQ(source, webkit_source().GetExtraData());
+ ASSERT_EQ(source, web_source().GetExtraData());
if (result == MEDIA_DEVICE_OK) {
++number_of_successful_constraints_applied_;
@@ -250,7 +251,7 @@ class MediaStreamVideoSourceTest : public ::testing::Test {
if (!track_to_release_.IsNull()) {
mock_source_ = nullptr;
- webkit_source_.Reset();
+ web_source_.Reset();
track_to_release_.Reset();
}
}
@@ -261,8 +262,8 @@ class MediaStreamVideoSourceTest : public ::testing::Test {
int number_of_failed_constraints_applied_;
content::MediaStreamRequestResult result_;
blink::WebString result_name_;
- blink::WebMediaStreamSource webkit_source_;
- // |mock_source_| is owned by |webkit_source_|.
+ blink::WebMediaStreamSource web_source_;
+ // |mock_source_| is owned by |web_source_|.
MockMediaStreamVideoSource* mock_source_;
};
@@ -697,4 +698,23 @@ TEST_F(MediaStreamVideoSourceTest, StopSuspendedTrack) {
EXPECT_FALSE(mock_source()->is_suspended());
}
+TEST_F(MediaStreamVideoSourceTest, AddTrackAfterStoppingSource) {
+ blink::WebMediaStreamTrack web_track1 = CreateTrack("123");
+ mock_source()->StartMockedSource();
+ EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
+ EXPECT_EQ(0, NumberOfFailedConstraintsCallbacks());
+
+ MediaStreamVideoTrack* track1 =
+ MediaStreamVideoTrack::GetVideoTrack(web_track1);
+ EXPECT_CALL(*this, MockNotification());
+ // This is equivalent to track.stop() in JavaScript.
+ track1->StopAndNotify(base::BindOnce(
+ &MediaStreamVideoSourceTest::MockNotification, base::Unretained(this)));
+
+ blink::WebMediaStreamTrack track2 = CreateTrack("456");
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
+ EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks());
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/stream/media_stream_video_track.cc b/chromium/content/renderer/media/stream/media_stream_video_track.cc
index 5a30ba62c91..b2f048e9d25 100644
--- a/chromium/content/renderer/media/stream/media_stream_video_track.cc
+++ b/chromium/content/renderer/media/stream/media_stream_video_track.cc
@@ -128,7 +128,7 @@ void MediaStreamVideoTrack::FrameDeliverer::RemoveCallbackOnIO(
VideoSinkId id,
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
- std::vector<VideoIdCallbackPair>::iterator it = callbacks_.begin();
+ auto it = callbacks_.begin();
for (; it != callbacks_.end(); ++it) {
if (it->first == id) {
// Callback is copied to heap and then deleted on the target thread.
@@ -318,8 +318,7 @@ void MediaStreamVideoTrack::AddSink(MediaStreamVideoSink* sink,
void MediaStreamVideoTrack::RemoveSink(MediaStreamVideoSink* sink) {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
- std::vector<MediaStreamVideoSink*>::iterator it =
- std::find(sinks_.begin(), sinks_.end(), sink);
+ auto it = std::find(sinks_.begin(), sinks_.end(), sink);
DCHECK(it != sinks_.end());
sinks_.erase(it);
frame_deliverer_->RemoveCallback(sink);
@@ -390,6 +389,12 @@ void MediaStreamVideoTrack::GetSettings(
settings.focal_length_x = calibration->focal_length_x;
settings.focal_length_y = calibration->focal_length_y;
}
+ if (source_->device().display_media_info.has_value()) {
+ const auto& info = source_->device().display_media_info.value();
+ settings.display_surface = ToWebDisplaySurface(info->display_surface);
+ settings.logical_surface = info->logical_surface;
+ settings.cursor = ToWebCursorCaptureType(info->cursor);
+ }
}
void MediaStreamVideoTrack::OnReadyStateChanged(
diff --git a/chromium/content/renderer/media/stream/processed_local_audio_source.cc b/chromium/content/renderer/media/stream/processed_local_audio_source.cc
index 7b6cfe95d94..bd946623d17 100644
--- a/chromium/content/renderer/media/stream/processed_local_audio_source.cc
+++ b/chromium/content/renderer/media/stream/processed_local_audio_source.cc
@@ -192,8 +192,8 @@ bool ProcessedLocalAudioSource::EnsureSourceIsStarted() {
UMA_HISTOGRAM_ENUMERATION(
"WebRTC.AudioInputSampleRate", asr, media::kAudioSampleRateMax + 1);
} else {
- UMA_HISTOGRAM_COUNTS("WebRTC.AudioInputSampleRateUnexpected",
- device().input.sample_rate());
+ UMA_HISTOGRAM_COUNTS_1M("WebRTC.AudioInputSampleRateUnexpected",
+ device().input.sample_rate());
}
// Determine the audio format required of the AudioCapturerSource. Then, pass
diff --git a/chromium/content/renderer/media/stream/processed_local_audio_source_unittest.cc b/chromium/content/renderer/media/stream/processed_local_audio_source_unittest.cc
index 6cc48ae1c3e..50003e741e3 100644
--- a/chromium/content/renderer/media/stream/processed_local_audio_source_unittest.cc
+++ b/chromium/content/renderer/media/stream/processed_local_audio_source_unittest.cc
@@ -6,7 +6,7 @@
#include <string>
#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "content/public/renderer/media_stream_audio_sink.h"
#include "content/renderer/media/audio/mock_audio_device_factory.h"
@@ -144,7 +144,8 @@ class ProcessedLocalAudioSourceTest : public testing::Test {
const blink::WebString& result_name) {}
private:
- base::MessageLoop main_thread_message_loop_; // Needed for MSAudioProcessor.
+ base::test::ScopedTaskEnvironment
+ task_environment_; // Needed for MSAudioProcessor.
MockAudioDeviceFactory mock_audio_device_factory_;
MockPeerConnectionDependencyFactory mock_dependency_factory_;
blink::WebMediaStreamSource blink_audio_source_;
diff --git a/chromium/content/renderer/media/stream/user_media_client_impl.cc b/chromium/content/renderer/media/stream/user_media_client_impl.cc
index 56cc10384ac..738a84c66ed 100644
--- a/chromium/content/renderer/media/stream/user_media_client_impl.cc
+++ b/chromium/content/renderer/media/stream/user_media_client_impl.cc
@@ -194,6 +194,10 @@ void UserMediaClientImpl::StopTrack(
MaybeProcessNextRequestInfo();
}
+bool UserMediaClientImpl::IsCapturing() {
+ return user_media_processor_->HasActiveSources();
+}
+
void UserMediaClientImpl::MaybeProcessNextRequestInfo() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (is_processing_request_ || pending_request_infos_.empty())
diff --git a/chromium/content/renderer/media/stream/user_media_client_impl.h b/chromium/content/renderer/media/stream/user_media_client_impl.h
index b87767c1b3b..1882252ddb5 100644
--- a/chromium/content/renderer/media/stream/user_media_client_impl.h
+++ b/chromium/content/renderer/media/stream/user_media_client_impl.h
@@ -59,6 +59,7 @@ class CONTENT_EXPORT UserMediaClientImpl : public RenderFrameObserver,
void ApplyConstraints(
const blink::WebApplyConstraintsRequest& web_request) override;
void StopTrack(const blink::WebMediaStreamTrack& web_track) override;
+ bool IsCapturing() override;
// RenderFrameObserver override
void WillCommitProvisionalLoad() override;
diff --git a/chromium/content/renderer/media/stream/user_media_client_impl_unittest.cc b/chromium/content/renderer/media/stream/user_media_client_impl_unittest.cc
index 703ea988283..f2f19559296 100644
--- a/chromium/content/renderer/media/stream/user_media_client_impl_unittest.cc
+++ b/chromium/content/renderer/media/stream/user_media_client_impl_unittest.cc
@@ -884,8 +884,6 @@ TEST_F(UserMediaClientImplTest, DefaultConstraintsPropagate) {
MediaStreamVideoSource::kDefaultFrameRate);
EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(),
media::ResolutionChangePolicy::FIXED_RESOLUTION);
- EXPECT_EQ(video_capture_settings.PowerLineFrequency(),
- media::PowerLineFrequency::FREQUENCY_DEFAULT);
EXPECT_FALSE(video_capture_settings.noise_reduction());
EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value());
@@ -945,8 +943,6 @@ TEST_F(UserMediaClientImplTest, DefaultTabCapturePropagate) {
EXPECT_EQ(video_capture_settings.FrameRate(), kDefaultScreenCastFrameRate);
EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(),
media::ResolutionChangePolicy::FIXED_RESOLUTION);
- EXPECT_EQ(video_capture_settings.PowerLineFrequency(),
- media::PowerLineFrequency::FREQUENCY_DEFAULT);
EXPECT_FALSE(video_capture_settings.noise_reduction());
EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value());
EXPECT_FALSE(video_capture_settings.max_frame_rate().has_value());
@@ -1006,8 +1002,6 @@ TEST_F(UserMediaClientImplTest, DefaultDesktopCapturePropagate) {
EXPECT_EQ(video_capture_settings.FrameRate(), kDefaultScreenCastFrameRate);
EXPECT_EQ(video_capture_settings.ResolutionChangePolicy(),
media::ResolutionChangePolicy::ANY_WITHIN_LIMIT);
- EXPECT_EQ(video_capture_settings.PowerLineFrequency(),
- media::PowerLineFrequency::FREQUENCY_DEFAULT);
EXPECT_FALSE(video_capture_settings.noise_reduction());
EXPECT_FALSE(video_capture_settings.min_frame_rate().has_value());
EXPECT_FALSE(video_capture_settings.max_frame_rate().has_value());
@@ -1339,4 +1333,19 @@ TEST_F(UserMediaClientImplTest,
EXPECT_FALSE(source->device().matched_output_device_id);
}
+TEST_F(UserMediaClientImplTest, IsCapturing) {
+ EXPECT_FALSE(user_media_client_impl_->IsCapturing());
+ EXPECT_CALL(mock_dispatcher_host_, OnStreamStarted(_));
+ blink::WebMediaStream stream = RequestLocalMediaStream();
+ EXPECT_TRUE(user_media_client_impl_->IsCapturing());
+
+ user_media_client_impl_->StopTrack(stream.AudioTracks()[0]);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(user_media_client_impl_->IsCapturing());
+
+ user_media_client_impl_->StopTrack(stream.VideoTracks()[0]);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(user_media_client_impl_->IsCapturing());
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/stream/user_media_processor.cc b/chromium/content/renderer/media/stream/user_media_processor.cc
index 150e73cdbbb..86c723b009e 100644
--- a/chromium/content/renderer/media/stream/user_media_processor.cc
+++ b/chromium/content/renderer/media/stream/user_media_processor.cc
@@ -609,10 +609,6 @@ void UserMediaProcessor::SelectVideoDeviceSettings(
VideoDeviceCaptureCapabilities capabilities;
capabilities.device_capabilities = std::move(video_input_capabilities);
- capabilities.power_line_capabilities = {
- media::PowerLineFrequency::FREQUENCY_DEFAULT,
- media::PowerLineFrequency::FREQUENCY_50HZ,
- media::PowerLineFrequency::FREQUENCY_60HZ};
capabilities.noise_reduction_capabilities = {base::Optional<bool>(),
base::Optional<bool>(true),
base::Optional<bool>(false)};
@@ -1256,7 +1252,7 @@ bool UserMediaProcessor::RemoveLocalSource(
const blink::WebMediaStreamSource& source) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- for (LocalStreamSources::iterator device_it = local_sources_.begin();
+ for (auto device_it = local_sources_.begin();
device_it != local_sources_.end(); ++device_it) {
if (IsSameSource(*device_it, source)) {
local_sources_.erase(device_it);
@@ -1265,7 +1261,7 @@ bool UserMediaProcessor::RemoveLocalSource(
}
// Check if the source was pending.
- for (LocalStreamSources::iterator device_it = pending_local_sources_.begin();
+ for (auto device_it = pending_local_sources_.begin();
device_it != pending_local_sources_.end(); ++device_it) {
if (IsSameSource(*device_it, source)) {
MediaStreamSource* const source_extra_data =
@@ -1376,6 +1372,10 @@ void UserMediaProcessor::StopLocalSource(
source_impl->StopSource();
}
+bool UserMediaProcessor::HasActiveSources() const {
+ return !local_sources_.empty();
+}
+
const mojom::MediaStreamDispatcherHostPtr&
UserMediaProcessor::GetMediaStreamDispatcherHost() {
if (!dispatcher_host_) {
diff --git a/chromium/content/renderer/media/stream/user_media_processor.h b/chromium/content/renderer/media/stream/user_media_processor.h
index 6b9e18f85e0..f323c3170ab 100644
--- a/chromium/content/renderer/media/stream/user_media_processor.h
+++ b/chromium/content/renderer/media/stream/user_media_processor.h
@@ -105,6 +105,8 @@ class CONTENT_EXPORT UserMediaProcessor
return media_stream_device_observer_.get();
}
+ bool HasActiveSources() const;
+
// MediaStreamDispatcherEventHandler implementation.
void OnDeviceStopped(const MediaStreamDevice& device) override;
diff --git a/chromium/content/renderer/media/stream/video_track_adapter.cc b/chromium/content/renderer/media/stream/video_track_adapter.cc
index 28727ef7b1c..cbe15d6b527 100644
--- a/chromium/content/renderer/media/stream/video_track_adapter.cc
+++ b/chromium/content/renderer/media/stream/video_track_adapter.cc
@@ -179,7 +179,7 @@ void VideoTrackAdapter::VideoFrameResolutionAdapter::AddCallback(
void VideoTrackAdapter::VideoFrameResolutionAdapter::RemoveAndReleaseCallback(
const MediaStreamVideoTrack* track) {
DCHECK(io_thread_checker_.CalledOnValidThread());
- std::vector<VideoIdCallbackPair>::iterator it = callbacks_.begin();
+ auto it = callbacks_.begin();
for (; it != callbacks_.end(); ++it) {
if (it->first == track) {
// Make sure the VideoCaptureDeliverFrameCB is released on the main
diff --git a/chromium/content/renderer/media/stream/webmediaplayer_ms.cc b/chromium/content/renderer/media/stream/webmediaplayer_ms.cc
index 45c8d7ee9d2..5031219c66a 100644
--- a/chromium/content/renderer/media/stream/webmediaplayer_ms.cc
+++ b/chromium/content/renderer/media/stream/webmediaplayer_ms.cc
@@ -174,13 +174,17 @@ class WebMediaPlayerMS::FrameDeliverer {
void EnqueueFrame(const scoped_refptr<media::VideoFrame>& frame) {
DCHECK(io_thread_checker_.CalledOnValidThread());
- base::TimeTicks render_time;
- if (frame->metadata()->GetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
- TRACE_EVENT1("media", "EnqueueFrame", "Ideal Render Instant",
- render_time.ToInternalValue());
- } else {
- TRACE_EVENT0("media", "EnqueueFrame");
+ bool tracing_enabled = false;
+ TRACE_EVENT_CATEGORY_GROUP_ENABLED("media", &tracing_enabled);
+ if (tracing_enabled) {
+ base::TimeTicks render_time;
+ if (frame->metadata()->GetTimeTicks(
+ media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
+ TRACE_EVENT1("media", "EnqueueFrame", "Ideal Render Instant",
+ render_time.ToInternalValue());
+ } else {
+ TRACE_EVENT0("media", "EnqueueFrame");
+ }
}
const bool is_opaque = media::IsOpaque(frame->format());
@@ -265,7 +269,8 @@ WebMediaPlayerMS::WebMediaPlayerMS(
media::GpuVideoAcceleratorFactories* gpu_factories,
const blink::WebString& sink_id,
CreateSurfaceLayerBridgeCB create_bridge_callback,
- bool surface_layer_for_video_enabled)
+ std::unique_ptr<blink::WebVideoFrameSubmitter> submitter,
+ blink::WebMediaPlayer::SurfaceLayerMode surface_layer_mode)
: frame_(frame),
network_state_(WebMediaPlayer::kNetworkStateEmpty),
ready_state_(WebMediaPlayer::kReadyStateHaveNothing),
@@ -287,7 +292,8 @@ WebMediaPlayerMS::WebMediaPlayerMS(
volume_multiplier_(1.0),
should_play_upon_shown_(false),
create_bridge_callback_(std::move(create_bridge_callback)),
- surface_layer_for_video_enabled_(surface_layer_for_video_enabled) {
+ submitter_(std::move(submitter)),
+ surface_layer_mode_(surface_layer_mode) {
DVLOG(1) << __func__;
DCHECK(client);
DCHECK(delegate_);
@@ -307,7 +313,8 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
// Destruct compositor resources in the proper order.
get_client()->SetCcLayer(nullptr);
if (video_layer_) {
- DCHECK(!surface_layer_for_video_enabled_);
+ DCHECK(surface_layer_mode_ !=
+ blink::WebMediaPlayer::SurfaceLayerMode::kAlways);
video_layer_->StopUsingProvider();
}
@@ -345,7 +352,8 @@ blink::WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
web_stream_.AddObserver(this);
compositor_ = new WebMediaPlayerMSCompositor(
- compositor_task_runner_, io_task_runner_, web_stream_, AsWeakPtr());
+ compositor_task_runner_, io_task_runner_, web_stream_,
+ std::move(submitter_), surface_layer_mode_, AsWeakPtr());
SetNetworkState(WebMediaPlayer::kNetworkStateLoading);
SetReadyState(WebMediaPlayer::kReadyStateHaveNothing);
@@ -371,8 +379,7 @@ blink::WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
if (frame) {
// Report UMA and RAPPOR metrics.
- media::ReportMetrics(load_type, url, frame_->GetSecurityOrigin(),
- media_log_.get());
+ media::ReportMetrics(load_type, url, *frame_, media_log_.get());
routing_id = frame->GetRoutingID();
}
@@ -442,8 +449,15 @@ void WebMediaPlayerMS::UnregisterContentsLayer(cc::Layer* layer) {
}
void WebMediaPlayerMS::OnSurfaceIdUpdated(viz::SurfaceId surface_id) {
- // TODO(apacible): Add implementation. See http://crbug/746182.
- NOTIMPLEMENTED();
+ // TODO(726619): Handle the behavior when Picture-in-Picture mode is
+ // disabled.
+ // The viz::SurfaceId may be updated when the video begins playback or when
+ // the size of the video changes.
+ if (client_ && IsInPictureInPicture() && !client_->IsInAutoPIP()) {
+ delegate_->DidPictureInPictureSurfaceChange(
+ delegate_id_, surface_id, NaturalSize(),
+ false /* show_play_pause_button */);
+ }
}
void WebMediaPlayerMS::TrackAdded(const blink::WebMediaStreamTrack& track) {
@@ -655,36 +669,42 @@ void WebMediaPlayerMS::SetVolume(double volume) {
void WebMediaPlayerMS::EnterPictureInPicture(
blink::WebMediaPlayer::PipWindowOpenedCallback callback) {
- // TODO(crbug.com/806249): Use Picture-in-Picture window size.
- std::move(callback).Run(this->NaturalSize());
+ if (!bridge_)
+ ActivateSurfaceLayerForVideo();
- NOTIMPLEMENTED();
- // TODO(apacible): Implement after video in surfaces is supported for
- // WebMediaPlayerMS. See http://crbug/746182.
+ DCHECK(bridge_);
+
+ const viz::SurfaceId& surface_id = bridge_->GetSurfaceId();
+ DCHECK(surface_id.is_valid());
+
+ // Notifies the browser process that the player should now be in
+ // Picture-in-Picture mode.
+ delegate_->DidPictureInPictureModeStart(delegate_id_, surface_id,
+ NaturalSize(), std::move(callback),
+ false /* show_play_pause_button */);
}
void WebMediaPlayerMS::ExitPictureInPicture(
blink::WebMediaPlayer::PipWindowClosedCallback callback) {
- // TODO(crbug.com/806249): Run callback when Picture-in-Picture window closes.
- std::move(callback).Run();
+ // Notifies the browser process that Picture-in-Picture has ended. It will
+ // clear out the states and close the window.
+ delegate_->DidPictureInPictureModeEnd(delegate_id_, std::move(callback));
- NOTIMPLEMENTED();
- // TODO(apacible): Implement after video in surfaces is supported for
- // WebMediaPlayerMS. See http://crbug/746182.
+ // Internal cleanups.
+ OnPictureInPictureModeEnded();
}
void WebMediaPlayerMS::SetPictureInPictureCustomControls(
const std::vector<blink::PictureInPictureControlInfo>& controls) {
- NOTIMPLEMENTED();
- // TODO(apacible): Implement after video in surfaces is supported for
- // WebMediaPlayerMS. See http://crbug/746182.
+ delegate_->DidSetPictureInPictureCustomControls(delegate_id_, controls);
}
void WebMediaPlayerMS::RegisterPictureInPictureWindowResizeCallback(
- blink::WebMediaPlayer::PipWindowResizedCallback) {
- NOTIMPLEMENTED();
- // TODO(apacible): Implement after video in surfaces is supported for
- // WebMediaPlayerMS. See http://crbug/746182.
+ blink::WebMediaPlayer::PipWindowResizedCallback callback) {
+ DCHECK(IsInPictureInPicture() && !client_->IsInAutoPIP());
+
+ delegate_->RegisterPictureInPictureWindowResizeCallback(delegate_id_,
+ std::move(callback));
}
void WebMediaPlayerMS::SetSinkId(
@@ -780,6 +800,11 @@ blink::WebMediaPlayer::ReadyState WebMediaPlayerMS::GetReadyState() const {
return ready_state_;
}
+blink::WebMediaPlayer::SurfaceLayerMode
+WebMediaPlayerMS::GetVideoSurfaceLayerMode() const {
+ return surface_layer_mode_;
+}
+
blink::WebString WebMediaPlayerMS::GetErrorMessage() const {
return blink::WebString::FromUTF8(media_log_->GetErrorMessage());
}
@@ -811,6 +836,7 @@ void WebMediaPlayerMS::Paint(cc::PaintCanvas* canvas,
compositor_->GetCurrentFrameWithoutUpdatingStatistics();
media::Context3D context_3d;
+ gpu::ContextSupport* context_support = nullptr;
if (frame && frame->HasTextures()) {
auto* provider =
RenderThreadImpl::current()->SharedMainThreadContextProvider().get();
@@ -818,28 +844,18 @@ void WebMediaPlayerMS::Paint(cc::PaintCanvas* canvas,
if (!provider)
return;
context_3d = media::Context3D(provider->ContextGL(), provider->GrContext());
- DCHECK(context_3d.gl);
+ context_support = provider->ContextSupport();
}
const gfx::RectF dest_rect(rect.x, rect.y, rect.width, rect.height);
video_renderer_.Paint(frame, canvas, dest_rect, flags, video_rotation_,
- context_3d);
+ context_3d, context_support);
}
-bool WebMediaPlayerMS::DidGetOpaqueResponseFromServiceWorker() const {
+bool WebMediaPlayerMS::WouldTaintOrigin() const {
DCHECK(thread_checker_.CalledOnValidThread());
return false;
}
-bool WebMediaPlayerMS::HasSingleSecurityOrigin() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- return true;
-}
-
-bool WebMediaPlayerMS::DidPassCORSAccessCheck() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- return true;
-}
-
double WebMediaPlayerMS::MediaTimeForTimeValue(double timeValue) const {
return base::TimeDelta::FromSecondsD(timeValue).InSecondsF();
}
@@ -954,7 +970,12 @@ void WebMediaPlayerMS::OnBecamePersistentVideo(bool value) {
}
void WebMediaPlayerMS::OnPictureInPictureModeEnded() {
- NOTIMPLEMENTED();
+ // It is possible for this method to be called when the player is no longer in
+ // Picture-in-Picture mode.
+ if (!client_ || !IsInPictureInPicture())
+ return;
+
+ client_->PictureInPictureStopped();
}
void WebMediaPlayerMS::OnPictureInPictureControlClicked(
@@ -993,8 +1014,8 @@ bool WebMediaPlayerMS::CopyVideoTextureToPlatformTexture(
DCHECK(context_3d.gl);
return video_renderer_.CopyVideoFrameTexturesToGLTexture(
- context_3d, gl, video_frame.get(), target, texture, internal_format,
- format, type, level, premultiply_alpha, flip_y);
+ context_3d, provider->ContextSupport(), gl, video_frame.get(), target,
+ texture, internal_format, format, type, level, premultiply_alpha, flip_y);
}
bool WebMediaPlayerMS::CopyVideoYUVDataToPlatformTexture(
@@ -1075,17 +1096,59 @@ bool WebMediaPlayerMS::TexImageImpl(TexImageFunctionID functionID,
return false;
}
+void WebMediaPlayerMS::OnFrameSinkDestroyed() {
+ bridge_->ClearSurfaceId();
+}
+
+void WebMediaPlayerMS::ActivateSurfaceLayerForVideo() {
+ // Note that we might or might not already be in VideoLayer mode.
+ DCHECK(!bridge_);
+
+ // If we're in VideoLayer mode, then get rid of the layer.
+ if (video_layer_) {
+ client_->SetCcLayer(nullptr);
+ video_layer_ = nullptr;
+ }
+
+ bridge_ = std::move(create_bridge_callback_)
+ .Run(this, compositor_->GetUpdateSubmissionStateCallback());
+ bridge_->CreateSurfaceLayer();
+ bridge_->SetContentsOpaque(opaque_);
+
+ compositor_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &WebMediaPlayerMSCompositor::EnableSubmission, compositor_,
+ bridge_->GetSurfaceId(), video_rotation_, IsInPictureInPicture(),
+ opaque_,
+ media::BindToCurrentLoop(base::BindRepeating(
+ &WebMediaPlayerMS::OnFrameSinkDestroyed, AsWeakPtr()))));
+
+ // If the element is already in Picture-in-Picture mode, it means that it
+ // was set in this mode prior to this load, with a different
+ // WebMediaPlayerImpl. The new player needs to send its id, size and
+ // surface id to the browser process to make sure the states are properly
+ // updated.
+ // TODO(872056): the surface should be activated but for some reason, it
+ // does not. It is possible that this will no longer be needed after 872056
+ // is fixed.
+ if (client_->DisplayType() ==
+ WebMediaPlayer::DisplayType::kPictureInPicture) {
+ OnSurfaceIdUpdated(bridge_->GetSurfaceId());
+ }
+}
+
void WebMediaPlayerMS::OnFirstFrameReceived(media::VideoRotation video_rotation,
bool is_opaque) {
DVLOG(1) << __func__;
DCHECK(thread_checker_.CalledOnValidThread());
- if (surface_layer_for_video_enabled_) {
- DCHECK(!bridge_);
-
- bridge_ = std::move(create_bridge_callback_)
- .Run(this, compositor_->GetUpdateSubmissionStateCallback());
- bridge_->CreateSurfaceLayer();
+ if (surface_layer_mode_ == blink::WebMediaPlayer::SurfaceLayerMode::kAlways ||
+ (surface_layer_mode_ ==
+ blink::WebMediaPlayer::SurfaceLayerMode::kOnDemand &&
+ client_->DisplayType() ==
+ WebMediaPlayer::DisplayType::kPictureInPicture)) {
+ ActivateSurfaceLayerForVideo();
}
SetReadyState(WebMediaPlayer::kReadyStateHaveMetadata);
@@ -1108,6 +1171,9 @@ void WebMediaPlayerMS::OnOpacityChanged(bool is_opaque) {
DCHECK(bridge_);
bridge_->SetContentsOpaque(opaque_);
+ compositor_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&WebMediaPlayerMSCompositor::UpdateIsOpaque,
+ compositor_, opaque_));
}
}
@@ -1128,12 +1194,20 @@ void WebMediaPlayerMS::OnRotationChanged(media::VideoRotation video_rotation,
get_client()->SetCcLayer(new_video_layer.get());
video_layer_ = std::move(new_video_layer);
- } else if (bridge_->GetCcLayer()) {
- // TODO(lethalantidote): Handle rotation.
- bridge_->SetContentsOpaque(opaque_);
+ } else {
+ compositor_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&WebMediaPlayerMSCompositor::UpdateRotation,
+ compositor_, video_rotation));
}
}
+bool WebMediaPlayerMS::IsInPictureInPicture() const {
+ DCHECK(client_);
+ return (!client_->IsInAutoPIP() &&
+ client_->DisplayType() ==
+ WebMediaPlayer::DisplayType::kPictureInPicture);
+}
+
void WebMediaPlayerMS::RepaintInternal() {
DVLOG(1) << __func__;
DCHECK(thread_checker_.CalledOnValidThread());
@@ -1183,4 +1257,17 @@ void WebMediaPlayerMS::SetGpuMemoryBufferVideoForTesting(
frame_deliverer_->gpu_memory_buffer_pool_.reset(gpu_memory_buffer_pool);
}
+void WebMediaPlayerMS::OnDisplayTypeChanged(
+ WebMediaPlayer::DisplayType display_type) {
+ if (!bridge_)
+ return;
+
+ compositor_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &WebMediaPlayerMSCompositor::SetForceSubmit,
+ base::Unretained(compositor_.get()),
+ display_type == WebMediaPlayer::DisplayType::kPictureInPicture));
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/stream/webmediaplayer_ms.h b/chromium/content/renderer/media/stream/webmediaplayer_ms.h
index 8408a5d40b5..8f78f0b9ab2 100644
--- a/chromium/content/renderer/media/stream/webmediaplayer_ms.h
+++ b/chromium/content/renderer/media/stream/webmediaplayer_ms.h
@@ -16,6 +16,7 @@
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "media/blink/webmediaplayer_delegate.h"
+#include "media/blink/webmediaplayer_params.h"
#include "media/blink/webmediaplayer_util.h"
#include "media/renderers/paint_canvas_video_renderer.h"
#include "media/video/gpu_video_accelerator_factories.h"
@@ -27,6 +28,7 @@ namespace blink {
class WebLocalFrame;
class WebMediaPlayerClient;
class WebString;
+class WebVideoFrameSubmitter;
}
namespace media {
@@ -91,7 +93,8 @@ class CONTENT_EXPORT WebMediaPlayerMS
media::GpuVideoAcceleratorFactories* gpu_factories,
const blink::WebString& sink_id,
CreateSurfaceLayerBridgeCB create_bridge_callback,
- bool surface_layer_for_video_enabled_);
+ std::unique_ptr<blink::WebVideoFrameSubmitter> submitter_,
+ blink::WebMediaPlayer::SurfaceLayerMode surface_layer_mode);
~WebMediaPlayerMS() override;
@@ -157,12 +160,13 @@ class CONTENT_EXPORT WebMediaPlayerMS
blink::WebMediaPlayer::NetworkState GetNetworkState() const override;
blink::WebMediaPlayer::ReadyState GetReadyState() const override;
+ blink::WebMediaPlayer::SurfaceLayerMode GetVideoSurfaceLayerMode()
+ const override;
+
blink::WebString GetErrorMessage() const override;
bool DidLoadingProgress() override;
- bool DidGetOpaqueResponseFromServiceWorker() const override;
- bool HasSingleSecurityOrigin() const override;
- bool DidPassCORSAccessCheck() const override;
+ bool WouldTaintOrigin() const override;
double MediaTimeForTimeValue(double timeValue) const override;
@@ -230,6 +234,8 @@ class CONTENT_EXPORT WebMediaPlayerMS
void TrackRemoved(const blink::WebMediaStreamTrack& track) override;
void ActiveStateChanged(bool is_active) override;
+ void OnDisplayTypeChanged(WebMediaPlayer::DisplayType) override;
+
private:
friend class WebMediaPlayerMSTest;
@@ -237,11 +243,21 @@ class CONTENT_EXPORT WebMediaPlayerMS
static const gfx::Size kUseGpuMemoryBufferVideoFramesMinResolution;
#endif // defined(OS_WIN)
+ // When we lose the context_provider, we destroy the CompositorFrameSink to
+ // prevent frames from being submitted. The current surface_ids become
+ // invalid.
+ void OnFrameSinkDestroyed();
+
void OnFirstFrameReceived(media::VideoRotation video_rotation,
bool is_opaque);
void OnOpacityChanged(bool is_opaque);
void OnRotationChanged(media::VideoRotation video_rotation, bool is_opaque);
+ bool IsInPictureInPicture() const;
+
+ // Switch to SurfaceLayer, either initially or from VideoLayer.
+ void ActivateSurfaceLayerForVideo();
+
// Need repaint due to state change.
void RepaintInternal();
@@ -309,6 +325,7 @@ class CONTENT_EXPORT WebMediaPlayerMS
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
const scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
+
const scoped_refptr<base::TaskRunner> worker_task_runner_;
media::GpuVideoAcceleratorFactories* gpu_factories_;
@@ -336,8 +353,11 @@ class CONTENT_EXPORT WebMediaPlayerMS
CreateSurfaceLayerBridgeCB create_bridge_callback_;
+ std::unique_ptr<blink::WebVideoFrameSubmitter> submitter_;
+
// Whether the use of a surface layer instead of a video layer is enabled.
- bool surface_layer_for_video_enabled_ = false;
+ blink::WebMediaPlayer::SurfaceLayerMode surface_layer_mode_ =
+ blink::WebMediaPlayer::SurfaceLayerMode::kNever;
// Owns the weblayer and obtains/maintains SurfaceIds for
// kUseSurfaceLayerForVideo feature.
diff --git a/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.cc b/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.cc
index 02b2d8ddb0f..02fc7ee8551 100644
--- a/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.cc
+++ b/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.cc
@@ -27,6 +27,7 @@
#include "third_party/blink/public/platform/web_media_stream.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
+#include "third_party/blink/public/platform/web_video_frame_submitter.h"
#include "third_party/libyuv/include/libyuv/convert.h"
#include "third_party/libyuv/include/libyuv/planar_functions.h"
#include "third_party/libyuv/include/libyuv/video_common.h"
@@ -67,7 +68,8 @@ scoped_refptr<media::VideoFrame> CopyFrame(
DCHECK(provider->ContextGL());
video_renderer->Copy(
frame.get(), &paint_canvas,
- media::Context3D(provider->ContextGL(), provider->GrContext()));
+ media::Context3D(provider->ContextGL(), provider->GrContext()),
+ provider->ContextSupport());
SkPixmap pixmap;
const bool result = bitmap.peekPixels(&pixmap);
@@ -128,11 +130,16 @@ scoped_refptr<media::VideoFrame> CopyFrame(
} // anonymous namespace
WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
- scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner>
+ video_frame_compositor_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
const blink::WebMediaStream& web_stream,
+ std::unique_ptr<blink::WebVideoFrameSubmitter> submitter,
+ blink::WebMediaPlayer::SurfaceLayerMode surface_layer_mode,
const base::WeakPtr<WebMediaPlayerMS>& player)
- : compositor_task_runner_(compositor_task_runner),
+ : RefCountedDeleteOnSequence<WebMediaPlayerMSCompositor>(
+ video_frame_compositor_task_runner),
+ video_frame_compositor_task_runner_(video_frame_compositor_task_runner),
io_task_runner_(io_task_runner),
player_(player),
video_frame_provider_client_(nullptr),
@@ -141,9 +148,23 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
total_frame_count_(0),
dropped_frame_count_(0),
stopped_(true),
- render_started_(!stopped_) {
+ render_started_(!stopped_),
+ weak_ptr_factory_(this) {
main_message_loop_ = base::MessageLoopCurrent::Get();
+ if (surface_layer_mode != blink::WebMediaPlayer::SurfaceLayerMode::kNever) {
+ submitter_ = std::move(submitter);
+
+ video_frame_compositor_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&WebMediaPlayerMSCompositor::InitializeSubmitter,
+ weak_ptr_factory_.GetWeakPtr()));
+ update_submission_state_callback_ = media::BindToLoop(
+ video_frame_compositor_task_runner_,
+ base::BindRepeating(&WebMediaPlayerMSCompositor::UpdateSubmissionState,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+
blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
if (!web_stream.IsNull())
video_tracks = web_stream.VideoTracks();
@@ -168,8 +189,64 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
}
WebMediaPlayerMSCompositor::~WebMediaPlayerMSCompositor() {
- DCHECK(!video_frame_provider_client_)
- << "Must call StopUsingProvider() before dtor!";
+ if (submitter_) {
+ video_frame_compositor_task_runner_->DeleteSoon(FROM_HERE,
+ std::move(submitter_));
+ } else {
+ DCHECK(!video_frame_provider_client_)
+ << "Must call StopUsingProvider() before dtor!";
+ }
+}
+
+void WebMediaPlayerMSCompositor::InitializeSubmitter() {
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
+ submitter_->Initialize(this);
+}
+
+void WebMediaPlayerMSCompositor::UpdateSubmissionState(bool state) {
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
+ submitter_->UpdateSubmissionState(state);
+}
+
+// TODO(https://crbug/879424): Rename, since it really doesn't enable
+// submission. Do this along with the VideoFrameSubmitter refactor.
+void WebMediaPlayerMSCompositor::EnableSubmission(
+ const viz::SurfaceId& id,
+ media::VideoRotation rotation,
+ bool force_submit,
+ bool is_opaque,
+ blink::WebFrameSinkDestroyedCallback frame_sink_destroyed_callback) {
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
+
+ // If we're switching to |submitter_| from some other client, then tell it.
+ if (video_frame_provider_client_ &&
+ video_frame_provider_client_ != submitter_.get()) {
+ video_frame_provider_client_->StopUsingProvider();
+ }
+
+ submitter_->SetRotation(rotation);
+ submitter_->SetForceSubmit(force_submit);
+ submitter_->SetIsOpaque(is_opaque);
+ submitter_->EnableSubmission(id, std::move(frame_sink_destroyed_callback));
+ video_frame_provider_client_ = submitter_.get();
+
+ if (!stopped_)
+ video_frame_provider_client_->StartRendering();
+}
+
+void WebMediaPlayerMSCompositor::UpdateRotation(media::VideoRotation rotation) {
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
+ submitter_->SetRotation(rotation);
+}
+
+void WebMediaPlayerMSCompositor::SetForceSubmit(bool force_submit) {
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
+ submitter_->SetForceSubmit(force_submit);
+}
+
+void WebMediaPlayerMSCompositor::UpdateIsOpaque(bool is_opaque) {
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
+ submitter_->SetIsOpaque(is_opaque);
}
gfx::Size WebMediaPlayerMSCompositor::GetCurrentSize() {
@@ -200,7 +277,7 @@ size_t WebMediaPlayerMSCompositor::dropped_frame_count() {
void WebMediaPlayerMSCompositor::SetVideoFrameProviderClient(
cc::VideoFrameProvider::Client* client) {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
if (video_frame_provider_client_)
video_frame_provider_client_->StopUsingProvider();
@@ -272,7 +349,7 @@ void WebMediaPlayerMSCompositor::EnqueueFrame(
bool WebMediaPlayerMSCompositor::UpdateCurrentFrame(
base::TimeTicks deadline_min,
base::TimeTicks deadline_max) {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
TRACE_EVENT_BEGIN2("media", "UpdateCurrentFrame", "Actual Render Begin",
deadline_min.ToInternalValue(), "Actual Render End",
@@ -280,22 +357,27 @@ bool WebMediaPlayerMSCompositor::UpdateCurrentFrame(
if (stopped_)
return false;
- base::TimeTicks render_time;
-
base::AutoLock auto_lock(current_frame_lock_);
if (rendering_frame_buffer_)
RenderUsingAlgorithm(deadline_min, deadline_max);
- if (!current_frame_->metadata()->GetTimeTicks(
- media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
- DCHECK(!rendering_frame_buffer_)
- << "VideoFrames need REFERENCE_TIME to use "
- "sophisticated video rendering algorithm.";
+ bool tracing_or_dcheck_enabled = false;
+ TRACE_EVENT_CATEGORY_GROUP_ENABLED("media", &tracing_or_dcheck_enabled);
+#if DCHECK_IS_ON()
+ tracing_or_dcheck_enabled = true;
+#endif // DCHECK_IS_ON()
+ if (tracing_or_dcheck_enabled) {
+ base::TimeTicks render_time;
+ if (!current_frame_->metadata()->GetTimeTicks(
+ media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
+ DCHECK(!rendering_frame_buffer_)
+ << "VideoFrames need REFERENCE_TIME to use "
+ "sophisticated video rendering algorithm.";
+ }
+ TRACE_EVENT_END2("media", "UpdateCurrentFrame", "Ideal Render Instant",
+ render_time.ToInternalValue(), "Serial", serial_);
}
-
- TRACE_EVENT_END2("media", "UpdateCurrentFrame", "Ideal Render Instant",
- render_time.ToInternalValue(), "Serial", serial_);
return !current_frame_rendered_;
}
@@ -306,7 +388,7 @@ bool WebMediaPlayerMSCompositor::HasCurrentFrame() {
scoped_refptr<media::VideoFrame> WebMediaPlayerMSCompositor::GetCurrentFrame() {
DVLOG(3) << __func__;
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
base::AutoLock auto_lock(current_frame_lock_);
TRACE_EVENT_INSTANT1("media", "WebMediaPlayerMSCompositor::GetCurrentFrame",
TRACE_EVENT_SCOPE_THREAD, "Timestamp",
@@ -319,7 +401,7 @@ scoped_refptr<media::VideoFrame> WebMediaPlayerMSCompositor::GetCurrentFrame() {
void WebMediaPlayerMSCompositor::PutCurrentFrame() {
DVLOG(3) << __func__;
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
current_frame_rendered_ = true;
}
@@ -339,7 +421,7 @@ void WebMediaPlayerMSCompositor::StartRendering() {
base::AutoLock auto_lock(current_frame_lock_);
render_started_ = true;
}
- compositor_task_runner_->PostTask(
+ video_frame_compositor_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebMediaPlayerMSCompositor::StartRenderingInternal,
this));
@@ -347,7 +429,7 @@ void WebMediaPlayerMSCompositor::StartRendering() {
void WebMediaPlayerMSCompositor::StopRendering() {
DCHECK(thread_checker_.CalledOnValidThread());
- compositor_task_runner_->PostTask(
+ video_frame_compositor_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebMediaPlayerMSCompositor::StopRenderingInternal, this));
}
@@ -365,7 +447,7 @@ void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() {
void WebMediaPlayerMSCompositor::StopUsingProvider() {
DCHECK(thread_checker_.CalledOnValidThread());
- compositor_task_runner_->PostTask(
+ video_frame_compositor_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&WebMediaPlayerMSCompositor::StopUsingProviderInternal,
this));
@@ -374,7 +456,7 @@ void WebMediaPlayerMSCompositor::StopUsingProvider() {
bool WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks(
const std::vector<base::TimeDelta>& timestamps,
std::vector<base::TimeTicks>* wall_clock_times) {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread() ||
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread() ||
thread_checker_.CalledOnValidThread() ||
io_task_runner_->BelongsToCurrentThread());
for (const base::TimeDelta& timestamp : timestamps) {
@@ -387,7 +469,7 @@ bool WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks(
void WebMediaPlayerMSCompositor::RenderUsingAlgorithm(
base::TimeTicks deadline_min,
base::TimeTicks deadline_max) {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
current_frame_lock_.AssertAcquired();
last_deadline_max_ = deadline_max;
last_render_length_ = deadline_max - deadline_min;
@@ -417,7 +499,7 @@ void WebMediaPlayerMSCompositor::RenderUsingAlgorithm(
void WebMediaPlayerMSCompositor::RenderWithoutAlgorithm(
const scoped_refptr<media::VideoFrame>& frame) {
DCHECK(io_task_runner_->BelongsToCurrentThread());
- compositor_task_runner_->PostTask(
+ video_frame_compositor_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor, this,
@@ -426,7 +508,7 @@ void WebMediaPlayerMSCompositor::RenderWithoutAlgorithm(
void WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor(
const scoped_refptr<media::VideoFrame>& frame) {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
{
base::AutoLock auto_lock(current_frame_lock_);
SetCurrentFrame(frame);
@@ -437,7 +519,7 @@ void WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor(
void WebMediaPlayerMSCompositor::SetCurrentFrame(
const scoped_refptr<media::VideoFrame>& frame) {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
current_frame_lock_.AssertAcquired();
TRACE_EVENT_INSTANT1("media", "WebMediaPlayerMSCompositor::SetCurrentFrame",
TRACE_EVENT_SCOPE_THREAD, "Timestamp",
@@ -459,7 +541,7 @@ void WebMediaPlayerMSCompositor::SetCurrentFrame(
}
void WebMediaPlayerMSCompositor::StartRenderingInternal() {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
stopped_ = false;
if (video_frame_provider_client_)
@@ -467,7 +549,7 @@ void WebMediaPlayerMSCompositor::StartRenderingInternal() {
}
void WebMediaPlayerMSCompositor::StopRenderingInternal() {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
stopped_ = true;
// It is possible that the video gets paused and then resumed. We need to
@@ -485,7 +567,7 @@ void WebMediaPlayerMSCompositor::StopRenderingInternal() {
}
void WebMediaPlayerMSCompositor::StopUsingProviderInternal() {
- DCHECK(compositor_task_runner_->BelongsToCurrentThread());
+ DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread());
if (video_frame_provider_client_)
video_frame_provider_client_->StopUsingProvider();
video_frame_provider_client_ = nullptr;
diff --git a/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.h b/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.h
index 921b0bb192a..f10a0d1b2c5 100644
--- a/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.h
+++ b/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.h
@@ -11,7 +11,7 @@
#include <memory>
#include <vector>
-#include "base/memory/ref_counted.h"
+#include "base/memory/ref_counted_delete_on_sequence.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/lock.h"
@@ -20,6 +20,8 @@
#include "cc/layers/video_frame_provider.h"
#include "content/common/content_export.h"
#include "media/base/media_log.h"
+#include "media/blink/webmediaplayer_params.h"
+#include "third_party/blink/public/platform/web_video_frame_submitter.h"
namespace base {
class SingleThreadTaskRunner;
@@ -37,6 +39,10 @@ namespace media {
class VideoRendererAlgorithm;
}
+namespace viz {
+class SurfaceId;
+}
+
namespace content {
class WebMediaPlayerMS;
@@ -51,16 +57,18 @@ class WebMediaPlayerMS;
// frame, and submit it whenever asked by the compositor.
class CONTENT_EXPORT WebMediaPlayerMSCompositor
: public cc::VideoFrameProvider,
- public base::RefCountedThreadSafe<WebMediaPlayerMSCompositor> {
+ public base::RefCountedDeleteOnSequence<WebMediaPlayerMSCompositor> {
public:
// This |url| represents the media stream we are rendering. |url| is used to
// find out what web stream this WebMediaPlayerMSCompositor is playing, and
// together with flag "--disable-rtc-smoothness-algorithm" determine whether
// we enable algorithm or not.
WebMediaPlayerMSCompositor(
- scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
const blink::WebMediaStream& web_stream,
+ std::unique_ptr<blink::WebVideoFrameSubmitter> submitter,
+ blink::WebMediaPlayer::SurfaceLayerMode surface_layer_mode,
const base::WeakPtr<WebMediaPlayerMS>& player);
// Can be called from any thread.
@@ -76,6 +84,24 @@ class CONTENT_EXPORT WebMediaPlayerMSCompositor
size_t total_frame_count();
size_t dropped_frame_count();
+ // Signals the VideoFrameSubmitter to prepare to receive BeginFrames and
+ // submit video frames given by WebMediaPlayerMSCompositor.
+ virtual void EnableSubmission(
+ const viz::SurfaceId& id,
+ media::VideoRotation rotation,
+ bool force_submit,
+ bool is_opaque,
+ blink::WebFrameSinkDestroyedCallback frame_sink_destroyed_callback);
+
+ // Updates the rotation information for frames given to |submitter_|.
+ void UpdateRotation(media::VideoRotation rotation);
+
+ // Notifies the |submitter_| that the frames must be submitted.
+ void SetForceSubmit(bool);
+
+ // Updates the opacity information for frames given to |submitter_|.
+ void UpdateIsOpaque(bool);
+
// VideoFrameProvider implementation.
void SetVideoFrameProviderClient(
cc::VideoFrameProvider::Client* client) override;
@@ -101,11 +127,19 @@ class CONTENT_EXPORT WebMediaPlayerMSCompositor
void StopUsingProvider();
private:
- friend class base::RefCountedThreadSafe<WebMediaPlayerMSCompositor>;
+ friend class base::RefCountedDeleteOnSequence<WebMediaPlayerMSCompositor>;
+ friend class base::DeleteHelper<WebMediaPlayerMSCompositor>;
friend class WebMediaPlayerMSTest;
~WebMediaPlayerMSCompositor() override;
+ // Ran on the |video_frame_compositor_task_runner_| to initialize
+ // |submitter_|
+ void InitializeSubmitter();
+
+ // Signals the VideoFrameSubmitter to stop submitting frames.
+ void UpdateSubmissionState(bool);
+
bool MapTimestampsToRenderTimeTicks(
const std::vector<base::TimeDelta>& timestamps,
std::vector<base::TimeTicks>* wall_clock_times);
@@ -138,7 +172,8 @@ class CONTENT_EXPORT WebMediaPlayerMSCompositor
// which is renderer main thread in this class.
base::ThreadChecker thread_checker_;
- const scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
+ const scoped_refptr<base::SingleThreadTaskRunner>
+ video_frame_compositor_task_runner_;
const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
base::MessageLoop* main_message_loop_;
@@ -186,6 +221,8 @@ class CONTENT_EXPORT WebMediaPlayerMSCompositor
bool stopped_;
bool render_started_;
+ std::unique_ptr<blink::WebVideoFrameSubmitter> submitter_;
+
std::map<base::TimeDelta, base::TimeTicks> timestamps_to_clock_times_;
cc::UpdateSubmissionStateCB update_submission_state_callback_;
@@ -194,6 +231,8 @@ class CONTENT_EXPORT WebMediaPlayerMSCompositor
// |dropped_frame_count_|, and |render_started_|.
base::Lock current_frame_lock_;
+ base::WeakPtrFactory<WebMediaPlayerMSCompositor> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerMSCompositor);
};
} // namespace content
diff --git a/chromium/content/renderer/media/stream/webmediaplayer_ms_unittest.cc b/chromium/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
index 065fc62abdf..e84c2bb4a8e 100644
--- a/chromium/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
+++ b/chromium/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
@@ -8,9 +8,9 @@
#include <vector>
#include "base/containers/circular_deque.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "cc/layers/layer.h"
#include "content/public/renderer/media_stream_renderer_factory.h"
@@ -21,12 +21,18 @@
#include "media/base/video_frame.h"
#include "media/video/mock_gpu_memory_buffer_video_frame_pool.h"
#include "media/video/mock_gpu_video_accelerator_factories.h"
+#include "third_party/blink/public/common/picture_in_picture/picture_in_picture_control_info.h"
#include "third_party/blink/public/platform/web_fullscreen_video_status.h"
#include "third_party/blink/public/platform/web_media_player.h"
#include "third_party/blink/public/platform/web_media_player_client.h"
#include "third_party/blink/public/platform/web_media_player_source.h"
+using ::testing::_;
+using ::testing::ByRef;
+using ::testing::Eq;
+using ::testing::NiceMock;
using ::testing::Return;
+using ::testing::ReturnRef;
using ::testing::StrictMock;
namespace content {
@@ -40,12 +46,22 @@ enum class FrameType {
class MockSurfaceLayerBridge : public blink::WebSurfaceLayerBridge {
public:
+ MockSurfaceLayerBridge() {
+ ON_CALL(*this, GetSurfaceId).WillByDefault(ReturnRef(surface_id_));
+ }
+
MOCK_CONST_METHOD0(GetCcLayer, cc::Layer*());
MOCK_CONST_METHOD0(GetFrameSinkId, const viz::FrameSinkId&());
MOCK_CONST_METHOD0(GetSurfaceId, const viz::SurfaceId&());
MOCK_METHOD1(SetContentsOpaque, void(bool));
MOCK_METHOD0(CreateSurfaceLayer, void());
MOCK_METHOD0(ClearSurfaceId, void());
+
+ viz::FrameSinkId frame_sink_id_ = viz::FrameSinkId(1, 1);
+ viz::LocalSurfaceId local_surface_id_ =
+ viz::LocalSurfaceId(11, base::UnguessableToken::Deserialize(0x111111, 0));
+ viz::SurfaceId surface_id_ =
+ viz::SurfaceId(frame_sink_id_, local_surface_id_);
};
using TestFrame = std::pair<FrameType, scoped_refptr<media::VideoFrame>>;
@@ -89,37 +105,21 @@ class FakeWebMediaPlayerDelegate
EXPECT_EQ(delegate_id_, delegate_id);
}
- void DidPictureInPictureModeStart(
- int delegate_id,
- const viz::SurfaceId&,
- const gfx::Size&,
- blink::WebMediaPlayer::PipWindowOpenedCallback) override {
- EXPECT_EQ(delegate_id_, delegate_id);
- }
-
- void DidPictureInPictureModeEnd(
- int delegate_id,
- blink::WebMediaPlayer::PipWindowClosedCallback) override {
- EXPECT_EQ(delegate_id_, delegate_id);
- }
-
- void DidSetPictureInPictureCustomControls(
- int delegate_id,
- const std::vector<blink::PictureInPictureControlInfo>&) override {
- EXPECT_EQ(delegate_id_, delegate_id);
- }
-
- void DidPictureInPictureSurfaceChange(int delegate_id,
- const viz::SurfaceId&,
- const gfx::Size&) override {
- EXPECT_EQ(delegate_id_, delegate_id);
- }
-
- void RegisterPictureInPictureWindowResizeCallback(
- int delegate_id,
- blink::WebMediaPlayer::PipWindowResizedCallback) override {
- EXPECT_EQ(delegate_id_, delegate_id);
- }
+ MOCK_METHOD5(DidPictureInPictureModeStart,
+ void(int,
+ const viz::SurfaceId&,
+ const gfx::Size&,
+ blink::WebMediaPlayer::PipWindowOpenedCallback,
+ bool));
+ MOCK_METHOD2(DidPictureInPictureModeEnd,
+ void(int, blink::WebMediaPlayer::PipWindowClosedCallback));
+ MOCK_METHOD2(DidSetPictureInPictureCustomControls,
+ void(int,
+ const std::vector<blink::PictureInPictureControlInfo>&));
+ MOCK_METHOD4(DidPictureInPictureSurfaceChange,
+ void(int, const viz::SurfaceId&, const gfx::Size&, bool));
+ MOCK_METHOD2(RegisterPictureInPictureWindowResizeCallback,
+ void(int, blink::WebMediaPlayer::PipWindowResizedCallback));
void DidPause(int delegate_id) override {
EXPECT_EQ(delegate_id_, delegate_id);
@@ -169,6 +169,8 @@ class FakeWebMediaPlayerDelegate
void set_hidden(bool is_hidden) { is_hidden_ = is_hidden; }
+ int delegate_id() { return delegate_id_; }
+
private:
int delegate_id_ = 1234;
Observer* observer_ = nullptr;
@@ -414,6 +416,23 @@ void MockMediaStreamVideoRenderer::InjectFrame() {
message_loop_controller_->GetClosure().Run();
}
+class MockWebVideoFrameSubmitter : public blink::WebVideoFrameSubmitter {
+ public:
+ // blink::WebVideoFrameSubmitter implementation.
+ MOCK_METHOD0(StopUsingProvider, void());
+ MOCK_METHOD0(DidReceiveFrame, void());
+ MOCK_METHOD2(EnableSubmission,
+ void(viz::SurfaceId, blink::WebFrameSinkDestroyedCallback));
+ MOCK_METHOD0(StartRendering, void());
+ MOCK_METHOD0(StopRendering, void());
+ MOCK_METHOD1(Initialize, void(cc::VideoFrameProvider*));
+ MOCK_METHOD1(SetRotation, void(media::VideoRotation));
+ MOCK_METHOD1(SetIsOpaque, void(bool));
+ MOCK_METHOD1(UpdateSubmissionState, void(bool));
+ MOCK_METHOD1(SetForceSubmit, void(bool));
+ MOCK_CONST_METHOD0(IsDrivingFrameUpdates, bool());
+};
+
// The class is used to generate a MockVideoProvider in
// WebMediaPlayerMS::load().
class MockRenderFactory : public MediaStreamRendererFactory {
@@ -498,27 +517,33 @@ scoped_refptr<MediaStreamVideoRenderer> MockRenderFactory::GetVideoRenderer(
// 7. When WebMediaPlayerMS::play gets called, evething paused in step 6 should
// be resumed.
class WebMediaPlayerMSTest
- : public testing::TestWithParam<testing::tuple<bool, bool>> ,
+ : public testing::TestWithParam<
+ testing::tuple<bool /* enable_surface_layer_for_video */,
+ bool /* opaque_frame */,
+ bool /* odd_size_frame */>>,
public blink::WebMediaPlayerClient,
public cc::VideoFrameProvider::Client {
public:
WebMediaPlayerMSTest()
- : render_factory_(new MockRenderFactory(message_loop_.task_runner(),
- &message_loop_controller_)),
+ : render_factory_(
+ new MockRenderFactory(base::ThreadTaskRunnerHandle::Get(),
+ &message_loop_controller_)),
gpu_factories_(new media::MockGpuVideoAcceleratorFactories(nullptr)),
surface_layer_bridge_(
- std::make_unique<StrictMock<MockSurfaceLayerBridge>>()),
+ std::make_unique<NiceMock<MockSurfaceLayerBridge>>()),
+ submitter_(std::make_unique<NiceMock<MockWebVideoFrameSubmitter>>()),
layer_set_(false),
rendering_(false),
background_rendering_(false) {
surface_layer_bridge_ptr_ = surface_layer_bridge_.get();
+ submitter_ptr_ = submitter_.get();
}
~WebMediaPlayerMSTest() override {
player_.reset();
base::RunLoop().RunUntilIdle();
}
- void InitializeWebMediaPlayerMS(bool enable_surface_layer_for_video);
+ void InitializeWebMediaPlayerMS();
MockMediaStreamVideoRenderer* LoadAndGetFrameProvider(bool algorithm_enabled);
@@ -566,9 +591,6 @@ class WebMediaPlayerMSTest
}
bool HasNativeControls() override { return false; }
bool IsAudioElement() override { return is_audio_element_; }
- blink::WebMediaPlayer::DisplayType DisplayType() const override {
- return blink::WebMediaPlayer::DisplayType::kInline;
- }
bool IsInAutoPIP() const override { return false; }
void ActivateViewportIntersectionMonitoring(bool activate) override {}
void MediaRemotingStarted(
@@ -613,6 +635,7 @@ class WebMediaPlayerMSTest
void(blink::WebMediaPlayer::NetworkState));
MOCK_METHOD1(DoReadyStateChanged, void(blink::WebMediaPlayer::ReadyState));
MOCK_METHOD1(CheckSizeChanged, void(gfx::Size));
+ MOCK_CONST_METHOD0(DisplayType, blink::WebMediaPlayer::DisplayType());
MOCK_CONST_METHOD0(CouldPlayIfEnoughData, bool());
std::unique_ptr<blink::WebSurfaceLayerBridge> CreateMockSurfaceLayerBridge(
@@ -621,7 +644,7 @@ class WebMediaPlayerMSTest
return std::move(surface_layer_bridge_);
}
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
MockRenderFactory* render_factory_;
std::unique_ptr<media::MockGpuVideoAcceleratorFactories> gpu_factories_;
FakeWebMediaPlayerDelegate delegate_;
@@ -631,8 +654,11 @@ class WebMediaPlayerMSTest
cc::Layer* layer_;
bool is_audio_element_ = false;
std::vector<base::OnceClosure> frame_ready_cbs_;
- std::unique_ptr<StrictMock<MockSurfaceLayerBridge>> surface_layer_bridge_;
- StrictMock<MockSurfaceLayerBridge>* surface_layer_bridge_ptr_ = nullptr;
+ std::unique_ptr<NiceMock<MockSurfaceLayerBridge>> surface_layer_bridge_;
+ std::unique_ptr<NiceMock<MockWebVideoFrameSubmitter>> submitter_;
+ NiceMock<MockSurfaceLayerBridge>* surface_layer_bridge_ptr_ = nullptr;
+ NiceMock<MockWebVideoFrameSubmitter>* submitter_ptr_ = nullptr;
+ bool enable_surface_layer_for_video_ = false;
private:
// Main function trying to ask WebMediaPlayerMS to submit a frame for
@@ -644,17 +670,21 @@ class WebMediaPlayerMSTest
bool background_rendering_;
};
-void WebMediaPlayerMSTest::InitializeWebMediaPlayerMS(
- bool enable_surface_layer_for_video) {
+void WebMediaPlayerMSTest::InitializeWebMediaPlayerMS() {
+ enable_surface_layer_for_video_ = testing::get<0>(GetParam());
+ blink::WebMediaPlayer::SurfaceLayerMode surface_layer_mode =
+ enable_surface_layer_for_video_
+ ? blink::WebMediaPlayer::SurfaceLayerMode::kAlways
+ : blink::WebMediaPlayer::SurfaceLayerMode::kNever;
player_ = std::make_unique<WebMediaPlayerMS>(
nullptr, this, &delegate_, std::make_unique<media::MediaLog>(),
std::unique_ptr<MediaStreamRendererFactory>(render_factory_),
- message_loop_.task_runner(), message_loop_.task_runner(),
- message_loop_.task_runner(), message_loop_.task_runner(),
+ base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
+ base::ThreadTaskRunnerHandle::Get(), base::ThreadTaskRunnerHandle::Get(),
gpu_factories_.get(), blink::WebString(),
- base::BindRepeating(&WebMediaPlayerMSTest::CreateMockSurfaceLayerBridge,
- base::Unretained(this)),
- enable_surface_layer_for_video);
+ base::BindOnce(&WebMediaPlayerMSTest::CreateMockSurfaceLayerBridge,
+ base::Unretained(this)),
+ std::move(submitter_), surface_layer_mode);
}
MockMediaStreamVideoRenderer* WebMediaPlayerMSTest::LoadAndGetFrameProvider(
@@ -709,8 +739,12 @@ void WebMediaPlayerMSTest::SetCcLayer(cc::Layer* layer) {
layer_set_ = layer ? true : false;
layer_ = layer;
- if (layer)
- compositor_->SetVideoFrameProviderClient(this);
+ if (layer) {
+ if (enable_surface_layer_for_video_)
+ compositor_->SetVideoFrameProviderClient(submitter_ptr_);
+ else
+ compositor_->SetVideoFrameProviderClient(this);
+ }
DoSetCcLayer(!!layer);
}
@@ -722,7 +756,7 @@ void WebMediaPlayerMSTest::StopUsingProvider() {
void WebMediaPlayerMSTest::StartRendering() {
if (!rendering_) {
rendering_ = true;
- message_loop_.task_runner()->PostTask(
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&WebMediaPlayerMSTest::RenderFrame,
base::Unretained(this)));
}
@@ -757,7 +791,7 @@ void WebMediaPlayerMSTest::RenderFrame() {
auto frame = compositor_->GetCurrentFrame();
compositor_->PutCurrentFrame();
}
- message_loop_.task_runner()->PostDelayedTask(
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&WebMediaPlayerMSTest::RenderFrame,
base::Unretained(this)),
@@ -769,8 +803,8 @@ void WebMediaPlayerMSTest::SizeChanged() {
CheckSizeChanged(frame_size);
}
-TEST_F(WebMediaPlayerMSTest, NoDataDuringLoadForVideo) {
- InitializeWebMediaPlayerMS(false);
+TEST_P(WebMediaPlayerMSTest, NoDataDuringLoadForVideo) {
+ InitializeWebMediaPlayerMS();
EXPECT_CALL(*this, DoReadyStateChanged(
blink::WebMediaPlayer::kReadyStateHaveMetadata))
.Times(0);
@@ -787,8 +821,8 @@ TEST_F(WebMediaPlayerMSTest, NoDataDuringLoadForVideo) {
EXPECT_CALL(*this, DoSetCcLayer(false));
}
-TEST_F(WebMediaPlayerMSTest, NoWaitForFrameForAudio) {
- InitializeWebMediaPlayerMS(false);
+TEST_P(WebMediaPlayerMSTest, NoWaitForFrameForAudio) {
+ InitializeWebMediaPlayerMS();
is_audio_element_ = true;
scoped_refptr<MediaStreamAudioRenderer> audio_renderer(
new MockMediaStreamAudioRenderer());
@@ -814,8 +848,8 @@ TEST_F(WebMediaPlayerMSTest, NoWaitForFrameForAudio) {
EXPECT_CALL(*this, DoSetCcLayer(false));
}
-TEST_F(WebMediaPlayerMSTest, NoWaitForFrameForAudioOnly) {
- InitializeWebMediaPlayerMS(false);
+TEST_P(WebMediaPlayerMSTest, NoWaitForFrameForAudioOnly) {
+ InitializeWebMediaPlayerMS();
render_factory_->set_support_video_renderer(false);
scoped_refptr<MediaStreamAudioRenderer> audio_renderer(
new MockMediaStreamAudioRenderer());
@@ -828,12 +862,12 @@ TEST_F(WebMediaPlayerMSTest, NoWaitForFrameForAudioOnly) {
EXPECT_CALL(*this, DoSetCcLayer(false));
}
-TEST_F(WebMediaPlayerMSTest, Playing_Normal) {
+TEST_P(WebMediaPlayerMSTest, Playing_Normal) {
// This test sends a bunch of normal frames with increasing timestamps
// and verifies that they are produced by WebMediaPlayerMS in appropriate
// order.
- InitializeWebMediaPlayerMS(false);
+ InitializeWebMediaPlayerMS();
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
@@ -842,8 +876,12 @@ TEST_F(WebMediaPlayerMSTest, Playing_Normal) {
std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
provider->QueueFrames(timestamps);
- EXPECT_CALL(*this, DoSetCcLayer(true));
- EXPECT_CALL(*this, DoStartRendering());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*submitter_ptr_, StartRendering());
+ } else {
+ EXPECT_CALL(*this, DoSetCcLayer(true));
+ EXPECT_CALL(*this, DoStartRendering());
+ }
EXPECT_CALL(*this, DoReadyStateChanged(
blink::WebMediaPlayer::kReadyStateHaveMetadata));
EXPECT_CALL(*this, DoReadyStateChanged(
@@ -858,14 +896,17 @@ TEST_F(WebMediaPlayerMSTest, Playing_Normal) {
testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*this, DoSetCcLayer(false));
- EXPECT_CALL(*this, DoStopRendering());
+ if (enable_surface_layer_for_video_)
+ EXPECT_CALL(*submitter_ptr_, StopUsingProvider());
+ else
+ EXPECT_CALL(*this, DoStopRendering());
}
-TEST_F(WebMediaPlayerMSTest, Playing_ErrorFrame) {
+TEST_P(WebMediaPlayerMSTest, Playing_ErrorFrame) {
// This tests sends a broken frame to WebMediaPlayerMS, and verifies
// OnSourceError function works as expected.
- InitializeWebMediaPlayerMS(false);
+ InitializeWebMediaPlayerMS();
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(false);
@@ -875,8 +916,12 @@ TEST_F(WebMediaPlayerMSTest, Playing_ErrorFrame) {
std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
provider->QueueFrames(timestamps);
- EXPECT_CALL(*this, DoSetCcLayer(true));
- EXPECT_CALL(*this, DoStartRendering());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*submitter_ptr_, StartRendering());
+ } else {
+ EXPECT_CALL(*this, DoSetCcLayer(true));
+ EXPECT_CALL(*this, DoStartRendering());
+ }
EXPECT_CALL(*this, DoReadyStateChanged(
blink::WebMediaPlayer::kReadyStateHaveMetadata));
EXPECT_CALL(*this, DoReadyStateChanged(
@@ -890,13 +935,16 @@ TEST_F(WebMediaPlayerMSTest, Playing_ErrorFrame) {
testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*this, DoSetCcLayer(false));
- EXPECT_CALL(*this, DoStopRendering());
+ if (enable_surface_layer_for_video_)
+ EXPECT_CALL(*submitter_ptr_, StopUsingProvider());
+ else
+ EXPECT_CALL(*this, DoStopRendering());
}
TEST_P(WebMediaPlayerMSTest, PlayThenPause) {
- InitializeWebMediaPlayerMS(false);
- const bool opaque_frame = testing::get<0>(GetParam());
- const bool odd_size_frame = testing::get<1>(GetParam());
+ InitializeWebMediaPlayerMS();
+ const bool opaque_frame = testing::get<1>(GetParam());
+ const bool odd_size_frame = testing::get<2>(GetParam());
// In the middle of this test, WebMediaPlayerMS::pause will be called, and we
// are going to verify that during the pause stage, a frame gets freezed, and
// cc::VideoFrameProviderClient should also be paused.
@@ -908,8 +956,13 @@ TEST_P(WebMediaPlayerMSTest, PlayThenPause) {
std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
provider->QueueFrames(timestamps, opaque_frame, odd_size_frame);
- EXPECT_CALL(*this, DoSetCcLayer(true));
- EXPECT_CALL(*this, DoStartRendering());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
+ EXPECT_CALL(*submitter_ptr_, StartRendering());
+ } else {
+ EXPECT_CALL(*this, DoSetCcLayer(true));
+ EXPECT_CALL(*this, DoStartRendering());
+ }
EXPECT_CALL(*this, DoReadyStateChanged(
blink::WebMediaPlayer::kReadyStateHaveMetadata));
EXPECT_CALL(*this, DoReadyStateChanged(
@@ -923,7 +976,11 @@ TEST_P(WebMediaPlayerMSTest, PlayThenPause) {
testing::Mock::VerifyAndClearExpectations(this);
// Here we call pause, and expect a freezing frame.
- EXPECT_CALL(*this, DoStopRendering());
+ if (enable_surface_layer_for_video_)
+ EXPECT_CALL(*submitter_ptr_, StopRendering());
+ else
+ EXPECT_CALL(*this, DoStopRendering());
+
player_->Pause();
auto prev_frame = compositor_->GetCurrentFrameWithoutUpdatingStatistics();
message_loop_controller_.RunAndWaitForStatus(
@@ -936,9 +993,9 @@ TEST_P(WebMediaPlayerMSTest, PlayThenPause) {
}
TEST_P(WebMediaPlayerMSTest, PlayThenPauseThenPlay) {
- InitializeWebMediaPlayerMS(false);
- const bool opaque_frame = testing::get<0>(GetParam());
- const bool odd_size_frame = testing::get<1>(GetParam());
+ InitializeWebMediaPlayerMS();
+ const bool opaque_frame = testing::get<1>(GetParam());
+ const bool odd_size_frame = testing::get<2>(GetParam());
// Similary to PlayAndPause test above, this one focuses on testing that
// WebMediaPlayerMS can be resumed after a period of paused status.
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(false);
@@ -950,8 +1007,13 @@ TEST_P(WebMediaPlayerMSTest, PlayThenPauseThenPlay) {
std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
provider->QueueFrames(timestamps, opaque_frame, odd_size_frame);
- EXPECT_CALL(*this, DoSetCcLayer(true));
- EXPECT_CALL(*this, DoStartRendering());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
+ EXPECT_CALL(*submitter_ptr_, StartRendering());
+ } else {
+ EXPECT_CALL(*this, DoSetCcLayer(true));
+ EXPECT_CALL(*this, DoStartRendering());
+ }
EXPECT_CALL(*this, DoReadyStateChanged(
blink::WebMediaPlayer::kReadyStateHaveMetadata));
EXPECT_CALL(*this, DoReadyStateChanged(
@@ -965,7 +1027,11 @@ TEST_P(WebMediaPlayerMSTest, PlayThenPauseThenPlay) {
testing::Mock::VerifyAndClearExpectations(this);
// Here we call pause, and expect a freezing frame.
- EXPECT_CALL(*this, DoStopRendering());
+ if (enable_surface_layer_for_video_)
+ EXPECT_CALL(*submitter_ptr_, StopRendering());
+ else
+ EXPECT_CALL(*this, DoStopRendering());
+
player_->Pause();
auto prev_frame = compositor_->GetCurrentFrameWithoutUpdatingStatistics();
message_loop_controller_.RunAndWaitForStatus(
@@ -975,7 +1041,11 @@ TEST_P(WebMediaPlayerMSTest, PlayThenPauseThenPlay) {
testing::Mock::VerifyAndClearExpectations(this);
// We resume the player, and expect rendering can continue.
- EXPECT_CALL(*this, DoStartRendering());
+ if (enable_surface_layer_for_video_)
+ EXPECT_CALL(*submitter_ptr_, StartRendering());
+ else
+ EXPECT_CALL(*this, DoStartRendering());
+
player_->Play();
prev_frame = compositor_->GetCurrentFrameWithoutUpdatingStatistics();
message_loop_controller_.RunAndWaitForStatus(
@@ -985,26 +1055,30 @@ TEST_P(WebMediaPlayerMSTest, PlayThenPauseThenPlay) {
testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*this, DoSetCcLayer(false));
- EXPECT_CALL(*this, DoStopRendering());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*submitter_ptr_, StopUsingProvider());
+ } else {
+ EXPECT_CALL(*this, DoStopRendering());
+ }
}
-INSTANTIATE_TEST_CASE_P(,
- WebMediaPlayerMSTest,
- ::testing::Combine(::testing::Bool(),
- ::testing::Bool()));
-
// During this test, we check that when we send rotated video frames, it applies
// to player's natural size.
-TEST_F(WebMediaPlayerMSTest, RotationChange) {
- InitializeWebMediaPlayerMS(false);
+TEST_P(WebMediaPlayerMSTest, RotationChange) {
+ InitializeWebMediaPlayerMS();
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
static int tokens[] = {0, 33, kTestBrake};
std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
provider->QueueFrames(timestamps, false, false, 17, media::VIDEO_ROTATION_90);
- EXPECT_CALL(*this, DoSetCcLayer(true));
- EXPECT_CALL(*this, DoStartRendering());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
+ EXPECT_CALL(*submitter_ptr_, StartRendering());
+ } else {
+ EXPECT_CALL(*this, DoSetCcLayer(true));
+ EXPECT_CALL(*this, DoStartRendering());
+ }
EXPECT_CALL(*this, DoReadyStateChanged(
blink::WebMediaPlayer::kReadyStateHaveMetadata));
EXPECT_CALL(*this, DoReadyStateChanged(
@@ -1020,9 +1094,13 @@ TEST_F(WebMediaPlayerMSTest, RotationChange) {
// Change rotation.
provider->QueueFrames(timestamps, false, false, 17, media::VIDEO_ROTATION_0);
- EXPECT_CALL(*this, DoSetCcLayer(true));
- EXPECT_CALL(*this, DoStopRendering());
- EXPECT_CALL(*this, DoStartRendering());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*submitter_ptr_, SetRotation(media::VIDEO_ROTATION_0));
+ } else {
+ EXPECT_CALL(*this, DoSetCcLayer(true));
+ EXPECT_CALL(*this, DoStopRendering());
+ EXPECT_CALL(*this, DoStartRendering());
+ }
message_loop_controller_.RunAndWaitForStatus(
media::PipelineStatus::PIPELINE_OK);
natural_size = player_->NaturalSize();
@@ -1031,13 +1109,17 @@ TEST_F(WebMediaPlayerMSTest, RotationChange) {
testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*this, DoSetCcLayer(false));
- EXPECT_CALL(*this, DoStopRendering());
+
+ if (enable_surface_layer_for_video_)
+ EXPECT_CALL(*submitter_ptr_, StopUsingProvider());
+ else
+ EXPECT_CALL(*this, DoStopRendering());
}
// During this test, we check that web layer changes opacity according to the
// given frames.
-TEST_F(WebMediaPlayerMSTest, OpacityChange) {
- InitializeWebMediaPlayerMS(false);
+TEST_P(WebMediaPlayerMSTest, OpacityChange) {
+ InitializeWebMediaPlayerMS();
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
// Push one opaque frame.
@@ -1045,8 +1127,13 @@ TEST_F(WebMediaPlayerMSTest, OpacityChange) {
static int tokens[] = {0, kTestBrake};
std::vector<int> timestamps(tokens, tokens + arraysize(tokens));
provider->QueueFrames(timestamps, true);
- EXPECT_CALL(*this, DoSetCcLayer(true));
- EXPECT_CALL(*this, DoStartRendering());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
+ EXPECT_CALL(*submitter_ptr_, StartRendering());
+ } else {
+ EXPECT_CALL(*this, DoSetCcLayer(true));
+ EXPECT_CALL(*this, DoStartRendering());
+ }
EXPECT_CALL(*this, DoReadyStateChanged(
blink::WebMediaPlayer::kReadyStateHaveMetadata));
EXPECT_CALL(*this, DoReadyStateChanged(
@@ -1055,34 +1142,50 @@ TEST_F(WebMediaPlayerMSTest, OpacityChange) {
CheckSizeChanged(gfx::Size(kStandardWidth, kStandardHeight)));
message_loop_controller_.RunAndWaitForStatus(
media::PipelineStatus::PIPELINE_OK);
- ASSERT_TRUE(layer_ != nullptr);
- EXPECT_TRUE(layer_->contents_opaque());
+
+ if (!enable_surface_layer_for_video_) {
+ ASSERT_TRUE(layer_ != nullptr);
+ EXPECT_TRUE(layer_->contents_opaque());
+ }
// Push one transparent frame.
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false));
+ EXPECT_CALL(*submitter_ptr_, SetIsOpaque(false));
+ }
provider->QueueFrames(timestamps, false);
message_loop_controller_.RunAndWaitForStatus(
media::PipelineStatus::PIPELINE_OK);
- EXPECT_FALSE(layer_->contents_opaque());
+ if (!enable_surface_layer_for_video_)
+ EXPECT_FALSE(layer_->contents_opaque());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(true));
+ EXPECT_CALL(*submitter_ptr_, SetIsOpaque(true));
+ }
// Push another opaque frame.
provider->QueueFrames(timestamps, true);
message_loop_controller_.RunAndWaitForStatus(
media::PipelineStatus::PIPELINE_OK);
- EXPECT_TRUE(layer_->contents_opaque());
+ if (!enable_surface_layer_for_video_)
+ EXPECT_TRUE(layer_->contents_opaque());
testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*this, DoSetCcLayer(false));
- EXPECT_CALL(*this, DoStopRendering());
+ if (enable_surface_layer_for_video_)
+ EXPECT_CALL(*submitter_ptr_, StopUsingProvider());
+ else
+ EXPECT_CALL(*this, DoStopRendering());
}
-TEST_F(WebMediaPlayerMSTest, BackgroundRendering) {
+TEST_P(WebMediaPlayerMSTest, BackgroundRendering) {
// During this test, we will switch to background rendering mode, in which
// WebMediaPlayerMS::pause does not get called, but
// cc::VideoFrameProviderClient simply stops asking frames from
// WebMediaPlayerMS without an explicit notification. We should expect that
// WebMediaPlayerMS can digest old frames, rather than piling frames up and
// explode.
- InitializeWebMediaPlayerMS(false);
+ InitializeWebMediaPlayerMS();
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
const int kTestBrake = static_cast<int>(FrameType::TEST_BRAKE);
@@ -1092,8 +1195,13 @@ TEST_F(WebMediaPlayerMSTest, BackgroundRendering) {
std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
provider->QueueFrames(timestamps);
- EXPECT_CALL(*this, DoSetCcLayer(true));
- EXPECT_CALL(*this, DoStartRendering());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
+ EXPECT_CALL(*submitter_ptr_, StartRendering());
+ } else {
+ EXPECT_CALL(*this, DoSetCcLayer(true));
+ EXPECT_CALL(*this, DoStartRendering());
+ }
EXPECT_CALL(*this, DoReadyStateChanged(
blink::WebMediaPlayer::kReadyStateHaveMetadata));
EXPECT_CALL(*this, DoReadyStateChanged(
@@ -1106,7 +1214,11 @@ TEST_F(WebMediaPlayerMSTest, BackgroundRendering) {
// Switch to background rendering, expect rendering to continue for all the
// frames between kTestBrake frames.
- EXPECT_CALL(*this, DoDidReceiveFrame()).Times(testing::AtLeast(1));
+ if (enable_surface_layer_for_video_)
+ EXPECT_CALL(*submitter_ptr_, DidReceiveFrame()).Times(testing::AtLeast(1));
+ else
+ EXPECT_CALL(*this, DoDidReceiveFrame()).Times(testing::AtLeast(1));
+
SetBackgroundRendering(true);
auto prev_frame = compositor_->GetCurrentFrameWithoutUpdatingStatistics();
message_loop_controller_.RunAndWaitForStatus(
@@ -1124,14 +1236,17 @@ TEST_F(WebMediaPlayerMSTest, BackgroundRendering) {
testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*this, DoSetCcLayer(false));
- EXPECT_CALL(*this, DoStopRendering());
+ if (enable_surface_layer_for_video_)
+ EXPECT_CALL(*submitter_ptr_, StopUsingProvider());
+ else
+ EXPECT_CALL(*this, DoStopRendering());
}
-TEST_F(WebMediaPlayerMSTest, FrameSizeChange) {
+TEST_P(WebMediaPlayerMSTest, FrameSizeChange) {
// During this test, the frame size of the input changes.
// We need to make sure, when sizeChanged() gets called, new size should be
// returned by GetCurrentSize().
- InitializeWebMediaPlayerMS(false);
+ InitializeWebMediaPlayerMS();
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300,
@@ -1139,8 +1254,13 @@ TEST_F(WebMediaPlayerMSTest, FrameSizeChange) {
std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
provider->QueueFrames(timestamps, false, false, 7);
- EXPECT_CALL(*this, DoSetCcLayer(true));
- EXPECT_CALL(*this, DoStartRendering());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
+ EXPECT_CALL(*submitter_ptr_, StartRendering());
+ } else {
+ EXPECT_CALL(*this, DoSetCcLayer(true));
+ EXPECT_CALL(*this, DoStartRendering());
+ }
EXPECT_CALL(*this, DoReadyStateChanged(
blink::WebMediaPlayer::kReadyStateHaveMetadata));
EXPECT_CALL(*this, DoReadyStateChanged(
@@ -1154,12 +1274,15 @@ TEST_F(WebMediaPlayerMSTest, FrameSizeChange) {
testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*this, DoSetCcLayer(false));
- EXPECT_CALL(*this, DoStopRendering());
+ if (enable_surface_layer_for_video_)
+ EXPECT_CALL(*submitter_ptr_, StopUsingProvider());
+ else
+ EXPECT_CALL(*this, DoStopRendering());
}
// Tests that GpuMemoryBufferVideoFramePool is called in the expected sequence.
-TEST_F(WebMediaPlayerMSTest, CreateHardwareFrames) {
- InitializeWebMediaPlayerMS(false);
+TEST_P(WebMediaPlayerMSTest, CreateHardwareFrames) {
+ InitializeWebMediaPlayerMS();
MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(false);
SetGpuMemoryBufferVideoForTesting();
@@ -1171,8 +1294,13 @@ TEST_F(WebMediaPlayerMSTest, CreateHardwareFrames) {
media::PipelineStatus::PIPELINE_OK);
ASSERT_EQ(1u, frame_ready_cbs_.size());
- EXPECT_CALL(*this, DoSetCcLayer(true));
- EXPECT_CALL(*this, DoStartRendering());
+ if (enable_surface_layer_for_video_) {
+ EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer());
+ EXPECT_CALL(*submitter_ptr_, StartRendering());
+ } else {
+ EXPECT_CALL(*this, DoSetCcLayer(true));
+ EXPECT_CALL(*this, DoStartRendering());
+ }
EXPECT_CALL(*this, DoReadyStateChanged(
blink::WebMediaPlayer::kReadyStateHaveMetadata));
EXPECT_CALL(*this, DoReadyStateChanged(
@@ -1189,12 +1317,14 @@ TEST_F(WebMediaPlayerMSTest, CreateHardwareFrames) {
testing::Mock::VerifyAndClearExpectations(this);
EXPECT_CALL(*this, DoSetCcLayer(false));
- EXPECT_CALL(*this, DoStopRendering());
+ if (enable_surface_layer_for_video_)
+ EXPECT_CALL(*submitter_ptr_, StopUsingProvider());
+ else
+ EXPECT_CALL(*this, DoStopRendering());
}
-
#if defined(OS_ANDROID)
-TEST_F(WebMediaPlayerMSTest, HiddenPlayerTests) {
- InitializeWebMediaPlayerMS(false);
+TEST_P(WebMediaPlayerMSTest, HiddenPlayerTests) {
+ InitializeWebMediaPlayerMS();
LoadAndGetFrameProvider(true);
// Hidden status should not affect playback.
@@ -1244,4 +1374,68 @@ TEST_F(WebMediaPlayerMSTest, HiddenPlayerTests) {
}
#endif
+// Tests delegate methods are called when Picture-in-Picture is triggered.
+TEST_P(WebMediaPlayerMSTest, PictureInPictureTriggerCallback) {
+ InitializeWebMediaPlayerMS();
+
+ // It works only a surface layer is used instead of a video layer.
+ if (!enable_surface_layer_for_video_) {
+ EXPECT_CALL(*this, DoSetCcLayer(false));
+ return;
+ }
+
+ MockMediaStreamVideoRenderer* provider = LoadAndGetFrameProvider(true);
+
+ int tokens[] = {0, 33, 66, 100, 133, 166, 200, 233, 266, 300,
+ 333, 366, 400, 433, 466, 500, 533, 566, 600};
+ std::vector<int> timestamps(tokens, tokens + sizeof(tokens) / sizeof(int));
+ provider->QueueFrames(timestamps);
+
+ EXPECT_CALL(*submitter_ptr_, StartRendering());
+ EXPECT_CALL(*this, DisplayType()).Times(2);
+ EXPECT_CALL(*this, DoReadyStateChanged(
+ blink::WebMediaPlayer::kReadyStateHaveMetadata));
+ EXPECT_CALL(*this, DoReadyStateChanged(
+ blink::WebMediaPlayer::kReadyStateHaveEnoughData));
+ EXPECT_CALL(*this,
+ CheckSizeChanged(gfx::Size(kStandardWidth, kStandardHeight)));
+ message_loop_controller_.RunAndWaitForStatus(
+ media::PipelineStatus::PIPELINE_OK);
+ testing::Mock::VerifyAndClearExpectations(this);
+
+ EXPECT_CALL(*this, DisplayType())
+ .WillRepeatedly(
+ Return(blink::WebMediaPlayer::DisplayType::kPictureInPicture));
+
+ const gfx::Size natural_size = player_->NaturalSize();
+ EXPECT_CALL(delegate_, DidPictureInPictureSurfaceChange(
+ delegate_.delegate_id(),
+ surface_layer_bridge_ptr_->GetSurfaceId(),
+ natural_size, false))
+ .Times(2);
+
+ player_->OnSurfaceIdUpdated(surface_layer_bridge_ptr_->GetSurfaceId());
+
+ EXPECT_CALL(delegate_, DidPictureInPictureModeStart(
+ delegate_.delegate_id(),
+ surface_layer_bridge_ptr_->GetSurfaceId(),
+ natural_size, _, false));
+
+ player_->EnterPictureInPicture(base::DoNothing());
+ player_->OnSurfaceIdUpdated(surface_layer_bridge_ptr_->GetSurfaceId());
+
+ // Updating SurfaceId should NOT exit Picture-in-Picture.
+ EXPECT_CALL(delegate_, DidPictureInPictureModeEnd(delegate_.delegate_id(), _))
+ .Times(0);
+
+ testing::Mock::VerifyAndClearExpectations(this);
+ EXPECT_CALL(*this, DoSetCcLayer(false));
+ EXPECT_CALL(*submitter_ptr_, StopUsingProvider());
+}
+
+INSTANTIATE_TEST_CASE_P(,
+ WebMediaPlayerMSTest,
+ ::testing::Combine(::testing::Bool(),
+ ::testing::Bool(),
+ ::testing::Bool()));
} // namespace content
diff --git a/chromium/content/renderer/media/video_capture_impl.cc b/chromium/content/renderer/media/video_capture_impl.cc
index 77ed36bf3d7..aedecff2864 100644
--- a/chromium/content/renderer/media/video_capture_impl.cc
+++ b/chromium/content/renderer/media/video_capture_impl.cc
@@ -357,18 +357,43 @@ void VideoCaptureImpl::OnBufferReady(int32_t buffer_id,
scoped_refptr<media::VideoFrame> frame;
switch (buffer_context->buffer_type()) {
case VideoFrameBufferHandleType::SHARED_BUFFER_HANDLE:
- frame = media::VideoFrame::WrapExternalSharedMemory(
- static_cast<media::VideoPixelFormat>(info->pixel_format),
- info->coded_size, info->visible_rect, info->visible_rect.size(),
- static_cast<uint8_t*>(buffer_context->shared_memory()->memory()),
- buffer_context->shared_memory_size(),
- buffer_context->shared_memory()->handle(),
- 0 /* shared_memory_offset */, info->timestamp);
+ if (info->strides) {
+ CHECK(IsYuvPlanar(info->pixel_format) &&
+ (media::VideoFrame::NumPlanes(info->pixel_format) == 3))
+ << "Currently, only YUV formats support custom strides.";
+ uint8_t* y_data =
+ static_cast<uint8_t*>(buffer_context->shared_memory()->memory());
+ uint8_t* u_data =
+ y_data + (media::VideoFrame::Rows(media::VideoFrame::kYPlane,
+ info->pixel_format,
+ info->coded_size.height()) *
+ info->strides->stride_by_plane[0]);
+ uint8_t* v_data =
+ u_data + (media::VideoFrame::Rows(media::VideoFrame::kUPlane,
+ info->pixel_format,
+ info->coded_size.height()) *
+ info->strides->stride_by_plane[1]);
+ frame = media::VideoFrame::WrapExternalYuvData(
+ info->pixel_format, info->coded_size, info->visible_rect,
+ info->visible_rect.size(), info->strides->stride_by_plane[0],
+ info->strides->stride_by_plane[1],
+ info->strides->stride_by_plane[2], y_data, u_data, v_data,
+ info->timestamp);
+ frame->AddSharedMemoryHandle(buffer_context->shared_memory()->handle());
+ } else {
+ frame = media::VideoFrame::WrapExternalSharedMemory(
+ info->pixel_format, info->coded_size, info->visible_rect,
+ info->visible_rect.size(),
+ static_cast<uint8_t*>(buffer_context->shared_memory()->memory()),
+ buffer_context->shared_memory_size(),
+ buffer_context->shared_memory()->handle(),
+ 0 /* shared_memory_offset */, info->timestamp);
+ }
break;
case VideoFrameBufferHandleType::READ_ONLY_SHMEM_REGION:
frame = media::VideoFrame::WrapExternalData(
- static_cast<media::VideoPixelFormat>(info->pixel_format),
- info->coded_size, info->visible_rect, info->visible_rect.size(),
+ info->pixel_format, info->coded_size, info->visible_rect,
+ info->visible_rect.size(),
const_cast<uint8_t*>(
static_cast<const uint8_t*>(buffer_context->read_only_shmem())),
buffer_context->read_only_shmem_size(), info->timestamp);
@@ -384,10 +409,9 @@ void VideoCaptureImpl::OnBufferReady(int32_t buffer_id,
mailbox_holder_array[i] = buffer_context->mailbox_holders()[i];
}
frame = media::VideoFrame::WrapNativeTextures(
- static_cast<media::VideoPixelFormat>(info->pixel_format),
- mailbox_holder_array, media::VideoFrame::ReleaseMailboxCB(),
- info->coded_size, info->visible_rect, info->visible_rect.size(),
- info->timestamp);
+ info->pixel_format, mailbox_holder_array,
+ media::VideoFrame::ReleaseMailboxCB(), info->coded_size,
+ info->visible_rect, info->visible_rect.size(), info->timestamp);
break;
}
if (!frame) {
diff --git a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc
index a3869e8e4bd..a87a95622e4 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc
@@ -20,6 +20,7 @@
#include "media/base/video_util.h"
#include "third_party/webrtc/api/video/i420_buffer.h"
#include "third_party/webrtc/api/video/video_sink_interface.h"
+#include "third_party/webrtc/rtc_base/timeutils.h" // for TimeMicros
namespace content {
diff --git a/chromium/content/renderer/media/webrtc/mock_peer_connection_dependency_factory.cc b/chromium/content/renderer/media/webrtc/mock_peer_connection_dependency_factory.cc
index 8a895d2ce41..2a48dee4925 100644
--- a/chromium/content/renderer/media/webrtc/mock_peer_connection_dependency_factory.cc
+++ b/chromium/content/renderer/media/webrtc/mock_peer_connection_dependency_factory.cc
@@ -31,7 +31,7 @@ namespace content {
template <class V>
static typename V::iterator FindTrack(V* vector,
const std::string& track_id) {
- typename V::iterator it = vector->begin();
+ auto it = vector->begin();
for (; it != vector->end(); ++it) {
if ((*it)->id() == track_id) {
break;
@@ -68,8 +68,7 @@ bool MockMediaStream::AddTrack(VideoTrackInterface* track) {
}
bool MockMediaStream::RemoveTrack(AudioTrackInterface* track) {
- AudioTrackVector::iterator it = FindTrack(&audio_track_vector_,
- track->id());
+ auto it = FindTrack(&audio_track_vector_, track->id());
if (it == audio_track_vector_.end())
return false;
audio_track_vector_.erase(it);
@@ -78,8 +77,7 @@ bool MockMediaStream::RemoveTrack(AudioTrackInterface* track) {
}
bool MockMediaStream::RemoveTrack(VideoTrackInterface* track) {
- VideoTrackVector::iterator it = FindTrack(&video_track_vector_,
- track->id());
+ auto it = FindTrack(&video_track_vector_, track->id());
if (it == video_track_vector_.end())
return false;
video_track_vector_.erase(it);
@@ -101,13 +99,13 @@ VideoTrackVector MockMediaStream::GetVideoTracks() {
rtc::scoped_refptr<AudioTrackInterface> MockMediaStream::FindAudioTrack(
const std::string& track_id) {
- AudioTrackVector::iterator it = FindTrack(&audio_track_vector_, track_id);
+ auto it = FindTrack(&audio_track_vector_, track_id);
return it == audio_track_vector_.end() ? nullptr : *it;
}
rtc::scoped_refptr<VideoTrackInterface> MockMediaStream::FindVideoTrack(
const std::string& track_id) {
- VideoTrackVector::iterator it = FindTrack(&video_track_vector_, track_id);
+ auto it = FindTrack(&video_track_vector_, track_id);
return it == video_track_vector_.end() ? nullptr : *it;
}
@@ -117,14 +115,13 @@ void MockMediaStream::RegisterObserver(ObserverInterface* observer) {
}
void MockMediaStream::UnregisterObserver(ObserverInterface* observer) {
- ObserverSet::iterator it = observers_.find(observer);
+ auto it = observers_.find(observer);
DCHECK(it != observers_.end());
observers_.erase(it);
}
void MockMediaStream::NotifyObservers() {
- for (ObserverSet::iterator it = observers_.begin(); it != observers_.end();
- ++it) {
+ for (auto it = observers_.begin(); it != observers_.end(); ++it) {
(*it)->OnChanged();
}
}
diff --git a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc
index ee019112cb9..410baa4b876 100644
--- a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc
+++ b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc
@@ -64,7 +64,7 @@ class MockStreamCollection : public webrtc::StreamCollectionInterface {
streams_.push_back(stream);
}
void RemoveStream(MediaStreamInterface* stream) {
- StreamVector::iterator it = streams_.begin();
+ auto it = streams_.begin();
for (; it != streams_.end(); ++it) {
if (it->get() == stream) {
streams_.erase(it);
@@ -144,6 +144,11 @@ std::vector<std::string> FakeRtpSender::stream_ids() const {
return stream_ids_;
}
+std::vector<webrtc::RtpEncodingParameters> FakeRtpSender::init_send_encodings()
+ const {
+ return {};
+}
+
webrtc::RtpParameters FakeRtpSender::GetParameters() {
NOTIMPLEMENTED();
return webrtc::RtpParameters();
@@ -265,11 +270,6 @@ void FakeRtpTransceiver::Stop() {
NOTIMPLEMENTED();
}
-void FakeRtpTransceiver::SetCodecPreferences(
- rtc::ArrayView<webrtc::RtpCodecCapability> codecs) {
- NOTIMPLEMENTED();
-}
-
const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer";
const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer";
diff --git a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h
index 5d348e74b72..3ae1fbafdd0 100644
--- a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h
+++ b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h
@@ -33,6 +33,8 @@ class FakeRtpSender : public webrtc::RtpSenderInterface {
cricket::MediaType media_type() const override;
std::string id() const override;
std::vector<std::string> stream_ids() const override;
+ std::vector<webrtc::RtpEncodingParameters> init_send_encodings()
+ const override;
webrtc::RtpParameters GetParameters() override;
webrtc::RTCError SetParameters(
const webrtc::RtpParameters& parameters) override;
@@ -90,8 +92,6 @@ class FakeRtpTransceiver : public webrtc::RtpTransceiverInterface {
absl::optional<webrtc::RtpTransceiverDirection> current_direction()
const override;
void Stop() override;
- void SetCodecPreferences(
- rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override;
private:
cricket::MediaType media_type_;
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
index 2d2cfb2223c..1368fe1d7bb 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -102,6 +102,25 @@ bool IsValidPortRange(uint16_t min_port, uint16_t max_port) {
return min_port != 0 && max_port != 0;
}
+// PeerConnectionDependencies wants to own the factory, so we provide a simple
+// object that delegates calls to the IpcPacketSocketFactory.
+// TODO(zstein): Move the creation logic from IpcPacketSocketFactory in to this
+// class.
+class ProxyAsyncResolverFactory final : public webrtc::AsyncResolverFactory {
+ public:
+ ProxyAsyncResolverFactory(IpcPacketSocketFactory* ipc_psf)
+ : ipc_psf_(ipc_psf) {
+ DCHECK(ipc_psf);
+ }
+
+ rtc::AsyncResolverInterface* Create() override {
+ return ipc_psf_->CreateAsyncResolver();
+ }
+
+ private:
+ IpcPacketSocketFactory* ipc_psf_;
+};
+
} // namespace
PeerConnectionDependencyFactory::PeerConnectionDependencyFactory(
@@ -340,11 +359,12 @@ PeerConnectionDependencyFactory::CreatePeerConnection(
if (!GetPcFactory().get())
return nullptr;
- std::unique_ptr<P2PPortAllocator> port_allocator =
- CreatePortAllocator(web_frame);
+ webrtc::PeerConnectionDependencies dependencies(observer);
+ dependencies.allocator = CreatePortAllocator(web_frame);
+ dependencies.async_resolver_factory =
+ std::make_unique<ProxyAsyncResolverFactory>(socket_factory_.get());
return GetPcFactory()
- ->CreatePeerConnection(config, std::move(port_allocator), nullptr,
- observer)
+ ->CreatePeerConnection(config, std::move(dependencies))
.get();
}
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc
index 79f3bcbc961..6f896e98e25 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -18,7 +18,7 @@ class PeerConnectionDependencyFactoryTest : public ::testing::Test {
}
protected:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
};
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc b/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc
index cfd1e8d81cb..4af9ed31a94 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc
@@ -433,8 +433,9 @@ static std::unique_ptr<base::DictionaryValue> GetDictValue(
class InternalStatsObserver : public webrtc::StatsObserver {
public:
- explicit InternalStatsObserver(int lid)
- : lid_(lid), main_thread_(base::ThreadTaskRunnerHandle::Get()) {}
+ InternalStatsObserver(int lid,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread)
+ : lid_(lid), main_thread_(std::move(main_thread)) {}
void OnComplete(const StatsReports& reports) override {
std::unique_ptr<base::ListValue> list(new base::ListValue());
@@ -473,14 +474,19 @@ class InternalStatsObserver : public webrtc::StatsObserver {
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
};
-PeerConnectionTracker::PeerConnectionTracker()
- : next_local_id_(1), send_target_for_test_(nullptr) {}
+PeerConnectionTracker::PeerConnectionTracker(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
+ : next_local_id_(1),
+ send_target_for_test_(nullptr),
+ main_thread_task_runner_(std::move(main_thread_task_runner)) {}
PeerConnectionTracker::PeerConnectionTracker(
- mojom::PeerConnectionTrackerHostAssociatedPtr host)
+ mojom::PeerConnectionTrackerHostAssociatedPtr host,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
: next_local_id_(1),
send_target_for_test_(nullptr),
- peer_connection_tracker_host_ptr_(std::move(host)) {}
+ peer_connection_tracker_host_ptr_(std::move(host)),
+ main_thread_task_runner_(std::move(main_thread_task_runner)) {}
PeerConnectionTracker::~PeerConnectionTracker() {
}
@@ -505,10 +511,11 @@ void PeerConnectionTracker::OnGetAllStats() {
DCHECK(main_thread_.CalledOnValidThread());
const std::string empty_track_id;
- for (PeerConnectionIdMap::iterator it = peer_connection_id_map_.begin();
+ for (auto it = peer_connection_id_map_.begin();
it != peer_connection_id_map_.end(); ++it) {
rtc::scoped_refptr<InternalStatsObserver> observer(
- new rtc::RefCountedObject<InternalStatsObserver>(it->second));
+ new rtc::RefCountedObject<InternalStatsObserver>(
+ it->second, main_thread_task_runner_));
it->first->GetStats(observer,
webrtc::PeerConnectionInterface::kStatsOutputLevelDebug,
@@ -525,7 +532,7 @@ RenderThread* PeerConnectionTracker::SendTarget() {
void PeerConnectionTracker::OnSuspend() {
DCHECK(main_thread_.CalledOnValidThread());
- for (PeerConnectionIdMap::iterator it = peer_connection_id_map_.begin();
+ for (auto it = peer_connection_id_map_.begin();
it != peer_connection_id_map_.end(); ++it) {
it->first->CloseClientPeerConnection();
}
@@ -604,8 +611,7 @@ void PeerConnectionTracker::UnregisterPeerConnection(
DCHECK(main_thread_.CalledOnValidThread());
DVLOG(1) << "PeerConnectionTracker::UnregisterPeerConnection()";
- std::map<RTCPeerConnectionHandler*, int>::iterator it =
- peer_connection_id_map_.find(pc_handler);
+ auto it = peer_connection_id_map_.find(pc_handler);
if (it == peer_connection_id_map_.end()) {
// The PeerConnection might not have been registered if its initilization
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_tracker.h b/chromium/content/renderer/media/webrtc/peer_connection_tracker.h
index 24e0fd85e1c..7f95e5df849 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_tracker.h
+++ b/chromium/content/renderer/media/webrtc/peer_connection_tracker.h
@@ -45,8 +45,11 @@ class CONTENT_EXPORT PeerConnectionTracker
: public RenderThreadObserver,
public base::SupportsWeakPtr<PeerConnectionTracker> {
public:
- PeerConnectionTracker();
- PeerConnectionTracker(mojom::PeerConnectionTrackerHostAssociatedPtr host);
+ explicit PeerConnectionTracker(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
+ PeerConnectionTracker(
+ mojom::PeerConnectionTrackerHostAssociatedPtr host,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
~PeerConnectionTracker() override;
enum Source {
@@ -262,6 +265,8 @@ class CONTENT_EXPORT PeerConnectionTracker
mojom::PeerConnectionTrackerHostAssociatedPtr
peer_connection_tracker_host_ptr_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
+
DISALLOW_COPY_AND_ASSIGN(PeerConnectionTracker);
};
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc b/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc
index 84865974755..7c43ad4f499 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc
@@ -4,7 +4,7 @@
#include "content/renderer/media/webrtc/peer_connection_tracker.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "content/common/media/peer_connection_tracker.mojom.h"
#include "content/common/media/peer_connection_tracker_messages.h"
#include "content/public/test/mock_render_thread.h"
@@ -151,8 +151,9 @@ class PeerConnectionTrackerTest : public ::testing::Test {
public:
void CreateTrackerWithMocks() {
mock_host_.reset(new MockPeerConnectionTrackerHost());
- tracker_.reset(
- new PeerConnectionTracker(mock_host_->CreateInterfacePtrAndBind()));
+ tracker_.reset(new PeerConnectionTracker(
+ mock_host_->CreateInterfacePtrAndBind(),
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting()));
target_thread_.reset(new MockSendTargetThread());
tracker_->OverrideSendTargetForTesting(target_thread_.get());
}
@@ -167,7 +168,7 @@ class PeerConnectionTrackerTest : public ::testing::Test {
}
protected:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
std::unique_ptr<MockPeerConnectionTrackerHost> mock_host_;
std::unique_ptr<PeerConnectionTracker> tracker_;
std::unique_ptr<MockSendTargetThread> target_thread_;
@@ -177,7 +178,8 @@ class PeerConnectionTrackerTest : public ::testing::Test {
} // namespace
TEST_F(PeerConnectionTrackerTest, CreatingObject) {
- PeerConnectionTracker tracker;
+ PeerConnectionTracker tracker(
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting());
}
TEST_F(PeerConnectionTrackerTest, TrackCreateOffer) {
diff --git a/chromium/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc b/chromium/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc
index 44a4b9ed325..ba3349f278e 100644
--- a/chromium/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_dtmf_sender_handler.cc
@@ -22,8 +22,9 @@ class RtcDtmfSenderHandler::Observer :
public base::RefCountedThreadSafe<Observer>,
public webrtc::DtmfSenderObserverInterface {
public:
- explicit Observer(const base::WeakPtr<RtcDtmfSenderHandler>& handler)
- : main_thread_(base::ThreadTaskRunnerHandle::Get()), handler_(handler) {}
+ explicit Observer(scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ const base::WeakPtr<RtcDtmfSenderHandler>& handler)
+ : main_thread_(std::move(main_thread)), handler_(handler) {}
private:
friend class base::RefCountedThreadSafe<Observer>;
@@ -49,10 +50,12 @@ class RtcDtmfSenderHandler::Observer :
base::WeakPtr<RtcDtmfSenderHandler> handler_;
};
-RtcDtmfSenderHandler::RtcDtmfSenderHandler(DtmfSenderInterface* dtmf_sender)
+RtcDtmfSenderHandler::RtcDtmfSenderHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ DtmfSenderInterface* dtmf_sender)
: dtmf_sender_(dtmf_sender), webkit_client_(nullptr), weak_factory_(this) {
DVLOG(1) << "::ctor";
- observer_ = new Observer(weak_factory_.GetWeakPtr());
+ observer_ = new Observer(std::move(main_thread), weak_factory_.GetWeakPtr());
dtmf_sender_->RegisterObserver(observer_.get());
}
diff --git a/chromium/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h b/chromium/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h
index 89f1c73d6d2..8f59a39a5ba 100644
--- a/chromium/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h
+++ b/chromium/content/renderer/media/webrtc/rtc_dtmf_sender_handler.h
@@ -16,6 +16,10 @@
#include "third_party/blink/public/platform/web_rtc_dtmf_sender_handler_client.h"
#include "third_party/webrtc/api/dtmfsenderinterface.h"
+namespace base {
+class SingleThreadTaskRunner;
+}
+
namespace content {
// RtcDtmfSenderHandler is a delegate for the RTC DTMF Sender API messages
@@ -27,7 +31,8 @@ namespace content {
class CONTENT_EXPORT RtcDtmfSenderHandler
: public blink::WebRTCDTMFSenderHandler {
public:
- explicit RtcDtmfSenderHandler(webrtc::DtmfSenderInterface* dtmf_sender);
+ RtcDtmfSenderHandler(scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ webrtc::DtmfSenderInterface* dtmf_sender);
~RtcDtmfSenderHandler() override;
// blink::WebRTCDTMFSenderHandler implementation.
diff --git a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
index e281ec9de24..fa770cfc0bc 100644
--- a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
@@ -148,6 +148,10 @@ class MockRTCStatsRequest : public LocalRTCStatsRequest {
class MockPeerConnectionTracker : public PeerConnectionTracker {
public:
+ MockPeerConnectionTracker()
+ : PeerConnectionTracker(
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting()) {}
+
MOCK_METHOD1(UnregisterPeerConnection,
void(RTCPeerConnectionHandler* pc_handler));
// TODO(jiayl): add coverage for the following methods
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
index a2d16ec7de7..14d7a5f5d55 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
@@ -185,7 +185,8 @@ class RTCRtpSender::RTCRtpSenderInternal
// webrtc signalling thread.
DCHECK(main_task_runner_->BelongsToCurrentThread());
auto dtmf_sender = webrtc_sender_->GetDtmfSender();
- return std::make_unique<RtcDtmfSenderHandler>(dtmf_sender);
+ return std::make_unique<RtcDtmfSenderHandler>(main_task_runner_,
+ dtmf_sender);
}
std::unique_ptr<webrtc::RtpParameters> GetParameters() {
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
index 3690936bfc8..dd1e0b29e35 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
@@ -8,11 +8,11 @@
#include "base/logging.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "content/child/child_process.h"
#include "content/renderer/media/stream/media_stream_audio_source.h"
@@ -172,7 +172,7 @@ class RTCRtpTransceiverTest : public ::testing::Test {
}
private:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
protected:
std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_decoder.cc b/chromium/content/renderer/media/webrtc/rtc_video_decoder.cc
index 6e9f6ada346..cc7016e3535 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_decoder.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_decoder.cc
@@ -241,7 +241,7 @@ int32_t RTCVideoDecoder::Decode(
}
// Create buffer metadata.
- BufferData buffer_data(next_bitstream_buffer_id_, input_image._timeStamp,
+ BufferData buffer_data(next_bitstream_buffer_id_, input_image.Timestamp(),
input_image._length, gfx::Rect(frame_size_));
// Mask against 30 bits, to avoid (undefined) wraparound on signed integer.
next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & ID_LAST;
@@ -361,8 +361,7 @@ void RTCVideoDecoder::DismissPictureBuffer(int32_t id) {
DVLOG(3) << "DismissPictureBuffer. id=" << id;
DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
- std::map<int32_t, media::PictureBuffer>::iterator it =
- assigned_picture_buffers_.find(id);
+ auto it = assigned_picture_buffers_.find(id);
if (it == assigned_picture_buffers_.end()) {
NOTREACHED() << "Missing picture buffer: " << id;
return;
@@ -385,8 +384,7 @@ void RTCVideoDecoder::PictureReady(const media::Picture& picture) {
DVLOG(3) << "PictureReady";
DCheckGpuVideoAcceleratorFactoriesTaskRunnerIsCurrent();
- std::map<int32_t, media::PictureBuffer>::iterator it =
- assigned_picture_buffers_.find(picture.picture_buffer_id());
+ auto it = assigned_picture_buffers_.find(picture.picture_buffer_id());
if (it == assigned_picture_buffers_.end()) {
NOTREACHED() << "Missing picture buffer: " << picture.picture_buffer_id();
NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE);
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc b/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc
index e64ad90561a..cb50f27ca39 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc
@@ -21,6 +21,7 @@
#include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h"
#include "media/base/media_log.h"
#include "media/base/media_util.h"
+#include "media/base/overlay_info.h"
#include "media/base/video_types.h"
#include "media/video/gpu_video_accelerator_factories.h"
#include "third_party/webrtc/api/video/video_frame.h"
@@ -28,6 +29,7 @@
#include "third_party/webrtc/rtc_base/bind.h"
#include "third_party/webrtc/rtc_base/refcount.h"
#include "third_party/webrtc/rtc_base/refcountedobject.h"
+#include "ui/gfx/color_space.h"
#if defined(OS_WIN)
#include "base/command_line.h"
@@ -97,13 +99,18 @@ void FinishWait(base::WaitableEvent* waiter, bool* result_out, bool result) {
waiter->Signal();
}
+void OnRequestOverlayInfo(bool decoder_requires_restart_for_overlay,
+ const media::ProvideOverlayInfoCB& overlay_info_cb) {
+ // Android overlays are not supported.
+ overlay_info_cb.Run(media::OverlayInfo());
+}
+
} // namespace
// static
std::unique_ptr<RTCVideoDecoderAdapter> RTCVideoDecoderAdapter::Create(
- webrtc::VideoCodecType video_codec_type,
media::GpuVideoAcceleratorFactories* gpu_factories,
- CreateVideoDecoderCB create_video_decoder_cb) {
+ webrtc::VideoCodecType video_codec_type) {
DVLOG(1) << __func__ << "(" << video_codec_type << ")";
#if defined(OS_WIN)
@@ -123,34 +130,24 @@ std::unique_ptr<RTCVideoDecoderAdapter> RTCVideoDecoderAdapter::Create(
return nullptr;
std::unique_ptr<RTCVideoDecoderAdapter> rtc_video_decoder_adapter =
- base::WrapUnique(new RTCVideoDecoderAdapter(
- gpu_factories->GetTaskRunner(), std::move(create_video_decoder_cb),
- video_codec_type));
+ base::WrapUnique(
+ new RTCVideoDecoderAdapter(gpu_factories, video_codec_type));
// Synchronously verify that the decoder can be initialized.
if (!rtc_video_decoder_adapter->InitializeSync()) {
- DeleteSoonOnMediaThread(std::move(rtc_video_decoder_adapter),
- gpu_factories);
+ gpu_factories->GetTaskRunner()->DeleteSoon(
+ FROM_HERE, std::move(rtc_video_decoder_adapter));
return nullptr;
}
return rtc_video_decoder_adapter;
}
-// static
-void RTCVideoDecoderAdapter::DeleteSoonOnMediaThread(
- std::unique_ptr<webrtc::VideoDecoder> rtc_video_decoder_adapter,
- media::GpuVideoAcceleratorFactories* gpu_factories) {
- gpu_factories->GetTaskRunner()->DeleteSoon(
- FROM_HERE, std::move(rtc_video_decoder_adapter));
-}
-
RTCVideoDecoderAdapter::RTCVideoDecoderAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
- CreateVideoDecoderCB create_video_decoder_cb,
+ media::GpuVideoAcceleratorFactories* gpu_factories,
webrtc::VideoCodecType video_codec_type)
- : media_task_runner_(std::move(media_task_runner)),
- create_video_decoder_cb_(std::move(create_video_decoder_cb)),
+ : media_task_runner_(gpu_factories->GetTaskRunner()),
+ gpu_factories_(gpu_factories),
video_codec_type_(video_codec_type),
weak_this_factory_(this) {
DVLOG(1) << __func__;
@@ -223,7 +220,7 @@ int32_t RTCVideoDecoderAdapter::Decode(
scoped_refptr<media::DecoderBuffer> buffer =
media::DecoderBuffer::CopyFrom(input_image._buffer, input_image._length);
buffer->set_timestamp(
- base::TimeDelta::FromMicroseconds(input_image._timeStamp));
+ base::TimeDelta::FromMicroseconds(input_image.Timestamp()));
// Queue for decoding.
{
@@ -234,12 +231,11 @@ int32_t RTCVideoDecoderAdapter::Decode(
// We are severely behind. Drop pending buffers and request a keyframe to
// catch up as quickly as possible.
DVLOG(2) << "Pending buffers overflow";
+ pending_buffers_.clear();
if (++consecutive_error_count_ > kMaxConsecutiveErrors) {
- pending_buffers_.clear();
decode_timestamps_.clear();
return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
}
- pending_buffers_.clear();
return WEBRTC_VIDEO_CODEC_ERROR;
}
pending_buffers_.push_back(std::move(buffer));
@@ -287,7 +283,9 @@ void RTCVideoDecoderAdapter::InitializeOnMediaThread(
// media-internals UI. The current log just discards all messages.
media_log_ = std::make_unique<media::MediaLog>();
- video_decoder_ = create_video_decoder_cb_.Run(media_log_.get());
+ video_decoder_ = gpu_factories_->CreateVideoDecoder(
+ media_log_.get(), base::BindRepeating(&OnRequestOverlayInfo),
+ gfx::ColorSpace());
if (!video_decoder_) {
media_task_runner_->PostTask(FROM_HERE,
base::BindRepeating(init_cb, false));
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter.h b/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter.h
index e7c6c8cc1e5..89ee3dfec59 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter.h
+++ b/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter.h
@@ -48,22 +48,12 @@ namespace content {
// way to synchronize this correctly.
class CONTENT_EXPORT RTCVideoDecoderAdapter : public webrtc::VideoDecoder {
public:
- using CreateVideoDecoderCB =
- base::RepeatingCallback<std::unique_ptr<media::VideoDecoder>(
- media::MediaLog*)>;
-
// Creates and initializes an RTCVideoDecoderAdapter. Returns nullptr if
// |video_codec_type| cannot be supported.
// Called on the worker thread.
static std::unique_ptr<RTCVideoDecoderAdapter> Create(
- webrtc::VideoCodecType video_codec_type,
media::GpuVideoAcceleratorFactories* gpu_factories,
- CreateVideoDecoderCB create_video_decoder_cb);
-
- // Called on the worker thread.
- static void DeleteSoonOnMediaThread(
- std::unique_ptr<webrtc::VideoDecoder> rtc_video_decoder_adapter,
- media::GpuVideoAcceleratorFactories* gpu_factories);
+ webrtc::VideoCodecType video_codec_type);
// Called on |media_task_runner_|.
~RTCVideoDecoderAdapter() override;
@@ -86,12 +76,13 @@ class CONTENT_EXPORT RTCVideoDecoderAdapter : public webrtc::VideoDecoder {
const char* ImplementationName() const override;
private:
- // |create_video_decoder_cb| will always be called on |media_task_runner|.
+ using CreateVideoDecoderCB =
+ base::RepeatingCallback<std::unique_ptr<media::VideoDecoder>(
+ media::MediaLog*)>;
+
// Called on the worker thread.
- RTCVideoDecoderAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
- CreateVideoDecoderCB create_video_decoder_cb,
- webrtc::VideoCodecType video_codec_type);
+ RTCVideoDecoderAdapter(media::GpuVideoAcceleratorFactories* gpu_factories,
+ webrtc::VideoCodecType video_codec_type);
bool InitializeSync();
void InitializeOnMediaThread(media::VideoDecoder::InitCB init_cb);
@@ -101,7 +92,7 @@ class CONTENT_EXPORT RTCVideoDecoderAdapter : public webrtc::VideoDecoder {
// Construction parameters.
scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_;
- CreateVideoDecoderCB create_video_decoder_cb_;
+ media::GpuVideoAcceleratorFactories* gpu_factories_;
webrtc::VideoCodecType video_codec_type_;
// Media thread members.
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter_unittest.cc
index 1b0c4e1e6d7..8629a9f7112 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_decoder_adapter_unittest.cc
@@ -92,29 +92,35 @@ class RTCVideoDecoderAdapterTest : public ::testing::Test {
gpu_factories_(nullptr),
decoded_image_callback_(decoded_cb_.Get()) {
media_thread_.Start();
+
+ owned_video_decoder_ = std::make_unique<StrictMock<MockVideoDecoder>>();
+ video_decoder_ = owned_video_decoder_.get();
+
ON_CALL(gpu_factories_, GetTaskRunner())
.WillByDefault(Return(media_thread_.task_runner()));
EXPECT_CALL(gpu_factories_, GetTaskRunner()).Times(AtLeast(0));
- owned_video_decoder_ = std::make_unique<StrictMock<MockVideoDecoder>>();
- video_decoder_ = owned_video_decoder_.get();
+
+ ON_CALL(gpu_factories_, CreateVideoDecoder(_, _, _))
+ .WillByDefault(
+ [this](media::MediaLog* media_log,
+ const media::RequestOverlayInfoCB& request_overlay_info_cb,
+ const gfx::ColorSpace& target_color_space) {
+ DCHECK(this->owned_video_decoder_);
+ return std::move(this->owned_video_decoder_);
+ });
+ EXPECT_CALL(gpu_factories_, CreateVideoDecoder(_, _, _)).Times(AtLeast(0));
}
~RTCVideoDecoderAdapterTest() {
if (!rtc_video_decoder_adapter_)
return;
- RTCVideoDecoderAdapter::DeleteSoonOnMediaThread(
- std::move(rtc_video_decoder_adapter_), &gpu_factories_);
+ media_thread_.task_runner()->DeleteSoon(
+ FROM_HERE, std::move(rtc_video_decoder_adapter_));
media_thread_.FlushForTesting();
}
protected:
- std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
- media::MediaLog* media_log) {
- DCHECK(owned_video_decoder_);
- return std::move(owned_video_decoder_);
- }
-
bool BasicSetup() {
if (!CreateAndInitialize())
return false;
@@ -135,10 +141,8 @@ class RTCVideoDecoderAdapterTest : public ::testing::Test {
EXPECT_CALL(*video_decoder_, Initialize(_, _, _, _, _, _))
.WillOnce(DoAll(SaveArg<4>(&output_cb_),
media::RunCallback<3>(init_cb_result)));
- rtc_video_decoder_adapter_ = RTCVideoDecoderAdapter::Create(
- webrtc::kVideoCodecVP9, &gpu_factories_,
- base::BindRepeating(&RTCVideoDecoderAdapterTest::CreateVideoDecoder,
- base::Unretained(this)));
+ rtc_video_decoder_adapter_ =
+ RTCVideoDecoderAdapter::Create(&gpu_factories_, webrtc::kVideoCodecVP9);
return !!rtc_video_decoder_adapter_;
}
@@ -157,7 +161,7 @@ class RTCVideoDecoderAdapterTest : public ::testing::Test {
uint8_t buf[] = {0};
webrtc::EncodedImage input_image(&buf[0], 1, 1);
input_image._completeFrame = true;
- input_image._timeStamp = timestamp;
+ input_image.SetTimestamp(timestamp);
return rtc_video_decoder_adapter_->Decode(input_image, false, nullptr, 0);
}
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_decoder_factory.cc b/chromium/content/renderer/media/webrtc/rtc_video_decoder_factory.cc
index c745d626953..c756159766b 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_decoder_factory.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_decoder_factory.cc
@@ -6,7 +6,10 @@
#include <memory>
+#include "base/feature_list.h"
#include "content/renderer/media/webrtc/rtc_video_decoder.h"
+#include "content/renderer/media/webrtc/rtc_video_decoder_adapter.h"
+#include "media/base/media_switches.h"
#include "media/video/gpu_video_accelerator_factories.h"
namespace content {
@@ -24,13 +27,18 @@ RTCVideoDecoderFactory::~RTCVideoDecoderFactory() {
webrtc::VideoDecoder* RTCVideoDecoderFactory::CreateVideoDecoder(
webrtc::VideoCodecType type) {
DVLOG(2) << __func__;
- return RTCVideoDecoder::Create(type, gpu_factories_).release();
+
+ if (base::FeatureList::IsEnabled(media::kRTCVideoDecoderAdapter)) {
+ return RTCVideoDecoderAdapter::Create(gpu_factories_, type).release();
+ } else {
+ return RTCVideoDecoder::Create(type, gpu_factories_).release();
+ }
}
void RTCVideoDecoderFactory::DestroyVideoDecoder(
webrtc::VideoDecoder* decoder) {
DVLOG(2) << __func__;
- RTCVideoDecoder::Destroy(decoder, gpu_factories_);
+ gpu_factories_->GetTaskRunner()->DeleteSoon(FROM_HERE, decoder);
}
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc b/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc
index fc6985e7f86..db6c04c42d0 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc
@@ -565,7 +565,7 @@ void RTCVideoEncoder::Impl::BitstreamBufferReady(
output_buffer->mapped_size());
image._encodedWidth = input_visible_size_.width();
image._encodedHeight = input_visible_size_.height();
- image._timeStamp = rtp_timestamp.value();
+ image.SetTimestamp(rtp_timestamp.value());
image.capture_time_ms_ = capture_timestamp_ms.value();
image._frameType =
(metadata.key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta);
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc
index 460fe992b7c..ae4a1acb1b2 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc
@@ -16,6 +16,7 @@
#include "third_party/webrtc/api/video/i420_buffer.h"
#include "third_party/webrtc/api/video_codecs/video_encoder.h"
#include "third_party/webrtc/modules/video_coding/include/video_codec_interface.h"
+#include "third_party/webrtc/rtc_base/timeutils.h"
using ::testing::_;
using ::testing::AtLeast;
@@ -188,7 +189,7 @@ class RTCVideoEncoderTest
const webrtc::CodecSpecificInfo* codec_specific_info,
const webrtc::RTPFragmentationHeader* fragmentation) {
DVLOG(3) << __func__;
- EXPECT_EQ(rtp_timestamp, encoded_image._timeStamp);
+ EXPECT_EQ(rtp_timestamp, encoded_image.Timestamp());
EXPECT_EQ(capture_time_ms, encoded_image.capture_time_ms_);
}
diff --git a/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc
index 4792cefac27..abd9eccfb59 100644
--- a/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc
+++ b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc
@@ -164,11 +164,6 @@ void SurfaceSenderStateOnly::Stop() {
NOTIMPLEMENTED();
}
-void SurfaceSenderStateOnly::SetCodecPreferences(
- rtc::ArrayView<webrtc::RtpCodecCapability> codecs) {
- NOTIMPLEMENTED();
-}
-
SurfaceReceiverStateOnly::SurfaceReceiverStateOnly(
rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver)
: receiver_(std::move(receiver)) {
@@ -217,9 +212,4 @@ void SurfaceReceiverStateOnly::Stop() {
NOTIMPLEMENTED();
}
-void SurfaceReceiverStateOnly::SetCodecPreferences(
- rtc::ArrayView<webrtc::RtpCodecCapability> codecs) {
- NOTIMPLEMENTED();
-}
-
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h
index ab7cdfeb695..b3bc9b75f99 100644
--- a/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h
+++ b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h
@@ -73,8 +73,6 @@ class CONTENT_EXPORT SurfaceSenderStateOnly
absl::optional<webrtc::RtpTransceiverDirection> current_direction()
const override;
void Stop() override;
- void SetCodecPreferences(
- rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override;
private:
rtc::scoped_refptr<webrtc::RtpSenderInterface> sender_;
@@ -100,8 +98,6 @@ class CONTENT_EXPORT SurfaceReceiverStateOnly
absl::optional<webrtc::RtpTransceiverDirection> current_direction()
const override;
void Stop() override;
- void SetCodecPreferences(
- rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override;
private:
rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver_;
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc
index 4d8da5ed05f..7b3d058a6e5 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc
@@ -26,11 +26,6 @@
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/webrtc/api/mediastreaminterface.h"
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#include "media/audio/win/core_audio_util_win.h"
-#endif
-
namespace content {
namespace {
@@ -515,7 +510,7 @@ void WebRtcAudioRenderer::UpdateSourceVolume(
// set to 0.0.
float volume = 0.0f;
- SourcePlayingStates::iterator entry = source_playing_states_.find(source);
+ auto entry = source_playing_states_.find(source);
if (entry != source_playing_states_.end()) {
PlayingStates& states = entry->second;
for (PlayingStates::const_iterator it = states.begin();
@@ -566,13 +561,12 @@ bool WebRtcAudioRenderer::RemovePlayingState(
PlayingState* state) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!state->playing());
- SourcePlayingStates::iterator found = source_playing_states_.find(source);
+ auto found = source_playing_states_.find(source);
if (found == source_playing_states_.end())
return false;
PlayingStates& array = found->second;
- PlayingStates::iterator state_it =
- std::find(array.begin(), array.end(), state);
+ auto state_it = std::find(array.begin(), array.end(), state);
if (state_it == array.end())
return false;
@@ -625,8 +619,7 @@ void WebRtcAudioRenderer::OnPlayStateRemoved(PlayingState* state) {
it != source_playing_states_.end();) {
PlayingStates& states = it->second;
// We cannot use RemovePlayingState as it might invalidate |it|.
- states.erase(std::remove(states.begin(), states.end(), state),
- states.end());
+ base::Erase(states, state);
if (states.empty())
it = source_playing_states_.erase(it);
else
@@ -662,7 +655,8 @@ void WebRtcAudioRenderer::PrepareSink() {
UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioOutputSampleRate", asr,
media::kAudioSampleRateMax + 1);
} else {
- UMA_HISTOGRAM_COUNTS("WebRTC.AudioOutputSampleRateUnexpected", sample_rate);
+ UMA_HISTOGRAM_COUNTS_1M("WebRTC.AudioOutputSampleRateUnexpected",
+ sample_rate);
}
// Calculate the frames per buffer for the source, i.e. the WebRTC client. We
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc
index 273bac1d183..6c98bc20669 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc
@@ -9,8 +9,9 @@
#include <vector>
#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/public/renderer/media_stream_audio_renderer.h"
#include "content/renderer/media/audio/audio_device_factory.h"
@@ -66,7 +67,8 @@ class WebRtcAudioRendererTest : public testing::Test,
protected:
WebRtcAudioRendererTest()
- : message_loop_(new base::MessageLoopForIO),
+ : task_environment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::IO),
source_(new MockAudioRendererSource()) {
blink::WebVector<blink::WebMediaStreamTrack> dummy_tracks;
stream_.Initialize(blink::WebString::FromUTF8("new stream"), dummy_tracks,
@@ -76,8 +78,8 @@ class WebRtcAudioRendererTest : public testing::Test,
}
void SetupRenderer(const std::string& device_id) {
- renderer_ = new WebRtcAudioRenderer(message_loop_->task_runner(), stream_,
- 1, 1, device_id);
+ renderer_ = new WebRtcAudioRenderer(base::ThreadTaskRunnerHandle::Get(),
+ stream_, 1, 1, device_id);
EXPECT_CALL(
*this, MockCreateAudioRendererSink(AudioDeviceFactory::kSourceWebRtc, _,
_, device_id, _));
@@ -142,7 +144,7 @@ class WebRtcAudioRendererTest : public testing::Test,
const base::Optional<base::UnguessableToken> kAudioProcessingId =
base::UnguessableToken::Create();
- std::unique_ptr<base::MessageLoopForIO> message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
scoped_refptr<media::MockAudioRendererSink> mock_sink_;
std::unique_ptr<MockAudioRendererSource> source_;
blink::WebMediaStream stream_;
@@ -292,8 +294,8 @@ TEST_F(WebRtcAudioRendererTest, SwitchOutputDeviceInvalidDevice) {
}
TEST_F(WebRtcAudioRendererTest, InitializeWithInvalidDevice) {
- renderer_ = new WebRtcAudioRenderer(message_loop_->task_runner(), stream_, 1,
- 1, kInvalidOutputDeviceId);
+ renderer_ = new WebRtcAudioRenderer(base::ThreadTaskRunnerHandle::Get(),
+ stream_, 1, 1, kInvalidOutputDeviceId);
EXPECT_CALL(*this, MockCreateAudioRendererSink(
AudioDeviceFactory::kSourceWebRtc, _, _,
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
index 81becdc4569..521f8ec0c42 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
@@ -18,9 +18,13 @@ namespace content {
WebRtcAudioSink::WebRtcAudioSink(
const std::string& label,
scoped_refptr<webrtc::AudioSourceInterface> track_source,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner)
- : adapter_(new rtc::RefCountedObject<Adapter>(
- label, std::move(track_source), std::move(signaling_task_runner))),
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
+ : adapter_(
+ new rtc::RefCountedObject<Adapter>(label,
+ std::move(track_source),
+ std::move(signaling_task_runner),
+ std::move(main_task_runner))),
fifo_(base::Bind(&WebRtcAudioSink::DeliverRebufferedAudio,
base::Unretained(this))) {
DVLOG(1) << "WebRtcAudioSink::WebRtcAudioSink()";
@@ -100,12 +104,14 @@ void DereferenceOnMainThread(
WebRtcAudioSink::Adapter::Adapter(
const std::string& label,
scoped_refptr<webrtc::AudioSourceInterface> source,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner)
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
: webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label),
source_(std::move(source)),
signaling_task_runner_(std::move(signaling_task_runner)),
- main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
+ main_task_runner_(std::move(main_task_runner)) {
DCHECK(signaling_task_runner_);
+ DCHECK(main_task_runner_);
}
WebRtcAudioSink::Adapter::~Adapter() {
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
index a5667cc3537..c2a6c381f33 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
@@ -40,7 +40,8 @@ class CONTENT_EXPORT WebRtcAudioSink : public MediaStreamAudioSink {
WebRtcAudioSink(
const std::string& label,
scoped_refptr<webrtc::AudioSourceInterface> track_source,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner);
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
~WebRtcAudioSink() override;
@@ -72,7 +73,8 @@ class CONTENT_EXPORT WebRtcAudioSink : public MediaStreamAudioSink {
public:
Adapter(const std::string& label,
scoped_refptr<webrtc::AudioSourceInterface> source,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner);
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
base::SingleThreadTaskRunner* signaling_task_runner() const {
return signaling_task_runner_.get();
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
index 92d4065c2e2..1bfd71b593b 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
@@ -72,6 +72,21 @@ WebRtcMediaStreamTrackAdapter::WebRtcMediaStreamTrackAdapter(
WebRtcMediaStreamTrackAdapter::~WebRtcMediaStreamTrackAdapter() {
DCHECK(!remote_track_can_complete_initialization_.IsSignaled());
DCHECK(is_disposed_);
+ // Ensured by destructor traits.
+ DCHECK(main_thread_->BelongsToCurrentThread());
+}
+
+// static
+void WebRtcMediaStreamTrackAdapterTraits::Destruct(
+ const WebRtcMediaStreamTrackAdapter* adapter) {
+ if (!adapter->main_thread_->BelongsToCurrentThread()) {
+ adapter->main_thread_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&WebRtcMediaStreamTrackAdapterTraits::Destruct,
+ base::Unretained(adapter)));
+ return;
+ }
+ delete adapter;
}
void WebRtcMediaStreamTrackAdapter::Dispose() {
@@ -149,7 +164,7 @@ void WebRtcMediaStreamTrackAdapter::InitializeLocalAudioTrack(
webrtc::AudioSourceInterface* source_interface = nullptr;
local_track_audio_sink_.reset(
new WebRtcAudioSink(web_track_.Id().Utf8(), source_interface,
- factory_->GetWebRtcSignalingThread()));
+ factory_->GetWebRtcSignalingThread(), main_thread_));
if (auto* media_stream_source = ProcessedLocalAudioSource::From(
MediaStreamAudioSource::From(web_track_.Source()))) {
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h
index 8be75b5b895..fbf4210e0dc 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h
@@ -21,6 +21,7 @@
namespace content {
class PeerConnectionDependencyFactory;
+struct WebRtcMediaStreamTrackAdapterTraits;
// This is a mapping between a webrtc and blink media stream track. It takes
// care of creation, initialization and disposing of tracks independently of
@@ -29,7 +30,8 @@ class PeerConnectionDependencyFactory;
// and whether it is an audio or video track; this adapter hides that fact and
// lets you use a single class for any type of track.
class CONTENT_EXPORT WebRtcMediaStreamTrackAdapter
- : public base::RefCountedThreadSafe<WebRtcMediaStreamTrackAdapter> {
+ : public base::RefCountedThreadSafe<WebRtcMediaStreamTrackAdapter,
+ WebRtcMediaStreamTrackAdapterTraits> {
public:
// Invoke on the main thread. The returned adapter is fully initialized, see
// |is_initialized|. The adapter will keep a reference to the |main_thread|.
@@ -76,7 +78,9 @@ class CONTENT_EXPORT WebRtcMediaStreamTrackAdapter
}
protected:
- friend class base::RefCountedThreadSafe<WebRtcMediaStreamTrackAdapter>;
+ friend class base::RefCountedThreadSafe<WebRtcMediaStreamTrackAdapter,
+ WebRtcMediaStreamTrackAdapterTraits>;
+ friend struct WebRtcMediaStreamTrackAdapterTraits;
WebRtcMediaStreamTrackAdapter(
PeerConnectionDependencyFactory* factory,
@@ -132,6 +136,16 @@ class CONTENT_EXPORT WebRtcMediaStreamTrackAdapter
DISALLOW_COPY_AND_ASSIGN(WebRtcMediaStreamTrackAdapter);
};
+struct CONTENT_EXPORT WebRtcMediaStreamTrackAdapterTraits {
+ private:
+ friend class base::RefCountedThreadSafe<WebRtcMediaStreamTrackAdapter,
+ WebRtcMediaStreamTrackAdapterTraits>;
+
+ // Ensure destruction occurs on main thread so that "Web" and other resources
+ // are destroyed on the correct thread.
+ static void Destruct(const WebRtcMediaStreamTrackAdapter* adapter);
+};
+
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_H_
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
index 74f586d44b1..1bccc573e1d 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
@@ -79,6 +79,12 @@ class WebRtcMediaStreamTrackAdapterTest : public ::testing::Test {
dependency_factory_.get(), main_thread_, webrtc_track);
}
+ void HoldOntoAdapterReference(
+ base::WaitableEvent* waitable_event,
+ scoped_refptr<WebRtcMediaStreamTrackAdapter> adapter) {
+ waitable_event->Wait();
+ }
+
// Runs message loops on the webrtc signaling thread and optionally the main
// thread until idle.
void RunMessageLoopsUntilIdle(bool run_loop_on_main_thread = true) {
@@ -228,4 +234,33 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteTrackExplicitlyInitialized) {
track_adapter_->GetRemoteAudioTrackAdapterForTesting()->initialized());
}
+TEST_F(WebRtcMediaStreamTrackAdapterTest, LastReferenceOnSignalingThread) {
+ scoped_refptr<MockWebRtcAudioTrack> webrtc_track =
+ MockWebRtcAudioTrack::Create("remote_audio_track");
+ dependency_factory_->GetWebRtcSignalingThread()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &WebRtcMediaStreamTrackAdapterTest::CreateRemoteTrackAdapter,
+ base::Unretained(this), base::Unretained(webrtc_track.get())));
+ // The adapter is initialized implicitly in a PostTask, allow it to run.
+ RunMessageLoopsUntilIdle();
+ DCHECK(track_adapter_);
+ EXPECT_TRUE(track_adapter_->is_initialized());
+
+ base::WaitableEvent waitable_event(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED);
+ dependency_factory_->GetWebRtcSignalingThread()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &WebRtcMediaStreamTrackAdapterTest::HoldOntoAdapterReference,
+ base::Unretained(this), base::Unretained(&waitable_event),
+ track_adapter_));
+ // Clear last reference on main thread.
+ track_adapter_->Dispose();
+ track_adapter_ = nullptr;
+ waitable_event.Signal();
+ RunMessageLoopsUntilIdle();
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media_capture_from_element/canvas_capture_handler_unittest.cc b/chromium/content/renderer/media_capture_from_element/canvas_capture_handler_unittest.cc
index 94b495d7b30..2f1e5c29bb7 100644
--- a/chromium/content/renderer/media_capture_from_element/canvas_capture_handler_unittest.cc
+++ b/chromium/content/renderer/media_capture_from_element/canvas_capture_handler_unittest.cc
@@ -83,7 +83,7 @@ class CanvasCaptureHandlerTest
static sk_sp<SkImage> GenerateTestImage(bool opaque, int width, int height) {
SkBitmap testBitmap;
testBitmap.allocN32Pixels(width, height, opaque);
- testBitmap.eraseARGB(kTestAlphaValue, 30, 60, 200);
+ testBitmap.eraseARGB(opaque ? 255 : kTestAlphaValue, 30, 60, 200);
return SkImage::MakeFromBitmap(testBitmap);
}
diff --git a/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc b/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc
index 6fc91036161..434ef105942 100644
--- a/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc
+++ b/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc
@@ -71,14 +71,15 @@ class MockWebMediaPlayer : public blink::WebMediaPlayer,
double CurrentTime() const override { return 0.0; }
NetworkState GetNetworkState() const override { return kNetworkStateEmpty; }
ReadyState GetReadyState() const override { return kReadyStateHaveNothing; }
+ SurfaceLayerMode GetVideoSurfaceLayerMode() const override {
+ return SurfaceLayerMode::kNever;
+ }
blink::WebString GetErrorMessage() const override {
return blink::WebString();
}
bool DidLoadingProgress() override { return true; }
- bool DidGetOpaqueResponseFromServiceWorker() const override { return false; }
- bool HasSingleSecurityOrigin() const override { return true; }
- bool DidPassCORSAccessCheck() const override { return true; }
+ bool WouldTaintOrigin() const override { return false; }
double MediaTimeForTimeValue(double timeValue) const override { return 0.0; }
unsigned DecodedFrameCount() const override { return 0; }
unsigned DroppedFrameCount() const override { return 0; }
diff --git a/chromium/content/renderer/media_recorder/media_recorder_handler.cc b/chromium/content/renderer/media_recorder/media_recorder_handler.cc
index 8e5f6b142e2..a817164d82b 100644
--- a/chromium/content/renderer/media_recorder/media_recorder_handler.cc
+++ b/chromium/content/renderer/media_recorder/media_recorder_handler.cc
@@ -133,10 +133,11 @@ MediaRecorderHandler::MediaRecorderHandler(
MediaRecorderHandler::~MediaRecorderHandler() {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
// Send a |last_in_slice| to our |client_|.
- if (client_)
+ if (client_) {
client_->WriteData(
nullptr, 0u, true,
(TimeTicks::Now() - TimeTicks::UnixEpoch()).InMillisecondsF());
+ }
}
bool MediaRecorderHandler::CanSupportMimeType(
@@ -168,7 +169,8 @@ bool MediaRecorderHandler::CanSupportMimeType(
video ? arraysize(kVideoCodecs) : arraysize(kAudioCodecs);
std::vector<std::string> codecs_list;
- media::SplitCodecsToVector(web_codecs.Utf8(), &codecs_list, true /* strip */);
+ media::SplitCodecs(web_codecs.Utf8(), &codecs_list);
+ media::StripCodecs(&codecs_list);
for (const auto& codec : codecs_list) {
auto* const* found = std::find_if(
&codecs[0], &codecs[codecs_count], [&codec](const char* name) {
diff --git a/chromium/content/renderer/media_recorder/video_track_recorder.cc b/chromium/content/renderer/media_recorder/video_track_recorder.cc
index c7fb3465bac..ef28d31704b 100644
--- a/chromium/content/renderer/media_recorder/video_track_recorder.cc
+++ b/chromium/content/renderer/media_recorder/video_track_recorder.cc
@@ -313,7 +313,8 @@ void VideoTrackRecorder::Encoder::RetrieveFrameOnMainThread(
DCHECK(context_provider->ContextGL());
video_renderer_->Copy(video_frame.get(), canvas_.get(),
media::Context3D(context_provider->ContextGL(),
- context_provider->GrContext()));
+ context_provider->GrContext()),
+ context_provider->ContextSupport());
SkPixmap pixmap;
if (!bitmap_.peekPixels(&pixmap)) {
diff --git a/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc b/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
index 8e046ca1fd6..48936a86312 100644
--- a/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
+++ b/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
@@ -4,7 +4,7 @@
#include <string>
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/test/render_view_test.h"
#include "content/renderer/mouse_lock_dispatcher.h"
#include "content/renderer/render_view_impl.h"
@@ -62,17 +62,17 @@ TEST_F(MouseLockDispatcherTest, BasicWebWidget) {
// Lock.
EXPECT_TRUE(widget()->RequestPointerLock());
- widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ widget()->OnMessageReceived(WidgetMsg_LockMouse_ACK(route_id_, true));
EXPECT_TRUE(widget()->IsPointerLocked());
// Unlock.
widget()->RequestPointerUnlock();
- widget()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ widget()->OnMessageReceived(WidgetMsg_MouseLockLost(route_id_));
EXPECT_FALSE(widget()->IsPointerLocked());
// Attempt a lock, and have it fail.
EXPECT_TRUE(widget()->RequestPointerLock());
- widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
+ widget()->OnMessageReceived(WidgetMsg_LockMouse_ACK(route_id_, false));
EXPECT_FALSE(widget()->IsPointerLocked());
}
@@ -90,7 +90,7 @@ TEST_F(MouseLockDispatcherTest, BasicMockLockTarget) {
// Lock.
EXPECT_TRUE(dispatcher()->LockMouse(target_));
- widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ widget()->OnMessageReceived(WidgetMsg_LockMouse_ACK(route_id_, true));
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
// Receive mouse event.
@@ -98,12 +98,12 @@ TEST_F(MouseLockDispatcherTest, BasicMockLockTarget) {
// Unlock.
dispatcher()->UnlockMouse(target_);
- widget()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ widget()->OnMessageReceived(WidgetMsg_MouseLockLost(route_id_));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
// Attempt a lock, and have it fail.
EXPECT_TRUE(dispatcher()->LockMouse(target_));
- widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
+ widget()->OnMessageReceived(WidgetMsg_LockMouse_ACK(route_id_, false));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
}
@@ -116,7 +116,7 @@ TEST_F(MouseLockDispatcherTest, DeleteAndUnlock) {
// Lock.
EXPECT_TRUE(dispatcher()->LockMouse(target_));
- widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ widget()->OnMessageReceived(WidgetMsg_LockMouse_ACK(route_id_, true));
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
// Unlock, with a deleted target.
@@ -125,7 +125,7 @@ TEST_F(MouseLockDispatcherTest, DeleteAndUnlock) {
delete target_;
target_ = nullptr;
dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
- widget()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ widget()->OnMessageReceived(WidgetMsg_MouseLockLost(route_id_));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
}
@@ -144,7 +144,7 @@ TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockSuccess) {
target_ = nullptr;
// Lock response.
- widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ widget()->OnMessageReceived(WidgetMsg_LockMouse_ACK(route_id_, true));
}
// Test deleting a target that is pending a lock request failure response.
@@ -162,7 +162,7 @@ TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockFail) {
target_ = nullptr;
// Lock response.
- widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, false));
+ widget()->OnMessageReceived(WidgetMsg_LockMouse_ACK(route_id_, false));
}
// Test not receiving mouse events when a target is not locked.
@@ -179,7 +179,7 @@ TEST_F(MouseLockDispatcherTest, MouseEventsNotReceived) {
// Lock.
EXPECT_TRUE(dispatcher()->LockMouse(target_));
- widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ widget()->OnMessageReceived(WidgetMsg_LockMouse_ACK(route_id_, true));
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
// Receive mouse event.
@@ -187,7 +187,7 @@ TEST_F(MouseLockDispatcherTest, MouseEventsNotReceived) {
// Unlock.
dispatcher()->UnlockMouse(target_);
- widget()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ widget()->OnMessageReceived(WidgetMsg_MouseLockLost(route_id_));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
// (Don't) receive mouse event.
@@ -212,7 +212,7 @@ TEST_F(MouseLockDispatcherTest, MultipleTargets) {
EXPECT_FALSE(dispatcher()->LockMouse(alternate_target_));
// Lock completion for target.
- widget()->OnMessageReceived(ViewMsg_LockMouse_ACK(route_id_, true));
+ widget()->OnMessageReceived(WidgetMsg_LockMouse_ACK(route_id_, true));
EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
// Fail attempt to lock alternate.
@@ -230,7 +230,7 @@ TEST_F(MouseLockDispatcherTest, MultipleTargets) {
// Though the call to UnlockMouse should not unlock any target, we will
// cause an unlock (as if e.g. user escaped mouse lock) and verify the
// correct target is unlocked.
- widget()->OnMessageReceived(ViewMsg_MouseLockLost(route_id_));
+ widget()->OnMessageReceived(WidgetMsg_MouseLockLost(route_id_));
EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
}
diff --git a/chromium/content/renderer/mus/mus_embedded_frame_delegate.h b/chromium/content/renderer/mus/mus_embedded_frame_delegate.h
index 4c6be417e88..cd61b383ce9 100644
--- a/chromium/content/renderer/mus/mus_embedded_frame_delegate.h
+++ b/chromium/content/renderer/mus/mus_embedded_frame_delegate.h
@@ -7,17 +7,12 @@
namespace viz {
class FrameSinkId;
-class SurfaceInfo;
} // namespace viz
namespace content {
class MusEmbeddedFrameDelegate {
public:
- // Called when the SurfaceInfo changes.
- virtual void OnMusEmbeddedFrameSurfaceChanged(
- const viz::SurfaceInfo& surface_info) = 0;
-
// Called when mus determines the FrameSinkId.
virtual void OnMusEmbeddedFrameSinkIdAllocated(
const viz::FrameSinkId& frame_sink_id) = 0;
diff --git a/chromium/content/renderer/mus/renderer_window_tree_client.cc b/chromium/content/renderer/mus/renderer_window_tree_client.cc
index 4eef295478b..7ca8a290106 100644
--- a/chromium/content/renderer/mus/renderer_window_tree_client.cc
+++ b/chromium/content/renderer/mus/renderer_window_tree_client.cc
@@ -32,7 +32,7 @@ base::LazyInstance<ConnectionMap>::Leaky g_connections =
// static
void RendererWindowTreeClient::CreateIfNecessary(int routing_id) {
- if (!features::IsUsingWindowService() || Get(routing_id))
+ if (!features::IsMultiProcessMash() || Get(routing_id))
return;
RendererWindowTreeClient* connection =
new RendererWindowTreeClient(routing_id);
@@ -145,7 +145,8 @@ void RendererWindowTreeClient::RequestLayerTreeFrameSinkInternal(
if (features::IsVizHitTestingDrawQuadEnabled()) {
params.hit_test_data_provider =
std::make_unique<viz::HitTestDataProviderDrawQuad>(
- true /* should_ask_for_child_region */);
+ true /* should_ask_for_child_region */,
+ true /* root_accepts_events */);
}
auto frame_sink =
std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>(
@@ -237,7 +238,7 @@ void RendererWindowTreeClient::OnFrameSinkIdAllocated(
const viz::FrameSinkId& frame_sink_id) {
// When mus is not hosting viz FrameSinkIds come from the browser, so we
// ignore them here.
- if (!features::IsUsingWindowService())
+ if (!features::IsMultiProcessMash())
return;
for (MusEmbeddedFrame* embedded_frame : embedded_frames_) {
@@ -299,6 +300,9 @@ void RendererWindowTreeClient::OnWindowOpacityChanged(ws::Id window_id,
float old_opacity,
float new_opacity) {}
+void RendererWindowTreeClient::OnWindowDisplayChanged(ws::Id window_id,
+ int64_t display_id) {}
+
void RendererWindowTreeClient::OnWindowParentDrawnStateChanged(ws::Id window_id,
bool drawn) {}
@@ -328,18 +332,6 @@ void RendererWindowTreeClient::OnWindowFocused(ws::Id focused_window_id) {}
void RendererWindowTreeClient::OnWindowCursorChanged(ws::Id window_id,
ui::CursorData cursor) {}
-void RendererWindowTreeClient::OnWindowSurfaceChanged(
- ws::Id window_id,
- const viz::SurfaceInfo& surface_info) {
- DCHECK(features::IsUsingWindowService());
- for (MusEmbeddedFrame* embedded_frame : embedded_frames_) {
- if (embedded_frame->window_id_ == window_id) {
- embedded_frame->delegate_->OnMusEmbeddedFrameSurfaceChanged(surface_info);
- return;
- }
- }
-}
-
void RendererWindowTreeClient::OnDragDropStart(
const base::flat_map<std::string, std::vector<uint8_t>>& mime_data) {}
diff --git a/chromium/content/renderer/mus/renderer_window_tree_client.h b/chromium/content/renderer/mus/renderer_window_tree_client.h
index 8a9352f388e..b76fbac6f9a 100644
--- a/chromium/content/renderer/mus/renderer_window_tree_client.h
+++ b/chromium/content/renderer/mus/renderer_window_tree_client.h
@@ -159,6 +159,7 @@ class RendererWindowTreeClient : public ws::mojom::WindowTreeClient,
void OnWindowOpacityChanged(ws::Id window_id,
float old_opacity,
float new_opacity) override;
+ void OnWindowDisplayChanged(ws::Id window_id, int64_t display_id) override;
void OnWindowParentDrawnStateChanged(ws::Id window_id, bool drawn) override;
void OnWindowSharedPropertyChanged(
ws::Id window_id,
@@ -174,8 +175,6 @@ class RendererWindowTreeClient : public ws::mojom::WindowTreeClient,
int64_t display_id) override;
void OnWindowFocused(ws::Id focused_window_id) override;
void OnWindowCursorChanged(ws::Id window_id, ui::CursorData cursor) override;
- void OnWindowSurfaceChanged(ws::Id window_id,
- const viz::SurfaceInfo& surface_info) override;
void OnDragDropStart(const base::flat_map<std::string, std::vector<uint8_t>>&
mime_data) override;
void OnDragEnter(ws::Id window_id,
diff --git a/chromium/content/renderer/navigation_state_impl.cc b/chromium/content/renderer/navigation_state.cc
index 5b9e23f3d26..54b4cc2b457 100644
--- a/chromium/content/renderer/navigation_state_impl.cc
+++ b/chromium/content/renderer/navigation_state.cc
@@ -2,49 +2,57 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/navigation_state_impl.h"
+#include "content/renderer/navigation_state.h"
+
+#include "content/renderer/internal_document_state_data.h"
namespace content {
-NavigationStateImpl::~NavigationStateImpl() {
+NavigationState::~NavigationState() {
RunCommitNavigationCallback(blink::mojom::CommitResult::Aborted);
}
-NavigationStateImpl* NavigationStateImpl::CreateBrowserInitiated(
+// static
+std::unique_ptr<NavigationState> NavigationState::CreateBrowserInitiated(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
base::TimeTicks time_commit_requested,
mojom::FrameNavigationControl::CommitNavigationCallback callback) {
- return new NavigationStateImpl(common_params, request_params,
- time_commit_requested, false,
- std::move(callback));
+ return base::WrapUnique(new NavigationState(common_params, request_params,
+ time_commit_requested, false,
+ std::move(callback)));
}
-NavigationStateImpl* NavigationStateImpl::CreateContentInitiated() {
- return new NavigationStateImpl(
+// static
+std::unique_ptr<NavigationState> NavigationState::CreateContentInitiated() {
+ return base::WrapUnique(new NavigationState(
CommonNavigationParams(), RequestNavigationParams(), base::TimeTicks(),
- true, content::mojom::FrameNavigationControl::CommitNavigationCallback());
+ true,
+ content::mojom::FrameNavigationControl::CommitNavigationCallback()));
}
-ui::PageTransition NavigationStateImpl::GetTransitionType() {
- return common_params_.transition;
+// static
+NavigationState* NavigationState::FromDocumentLoader(
+ blink::WebDocumentLoader* document_loader) {
+ return InternalDocumentStateData::FromDocumentLoader(document_loader)
+ ->navigation_state();
}
-bool NavigationStateImpl::WasWithinSameDocument() {
+bool NavigationState::WasWithinSameDocument() {
return was_within_same_document_;
}
-bool NavigationStateImpl::IsContentInitiated() {
+bool NavigationState::IsContentInitiated() {
return is_content_initiated_;
}
-void NavigationStateImpl::RunCommitNavigationCallback(
+void NavigationState::RunCommitNavigationCallback(
blink::mojom::CommitResult result) {
if (commit_callback_)
std::move(commit_callback_).Run(result);
}
-NavigationStateImpl::NavigationStateImpl(
+NavigationState::NavigationState(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
base::TimeTicks time_commit_requested,
diff --git a/chromium/content/renderer/navigation_state_impl.h b/chromium/content/renderer/navigation_state.h
index 9b3628b9591..ea329af780b 100644
--- a/chromium/content/renderer/navigation_state_impl.h
+++ b/chromium/content/renderer/navigation_state.h
@@ -2,36 +2,43 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_NAVIGATION_STATE_IMPL_H_
-#define CONTENT_RENDERER_NAVIGATION_STATE_IMPL_H_
+#ifndef CONTENT_RENDERER_NAVIGATION_STATE_H_
+#define CONTENT_RENDERER_NAVIGATION_STATE_H_
#include <string>
#include "base/macros.h"
#include "content/common/frame.mojom.h"
#include "content/common/navigation_params.h"
-#include "content/public/renderer/navigation_state.h"
#include "content/renderer/navigation_client.h"
#include "third_party/blink/public/web/commit_result.mojom.h"
+namespace blink {
+class WebDocumentLoader;
+}
+
namespace content {
-class CONTENT_EXPORT NavigationStateImpl : public NavigationState {
+class CONTENT_EXPORT NavigationState {
public:
- ~NavigationStateImpl() override;
+ ~NavigationState();
- static NavigationStateImpl* CreateBrowserInitiated(
+ static std::unique_ptr<NavigationState> CreateBrowserInitiated(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
base::TimeTicks time_commit_requested,
mojom::FrameNavigationControl::CommitNavigationCallback callback);
- static NavigationStateImpl* CreateContentInitiated();
+ static std::unique_ptr<NavigationState> CreateContentInitiated();
+
+ static NavigationState* FromDocumentLoader(
+ blink::WebDocumentLoader* document_loader);
- // NavigationState implementation.
- ui::PageTransition GetTransitionType() override;
- bool WasWithinSameDocument() override;
- bool IsContentInitiated() override;
+ // True iff the frame's navigation was within the same document.
+ bool WasWithinSameDocument();
+
+ // True if this navigation was not initiated via WebFrame::LoadRequest.
+ bool IsContentInitiated();
const CommonNavigationParams& common_params() const { return common_params_; }
const RequestNavigationParams& request_params() const {
@@ -64,7 +71,7 @@ class CONTENT_EXPORT NavigationStateImpl : public NavigationState {
void RunCommitNavigationCallback(blink::mojom::CommitResult result);
private:
- NavigationStateImpl(
+ NavigationState(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
base::TimeTicks time_commit_requested,
@@ -105,9 +112,9 @@ class CONTENT_EXPORT NavigationStateImpl : public NavigationState {
// successful or not.
mojom::FrameNavigationControl::CommitNavigationCallback commit_callback_;
- DISALLOW_COPY_AND_ASSIGN(NavigationStateImpl);
+ DISALLOW_COPY_AND_ASSIGN(NavigationState);
};
} // namespace content
-#endif // CONTENT_RENDERER_NAVIGATION_STATE_IMPL_H_
+#endif // CONTENT_RENDERER_NAVIGATION_STATE_H_
diff --git a/chromium/content/renderer/notifications/notification_data_conversions.cc b/chromium/content/renderer/notifications/notification_data_conversions.cc
index 65556cd4b51..72c20d6cdf2 100644
--- a/chromium/content/renderer/notifications/notification_data_conversions.cc
+++ b/chromium/content/renderer/notifications/notification_data_conversions.cc
@@ -20,18 +20,18 @@ using blink::WebString;
namespace content {
WebNotificationData ToWebNotificationData(
- const PlatformNotificationData& platform_data) {
+ const blink::PlatformNotificationData& platform_data) {
WebNotificationData web_data;
web_data.title = WebString::FromUTF16(platform_data.title);
switch (platform_data.direction) {
- case PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT:
+ case blink::PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT:
web_data.direction = WebNotificationData::kDirectionLeftToRight;
break;
- case PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT:
+ case blink::PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT:
web_data.direction = WebNotificationData::kDirectionRightToLeft;
break;
- case PlatformNotificationData::DIRECTION_AUTO:
+ case blink::PlatformNotificationData::DIRECTION_AUTO:
web_data.direction = WebNotificationData::kDirectionAuto;
break;
}
@@ -53,10 +53,10 @@ WebNotificationData ToWebNotificationData(
web_data.actions.Swap(resized);
for (size_t i = 0; i < platform_data.actions.size(); ++i) {
switch (platform_data.actions[i].type) {
- case PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON:
+ case blink::PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON:
web_data.actions[i].type = blink::WebNotificationAction::kButton;
break;
- case PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT:
+ case blink::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT:
web_data.actions[i].type = blink::WebNotificationAction::kText;
break;
default:
diff --git a/chromium/content/renderer/notifications/notification_data_conversions.h b/chromium/content/renderer/notifications/notification_data_conversions.h
index d6bf25e5b91..916265779ed 100644
--- a/chromium/content/renderer/notifications/notification_data_conversions.h
+++ b/chromium/content/renderer/notifications/notification_data_conversions.h
@@ -6,14 +6,14 @@
#define CONTENT_RENDERER_NOTIFICATIONS_NOTIFICATION_DATA_CONVERSIONS_H_
#include "content/common/content_export.h"
-#include "content/public/common/platform_notification_data.h"
+#include "third_party/blink/public/common/notifications/platform_notification_data.h"
#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
namespace content {
-// Converts PlatformNotificationData to Blink WebNotificationData.
+// Converts blink::PlatformNotificationData to Blink WebNotificationData.
CONTENT_EXPORT blink::WebNotificationData ToWebNotificationData(
- const PlatformNotificationData& platform_data);
+ const blink::PlatformNotificationData& platform_data);
} // namespace content
diff --git a/chromium/content/renderer/notifications/notification_data_conversions_unittest.cc b/chromium/content/renderer/notifications/notification_data_conversions_unittest.cc
index 35fd3f2b894..33636ba9c03 100644
--- a/chromium/content/renderer/notifications/notification_data_conversions_unittest.cc
+++ b/chromium/content/renderer/notifications/notification_data_conversions_unittest.cc
@@ -9,9 +9,9 @@
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
-#include "content/public/common/platform_notification_data.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/notifications/platform_notification_data.h"
#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
@@ -44,9 +44,10 @@ TEST(NotificationDataConversionsTest, ToWebNotificationData) {
std::vector<char> developer_data(
kNotificationData, kNotificationData + arraysize(kNotificationData));
- PlatformNotificationData platform_data;
+ blink::PlatformNotificationData platform_data;
platform_data.title = base::ASCIIToUTF16(kNotificationTitle);
- platform_data.direction = PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT;
+ platform_data.direction =
+ blink::PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT;
platform_data.lang = kNotificationLang;
platform_data.body = base::ASCIIToUTF16(kNotificationBody);
platform_data.tag = kNotificationTag;
@@ -60,13 +61,14 @@ TEST(NotificationDataConversionsTest, ToWebNotificationData) {
platform_data.require_interaction = true;
platform_data.data = developer_data;
platform_data.actions.resize(2);
- platform_data.actions[0].type = PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON;
+ platform_data.actions[0].type =
+ blink::PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON;
platform_data.actions[0].action = kAction1Name;
platform_data.actions[0].title = base::ASCIIToUTF16(kAction1Title);
platform_data.actions[0].icon = GURL(kAction1IconUrl);
platform_data.actions[0].placeholder =
base::NullableString16(base::ASCIIToUTF16(kAction1Placeholder), false);
- platform_data.actions[1].type = PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT;
+ platform_data.actions[1].type = blink::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT;
platform_data.actions[1].action = kAction2Name;
platform_data.actions[1].title = base::ASCIIToUTF16(kAction2Title);
platform_data.actions[1].icon = GURL(kAction2IconUrl);
diff --git a/chromium/content/renderer/p2p/host_address_request.cc b/chromium/content/renderer/p2p/host_address_request.cc
index 0b0c8747e53..a372aac5ebc 100644
--- a/chromium/content/renderer/p2p/host_address_request.cc
+++ b/chromium/content/renderer/p2p/host_address_request.cc
@@ -30,7 +30,7 @@ void P2PAsyncAddressResolver::Start(const rtc::SocketAddress& host_name,
state_ = STATE_SENT;
done_callback_ = done_callback;
- dispatcher_->GetP2PSocketManager()->GetHostAddress(
+ dispatcher_->GetP2PSocketManager()->get()->GetHostAddress(
host_name.hostname(), base::BindOnce(&P2PAsyncAddressResolver::OnResponse,
base::Unretained(this)));
}
diff --git a/chromium/content/renderer/p2p/ipc_network_manager.cc b/chromium/content/renderer/p2p/ipc_network_manager.cc
index 430f61d6610..169c27a05a1 100644
--- a/chromium/content/renderer/p2p/ipc_network_manager.cc
+++ b/chromium/content/renderer/p2p/ipc_network_manager.cc
@@ -93,8 +93,7 @@ void IpcNetworkManager::OnNetworkListChanged(
// rtc::Network uses these prefix_length to compare network
// interfaces discovered.
std::vector<rtc::Network*> networks;
- for (net::NetworkInterfaceList::const_iterator it = list.begin();
- it != list.end(); it++) {
+ for (auto it = list.begin(); it != list.end(); it++) {
rtc::IPAddress ip_address =
jingle_glue::NetIPAddressToRtcIPAddress(it->address);
DCHECK(!ip_address.IsNil());
diff --git a/chromium/content/renderer/p2p/socket_client_impl.cc b/chromium/content/renderer/p2p/socket_client_impl.cc
index 2b0de5c4a0e..96452cce577 100644
--- a/chromium/content/renderer/p2p/socket_client_impl.cc
+++ b/chromium/content/renderer/p2p/socket_client_impl.cc
@@ -64,7 +64,7 @@ void P2PSocketClientImpl::Init(
binding_.Bind(mojo::MakeRequest(&socket_client));
binding_.set_connection_error_handler(base::Bind(
&P2PSocketClientImpl::OnConnectionError, base::Unretained(this)));
- dispatcher_->GetP2PSocketManager()->CreateSocket(
+ dispatcher_->GetP2PSocketManager()->get()->CreateSocket(
type, local_address, network::P2PPortRange(min_port, max_port),
remote_address, std::move(socket_client), mojo::MakeRequest(&socket_));
}
diff --git a/chromium/content/renderer/p2p/socket_dispatcher.cc b/chromium/content/renderer/p2p/socket_dispatcher.cc
index ce4ed09485c..8a4a32d6d9e 100644
--- a/chromium/content/renderer/p2p/socket_dispatcher.cc
+++ b/chromium/content/renderer/p2p/socket_dispatcher.cc
@@ -22,11 +22,6 @@ P2PSocketDispatcher::P2PSocketDispatcher()
network_list_observers_(
new base::ObserverListThreadSafe<NetworkListObserver>()),
network_notification_client_binding_(this) {
- network::mojom::P2PSocketManagerPtr p2p_socket_manager;
- p2p_socket_manager_request_ = mojo::MakeRequest(&p2p_socket_manager);
- thread_safe_p2p_socket_manager_ =
- network::mojom::ThreadSafeP2PSocketManagerPtr::Create(
- std::move(p2p_socket_manager));
}
P2PSocketDispatcher::~P2PSocketDispatcher() {
@@ -45,11 +40,22 @@ void P2PSocketDispatcher::RemoveNetworkListObserver(
network_list_observers_->RemoveObserver(network_list_observer);
}
-network::mojom::P2PSocketManager* P2PSocketDispatcher::GetP2PSocketManager() {
+scoped_refptr<network::mojom::ThreadSafeP2PSocketManagerPtr>
+P2PSocketDispatcher::GetP2PSocketManager() {
+ base::AutoLock lock(p2p_socket_manager_lock_);
+ if (!thread_safe_p2p_socket_manager_) {
+ network::mojom::P2PSocketManagerPtr p2p_socket_manager;
+ p2p_socket_manager_request_ = mojo::MakeRequest(&p2p_socket_manager);
+ p2p_socket_manager.set_connection_error_handler(base::BindOnce(
+ &P2PSocketDispatcher::OnConnectionError, base::Unretained(this)));
+ thread_safe_p2p_socket_manager_ =
+ network::mojom::ThreadSafeP2PSocketManagerPtr::Create(
+ std::move(p2p_socket_manager));
+ }
main_task_runner_->PostTask(
FROM_HERE,
base::Bind(&P2PSocketDispatcher::RequestInterfaceIfNecessary, this));
- return thread_safe_p2p_socket_manager_->get();
+ return thread_safe_p2p_socket_manager_;
}
void P2PSocketDispatcher::NetworkListChanged(
@@ -82,9 +88,14 @@ void P2PSocketDispatcher::RequestNetworkEventsIfNecessary() {
network::mojom::P2PNetworkNotificationClientPtr network_notification_client;
network_notification_client_binding_.Bind(
mojo::MakeRequest(&network_notification_client));
- GetP2PSocketManager()->StartNetworkNotifications(
+ GetP2PSocketManager()->get()->StartNetworkNotifications(
std::move(network_notification_client));
}
}
+void P2PSocketDispatcher::OnConnectionError() {
+ base::AutoLock lock(p2p_socket_manager_lock_);
+ thread_safe_p2p_socket_manager_.reset();
+}
+
} // namespace content
diff --git a/chromium/content/renderer/p2p/socket_dispatcher.h b/chromium/content/renderer/p2p/socket_dispatcher.h
index 70b2696be52..7ceceaf764a 100644
--- a/chromium/content/renderer/p2p/socket_dispatcher.h
+++ b/chromium/content/renderer/p2p/socket_dispatcher.h
@@ -63,7 +63,8 @@ class CONTENT_EXPORT P2PSocketDispatcher
void RemoveNetworkListObserver(
NetworkListObserver* network_list_observer) override;
- network::mojom::P2PSocketManager* GetP2PSocketManager();
+ scoped_refptr<network::mojom::ThreadSafeP2PSocketManagerPtr>
+ GetP2PSocketManager();
private:
friend class base::RefCountedThreadSafe<P2PSocketDispatcher>;
@@ -79,6 +80,8 @@ class CONTENT_EXPORT P2PSocketDispatcher
void RequestInterfaceIfNecessary();
void RequestNetworkEventsIfNecessary();
+ void OnConnectionError();
+
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
scoped_refptr<base::ObserverListThreadSafe<NetworkListObserver>>
@@ -87,6 +90,7 @@ class CONTENT_EXPORT P2PSocketDispatcher
network::mojom::P2PSocketManagerRequest p2p_socket_manager_request_;
scoped_refptr<network::mojom::ThreadSafeP2PSocketManagerPtr>
thread_safe_p2p_socket_manager_;
+ base::Lock p2p_socket_manager_lock_;
// Cached from last |NetworkListChanged| call.
std::vector<net::NetworkInterface> networks_;
diff --git a/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc b/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc
index 2c396ffb834..401e48c605d 100644
--- a/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc
+++ b/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc
@@ -27,9 +27,7 @@
#include "content/renderer/pepper/pepper_url_loader_host.h"
#include "content/renderer/pepper/pepper_video_capture_host.h"
#include "content/renderer/pepper/pepper_video_decoder_host.h"
-#include "content/renderer/pepper/pepper_video_destination_host.h"
#include "content/renderer/pepper/pepper_video_encoder_host.h"
-#include "content/renderer/pepper/pepper_video_source_host.h"
#include "content/renderer/pepper/pepper_websocket_host.h"
#include "content/renderer/pepper/ppb_image_data_impl.h"
#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
@@ -55,18 +53,6 @@ namespace content {
namespace {
-bool CanUseMediaStreamAPI(const RendererPpapiHost* host, PP_Instance instance) {
- blink::WebPluginContainer* container =
- host->GetContainerForInstance(instance);
- if (!container)
- return false;
-
- GURL document_url = container->GetDocument().Url();
- ContentRendererClient* content_renderer_client =
- GetContentClient()->renderer();
- return content_renderer_client->AllowPepperMediaStreamAPI(document_url);
-}
-
static bool CanUseCameraDeviceAPI(const RendererPpapiHost* host,
PP_Instance instance) {
blink::WebPluginContainer* container =
@@ -187,19 +173,6 @@ ContentRendererPepperHostFactory::CreateResourceHost(
case PpapiHostMsg_MediaStreamVideoTrack_Create::ID:
return std::make_unique<PepperMediaStreamVideoTrackHost>(host_, instance,
resource);
- // These private MediaStream interfaces are exposed as if they were public
- // so they can be used by NaCl plugins. However, they are available only
- // for whitelisted apps.
- case PpapiHostMsg_VideoDestination_Create::ID:
- if (CanUseMediaStreamAPI(host_, instance))
- return std::make_unique<PepperVideoDestinationHost>(host_, instance,
- resource);
- return nullptr;
- case PpapiHostMsg_VideoSource_Create::ID:
- if (CanUseMediaStreamAPI(host_, instance))
- return std::make_unique<PepperVideoSourceHost>(host_, instance,
- resource);
- return nullptr;
}
// Dev interfaces.
diff --git a/chromium/content/renderer/pepper/host_globals.cc b/chromium/content/renderer/pepper/host_globals.cc
index 5ef70b58473..4a43be09fa7 100644
--- a/chromium/content/renderer/pepper/host_globals.cc
+++ b/chromium/content/renderer/pepper/host_globals.cc
@@ -43,9 +43,7 @@ typedef std::set<WebPluginContainer*> ContainerSet;
// Adds all WebPluginContainers associated with the given module to the set.
void GetAllContainersForModule(PluginModule* module, ContainerSet* containers) {
const PluginModule::PluginInstanceSet& instances = module->GetAllInstances();
- for (PluginModule::PluginInstanceSet::const_iterator i = instances.begin();
- i != instances.end();
- ++i) {
+ for (auto i = instances.begin(); i != instances.end(); ++i) {
WebPluginContainer* container = (*i)->container();
// If "Delete" is called on an instance, the instance sets its container to
// NULL, but the instance may actually outlive its container. Callers of
@@ -107,7 +105,7 @@ ppapi::VarTracker* HostGlobals::GetVarTracker() { return &host_var_tracker_; }
ppapi::CallbackTracker* HostGlobals::GetCallbackTrackerForInstance(
PP_Instance instance) {
- InstanceMap::iterator found = instance_map_.find(instance);
+ auto found = instance_map_.find(instance);
if (found == instance_map_.end())
return nullptr;
return found->second->module()->GetCallbackTracker().get();
@@ -182,8 +180,7 @@ void HostGlobals::BroadcastLogWithSource(PP_Module pp_module,
}
WebConsoleMessage message = MakeLogMessage(level, source, value);
- for (ContainerSet::iterator i = containers.begin(); i != containers.end();
- ++i) {
+ for (auto i = containers.begin(); i != containers.end(); ++i) {
WebLocalFrame* frame = (*i)->GetDocument().GetFrame();
if (frame)
frame->AddMessageToConsole(message);
@@ -222,7 +219,7 @@ PP_Module HostGlobals::AddModule(PluginModule* module) {
void HostGlobals::ModuleDeleted(PP_Module module) {
DLOG_IF(ERROR, !CheckIdType(module, ppapi::PP_ID_TYPE_MODULE))
<< module << " is not a PP_Module.";
- ModuleMap::iterator found = module_map_.find(module);
+ auto found = module_map_.find(module);
if (found == module_map_.end()) {
NOTREACHED();
return;
@@ -233,7 +230,7 @@ void HostGlobals::ModuleDeleted(PP_Module module) {
PluginModule* HostGlobals::GetModule(PP_Module module) {
DLOG_IF(ERROR, !CheckIdType(module, ppapi::PP_ID_TYPE_MODULE))
<< module << " is not a PP_Module.";
- ModuleMap::iterator found = module_map_.find(module);
+ auto found = module_map_.find(module);
if (found == module_map_.end())
return nullptr;
return found->second;
@@ -274,7 +271,7 @@ void HostGlobals::InstanceCrashed(PP_Instance instance) {
PepperPluginInstanceImpl* HostGlobals::GetInstance(PP_Instance instance) {
DLOG_IF(ERROR, !CheckIdType(instance, ppapi::PP_ID_TYPE_INSTANCE))
<< instance << " is not a PP_Instance.";
- InstanceMap::iterator found = instance_map_.find(instance);
+ auto found = instance_map_.find(instance);
if (found == instance_map_.end())
return nullptr;
return found->second;
diff --git a/chromium/content/renderer/pepper/host_var_tracker.cc b/chromium/content/renderer/pepper/host_var_tracker.cc
index b058576d61e..0424b3d736c 100644
--- a/chromium/content/renderer/pepper/host_var_tracker.cc
+++ b/chromium/content/renderer/pepper/host_var_tracker.cc
@@ -63,8 +63,8 @@ void HostVarTracker::AddV8ObjectVar(V8ObjectVar* object_var) {
void HostVarTracker::RemoveV8ObjectVar(V8ObjectVar* object_var) {
CheckThreadingPreconditions();
v8::HandleScope handle_scope(object_var->instance()->GetIsolate());
- ObjectMap::iterator it = GetForV8Object(
- object_var->instance()->pp_instance(), object_var->GetHandle());
+ auto it = GetForV8Object(object_var->instance()->pp_instance(),
+ object_var->GetHandle());
DCHECK(it != object_map_.end());
object_map_.erase(it);
}
@@ -120,7 +120,7 @@ void HostVarTracker::DidDeleteInstance(PP_Instance pp_instance) {
// Use a key with an empty handle to find the v8 object var in the map with
// the given instance and the lowest hash.
V8ObjectVarKey key(pp_instance, v8::Local<v8::Object>());
- ObjectMap::iterator it = object_map_.lower_bound(key);
+ auto it = object_map_.lower_bound(key);
while (it != object_map_.end() && it->first.instance == pp_instance) {
ForceReleaseV8Object(it->second);
object_map_.erase(it++);
@@ -129,7 +129,7 @@ void HostVarTracker::DidDeleteInstance(PP_Instance pp_instance) {
void HostVarTracker::ForceReleaseV8Object(ppapi::V8ObjectVar* object_var) {
object_var->InstanceDeleted();
- VarMap::iterator iter = live_vars_.find(object_var->GetExistingVarID());
+ auto iter = live_vars_.find(object_var->GetExistingVarID());
if (iter == live_vars_.end()) {
NOTREACHED();
return;
@@ -145,7 +145,7 @@ HostVarTracker::ObjectMap::iterator HostVarTracker::GetForV8Object(
std::pair<ObjectMap::iterator, ObjectMap::iterator> range =
object_map_.equal_range(V8ObjectVarKey(instance, object));
- for (ObjectMap::iterator it = range.first; it != range.second; ++it) {
+ for (auto it = range.first; it != range.second; ++it) {
if (object == it->second->GetHandle())
return it;
}
@@ -174,7 +174,7 @@ bool HostVarTracker::StopTrackingSharedMemoryHandle(
PP_Instance instance,
base::SharedMemoryHandle* handle,
uint32_t* size_in_bytes) {
- SharedMemoryMap::iterator it = shared_memory_map_.find(id);
+ auto it = shared_memory_map_.find(id);
if (it == shared_memory_map_.end())
return false;
if (it->second.instance != instance)
diff --git a/chromium/content/renderer/pepper/message_channel.cc b/chromium/content/renderer/pepper/message_channel.cc
index 219a0c76744..738d86028ba 100644
--- a/chromium/content/renderer/pepper/message_channel.cc
+++ b/chromium/content/renderer/pepper/message_channel.cc
@@ -211,13 +211,17 @@ v8::Local<v8::Value> MessageChannel::GetNamedProperty(
PepperTryCatchV8 try_catch(instance_, &var_converter_, isolate);
if (identifier == kPostMessage) {
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
return GetFunctionTemplate(isolate, identifier,
&MessageChannel::PostMessageToNative)
- ->GetFunction();
+ ->GetFunction(context)
+ .ToLocalChecked();
} else if (identifier == kPostMessageAndAwaitResponse) {
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
return GetFunctionTemplate(isolate, identifier,
&MessageChannel::PostBlockingMessageToNative)
- ->GetFunction();
+ ->GetFunction(context)
+ .ToLocalChecked();
}
std::map<std::string, ScopedPPVar>::const_iterator it =
diff --git a/chromium/content/renderer/pepper/pepper_broker.cc b/chromium/content/renderer/pepper/pepper_broker.cc
index 1f5cd9fd35a..4d75b47da77 100644
--- a/chromium/content/renderer/pepper/pepper_broker.cc
+++ b/chromium/content/renderer/pepper/pepper_broker.cc
@@ -156,8 +156,7 @@ void PepperBroker::OnBrokerChannelConnected(
dispatcher_.reset(dispatcher.release());
// Process all pending channel requests from the plugins.
- for (ClientMap::iterator i = pending_connects_.begin();
- i != pending_connects_.end();) {
+ for (auto i = pending_connects_.begin(); i != pending_connects_.end();) {
base::WeakPtr<PPB_Broker_Impl>& weak_ptr = i->second.client;
if (!i->second.is_authorized) {
++i;
@@ -173,7 +172,7 @@ void PepperBroker::OnBrokerChannelConnected(
void PepperBroker::OnBrokerPermissionResult(PPB_Broker_Impl* client,
bool result) {
- ClientMap::iterator entry = pending_connects_.find(client);
+ auto entry = pending_connects_.find(client);
if (entry == pending_connects_.end())
return;
@@ -213,9 +212,7 @@ PepperBroker::PendingConnection::~PendingConnection() {}
void PepperBroker::ReportFailureToClients(int error_code) {
DCHECK_NE(PP_OK, error_code);
- for (ClientMap::iterator i = pending_connects_.begin();
- i != pending_connects_.end();
- ++i) {
+ for (auto i = pending_connects_.begin(); i != pending_connects_.end(); ++i) {
base::WeakPtr<PPB_Broker_Impl>& weak_ptr = i->second.client;
if (weak_ptr.get()) {
weak_ptr->BrokerConnected(
diff --git a/chromium/content/renderer/pepper/pepper_browser_connection.cc b/chromium/content/renderer/pepper/pepper_browser_connection.cc
index 19ba1cc7a35..71b3e6c01a9 100644
--- a/chromium/content/renderer/pepper/pepper_browser_connection.cc
+++ b/chromium/content/renderer/pepper/pepper_browser_connection.cc
@@ -74,8 +74,7 @@ void PepperBrowserConnection::OnMsgCreateResourceHostsFromHostReply(
const std::vector<int>& pending_resource_host_ids) {
// Check that the message is destined for the plugin this object is associated
// with.
- std::map<int32_t, PendingResourceIDCallback>::iterator it =
- pending_create_map_.find(sequence_number);
+ auto it = pending_create_map_.find(sequence_number);
if (it != pending_create_map_.end()) {
it->second.Run(pending_resource_host_ids);
pending_create_map_.erase(it);
diff --git a/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc b/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc
index 6c2d52e1309..8e20a934c21 100644
--- a/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc
+++ b/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc
@@ -11,8 +11,8 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/host_message_context.h"
@@ -146,7 +146,8 @@ class PepperDeviceEnumerationHostHelperTest : public testing::Test {
ppapi::host::PpapiHost ppapi_host_;
ppapi::host::ResourceHost resource_host_;
PepperDeviceEnumerationHostHelper device_enumeration_;
- base::MessageLoop message_loop_; // required for async calls to work.
+ base::test::ScopedTaskEnvironment
+ task_environment_; // required for async calls to work.
private:
DISALLOW_COPY_AND_ASSIGN(PepperDeviceEnumerationHostHelperTest);
diff --git a/chromium/content/renderer/pepper/pepper_file_chooser_host.cc b/chromium/content/renderer/pepper/pepper_file_chooser_host.cc
index 9c93b39c851..62feee1c4c2 100644
--- a/chromium/content/renderer/pepper/pepper_file_chooser_host.cc
+++ b/chromium/content/renderer/pepper/pepper_file_chooser_host.cc
@@ -9,7 +9,6 @@
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
-#include "content/public/common/file_chooser_params.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "content/renderer/pepper/pepper_file_ref_renderer_host.h"
#include "content/renderer/render_view_impl.h"
@@ -17,12 +16,16 @@
#include "ppapi/host/dispatch_host_message.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"
+#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
+#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_file_chooser_completion.h"
namespace content {
+using blink::mojom::FileChooserParams;
+
class PepperFileChooserHost::CompletionHandler
: public blink::WebFileChooserCompletion {
public:
@@ -37,7 +40,7 @@ class PepperFileChooserHost::CompletionHandler
std::vector<PepperFileChooserHost::ChosenFileInfo> files;
for (size_t i = 0; i < file_names.size(); i++) {
files.push_back(PepperFileChooserHost::ChosenFileInfo(
- file_names[i].Utf8(), std::string()));
+ blink::WebStringToFilePath(file_names[i]), std::string()));
}
host_->StoreChosenFiles(files);
}
@@ -51,7 +54,7 @@ class PepperFileChooserHost::CompletionHandler
std::vector<PepperFileChooserHost::ChosenFileInfo> files;
for (size_t i = 0; i < file_names.size(); i++) {
files.push_back(PepperFileChooserHost::ChosenFileInfo(
- file_names[i].path.Utf8(), file_names[i].display_name.Utf8()));
+ file_names[i].file_path, file_names[i].display_name.Utf8()));
}
host_->StoreChosenFiles(files);
}
@@ -67,9 +70,9 @@ class PepperFileChooserHost::CompletionHandler
};
PepperFileChooserHost::ChosenFileInfo::ChosenFileInfo(
- const std::string& path,
+ const base::FilePath& file_path,
const std::string& display_name)
- : path(path), display_name(display_name) {}
+ : file_path(file_path), display_name(display_name) {}
PepperFileChooserHost::PepperFileChooserHost(RendererPpapiHost* host,
PP_Instance instance,
@@ -96,7 +99,7 @@ void PepperFileChooserHost::StoreChosenFiles(
std::vector<base::FilePath> file_paths;
std::vector<std::string> display_names;
for (size_t i = 0; i < files.size(); i++) {
- base::FilePath file_path = base::FilePath::FromUTF8Unsafe(files[i].path);
+ base::FilePath file_path = files[i].file_path;
file_paths.push_back(file_path);
create_msgs.push_back(PpapiHostMsg_FileRef_CreateForRawFS(file_path));
display_names.push_back(files[i].display_name);
@@ -137,12 +140,12 @@ int32_t PepperFileChooserHost::OnShow(
FileChooserParams params;
if (save_as) {
- params.mode = FileChooserParams::Save;
+ params.mode = FileChooserParams::Mode::kSave;
params.default_file_name =
base::FilePath::FromUTF8Unsafe(suggested_file_name).BaseName();
} else {
- params.mode = open_multiple ? FileChooserParams::OpenMultiple
- : FileChooserParams::Open;
+ params.mode = open_multiple ? FileChooserParams::Mode::kOpenMultiple
+ : FileChooserParams::Mode::kOpen;
}
params.accept_types.reserve(accept_mime_types.size());
for (const auto& mime_type : accept_mime_types)
diff --git a/chromium/content/renderer/pepper/pepper_file_chooser_host.h b/chromium/content/renderer/pepper/pepper_file_chooser_host.h
index 3032da07407..c37930e566a 100644
--- a/chromium/content/renderer/pepper/pepper_file_chooser_host.h
+++ b/chromium/content/renderer/pepper/pepper_file_chooser_host.h
@@ -27,8 +27,9 @@ class CONTENT_EXPORT PepperFileChooserHost
public:
// Structure to store the information about chosen files.
struct ChosenFileInfo {
- ChosenFileInfo(const std::string& path, const std::string& display_name);
- std::string path;
+ ChosenFileInfo(const base::FilePath& file_path,
+ const std::string& display_name);
+ base::FilePath file_path;
std::string display_name; // May be empty.
};
diff --git a/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc b/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc
index d610636955d..4299de315c5 100644
--- a/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc
+++ b/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc
@@ -10,8 +10,6 @@
#include "build/build_config.h"
#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
-#include "content/public/common/file_chooser_file_info.h"
-#include "content/public/common/file_chooser_params.h"
#include "content/public/test/render_view_test.h"
#include "content/renderer/pepper/mock_renderer_ppapi_host.h"
#include "content/renderer/pepper/pepper_file_chooser_host.h"
@@ -61,15 +59,6 @@ class PepperFileChooserHostTest : public RenderViewTest {
TestContentClient client_;
};
-// For testing to convert our hardcoded file paths to 8-bit.
-std::string FilePathToUTF8(const base::FilePath::StringType& path) {
-#if defined(OS_WIN)
- return base::UTF16ToUTF8(path);
-#else
- return path;
-#endif
-}
-
} // namespace
TEST_F(PepperFileChooserHostTest, Show) {
@@ -97,20 +86,22 @@ TEST_F(PepperFileChooserHostTest, Show) {
ASSERT_TRUE(msg);
FrameHostMsg_RunFileChooser::Schema::Param call_msg_param;
ASSERT_TRUE(FrameHostMsg_RunFileChooser::Read(msg, &call_msg_param));
- const FileChooserParams& chooser_params = std::get<0>(call_msg_param);
+ const blink::mojom::FileChooserParams& chooser_params =
+ std::get<0>(call_msg_param);
// Basic validation of request.
- EXPECT_EQ(FileChooserParams::Open, chooser_params.mode);
+ EXPECT_EQ(blink::mojom::FileChooserParams::Mode::kOpen, chooser_params.mode);
ASSERT_EQ(1u, chooser_params.accept_types.size());
EXPECT_EQ(accept[0], base::UTF16ToUTF8(chooser_params.accept_types[0]));
// Send a chooser reply to the render view. Note our reply path has to have a
// path separator so we include both a Unix and a Windows one.
- content::FileChooserFileInfo selected_info;
- selected_info.display_name = FILE_PATH_LITERAL("Hello, world");
- selected_info.file_path = base::FilePath(FILE_PATH_LITERAL("myp\\ath/foo"));
- std::vector<content::FileChooserFileInfo> selected_info_vector;
- selected_info_vector.push_back(selected_info);
+ std::vector<blink::mojom::FileChooserFileInfoPtr> selected_info_vector;
+ selected_info_vector.push_back(
+ blink::mojom::FileChooserFileInfo::NewNativeFile(
+ blink::mojom::NativeFileInfo::New(
+ base::FilePath(FILE_PATH_LITERAL("myp\\ath/foo")),
+ base::ASCIIToUTF16("Hello, world"))));
RenderFrameImpl* frame_impl =
static_cast<RenderFrameImpl*>(view_->GetMainRenderFrame());
FrameMsg_RunFileChooserResponse response(frame_impl->GetRoutingID(),
@@ -132,7 +123,8 @@ TEST_F(PepperFileChooserHostTest, Show) {
const std::vector<ppapi::FileRefCreateInfo>& chooser_results =
std::get<0>(reply_msg_param);
ASSERT_EQ(1u, chooser_results.size());
- EXPECT_EQ(FilePathToUTF8(selected_info.display_name),
+ EXPECT_EQ(base::UTF16ToUTF8(
+ selected_info_vector[0]->get_native_file()->display_name),
chooser_results[0].display_name);
}
diff --git a/chromium/content/renderer/pepper/pepper_file_system_host.cc b/chromium/content/renderer/pepper/pepper_file_system_host.cc
index 53915dfd0d7..26224903006 100644
--- a/chromium/content/renderer/pepper/pepper_file_system_host.cc
+++ b/chromium/content/renderer/pepper/pepper_file_system_host.cc
@@ -10,7 +10,6 @@
#include "content/public/common/service_names.mojom.h"
#include "content/public/renderer/render_view.h"
#include "content/public/renderer/renderer_ppapi_host.h"
-#include "content/renderer/fileapi/file_system_dispatcher.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "ppapi/c/pp_errors.h"
diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc b/chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc
index 5b24e209631..c2d365aa581 100644
--- a/chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc
+++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc
@@ -7,7 +7,7 @@
#include <stddef.h>
#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "content/renderer/pepper/gfx_conversion.h"
#include "content/renderer/pepper/mock_renderer_ppapi_host.h"
#include "content/renderer/pepper/ppb_image_data_impl.h"
@@ -82,7 +82,7 @@ class PepperGraphics2DHostTest : public testing::Test {
private:
ppapi::ViewData renderer_view_data_;
std::unique_ptr<PepperGraphics2DHost> host_;
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
MockRendererPpapiHost renderer_ppapi_host_;
ppapi::TestGlobals test_globals_;
};
diff --git a/chromium/content/renderer/pepper/pepper_media_device_manager.cc b/chromium/content/renderer/pepper/pepper_media_device_manager.cc
index 606cec34a66..7e09fcc6cd5 100644
--- a/chromium/content/renderer/pepper/pepper_media_device_manager.cc
+++ b/chromium/content/renderer/pepper/pepper_media_device_manager.cc
@@ -232,7 +232,7 @@ void PepperMediaDeviceManager::OnDeviceOpened(int request_id,
bool success,
const std::string& label,
const MediaStreamDevice& device) {
- OpenCallbackMap::iterator iter = open_callbacks_.find(request_id);
+ auto iter = open_callbacks_.find(request_id);
if (iter == open_callbacks_.end()) {
// The callback may have been unregistered.
return;
diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 6cde87d05de..fa9f391cd08 100644
--- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -194,9 +194,11 @@ namespace content {
namespace {
+#ifndef STATIC_ASSERT_ENUM
#define STATIC_ASSERT_ENUM(a, b) \
static_assert(static_cast<int>(a) == static_cast<int>(b), \
"mismatching enums: " #a)
+#endif
// Check PP_TextInput_Type and ui::TextInputType are kept in sync.
STATIC_ASSERT_ENUM(ui::TEXT_INPUT_TYPE_NONE, PP_TEXTINPUT_TYPE_NONE);
@@ -438,8 +440,7 @@ PepperPluginInstanceImpl::ExternalDocumentLoader::~ExternalDocumentLoader() {}
void PepperPluginInstanceImpl::ExternalDocumentLoader::ReplayReceivedData(
WebAssociatedURLLoaderClient* document_loader) {
- for (std::list<std::string>::iterator it = data_.begin(); it != data_.end();
- ++it) {
+ for (auto it = data_.begin(); it != data_.end(); ++it) {
document_loader->DidReceiveData(it->c_str(), it->length());
}
if (finished_loading_) {
@@ -591,8 +592,7 @@ PepperPluginInstanceImpl::~PepperPluginInstanceImpl() {
// unregister themselves inside the delete call).
PluginObjectSet plugin_object_copy;
live_plugin_objects_.swap(plugin_object_copy);
- for (PluginObjectSet::iterator i = plugin_object_copy.begin();
- i != plugin_object_copy.end();
+ for (auto i = plugin_object_copy.begin(); i != plugin_object_copy.end();
++i) {
(*i)->InstanceDeleted();
}
@@ -1020,10 +1020,9 @@ bool PepperPluginInstanceImpl::
for (size_t i = 0; i < ime_text_spans.size(); ++i) {
if (ime_text_spans[i].thickness ==
ws::mojom::ImeTextSpanThickness::kThick) {
- std::vector<uint32_t>::iterator it =
- std::find(event.composition_segment_offsets.begin(),
- event.composition_segment_offsets.end(),
- utf8_offsets[2 * i + 2]);
+ auto it = std::find(event.composition_segment_offsets.begin(),
+ event.composition_segment_offsets.end(),
+ utf8_offsets[2 * i + 2]);
if (it != event.composition_segment_offsets.end()) {
event.composition_target_segment =
it - event.composition_segment_offsets.begin();
@@ -2370,9 +2369,7 @@ void PepperPluginInstanceImpl::SimulateInputEvent(
CreateSimulatedWebInputEvents(
input_event, view_data_.rect.point.x + view_data_.rect.size.width / 2,
view_data_.rect.point.y + view_data_.rect.size.height / 2);
- for (std::vector<std::unique_ptr<WebInputEvent>>::iterator it =
- events.begin();
- it != events.end(); ++it) {
+ for (auto it = events.begin(); it != events.end(); ++it) {
widget->HandleInputEvent(blink::WebCoalescedInputEvent(*it->get()));
}
if (input_event.event_type == PP_INPUTEVENT_TYPE_TOUCHSTART ||
@@ -3103,7 +3100,7 @@ PP_Resource PepperPluginInstanceImpl::CreateImage(gfx::ImageSkia* source_image,
SkCanvas* canvas = image_data->GetCanvas();
// Note: Do not SkBitmap::copyTo the canvas bitmap directly because it will
// ignore the allocated pixels in shared memory and re-allocate a new buffer.
- canvas->writePixels(image_skia_rep.sk_bitmap(), 0, 0);
+ canvas->writePixels(image_skia_rep.GetBitmap(), 0, 0);
return image_data->GetReference();
}
diff --git a/chromium/content/renderer/pepper/pepper_plugin_registry.cc b/chromium/content/renderer/pepper/pepper_plugin_registry.cc
index 73ddbac0b5b..0f875975979 100644
--- a/chromium/content/renderer/pepper/pepper_plugin_registry.cc
+++ b/chromium/content/renderer/pepper/pepper_plugin_registry.cc
@@ -48,8 +48,7 @@ const PepperPluginInfo* PepperPluginRegistry::GetInfoForPlugin(
PluginModule* PepperPluginRegistry::GetLiveModule(
const base::FilePath& path,
const base::Optional<url::Origin>& origin_lock) {
- NonOwningModuleMap::iterator module_iter =
- live_modules_.find({path, origin_lock});
+ auto module_iter = live_modules_.find({path, origin_lock});
if (module_iter == live_modules_.end())
return nullptr;
@@ -64,8 +63,7 @@ PluginModule* PepperPluginRegistry::GetLiveModule(
if (instance_set.empty())
return module_iter->second;
- PluginModule::PluginInstanceSet::const_iterator instance_iter =
- instance_set.begin();
+ auto instance_iter = instance_set.begin();
while (instance_iter != instance_set.end()) {
if (!(*instance_iter)->is_deleted())
return module_iter->second;
@@ -88,9 +86,7 @@ void PepperPluginRegistry::PluginModuleDead(PluginModule* dead_module) {
// Modules aren't destroyed very often and there are normally at most a
// couple of them. So for now we just do a brute-force search.
- for (NonOwningModuleMap::iterator i = live_modules_.begin();
- i != live_modules_.end();
- ++i) {
+ for (auto i = live_modules_.begin(); i != live_modules_.end(); ++i) {
if (i->second == dead_module) {
live_modules_.erase(i);
return;
diff --git a/chromium/content/renderer/pepper/pepper_url_loader_host.cc b/chromium/content/renderer/pepper/pepper_url_loader_host.cc
index b4a262c9203..43807f48531 100644
--- a/chromium/content/renderer/pepper/pepper_url_loader_host.cc
+++ b/chromium/content/renderer/pepper/pepper_url_loader_host.cc
@@ -252,7 +252,7 @@ int32_t PepperURLLoaderHost::InternalOnHostMsgOpen(
return PP_ERROR_FAILED;
}
- web_request.SetRequestContext(WebURLRequest::kRequestContextPlugin);
+ web_request.SetRequestContext(blink::mojom::RequestContextType::PLUGIN);
web_request.SetPluginChildID(renderer_ppapi_host_->GetPluginChildId());
// Requests from plug-ins must skip service workers, see the comment in
diff --git a/chromium/content/renderer/pepper/pepper_video_decoder_host.cc b/chromium/content/renderer/pepper/pepper_video_decoder_host.cc
index 5201b8dc049..ae99e9285fd 100644
--- a/chromium/content/renderer/pepper/pepper_video_decoder_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_decoder_host.cc
@@ -319,7 +319,7 @@ int32_t PepperVideoDecoderHost::OnHostMsgRecyclePicture(
return PP_ERROR_FAILED;
DCHECK(decoder_);
- PictureBufferMap::iterator it = picture_buffer_map_.find(texture_id);
+ auto it = picture_buffer_map_.find(texture_id);
if (it == picture_buffer_map_.end())
return PP_ERROR_BADARGUMENT;
@@ -388,8 +388,7 @@ void PepperVideoDecoderHost::ProvidePictureBuffers(
}
void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) {
- PictureBufferMap::iterator it =
- picture_buffer_map_.find(picture.picture_buffer_id());
+ auto it = picture_buffer_map_.find(picture.picture_buffer_id());
DCHECK(it != picture_buffer_map_.end());
DCHECK(it->second == PictureBufferState::ASSIGNED);
it->second = PictureBufferState::IN_USE;
@@ -404,7 +403,7 @@ void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) {
}
void PepperVideoDecoderHost::DismissPictureBuffer(int32_t picture_buffer_id) {
- PictureBufferMap::iterator it = picture_buffer_map_.find(picture_buffer_id);
+ auto it = picture_buffer_map_.find(picture_buffer_id);
DCHECK(it != picture_buffer_map_.end());
// If the texture is still used by the plugin keep it until the plugin
@@ -423,7 +422,7 @@ void PepperVideoDecoderHost::DismissPictureBuffer(int32_t picture_buffer_id) {
void PepperVideoDecoderHost::NotifyEndOfBitstreamBuffer(
int32_t bitstream_buffer_id) {
- PendingDecodeList::iterator it = GetPendingDecodeById(bitstream_buffer_id);
+ auto it = GetPendingDecodeById(bitstream_buffer_id);
if (it == pending_decodes_.end()) {
NOTREACHED();
return;
diff --git a/chromium/content/renderer/pepper/pepper_video_destination_host.cc b/chromium/content/renderer/pepper/pepper_video_destination_host.cc
deleted file mode 100644
index aa3567d20c6..00000000000
--- a/chromium/content/renderer/pepper/pepper_video_destination_host.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 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 "content/renderer/pepper/pepper_video_destination_host.h"
-
-#include "base/time/time.h"
-#include "content/public/renderer/renderer_ppapi_host.h"
-#include "content/renderer/pepper/ppb_image_data_impl.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/host/dispatch_host_message.h"
-#include "ppapi/host/host_message_context.h"
-#include "ppapi/host/ppapi_host.h"
-#include "ppapi/proxy/ppapi_messages.h"
-#include "ppapi/thunk/enter.h"
-#include "ppapi/thunk/ppb_image_data_api.h"
-
-using ppapi::host::HostMessageContext;
-using ppapi::host::ReplyMessageContext;
-
-namespace content {
-
-PepperVideoDestinationHost::PepperVideoDestinationHost(RendererPpapiHost* host,
- PP_Instance instance,
- PP_Resource resource)
- : ResourceHost(host->GetPpapiHost(), instance, resource),
-#if DCHECK_IS_ON()
- has_received_frame_(false),
-#endif
- weak_factory_(this) {}
-
-PepperVideoDestinationHost::~PepperVideoDestinationHost() {}
-
-int32_t PepperVideoDestinationHost::OnResourceMessageReceived(
- const IPC::Message& msg,
- HostMessageContext* context) {
- PPAPI_BEGIN_MESSAGE_MAP(PepperVideoDestinationHost, msg)
- PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDestination_Open,
- OnHostMsgOpen)
- PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDestination_PutFrame,
- OnHostMsgPutFrame)
- PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoDestination_Close,
- OnHostMsgClose)
- PPAPI_END_MESSAGE_MAP()
- return PP_ERROR_FAILED;
-}
-
-int32_t PepperVideoDestinationHost::OnHostMsgOpen(
- HostMessageContext* context,
- const std::string& stream_url) {
- GURL gurl(stream_url);
- if (!gurl.is_valid())
- return PP_ERROR_BADARGUMENT;
-
- FrameWriterInterface* frame_writer = nullptr;
- if (!PepperToVideoTrackAdapter::Open(nullptr /* registry */, gurl.spec(),
- &frame_writer))
- return PP_ERROR_FAILED;
- frame_writer_.reset(frame_writer);
-
- ReplyMessageContext reply_context = context->MakeReplyMessageContext();
- reply_context.params.set_result(PP_OK);
- host()->SendReply(reply_context, PpapiPluginMsg_VideoDestination_OpenReply());
- return PP_OK_COMPLETIONPENDING;
-}
-
-int32_t PepperVideoDestinationHost::OnHostMsgPutFrame(
- HostMessageContext* context,
- const ppapi::HostResource& image_data_resource,
- PP_TimeTicks timestamp) {
- ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API> enter(
- image_data_resource.host_resource(), true);
- if (enter.failed())
- return PP_ERROR_BADRESOURCE;
- PPB_ImageData_Impl* image_data_impl =
- static_cast<PPB_ImageData_Impl*>(enter.object());
-
- if (!PPB_ImageData_Impl::IsImageDataFormatSupported(
- image_data_impl->format()))
- return PP_ERROR_BADARGUMENT;
-
- if (!frame_writer_.get())
- return PP_ERROR_FAILED;
-
- // Convert PP_TimeTicks (a double, in seconds) to a video timestamp (int64_t,
- // nanoseconds).
- const int64_t timestamp_ns =
- static_cast<int64_t>(timestamp * base::Time::kNanosecondsPerSecond);
- // Check that timestamps are strictly increasing.
-#if DCHECK_IS_ON()
- if (has_received_frame_)
- DCHECK_GT(timestamp_ns, previous_timestamp_ns_);
- has_received_frame_ = true;
- previous_timestamp_ns_ = timestamp_ns;
-#endif
-
- frame_writer_->PutFrame(image_data_impl, timestamp_ns);
-
- return PP_OK;
-}
-
-int32_t PepperVideoDestinationHost::OnHostMsgClose(
- HostMessageContext* context) {
- frame_writer_.reset(nullptr);
- return PP_OK;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_video_destination_host.h b/chromium/content/renderer/pepper/pepper_video_destination_host.h
deleted file mode 100644
index 1041952ab5c..00000000000
--- a/chromium/content/renderer/pepper/pepper_video_destination_host.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 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 CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DESTINATION_HOST_H_
-#define CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DESTINATION_HOST_H_
-
-#include <stdint.h>
-
-#include <memory>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/pepper/pepper_to_video_track_adapter.h"
-#include "ppapi/c/pp_time.h"
-#include "ppapi/host/resource_host.h"
-
-namespace content {
-
-class RendererPpapiHost;
-
-class CONTENT_EXPORT PepperVideoDestinationHost
- : public ppapi::host::ResourceHost {
- public:
- PepperVideoDestinationHost(RendererPpapiHost* host,
- PP_Instance instance,
- PP_Resource resource);
-
- ~PepperVideoDestinationHost() override;
-
- int32_t OnResourceMessageReceived(
- const IPC::Message& msg,
- ppapi::host::HostMessageContext* context) override;
-
- private:
- int32_t OnHostMsgOpen(ppapi::host::HostMessageContext* context,
- const std::string& stream_url);
- int32_t OnHostMsgPutFrame(ppapi::host::HostMessageContext* context,
- const ppapi::HostResource& image_data_resource,
- PP_TimeTicks timestamp);
- int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context);
-
- std::unique_ptr<FrameWriterInterface> frame_writer_;
- // Used for checking that timestamps are strictly increasing.
-#if DCHECK_IS_ON()
- bool has_received_frame_;
- int64_t previous_timestamp_ns_;
-#endif
-
- base::WeakPtrFactory<PepperVideoDestinationHost> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(PepperVideoDestinationHost);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DESTINATION_HOST_H_
diff --git a/chromium/content/renderer/pepper/pepper_video_encoder_host.cc b/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
index cf8e6333142..1cb22a60969 100644
--- a/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
@@ -11,8 +11,8 @@
#include "base/numerics/safe_math.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
-#include "content/common/gpu_stream_constants.h"
#include "content/common/pepper_file_util.h"
+#include "content/public/common/gpu_stream_constants.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "content/renderer/pepper/gfx_conversion.h"
#include "content/renderer/pepper/host_globals.h"
diff --git a/chromium/content/renderer/pepper/pepper_video_source_host.cc b/chromium/content/renderer/pepper/pepper_video_source_host.cc
deleted file mode 100644
index 48047137deb..00000000000
--- a/chromium/content/renderer/pepper/pepper_video_source_host.cc
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright (c) 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 "content/renderer/pepper/pepper_video_source_host.h"
-
-#include <string.h>
-
-#include "base/bind.h"
-#include "base/numerics/safe_conversions.h"
-#include "content/public/renderer/renderer_ppapi_host.h"
-#include "content/renderer/media/pepper/video_track_to_pepper_adapter.h"
-#include "content/renderer/pepper/ppb_image_data_impl.h"
-#include "content/renderer/render_thread_impl.h"
-#include "media/base/video_util.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/host/dispatch_host_message.h"
-#include "ppapi/host/ppapi_host.h"
-#include "ppapi/proxy/host_dispatcher.h"
-#include "ppapi/proxy/ppapi_messages.h"
-#include "ppapi/proxy/ppb_image_data_proxy.h"
-#include "ppapi/shared_impl/scoped_pp_resource.h"
-#include "ppapi/thunk/enter.h"
-#include "ppapi/thunk/ppb_image_data_api.h"
-#include "third_party/libyuv/include/libyuv/convert.h"
-#include "third_party/libyuv/include/libyuv/scale.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-using ppapi::host::HostMessageContext;
-using ppapi::host::ReplyMessageContext;
-
-namespace content {
-
-class PepperVideoSourceHost::FrameReceiver
- : public FrameReaderInterface,
- public base::RefCountedThreadSafe<FrameReceiver> {
- public:
- explicit FrameReceiver(const base::WeakPtr<PepperVideoSourceHost>& host);
-
- // FrameReaderInterface implementation.
- void GotFrame(const scoped_refptr<media::VideoFrame>& frame) override;
-
- private:
- friend class base::RefCountedThreadSafe<FrameReceiver>;
- ~FrameReceiver() override;
-
- base::WeakPtr<PepperVideoSourceHost> host_;
- // |thread_checker_| is bound to the main render thread.
- base::ThreadChecker thread_checker_;
-};
-
-PepperVideoSourceHost::FrameReceiver::FrameReceiver(
- const base::WeakPtr<PepperVideoSourceHost>& host)
- : host_(host) {}
-
-PepperVideoSourceHost::FrameReceiver::~FrameReceiver() {}
-
-void PepperVideoSourceHost::FrameReceiver::GotFrame(
- const scoped_refptr<media::VideoFrame>& video_frame) {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (!host_)
- return;
-
- if (!(video_frame->format() == media::PIXEL_FORMAT_I420 ||
- video_frame->format() == media::PIXEL_FORMAT_I420A)) {
- NOTREACHED();
- return;
- }
- scoped_refptr<media::VideoFrame> frame = video_frame;
- // Drop alpha channel since we do not support it yet.
- if (frame->format() == media::PIXEL_FORMAT_I420A)
- frame = media::WrapAsI420VideoFrame(video_frame);
-
- // Hold a reference to the new frame and release the previous.
- host_->last_frame_ = frame;
- if (host_->get_frame_pending_)
- host_->SendGetFrameReply();
-}
-
-PepperVideoSourceHost::PepperVideoSourceHost(RendererPpapiHost* host,
- PP_Instance instance,
- PP_Resource resource)
- : ResourceHost(host->GetPpapiHost(), instance, resource),
- frame_source_(new VideoTrackToPepperAdapter(nullptr)),
- get_frame_pending_(false),
- weak_factory_(this) {
- frame_receiver_ = new FrameReceiver(weak_factory_.GetWeakPtr());
- memset(&shared_image_desc_, 0, sizeof(shared_image_desc_));
-}
-
-PepperVideoSourceHost::~PepperVideoSourceHost() { Close(); }
-
-int32_t PepperVideoSourceHost::OnResourceMessageReceived(
- const IPC::Message& msg,
- HostMessageContext* context) {
- PPAPI_BEGIN_MESSAGE_MAP(PepperVideoSourceHost, msg)
- PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoSource_Open,
- OnHostMsgOpen)
- PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_GetFrame,
- OnHostMsgGetFrame)
- PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_Close,
- OnHostMsgClose)
- PPAPI_END_MESSAGE_MAP()
- return PP_ERROR_FAILED;
-}
-
-int32_t PepperVideoSourceHost::OnHostMsgOpen(HostMessageContext* context,
- const std::string& stream_url) {
- GURL gurl(stream_url);
- if (!gurl.is_valid())
- return PP_ERROR_BADARGUMENT;
-
- if (!frame_source_->Open(gurl.spec(), frame_receiver_.get()))
- return PP_ERROR_BADARGUMENT;
-
- stream_url_ = gurl.spec();
-
- ReplyMessageContext reply_context = context->MakeReplyMessageContext();
- reply_context.params.set_result(PP_OK);
- host()->SendReply(reply_context, PpapiPluginMsg_VideoSource_OpenReply());
- return PP_OK_COMPLETIONPENDING;
-}
-
-int32_t PepperVideoSourceHost::OnHostMsgGetFrame(HostMessageContext* context) {
- if (!frame_source_.get())
- return PP_ERROR_FAILED;
- if (get_frame_pending_)
- return PP_ERROR_INPROGRESS;
-
- reply_context_ = context->MakeReplyMessageContext();
- get_frame_pending_ = true;
-
- // If a frame is ready, try to convert it and send the reply.
- if (last_frame_.get())
- SendGetFrameReply();
-
- return PP_OK_COMPLETIONPENDING;
-}
-
-int32_t PepperVideoSourceHost::OnHostMsgClose(HostMessageContext* context) {
- Close();
- return PP_OK;
-}
-
-void PepperVideoSourceHost::SendGetFrameReply() {
- DCHECK(get_frame_pending_);
- get_frame_pending_ = false;
-
- DCHECK(last_frame_.get());
- const gfx::Size dst_size = last_frame_->natural_size();
-
- // Note: We try to reuse the shared memory for the previous frame here. This
- // means that the previous frame may be overwritten and is no longer valid
- // after calling this function again.
- base::SharedMemoryHandle image_handle;
- uint32_t byte_count;
- if (shared_image_.get() && dst_size.width() == shared_image_->width() &&
- dst_size.height() == shared_image_->height()) {
- // We have already allocated the correct size in shared memory. We need to
- // duplicate the handle for IPC however, which will close down the
- // duplicated handle when it's done.
- base::SharedMemory* local_shm;
- if (shared_image_->GetSharedMemory(&local_shm, &byte_count) != PP_OK) {
- SendGetFrameErrorReply(PP_ERROR_FAILED);
- return;
- }
-
- ppapi::proxy::HostDispatcher* dispatcher =
- ppapi::proxy::HostDispatcher::GetForInstance(pp_instance());
- if (!dispatcher) {
- SendGetFrameErrorReply(PP_ERROR_FAILED);
- return;
- }
-
- image_handle =
- dispatcher->ShareSharedMemoryHandleWithRemote(local_shm->handle());
- } else {
- // We need to allocate new shared memory.
- shared_image_ = nullptr; // Release any previous image.
-
- ppapi::ScopedPPResource resource(
- ppapi::ScopedPPResource::PassRef(),
- ppapi::proxy::PPB_ImageData_Proxy::CreateImageData(
- pp_instance(),
- ppapi::PPB_ImageData_Shared::SIMPLE,
- PP_IMAGEDATAFORMAT_BGRA_PREMUL,
- PP_MakeSize(dst_size.width(), dst_size.height()),
- false /* init_to_zero */,
- &shared_image_desc_,
- &image_handle,
- &byte_count));
- if (!resource) {
- SendGetFrameErrorReply(PP_ERROR_FAILED);
- return;
- }
-
- ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API>
- enter_resource(resource, false);
- if (enter_resource.failed()) {
- SendGetFrameErrorReply(PP_ERROR_FAILED);
- return;
- }
-
- shared_image_ = static_cast<PPB_ImageData_Impl*>(enter_resource.object());
- if (!shared_image_.get()) {
- SendGetFrameErrorReply(PP_ERROR_FAILED);
- return;
- }
-
- DCHECK(!shared_image_->IsMapped()); // New memory should not be mapped.
- if (!shared_image_->Map() || shared_image_->GetMappedBitmap().empty()) {
- shared_image_ = nullptr;
- SendGetFrameErrorReply(PP_ERROR_FAILED);
- return;
- }
- }
-
- SkBitmap bitmap(shared_image_->GetMappedBitmap());
- if (bitmap.empty()) {
- SendGetFrameErrorReply(PP_ERROR_FAILED);
- return;
- }
-
- uint8_t* bitmap_pixels = static_cast<uint8_t*>(bitmap.getPixels());
- if (!bitmap_pixels) {
- SendGetFrameErrorReply(PP_ERROR_FAILED);
- return;
- }
-
- // Calculate the portion of the |last_frame_| that should be copied into
- // |bitmap|. If |last_frame_| is lazily scaled, then
- // last_frame_->visible_rect()._size() != last_frame_.natural_size().
- scoped_refptr<media::VideoFrame> frame;
- if (dst_size == last_frame_->visible_rect().size()) {
- // No scaling is needed, convert directly from last_frame_.
- frame = last_frame_;
- // Frame resolution doesn't change frequently, so don't keep any unnecessary
- // buffers around.
- scaled_frame_ = nullptr;
- } else {
- // We need to create an intermediate scaled frame. Make sure we have
- // allocated one of correct size.
- if (!scaled_frame_.get() || scaled_frame_->coded_size() != dst_size) {
- scaled_frame_ = media::VideoFrame::CreateFrame(
- media::PIXEL_FORMAT_I420, dst_size, gfx::Rect(dst_size), dst_size,
- last_frame_->timestamp());
- if (!scaled_frame_.get()) {
- LOG(ERROR) << "Failed to allocate a media::VideoFrame";
- SendGetFrameErrorReply(PP_ERROR_FAILED);
- return;
- }
- }
- scaled_frame_->set_timestamp(last_frame_->timestamp());
- libyuv::I420Scale(last_frame_->visible_data(media::VideoFrame::kYPlane),
- last_frame_->stride(media::VideoFrame::kYPlane),
- last_frame_->visible_data(media::VideoFrame::kUPlane),
- last_frame_->stride(media::VideoFrame::kUPlane),
- last_frame_->visible_data(media::VideoFrame::kVPlane),
- last_frame_->stride(media::VideoFrame::kVPlane),
- last_frame_->visible_rect().width(),
- last_frame_->visible_rect().height(),
- scaled_frame_->data(media::VideoFrame::kYPlane),
- scaled_frame_->stride(media::VideoFrame::kYPlane),
- scaled_frame_->data(media::VideoFrame::kUPlane),
- scaled_frame_->stride(media::VideoFrame::kUPlane),
- scaled_frame_->data(media::VideoFrame::kVPlane),
- scaled_frame_->stride(media::VideoFrame::kVPlane),
- dst_size.width(),
- dst_size.height(),
- libyuv::kFilterBilinear);
- frame = scaled_frame_;
- }
- last_frame_ = nullptr;
-
- libyuv::I420ToARGB(frame->visible_data(media::VideoFrame::kYPlane),
- frame->stride(media::VideoFrame::kYPlane),
- frame->visible_data(media::VideoFrame::kUPlane),
- frame->stride(media::VideoFrame::kUPlane),
- frame->visible_data(media::VideoFrame::kVPlane),
- frame->stride(media::VideoFrame::kVPlane),
- bitmap_pixels,
- bitmap.rowBytes(),
- dst_size.width(),
- dst_size.height());
-
- ppapi::HostResource host_resource;
- host_resource.SetHostResource(pp_instance(), shared_image_->GetReference());
-
- // Convert a video timestamp to a PP_TimeTicks (a double, in seconds).
- const PP_TimeTicks timestamp = frame->timestamp().InSecondsF();
-
- ppapi::proxy::SerializedHandle serialized_handle;
- serialized_handle.set_shmem(image_handle, byte_count);
- reply_context_.params.AppendHandle(std::move(serialized_handle));
-
- host()->SendReply(reply_context_,
- PpapiPluginMsg_VideoSource_GetFrameReply(
- host_resource, shared_image_desc_, timestamp));
-
- reply_context_ = ppapi::host::ReplyMessageContext();
-}
-
-void PepperVideoSourceHost::SendGetFrameErrorReply(int32_t error) {
- reply_context_.params.set_result(error);
- host()->SendReply(
- reply_context_,
- PpapiPluginMsg_VideoSource_GetFrameReply(
- ppapi::HostResource(), PP_ImageDataDesc(), 0.0 /* timestamp */));
- reply_context_ = ppapi::host::ReplyMessageContext();
-}
-
-void PepperVideoSourceHost::Close() {
- if (frame_source_.get() && !stream_url_.empty())
- frame_source_->Close(frame_receiver_.get());
-
- frame_source_.reset(nullptr);
- stream_url_.clear();
-
- shared_image_ = nullptr;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_video_source_host.h b/chromium/content/renderer/pepper/pepper_video_source_host.h
deleted file mode 100644
index 811a4616876..00000000000
--- a/chromium/content/renderer/pepper/pepper_video_source_host.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 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 CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_SOURCE_HOST_H_
-#define CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_SOURCE_HOST_H_
-
-#include <stdint.h>
-
-#include <memory>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "content/common/content_export.h"
-#include "ppapi/c/pp_time.h"
-#include "ppapi/c/ppb_image_data.h"
-#include "ppapi/host/host_message_context.h"
-#include "ppapi/host/resource_host.h"
-
-struct PP_ImageDataDesc;
-
-namespace media {
-class VideoFrame;
-} // namespace media
-
-namespace content {
-
-class PPB_ImageData_Impl;
-class RendererPpapiHost;
-class VideoTrackToPepperAdapter;
-
-class CONTENT_EXPORT PepperVideoSourceHost : public ppapi::host::ResourceHost {
- public:
- PepperVideoSourceHost(RendererPpapiHost* host,
- PP_Instance instance,
- PP_Resource resource);
-
- ~PepperVideoSourceHost() override;
-
- int32_t OnResourceMessageReceived(
- const IPC::Message& msg,
- ppapi::host::HostMessageContext* context) override;
-
- private:
- // Helper object to receive frames on a video worker thread and pass them on
- // to us.
- class FrameReceiver;
-
- int32_t OnHostMsgOpen(ppapi::host::HostMessageContext* context,
- const std::string& stream_url);
- int32_t OnHostMsgGetFrame(ppapi::host::HostMessageContext* context);
- int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context);
-
- // Sends the reply to a GetFrame message from the plugin. A reply is always
- // sent and last_frame_, reply_context_, and get_frame_pending_ are all reset.
- void SendGetFrameReply();
- // Sends the reply to a GetFrame message from the plugin in case of an error.
- void SendGetFrameErrorReply(int32_t error);
-
- void Close();
-
- ppapi::host::ReplyMessageContext reply_context_;
-
- std::unique_ptr<VideoTrackToPepperAdapter> frame_source_;
- scoped_refptr<FrameReceiver> frame_receiver_;
- std::string stream_url_;
- scoped_refptr<media::VideoFrame> last_frame_;
- // An internal frame buffer to avoid reallocations. It is only allocated if
- // scaling is needed.
- scoped_refptr<media::VideoFrame> scaled_frame_;
- bool get_frame_pending_;
- // We use only one ImageData resource in order to avoid allocating
- // shared memory repeatedly. We send the same one each time the plugin
- // requests a frame. For this to work, the plugin must finish using
- // the ImageData it receives prior to calling GetFrame, and not access
- // the ImageData until it gets its next callback to GetFrame.
- scoped_refptr<PPB_ImageData_Impl> shared_image_;
- PP_ImageDataDesc shared_image_desc_;
-
- base::WeakPtrFactory<PepperVideoSourceHost> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(PepperVideoSourceHost);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_SOURCE_HOST_H_
diff --git a/chromium/content/renderer/pepper/pepper_webplugin_impl.cc b/chromium/content/renderer/pepper/pepper_webplugin_impl.cc
index ed9dd9bcee9..183c17f4aba 100644
--- a/chromium/content/renderer/pepper/pepper_webplugin_impl.cc
+++ b/chromium/content/renderer/pepper/pepper_webplugin_impl.cc
@@ -238,7 +238,7 @@ void PepperWebPluginImpl::DidReceiveResponse(
instance_->HandleDocumentLoad(response);
}
-void PepperWebPluginImpl::DidReceiveData(const char* data, int data_length) {
+void PepperWebPluginImpl::DidReceiveData(const char* data, size_t data_length) {
// Re-entrancy may cause JS to try to execute script on the plugin before it
// is fully initialized. See: crbug.com/715747.
if (!instance_)
diff --git a/chromium/content/renderer/pepper/pepper_webplugin_impl.h b/chromium/content/renderer/pepper/pepper_webplugin_impl.h
index fb0a58b0d9e..0b192933256 100644
--- a/chromium/content/renderer/pepper/pepper_webplugin_impl.h
+++ b/chromium/content/renderer/pepper/pepper_webplugin_impl.h
@@ -55,7 +55,7 @@ class PepperWebPluginImpl : public blink::WebPlugin {
const blink::WebCoalescedInputEvent& event,
blink::WebCursorInfo& cursor_info) override;
void DidReceiveResponse(const blink::WebURLResponse& response) override;
- void DidReceiveData(const char* data, int data_length) override;
+ void DidReceiveData(const char* data, size_t data_length) override;
void DidFinishLoading() override;
void DidFailLoading(const blink::WebURLError&) override;
bool HasSelection() const override;
diff --git a/chromium/content/renderer/pepper/pepper_websocket_host.cc b/chromium/content/renderer/pepper/pepper_websocket_host.cc
index 0a8e50abe68..0a6e752cdfc 100644
--- a/chromium/content/renderer/pepper/pepper_websocket_host.cc
+++ b/chromium/content/renderer/pepper/pepper_websocket_host.cc
@@ -216,10 +216,8 @@ int32_t PepperWebSocketHost::OnHostMsgConnect(
// Validate protocols.
std::string protocol_string;
- for (std::vector<std::string>::const_iterator vector_it = protocols.begin();
- vector_it != protocols.end();
+ for (auto vector_it = protocols.begin(); vector_it != protocols.end();
++vector_it) {
-
// Check containing characters.
for (std::string::const_iterator string_it = vector_it->begin();
string_it != vector_it->end();
diff --git a/chromium/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc b/chromium/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc
index 1165db9b75e..65dea551fda 100644
--- a/chromium/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc
+++ b/chromium/content/renderer/pepper/plugin_instance_throttler_impl_unittest.cc
@@ -9,7 +9,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_frame.h"
#include "skia/ext/platform_canvas.h"
@@ -83,7 +83,7 @@ class PluginInstanceThrottlerImplTest
int change_callback_calls_;
- base::MessageLoop loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
};
TEST_F(PluginInstanceThrottlerImplTest, ThrottleAndUnthrottleByClick) {
diff --git a/chromium/content/renderer/pepper/plugin_module.cc b/chromium/content/renderer/pepper/plugin_module.cc
index 7f3d594f71b..1cf83074a8d 100644
--- a/chromium/content/renderer/pepper/plugin_module.cc
+++ b/chromium/content/renderer/pepper/plugin_module.cc
@@ -15,6 +15,7 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/no_destructor.h"
#include "base/run_loop.h"
#include "base/time/time.h"
#include "build/build_config.h"
@@ -127,8 +128,6 @@
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/c/private/ppb_udp_socket_private.h"
#include "ppapi/c/private/ppb_uma_private.h"
-#include "ppapi/c/private/ppb_video_destination_private.h"
-#include "ppapi/c/private/ppb_video_source_private.h"
#include "ppapi/c/private/ppb_x509_certificate_private.h"
#include "ppapi/c/trusted/ppb_broker_trusted.h"
#include "ppapi/c/trusted/ppb_browser_font_trusted.h"
@@ -175,8 +174,8 @@ HostGlobals* host_globals = nullptr;
typedef std::set<PluginModule*> PluginModuleSet;
PluginModuleSet* GetLivePluginSet() {
- CR_DEFINE_STATIC_LOCAL(PluginModuleSet, live_plugin_libs, ());
- return &live_plugin_libs;
+ static base::NoDestructor<PluginModuleSet> live_plugin_libs;
+ return live_plugin_libs.get();
}
class PowerSaverTestPluginDelegate : public PluginInstanceThrottler::Observer {
@@ -681,9 +680,7 @@ void PluginModule::PluginCrashed() {
is_crashed_ = true;
// Notify all instances that they crashed.
- for (PluginInstanceSet::iterator i = instances_.begin();
- i != instances_.end();
- ++i)
+ for (auto i = instances_.begin(); i != instances_.end(); ++i)
(*i)->InstanceCrashed();
PepperPluginRegistry::GetInstance()->PluginModuleDead(this);
diff --git a/chromium/content/renderer/pepper/plugin_object.cc b/chromium/content/renderer/pepper/plugin_object.cc
index 98d8a2257e0..71e4a9bb976 100644
--- a/chromium/content/renderer/pepper/plugin_object.cc
+++ b/chromium/content/renderer/pepper/plugin_object.cc
@@ -239,9 +239,12 @@ v8::Local<v8::Value> PluginObject::GetPropertyOrMethod(v8::Isolate* isolate,
return v8::Local<v8::Value>();
if (has_method) {
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
const std::string& identifier =
StringVar::FromPPVar(identifier_var)->value();
- return GetFunctionTemplate(isolate, identifier)->GetFunction();
+ return GetFunctionTemplate(isolate, identifier)
+ ->GetFunction(context)
+ .ToLocalChecked();
}
return v8::Local<v8::Value>();
diff --git a/chromium/content/renderer/pepper/plugin_power_saver_helper.cc b/chromium/content/renderer/pepper/plugin_power_saver_helper.cc
index b16d1e11e3e..7b5c4db65f4 100644
--- a/chromium/content/renderer/pepper/plugin_power_saver_helper.cc
+++ b/chromium/content/renderer/pepper/plugin_power_saver_helper.cc
@@ -48,8 +48,8 @@ PluginPowerSaverHelper::~PluginPowerSaverHelper() {
}
void PluginPowerSaverHelper::DidCommitProvisionalLoad(
- bool is_new_navigation,
- bool is_same_document_navigation) {
+ bool is_same_document_navigation,
+ ui::PageTransition transition) {
blink::WebFrame* frame = render_frame()->GetWebFrame();
// Only apply to top-level and new page navigation.
if (frame->Parent() || is_same_document_navigation)
diff --git a/chromium/content/renderer/pepper/plugin_power_saver_helper.h b/chromium/content/renderer/pepper/plugin_power_saver_helper.h
index b89e911c4f1..e178201b826 100644
--- a/chromium/content/renderer/pepper/plugin_power_saver_helper.h
+++ b/chromium/content/renderer/pepper/plugin_power_saver_helper.h
@@ -50,8 +50,8 @@ class CONTENT_EXPORT PluginPowerSaverHelper : public RenderFrameObserver {
void WhitelistContentOrigin(const url::Origin& content_origin);
// RenderFrameObserver implementation.
- void DidCommitProvisionalLoad(bool is_new_navigation,
- bool is_same_document_navigation) override;
+ void DidCommitProvisionalLoad(bool is_same_document_navigation,
+ ui::PageTransition transition) override;
bool OnMessageReceived(const IPC::Message& message) override;
void OnDestruct() override;
diff --git a/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc b/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc
index 7b44d06a87c..3496efeda9e 100644
--- a/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc
+++ b/chromium/content/renderer/pepper/plugin_power_saver_helper_browsertest.cc
@@ -7,7 +7,6 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "content/common/frame_messages.h"
-#include "content/common/view_message_enums.h"
#include "content/public/common/content_constants.h"
#include "content/public/test/frame_load_waiter.h"
#include "content/public/test/render_view_test.h"
diff --git a/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc b/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc
index ec02280deb6..45c2f3b674d 100644
--- a/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc
@@ -16,7 +16,7 @@ namespace content {
class PPB_Flash_MessageLoop_Impl::State
: public base::RefCounted<PPB_Flash_MessageLoop_Impl::State> {
public:
- State() : result_(PP_OK), run_called_(false), quit_called_(false) {}
+ explicit State() : result_(PP_OK), run_called_(false) {}
int32_t result() const { return result_; }
void set_result(int32_t result) { result_ = result; }
@@ -24,8 +24,10 @@ class PPB_Flash_MessageLoop_Impl::State
bool run_called() const { return run_called_; }
void set_run_called() { run_called_ = true; }
- bool quit_called() const { return quit_called_; }
- void set_quit_called() { quit_called_ = true; }
+ void set_quit_closure(base::OnceClosure quit_closure) {
+ quit_closure_ = std::move(quit_closure);
+ }
+ base::OnceClosure& quit_closure() { return quit_closure_; }
const RunFromHostProxyCallback& run_callback() const { return run_callback_; }
void set_run_callback(const RunFromHostProxyCallback& run_callback) {
@@ -38,7 +40,7 @@ class PPB_Flash_MessageLoop_Impl::State
int32_t result_;
bool run_called_;
- bool quit_called_;
+ base::OnceClosure quit_closure_;
RunFromHostProxyCallback run_callback_;
};
@@ -82,13 +84,16 @@ int32_t PPB_Flash_MessageLoop_Impl::InternalRun(
state_->set_run_called();
state_->set_run_callback(callback);
+ base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
+ state_->set_quit_closure(run_loop.QuitClosure());
+
// It is possible that the PPB_Flash_MessageLoop_Impl object has been
// destroyed when the nested run loop exits.
scoped_refptr<State> state_protector(state_);
{
blink::WebView::WillEnterModalLoop();
- base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).Run();
+ run_loop.Run();
blink::WebView::DidExitModalLoop();
}
@@ -98,12 +103,11 @@ int32_t PPB_Flash_MessageLoop_Impl::InternalRun(
}
void PPB_Flash_MessageLoop_Impl::InternalQuit(int32_t result) {
- if (!state_->run_called() || state_->quit_called())
+ if (!state_->run_called() || state_->quit_closure().is_null())
return;
- state_->set_quit_called();
state_->set_result(result);
- base::RunLoop::QuitCurrentDeprecated();
+ std::move(state_->quit_closure()).Run();
if (!state_->run_callback().is_null())
state_->run_callback().Run(result);
diff --git a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
index 4e2717ba4b3..6043089b539 100644
--- a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -12,9 +12,9 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/common/gpu_stream_constants.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_stream_constants.h"
#include "content/public/common/web_preferences.h"
#include "content/renderer/pepper/host_globals.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
diff --git a/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc b/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc
index e08f0a87445..9434262d0c6 100644
--- a/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc
@@ -98,9 +98,16 @@ bool HasPropertyDeprecated(PP_Var var, PP_Var name, PP_Var* exception) {
if (try_catch.HasException())
return false;
- bool result = accessor.GetObject()->Has(v8_name);
+ v8::Local<v8::Context> context = try_catch.GetContext();
if (try_catch.HasException())
return false;
+
+ bool result = false;
+ if (!accessor.GetObject()->Has(context, v8_name).To(&result)) {
+ try_catch.HasException();
+ return false;
+ }
+
return result;
}
@@ -115,8 +122,17 @@ bool HasMethodDeprecated(PP_Var var, PP_Var name, PP_Var* exception) {
if (try_catch.HasException())
return false;
- bool result = accessor.GetObject()->Has(v8_name) &&
- accessor.GetObject()->Get(v8_name)->IsFunction();
+ v8::Local<v8::Context> context = try_catch.GetContext();
+ if (try_catch.HasException())
+ return false;
+
+ bool has_name = false;
+ if (!accessor.GetObject()->Has(context, v8_name).To(&has_name)) {
+ try_catch.HasException();
+ return false;
+ }
+
+ bool result = has_name && accessor.GetObject()->Get(v8_name)->IsFunction();
if (try_catch.HasException())
return false;
return result;
@@ -203,8 +219,16 @@ void DeletePropertyDeprecated(PP_Var var, PP_Var name, PP_Var* exception) {
if (try_catch.HasException())
return;
- accessor.GetObject()->Delete(v8_name);
- try_catch.HasException(); // Ensure an exception gets set if one occured.
+ v8::Local<v8::Context> context = try_catch.GetContext();
+ if (try_catch.HasException())
+ return;
+
+ if (accessor.GetObject()->Delete(context, v8_name).IsNothing()) {
+ // Ensure exception object is created if V8 has thrown.
+ try_catch.HasException();
+ return;
+ }
+ return;
}
PP_Var CallDeprecatedInternal(PP_Var var,
diff --git a/chromium/content/renderer/pepper/resource_converter.cc b/chromium/content/renderer/pepper/resource_converter.cc
index c2c6b691472..e97b9afb726 100644
--- a/chromium/content/renderer/pepper/resource_converter.cc
+++ b/chromium/content/renderer/pepper/resource_converter.cc
@@ -19,7 +19,7 @@
#include "ppapi/shared_impl/resource_var.h"
#include "ppapi/shared_impl/scoped_pp_var.h"
#include "storage/common/fileapi/file_system_util.h"
-#include "third_party/blink/public/platform/web_file_system.h"
+#include "third_party/blink/public/platform/web_file_system_type.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/web/web_dom_file_system.h"
@@ -42,16 +42,15 @@ void FlushComplete(
callback.Run(true);
}
-// Converts a blink::WebFileSystem::Type to a PP_FileSystemType.
-PP_FileSystemType WebFileSystemTypeToPPAPI(blink::WebFileSystem::Type type) {
+PP_FileSystemType WebFileSystemTypeToPPAPI(blink::WebFileSystemType type) {
switch (type) {
- case blink::WebFileSystem::kTypeTemporary:
+ case blink::WebFileSystemType::kWebFileSystemTypeTemporary:
return PP_FILESYSTEMTYPE_LOCALTEMPORARY;
- case blink::WebFileSystem::kTypePersistent:
+ case blink::WebFileSystemType::kWebFileSystemTypePersistent:
return PP_FILESYSTEMTYPE_LOCALPERSISTENT;
- case blink::WebFileSystem::kTypeIsolated:
+ case blink::WebFileSystemType::kWebFileSystemTypeIsolated:
return PP_FILESYSTEMTYPE_ISOLATED;
- case blink::WebFileSystem::kTypeExternal:
+ case blink::WebFileSystemType::kWebFileSystemTypeExternal:
return PP_FILESYSTEMTYPE_EXTERNAL;
default:
NOTREACHED();
diff --git a/chromium/content/renderer/pepper/resource_creation_impl.cc b/chromium/content/renderer/pepper/resource_creation_impl.cc
index 418806ab0db..5f0db4a60a6 100644
--- a/chromium/content/renderer/pepper/resource_creation_impl.cc
+++ b/chromium/content/renderer/pepper/resource_creation_impl.cc
@@ -331,18 +331,10 @@ PP_Resource ResourceCreationImpl::CreateVideoDecoderDev(
return PPB_VideoDecoder_Impl::Create(instance, graphics3d_id, profile);
}
-PP_Resource ResourceCreationImpl::CreateVideoDestination(PP_Instance instance) {
- return 0; // Not supported in-process.
-}
-
PP_Resource ResourceCreationImpl::CreateVideoEncoder(PP_Instance instance) {
return 0; // Not supported in-process.
}
-PP_Resource ResourceCreationImpl::CreateVideoSource(PP_Instance instance) {
- return 0; // Not supported in-process.
-}
-
PP_Resource ResourceCreationImpl::CreateVpnProvider(PP_Instance instance) {
return 0; // Not supported in-process.
}
diff --git a/chromium/content/renderer/pepper/resource_creation_impl.h b/chromium/content/renderer/pepper/resource_creation_impl.h
index d89ded28eac..13b5c04435b 100644
--- a/chromium/content/renderer/pepper/resource_creation_impl.h
+++ b/chromium/content/renderer/pepper/resource_creation_impl.h
@@ -128,9 +128,7 @@ class ResourceCreationImpl : public ppapi::thunk::ResourceCreationAPI {
PP_Resource CreateVideoDecoderDev(PP_Instance instance,
PP_Resource graphics3d_id,
PP_VideoDecoder_Profile profile) override;
- PP_Resource CreateVideoDestination(PP_Instance instance) override;
PP_Resource CreateVideoEncoder(PP_Instance instance) override;
- PP_Resource CreateVideoSource(PP_Instance instance) override;
PP_Resource CreateVpnProvider(PP_Instance instance) override;
PP_Resource CreateWheelInputEvent(PP_Instance instance,
PP_TimeTicks time_stamp,
diff --git a/chromium/content/renderer/pepper/url_request_info_util.cc b/chromium/content/renderer/pepper/url_request_info_util.cc
index 5108a428a42..e9f7dfa0c71 100644
--- a/chromium/content/renderer/pepper/url_request_info_util.cc
+++ b/chromium/content/renderer/pepper/url_request_info_util.cc
@@ -238,15 +238,13 @@ bool CreateWebURLRequest(PP_Instance instance,
WebString::FromUTF8(data->custom_content_transfer_encoding));
}
- if (data->has_custom_user_agent || !name_version.empty()) {
+ if (!name_version.empty())
+ dest->SetRequestedWith(WebString::FromUTF8(name_version));
+
+ if (data->has_custom_user_agent) {
auto extra_data = std::make_unique<RequestExtraData>();
- if (data->has_custom_user_agent) {
- extra_data->set_custom_user_agent(
- WebString::FromUTF8(data->custom_user_agent));
- }
- if (!name_version.empty()) {
- extra_data->set_requested_with(WebString::FromUTF8(name_version));
- }
+ extra_data->set_custom_user_agent(
+ WebString::FromUTF8(data->custom_user_agent));
dest->SetExtraData(std::move(extra_data));
}
diff --git a/chromium/content/renderer/pepper/v8_var_converter.cc b/chromium/content/renderer/pepper/v8_var_converter.cc
index 5c4319dca59..ca81eb01bab 100644
--- a/chromium/content/renderer/pepper/v8_var_converter.cc
+++ b/chromium/content/renderer/pepper/v8_var_converter.cc
@@ -94,7 +94,7 @@ bool GetOrCreateV8Value(v8::Local<v8::Context> context,
if (ppapi::VarTracker::IsVarTypeRefcounted(var.type)) {
if (parent_ids->count(var.value.as_id) != 0)
return false;
- VarHandleMap::iterator it = visited_ids->find(var.value.as_id);
+ auto it = visited_ids->find(var.value.as_id);
if (it != visited_ids->end()) {
*result = it->second;
return true;
@@ -130,8 +130,10 @@ bool GetOrCreateV8Value(v8::Local<v8::Context> context,
// in the sense that string primitives in JavaScript can't be referenced
// in the same way that string vars can in pepper. But that information
// isn't very useful and primitive strings are a more expected form in JS.
- *result = v8::String::NewFromUtf8(
- isolate, value.c_str(), v8::String::kNormalString, value.size());
+ *result =
+ v8::String::NewFromUtf8(isolate, value.c_str(),
+ v8::NewStringType::kNormal, value.size())
+ .ToLocalChecked();
break;
}
case PP_VARTYPE_ARRAY_BUFFER: {
@@ -399,10 +401,8 @@ bool V8VarConverter::ToV8Value(const PP_Var& var,
DCHECK(current_v8->IsObject());
v8::Local<v8::Object> v8_object = current_v8.As<v8::Object>();
- for (DictionaryVar::KeyValueMap::const_iterator iter =
- dict_var->key_value_map().begin();
- iter != dict_var->key_value_map().end();
- ++iter) {
+ for (auto iter = dict_var->key_value_map().begin();
+ iter != dict_var->key_value_map().end(); ++iter) {
const std::string& key = iter->first;
const PP_Var& child_var = iter->second.get();
v8::Local<v8::Value> child_v8;
@@ -419,10 +419,11 @@ bool V8VarConverter::ToV8Value(const PP_Var& var,
if (did_create && CanHaveChildren(child_var))
stack.push_back(child_var);
v8::TryCatch try_catch(isolate);
- v8_object->Set(
- v8::String::NewFromUtf8(
- isolate, key.c_str(), v8::String::kNormalString, key.length()),
- child_v8);
+ v8_object->Set(v8::String::NewFromUtf8(isolate, key.c_str(),
+ v8::NewStringType::kInternalized,
+ key.length())
+ .ToLocalChecked(),
+ child_v8);
if (try_catch.HasCaught()) {
LOG(ERROR) << "Setter for property " << key.c_str() << " threw an "
<< "exception.";
diff --git a/chromium/content/renderer/pepper/v8_var_converter_unittest.cc b/chromium/content/renderer/pepper/v8_var_converter_unittest.cc
index 6c4bfd95190..543fb868b01 100644
--- a/chromium/content/renderer/pepper/v8_var_converter_unittest.cc
+++ b/chromium/content/renderer/pepper/v8_var_converter_unittest.cc
@@ -12,9 +12,9 @@
#include "base/logging.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_task_environment.h"
#include "base/values.h"
#include "content/renderer/pepper/resource_converter.h"
#include "ppapi/c/pp_bool.h"
@@ -80,7 +80,7 @@ bool Equals(const PP_Var& var,
v8::Local<v8::Value> val,
VarHandleMap* visited_ids) {
if (ppapi::VarTracker::IsVarTypeRefcounted(var.type)) {
- VarHandleMap::iterator it = visited_ids->find(var.value.as_id);
+ auto it = visited_ids->find(var.value.as_id);
if (it != visited_ids->end())
return it->second == val;
(*visited_ids)[var.value.as_id] = val;
@@ -236,7 +236,8 @@ class V8VarConverterTest : public testing::Test {
std::unique_ptr<V8VarConverter> converter_;
private:
- base::MessageLoop message_loop_; // Required to receive callbacks.
+ base::test::ScopedTaskEnvironment
+ task_environment_; // Required to receive callbacks.
TestGlobals globals_;
};
diff --git a/chromium/content/renderer/pepper/video_decoder_shim.cc b/chromium/content/renderer/pepper/video_decoder_shim.cc
index ac45730b1c3..b7ea303d191 100644
--- a/chromium/content/renderer/pepper/video_decoder_shim.cc
+++ b/chromium/content/renderer/pepper/video_decoder_shim.cc
@@ -848,7 +848,7 @@ VideoDecoderShim::VideoDecoderShim(
VideoDecoderShim::~VideoDecoderShim() {
DCHECK(RenderThreadImpl::current());
// Delete any remaining textures.
- TextureIdMap::iterator it = texture_id_map_.begin();
+ auto it = texture_id_map_.begin();
for (; it != texture_id_map_.end(); ++it)
DeleteTexture(it->second);
texture_id_map_.clear();
@@ -1024,9 +1024,8 @@ void VideoDecoderShim::OnOutputComplete(std::unique_ptr<PendingFrame> frame) {
++it) {
textures_to_dismiss_.insert(it->first);
}
- for (TextureIdSet::const_iterator it = available_textures_.begin();
- it != available_textures_.end();
- ++it) {
+ for (auto it = available_textures_.begin();
+ it != available_textures_.end(); ++it) {
DismissTexture(*it);
}
available_textures_.clear();
@@ -1049,7 +1048,7 @@ void VideoDecoderShim::SendPictures() {
while (!pending_frames_.empty() && !available_textures_.empty()) {
const std::unique_ptr<PendingFrame>& frame = pending_frames_.front();
- TextureIdSet::iterator it = available_textures_.begin();
+ auto it = available_textures_.begin();
uint32_t texture_id = *it;
available_textures_.erase(it);
diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc
index 52270733e64..cf3e520475a 100644
--- a/chromium/content/renderer/render_frame_impl.cc
+++ b/chromium/content/renderer/render_frame_impl.cc
@@ -56,6 +56,7 @@
#include "content/common/frame_owner_properties.h"
#include "content/common/frame_replication_state.h"
#include "content/common/input_messages.h"
+#include "content/common/navigation_gesture.h"
#include "content/common/navigation_params.h"
#include "content/common/page_messages.h"
#include "content/common/possibly_associated_wrapper_shared_url_loader_factory.h"
@@ -73,8 +74,6 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/context_menu_params.h"
#include "content/public/common/favicon_url.h"
-#include "content/public/common/file_chooser_file_info.h"
-#include "content/public/common/file_chooser_params.h"
#include "content/public/common/isolated_world_ids.h"
#include "content/public/common/page_state.h"
#include "content/public/common/service_manager_connection.h"
@@ -85,7 +84,6 @@
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/context_menu_client.h"
#include "content/public/renderer/document_state.h"
-#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_frame_visitor.h"
#include "content/public/renderer/renderer_ppapi_host.h"
@@ -130,7 +128,7 @@
#include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
#include "content/renderer/mojo/blink_interface_registry_impl.h"
#include "content/renderer/navigation_client.h"
-#include "content/renderer/navigation_state_impl.h"
+#include "content/renderer/navigation_state.h"
#include "content/renderer/pepper/pepper_audio_controller.h"
#include "content/renderer/pepper/plugin_instance_throttler_impl.h"
#include "content/renderer/push_messaging/push_messaging_client.h"
@@ -172,10 +170,11 @@
#include "third_party/blink/public/common/frame/sandbox_flags.h"
#include "third_party/blink/public/common/frame/user_activation_update_type.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
+#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/interface_provider.h"
-#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/modules/permissions/permission.mojom.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/url_conversion.h"
@@ -310,31 +309,6 @@ using blink::WebFloatRect;
namespace content {
-// Helper struct keeping track in one place of all the parameters the browser
-// provided to the renderer to commit a navigation.
-struct PendingNavigationParams {
- PendingNavigationParams(
- const CommonNavigationParams& common_params,
- const RequestNavigationParams& request_params,
- base::TimeTicks time_commit_requested,
- content::mojom::FrameNavigationControl::CommitNavigationCallback
- commit_callback)
- : common_params(common_params),
- request_params(request_params),
- time_commit_requested(time_commit_requested),
- commit_callback_(std::move(commit_callback)) {}
- ~PendingNavigationParams() = default;
-
- CommonNavigationParams common_params;
- RequestNavigationParams request_params;
-
- // Time when RenderFrameImpl::CommitNavigation() is called.
- base::TimeTicks time_commit_requested;
-
- content::mojom::FrameNavigationControl::CommitNavigationCallback
- commit_callback_;
-};
-
namespace {
const int kExtraCharsBeforeAndAfterSelection = 100;
@@ -364,6 +338,37 @@ int64_t ExtractPostId(const WebHistoryItem& item) {
return item.HttpBody().Identifier();
}
+ui::PageTransition GetTransitionType(blink::WebDocumentLoader* document_loader,
+ blink::WebLocalFrame* frame,
+ bool loading) {
+ NavigationState* navigation_state =
+ NavigationState::FromDocumentLoader(document_loader);
+ ui::PageTransition default_transition =
+ navigation_state->IsContentInitiated()
+ ? ui::PAGE_TRANSITION_LINK
+ : navigation_state->common_params().transition;
+ if (navigation_state->WasWithinSameDocument())
+ return default_transition;
+ if (loading || document_loader->GetResponse().IsNull()) {
+ if (document_loader->ReplacesCurrentHistoryItem() && frame->Parent()) {
+ // Subframe navigations that don't add session history items must be
+ // marked with AUTO_SUBFRAME. See also didFailProvisionalLoad for how we
+ // handle loading of error pages.
+ return ui::PAGE_TRANSITION_AUTO_SUBFRAME;
+ }
+ bool is_form_submit = document_loader->GetNavigationType() ==
+ blink::kWebNavigationTypeFormSubmitted ||
+ document_loader->GetNavigationType() ==
+ blink::kWebNavigationTypeFormResubmitted;
+ if (ui::PageTransitionCoreTypeIs(default_transition,
+ ui::PAGE_TRANSITION_LINK) &&
+ is_form_submit) {
+ return ui::PAGE_TRANSITION_FORM_SUBMIT;
+ }
+ }
+ return default_transition;
+}
+
WebURLResponseExtraDataImpl* GetExtraDataFromResponse(
const WebURLResponse& response) {
return static_cast<WebURLResponseExtraDataImpl*>(response.GetExtraData());
@@ -421,14 +426,6 @@ GURL GetOriginalRequestURL(WebDocumentLoader* document_loader) {
return document_loader->OriginalRequest().Url();
}
-bool IsBrowserInitiated(PendingNavigationParams* pending) {
- // A navigation resulting from loading a javascript URL should not be treated
- // as a browser initiated event. Instead, we want it to look as if the page
- // initiated any load resulting from JS execution.
- return pending &&
- !pending->common_params.url.SchemeIs(url::kJavaScriptScheme);
-}
-
// Returns false unless this is a top-level navigation.
bool IsTopLevelNavigation(WebFrame* frame) {
return frame->Parent() == nullptr;
@@ -540,13 +537,14 @@ CommonNavigationParams MakeCommonNavigationParams(
static_cast<PreviewsState>(info.url_request.GetPreviewsState()),
base::TimeTicks::Now(), info.url_request.HttpMethod().Latin1(),
GetRequestBodyForWebURLRequest(info.url_request), source_location,
- should_check_main_world_csp, false /* started_from_context_menu */,
- info.url_request.HasUserGesture(),
- BuildContentSecurityPolicyList(info.url_request.GetNavigationCSP()),
- info.url_request.GetNavigationCSP().self_source.has_value()
- ? base::Optional<CSPSource>(BuildCSPSource(
- info.url_request.GetNavigationCSP().self_source.value()))
- : base::nullopt,
+ false /* started_from_context_menu */, info.url_request.HasUserGesture(),
+ InitiatorCSPInfo(
+ should_check_main_world_csp,
+ BuildContentSecurityPolicyList(info.url_request.GetInitiatorCSP()),
+ info.url_request.GetInitiatorCSP().self_source.has_value()
+ ? base::Optional<CSPSource>(BuildCSPSource(
+ info.url_request.GetInitiatorCSP().self_source.value()))
+ : base::nullopt),
input_start);
}
@@ -587,6 +585,10 @@ WebFrameLoadType NavigationTypeToLoadType(
RenderFrameImpl::CreateRenderFrameImplFunction g_create_render_frame_impl =
nullptr;
+RenderFrameImpl::CreateRenderWidgetForChildLocalRootFunction
+ g_create_render_widget = nullptr;
+RenderFrameImpl::RenderWidgetForChildLocalRootInitializedCallback
+ g_render_widget_initialized = nullptr;
WebString ConvertRelativePathToHtmlAttribute(const base::FilePath& path) {
DCHECK(!path.IsAbsolute());
@@ -804,33 +806,27 @@ blink::mojom::BlobURLTokenPtrInfo CloneBlobURLToken(
}
// Creates a fully functional DocumentState in the case where we do not have
-// pending_navigation_params_ available in the RenderFrameImpl.
+// navigation parameters available.
std::unique_ptr<DocumentState> BuildDocumentState() {
std::unique_ptr<DocumentState> document_state =
std::make_unique<DocumentState>();
- document_state->set_navigation_state(
- NavigationStateImpl::CreateContentInitiated());
+ InternalDocumentStateData::FromDocumentState(document_state.get())
+ ->set_navigation_state(NavigationState::CreateContentInitiated());
return document_state;
}
// Creates a fully functional DocumentState in the case where we have
-// pending_navigation_params_ available in the RenderFrameImpl.
-// TODO(ahemery): This currently removes the callback from the pending params
-// which is a bit counterintuitive. We would like to leave
-// pending_navigation_params in a valid state. Callback should probably not be
-// a part of PendingNavigationParams.
-std::unique_ptr<DocumentState> BuildDocumentStateFromPending(
- PendingNavigationParams* pending_navigation_params,
+// navigation parameters available in the RenderFrameImpl.
+std::unique_ptr<DocumentState> BuildDocumentStateFromParams(
+ const CommonNavigationParams& common_params,
+ const RequestNavigationParams& request_params,
+ base::TimeTicks time_commit_requested,
+ mojom::FrameNavigationControl::CommitNavigationCallback commit_callback,
const network::ResourceResponseHead* head) {
std::unique_ptr<DocumentState> document_state(new DocumentState());
InternalDocumentStateData* internal_data =
InternalDocumentStateData::FromDocumentState(document_state.get());
- const CommonNavigationParams& common_params =
- pending_navigation_params->common_params;
- const RequestNavigationParams& request_params =
- pending_navigation_params->request_params;
-
DCHECK(!common_params.navigation_start.is_null());
DCHECK(!common_params.url.SchemeIs(url::kJavaScriptScheme));
@@ -876,12 +872,10 @@ std::unique_ptr<DocumentState> BuildDocumentStateFromPending(
if (load_data)
document_state->set_data_url(common_params.url);
- document_state->set_navigation_state(
- NavigationStateImpl::CreateBrowserInitiated(
- pending_navigation_params->common_params,
- pending_navigation_params->request_params,
- pending_navigation_params->time_commit_requested,
- std::move(pending_navigation_params->commit_callback_)));
+ InternalDocumentStateData::FromDocumentState(document_state.get())
+ ->set_navigation_state(NavigationState::CreateBrowserInitiated(
+ common_params, request_params, time_commit_requested,
+ std::move(commit_callback)));
return document_state;
}
@@ -974,7 +968,8 @@ std::unique_ptr<blink::WebNavigationParams> BuildNavigationParams(
common_params.source_location->column_number;
}
- navigation_params->is_user_activated = request_params.was_activated;
+ navigation_params->is_user_activated =
+ request_params.was_activated == WasActivatedOption::kYes;
navigation_params->service_worker_network_provider =
std::move(service_worker_network_provider);
return navigation_params;
@@ -1002,16 +997,9 @@ class RenderFrameImpl::FrameURLLoaderFactory
frame_->GetFrameHost()->IssueKeepAliveHandle(
mojo::MakeRequest(&keep_alive_handle));
}
- scoped_refptr<network::SharedURLLoaderFactory> loader_factory =
- frame_->GetLoaderFactoryBundle();
- if (request.GetRequestContext() == WebURLRequest::kRequestContextPrefetch &&
- frame_->prefetch_shared_loader_factory_) {
- // The frame should be alive when this factory is used.
- loader_factory = frame_->prefetch_shared_loader_factory_;
- }
return std::make_unique<WebURLLoaderImpl>(
RenderThreadImpl::current()->resource_dispatcher(),
- std::move(task_runner_handle), std::move(loader_factory),
+ std::move(task_runner_handle), frame_->GetLoaderFactoryBundle(),
std::move(keep_alive_handle));
}
@@ -1256,8 +1244,7 @@ RenderFrame* RenderFrame::FromRoutingID(int routing_id) {
// static
RenderFrameImpl* RenderFrameImpl::FromRoutingID(int routing_id) {
- RoutingIDFrameMap::iterator iter =
- g_routing_id_frame_map.Get().find(routing_id);
+ auto iter = g_routing_id_frame_map.Get().find(routing_id);
if (iter != g_routing_id_frame_map.Get().end())
return iter->second;
return nullptr;
@@ -1292,12 +1279,25 @@ RenderFrameImpl* RenderFrameImpl::CreateMainFrame(
replicated_state.frame_policy.sandbox_flags);
if (has_committed_real_load)
web_frame->SetCommittedFirstRealLoad();
- render_frame->render_widget_ = RenderWidget::CreateForFrame(
- widget_routing_id, hidden, screen_info, compositor_deps, web_frame);
- // TODO(avi): This DCHECK is to track cleanup for https://crbug.com/545684
- DCHECK_EQ(render_view->GetWidget(), render_frame->render_widget_)
- << "Main frame is no longer reusing the RenderView as its widget! "
- << "Does the RenderFrame need to register itself with the RenderWidget?";
+
+ // The RenderViewImpl and its RenderWidget already exist by the time we get
+ // here.
+ // TODO(crbug.com/419087): We probably want to create the RenderWidget here
+ // though (when we make the WebFrameWidget?).
+ RenderWidget* render_widget = render_view->GetWidget();
+
+ // Non-owning pointer that is self-referencing and destroyed by calling
+ // Close(). The RenderViewImpl has a RenderWidget already, but not a
+ // WebFrameWidget, which is now attached here.
+ auto* web_frame_widget = blink::WebFrameWidget::CreateForMainFrame(
+ render_view->WidgetClient(), web_frame);
+ render_view->AttachWebFrameWidget(web_frame_widget);
+ // TODO(crbug.com/419087): This was added in 6ccadf770766e89c3 to prevent an
+ // empty ScreenInfo, but the WebView has already been created and initialized
+ // by RenderViewImpl, so this is surely redundant?
+ render_widget->UpdateWebViewWithDeviceScaleFactor();
+
+ render_frame->render_widget_ = render_widget;
render_frame->in_frame_tree_ = true;
return render_frame;
}
@@ -1316,8 +1316,12 @@ void RenderFrameImpl::CreateFrame(
const mojom::CreateFrameWidgetParams& widget_params,
const FrameOwnerProperties& frame_owner_properties,
bool has_committed_real_load) {
- blink::WebLocalFrame* web_frame;
- RenderFrameImpl* render_frame;
+ // TODO(danakj): Split this method into two pieces. The first block makes a
+ // WebLocalFrame and collects the RenderView and RenderFrame for it. The
+ // second block uses that to make/setup a RenderWidget, if needed.
+ RenderViewImpl* render_view = nullptr;
+ RenderFrameImpl* render_frame = nullptr;
+ blink::WebLocalFrame* web_frame = nullptr;
if (proxy_routing_id == MSG_ROUTING_NONE) {
// TODO(alexmos): This path is currently used only:
// 1) When recreating a RenderFrame after a crash.
@@ -1339,6 +1343,7 @@ void RenderFrameImpl::CreateFrame(
if (previous_sibling_proxy)
previous_sibling_web_frame = previous_sibling_proxy->web_frame();
+ render_view = parent_proxy->render_view();
// Create the RenderFrame and WebLocalFrame, linking the two.
render_frame = RenderFrameImpl::Create(
parent_proxy->render_view(), routing_id, std::move(interface_provider),
@@ -1369,7 +1374,15 @@ void RenderFrameImpl::CreateFrame(
if (!proxy)
return;
- render_frame = RenderFrameImpl::Create(proxy->render_view(), routing_id,
+ // This path is creating a local frame. It may or may not be a local root,
+ // depending if the frame's parent is local or remote. It may also be the
+ // main frame, as in the case where a navigation to the current process'
+ // origin replaces a remote main frame (the proxy's web_frame()) with a
+ // local one.
+ const bool proxy_is_main_frame = !proxy->web_frame()->Parent();
+
+ render_view = proxy->render_view();
+ render_frame = RenderFrameImpl::Create(render_view, routing_id,
std::move(interface_provider),
devtools_frame_token);
render_frame->InitializeBlameContext(nullptr);
@@ -1379,16 +1392,119 @@ void RenderFrameImpl::CreateFrame(
render_frame, render_frame->blink_interface_registry_.get(),
proxy->web_frame(), replicated_state.frame_policy.sandbox_flags,
replicated_state.frame_policy.container_policy);
+ // The new |web_frame| is a main frame iff the proxy's frame was.
+ DCHECK_EQ(proxy_is_main_frame, !web_frame->Parent());
}
- CHECK(parent_routing_id != MSG_ROUTING_NONE || !web_frame->Parent());
- if (widget_params.routing_id != MSG_ROUTING_NONE) {
- // TODO(fsamuel): It's not clear if we should be passing in the
- // web ScreenInfo or the original ScreenInfo here.
- render_frame->render_widget_ = RenderWidget::CreateForFrame(
- widget_params.routing_id, widget_params.hidden,
- render_frame->render_view_->GetWebScreenInfo(), compositor_deps,
- web_frame);
+ DCHECK(render_view);
+ DCHECK(render_frame);
+ DCHECK(web_frame);
+
+ const bool is_main_frame = !web_frame->Parent();
+
+ // Child frames require there to be a |parent_routing_id| present, for the
+ // remote parent frame. Though it is only used if the |proxy_routing_id| is
+ // not given, which happens in some corner cases.
+ if (!is_main_frame)
+ DCHECK_NE(parent_routing_id, MSG_ROUTING_NONE);
+
+ // We now have a WebLocalFrame for the new frame. The next step is to set
+ // up a RenderWidget for it, if it is needed.
+ //
+ // If there is no widget routing id, then the new frame is not a local root,
+ // and does not need a RenderWidget. In that case we'll do nothing. Otherwise
+ // it does.
+ if (is_main_frame) {
+ // For a main frame, we use the RenderWidget already attached to the
+ // RenderView (this is being changed by https://crbug.com/419087).
+
+ // Main frames are always local roots, so they should always have a routing
+ // id. Surprisingly, this routing id is *not* used though, as the routing id
+ // on the existing RenderWidget is not changed. (I don't know why.)
+ // TODO(crbug.com/888105): It's a bug that the RenderWidget is not using
+ // this routing id.
+ DCHECK_NE(widget_params.routing_id, MSG_ROUTING_NONE);
+
+ // The RenderViewImpl and its RenderWidget already exist by the time we
+ // get here (we get them from the RenderFrameProxy).
+ // TODO(crbug.com/419087): We probably want to create the RenderWidget
+ // here though (when we make the WebFrameWidget?).
+ RenderWidget* render_widget = render_view->GetWidget();
+
+ // Non-owning pointer that is self-referencing and destroyed by calling
+ // Close(). The RenderViewImpl has a RenderWidget already, but not a
+ // WebFrameWidget, which is now attached here.
+ auto* web_frame_widget = blink::WebFrameWidget::CreateForMainFrame(
+ render_view->WidgetClient(), web_frame);
+ render_view->AttachWebFrameWidget(web_frame_widget);
+ // TODO(crbug.com/419087): This was added in 6ccadf770766e89c3 to prevent
+ // an empty ScreenInfo, but the WebView has already been created and
+ // initialized by RenderViewImpl, so this is surely redundant? It will be
+ // pulling the device scale factor off the WebView itself.
+ render_widget->UpdateWebViewWithDeviceScaleFactor();
+
+ render_frame->render_widget_ = render_widget;
+ } else if (widget_params.routing_id != MSG_ROUTING_NONE) {
+ // This frame is a child local root, so we require a separate RenderWidget
+ // for it from any other frames in the frame tree. Each local root defines
+ // a separate context/coordinate space/world for compositing, painting,
+ // input, etc. And each local root has a RenderWidget which provides
+ // such services independent from other RenderWidgets.
+ // Notably, we do not attempt to reuse the main frame's RenderWidget (if the
+ // main frame in this frame tree is local) as that RenderWidget is
+ // functioning in a different local root. Because this is a child local
+ // root, it implies there is some remote frame ancestor between this frame
+ // and the main frame, thus its coordinate space etc is not known relative
+ // to the main frame.
+
+ // TODO(crbug.com/419087): This is grabbing something off the view's
+ // widget but if the main frame is remote this widget would not be valid?
+ const ScreenInfo& screen_info_from_main_frame =
+ render_view->GetWidget()->GetWebScreenInfo();
+
+ // Makes a new RenderWidget for the child local root. It provides the
+ // local root with a new compositing, painting, and input coordinate
+ // space/context.
+ scoped_refptr<RenderWidget> render_widget;
+ if (g_create_render_widget) {
+ // LayoutTest hooks inject a different type (subclass) for RenderWidget,
+ // allowing it to override the behaviour of the WebWidgetClient which
+ // RenderWidget provides.
+ render_widget = g_create_render_widget(
+ widget_params.routing_id, compositor_deps, WidgetType::kFrame,
+ screen_info_from_main_frame, blink::kWebDisplayModeUndefined,
+ /*swapped_out=*/false, widget_params.hidden,
+ /*never_visible=*/false);
+ } else {
+ render_widget = base::MakeRefCounted<RenderWidget>(
+ widget_params.routing_id, compositor_deps, WidgetType::kFrame,
+ screen_info_from_main_frame, blink::kWebDisplayModeUndefined,
+ /*swapped_out=*/false, widget_params.hidden,
+ /*never_visible=*/false);
+ }
+
+ // Non-owning pointer that is self-referencing and destroyed by calling
+ // Close(). We use the new RenderWidget as the client for this
+ // WebFrameWidget, *not* the RenderWidget of the MainFrame, which is
+ // accessible from the RenderViewImpl.
+ auto* web_frame_widget = blink::WebFrameWidget::CreateForChildLocalRoot(
+ render_widget.get(), web_frame);
+
+ // Adds a reference on RenderWidget, making it self-referencing. So it
+ // will not be destroyed by scoped_refptr unless Close() has been called
+ // and run.
+ render_widget->InitForChildLocalRoot(web_frame_widget);
+ // TODO(crbug.com/419087): This was added in 6ccadf770766e89c3 to prevent
+ // an empty ScreenInfo, but the WebView has already been created and
+ // initialized by RenderViewImpl, so this is surely redundant? It will be
+ // pulling the device scale factor off the WebView itself.
+ render_widget->UpdateWebViewWithDeviceScaleFactor();
+
+ // LayoutTest hooks to set up the injected type for RenderWidget.
+ if (g_render_widget_initialized)
+ g_render_widget_initialized(render_widget.get());
+
+ render_frame->render_widget_ = std::move(render_widget);
}
if (has_committed_real_load)
@@ -1405,7 +1521,7 @@ RenderFrame* RenderFrame::FromWebFrame(blink::WebLocalFrame* web_frame) {
// static
void RenderFrame::ForEach(RenderFrameVisitor* visitor) {
FrameMap* frames = g_frame_map.Pointer();
- for (FrameMap::iterator it = frames->begin(); it != frames->end(); ++it) {
+ for (auto it = frames->begin(); it != frames->end(); ++it) {
if (!visitor->Visit(it->second))
return;
}
@@ -1424,7 +1540,7 @@ int RenderFrame::GetRoutingIdForWebFrame(blink::WebFrame* web_frame) {
// static
RenderFrameImpl* RenderFrameImpl::FromWebFrame(blink::WebFrame* web_frame) {
- FrameMap::iterator iter = g_frame_map.Get().find(web_frame);
+ auto iter = g_frame_map.Get().find(web_frame);
if (iter != g_frame_map.Get().end())
return iter->second;
return nullptr;
@@ -1432,9 +1548,15 @@ RenderFrameImpl* RenderFrameImpl::FromWebFrame(blink::WebFrame* web_frame) {
// static
void RenderFrameImpl::InstallCreateHook(
- CreateRenderFrameImplFunction create_render_frame_impl) {
- CHECK(!g_create_render_frame_impl);
- g_create_render_frame_impl = create_render_frame_impl;
+ CreateRenderFrameImplFunction create_frame,
+ CreateRenderWidgetForChildLocalRootFunction create_widget,
+ RenderWidgetForChildLocalRootInitializedCallback widget_initialized) {
+ DCHECK(!g_create_render_frame_impl);
+ DCHECK(!g_create_render_widget);
+ DCHECK(!g_render_widget_initialized);
+ g_create_render_frame_impl = create_frame;
+ g_create_render_widget = create_widget;
+ g_render_widget_initialized = widget_initialized;
}
// static
@@ -1509,7 +1631,6 @@ RenderFrameImpl::RenderFrameImpl(CreateParams params)
focused_pepper_plugin_(nullptr),
pepper_last_mouse_event_target_(nullptr),
#endif
- engagement_binding_(this),
autoplay_configuration_binding_(this),
frame_binding_(this),
host_zoom_binding_(this),
@@ -1568,9 +1689,6 @@ mojom::FrameHost* RenderFrameImpl::GetFrameHost() {
}
RenderFrameImpl::~RenderFrameImpl() {
- if (prefetch_shared_loader_factory_)
- prefetch_shared_loader_factory_->Detach();
-
// If file chooser is still waiting for answer, dispatch empty answer.
if (file_chooser_completion_) {
file_chooser_completion_->DidChooseFile(WebVector<WebString>());
@@ -1751,9 +1869,11 @@ void RenderFrameImpl::PepperSelectionChanged(
RenderWidgetFullscreenPepper* RenderFrameImpl::CreatePepperFullscreenContainer(
PepperPluginInstanceImpl* plugin) {
- GURL active_url;
- if (render_view()->webview())
- active_url = render_view()->GetURLForGraphicsContext3D();
+ // Get the URL of the main frame if possible.
+ blink::WebURL main_frame_url;
+ WebFrame* main_frame = render_view()->webview()->MainFrame();
+ if (main_frame->IsWebLocalFrame())
+ main_frame_url = main_frame->ToWebLocalFrame()->GetDocument().Url();
mojom::WidgetPtr widget_channel;
mojom::WidgetRequest widget_channel_request =
@@ -1775,7 +1895,7 @@ RenderWidgetFullscreenPepper* RenderFrameImpl::CreatePepperFullscreenContainer(
// web ScreenInfo or the original ScreenInfo here.
RenderWidgetFullscreenPepper* widget = RenderWidgetFullscreenPepper::Create(
fullscreen_widget_routing_id, std::move(show_callback),
- GetRenderWidget()->compositor_deps(), plugin, active_url,
+ GetRenderWidget()->compositor_deps(), plugin, std::move(main_frame_url),
GetRenderWidget()->GetWebScreenInfo(), std::move(widget_channel_request));
// TODO(nick): The show() handshake seems like unnecessary complexity here,
// since there's no real delay between CreateFullscreenWidget and
@@ -2005,12 +2125,6 @@ void RenderFrameImpl::OnAssociatedInterfaceRequest(
}
}
-void RenderFrameImpl::BindEngagement(
- blink::mojom::EngagementClientAssociatedRequest request) {
- engagement_binding_.Bind(std::move(request),
- GetTaskRunner(blink::TaskType::kInternalIPC));
-}
-
void RenderFrameImpl::BindFullscreen(
mojom::FullscreenVideoElementHandlerAssociatedRequest request) {
fullscreen_binding_.Bind(std::move(request),
@@ -2084,8 +2198,7 @@ void RenderFrameImpl::OnSwapOut(
// Swap this RenderFrame out so the frame can navigate to a page rendered by
// a different process. This involves running the unload handler and
- // clearing the page. We also allow this process to exit if there are no
- // other active RenderFrames in it.
+ // clearing the page.
// Send an UpdateState message before we get deleted.
SendUpdateState();
@@ -2157,13 +2270,6 @@ void RenderFrameImpl::OnSwapOut(
auto send_swapout_ack = base::BindOnce(
[](int routing_id, bool is_main_frame) {
RenderThread::Get()->Send(new FrameHostMsg_SwapOut_ACK(routing_id));
- // Now that the unload handler, and any postMessages posted from it,
- // have finished, and we've sent the swapout ACK, it's safe to exit if
- // no one else is using the process. Release the process if we've
- // swapped the main frame out, and hence transitioned the
- // RenderView/Widget to swapped out state.
- if (is_main_frame)
- RenderProcess::current()->ReleaseProcess();
},
routing_id, is_main_frame);
task_runner->PostTask(FROM_HERE, std::move(send_swapout_ack));
@@ -2590,17 +2696,19 @@ bool RenderFrameImpl::RunJavaScriptDialog(JavaScriptDialogType type,
int32_t message_length = static_cast<int32_t>(message.length());
if (WebUserGestureIndicator::ProcessedUserGestureSinceLoad(frame_)) {
- UMA_HISTOGRAM_COUNTS("JSDialogs.CharacterCount.UserGestureSinceLoad",
- message_length);
+ UMA_HISTOGRAM_COUNTS_1M("JSDialogs.CharacterCount.UserGestureSinceLoad",
+ message_length);
} else {
- UMA_HISTOGRAM_COUNTS("JSDialogs.CharacterCount.NoUserGestureSinceLoad",
- message_length);
+ UMA_HISTOGRAM_COUNTS_1M("JSDialogs.CharacterCount.NoUserGestureSinceLoad",
+ message_length);
}
if (is_main_frame_)
- UMA_HISTOGRAM_COUNTS("JSDialogs.CharacterCount.MainFrame", message_length);
+ UMA_HISTOGRAM_COUNTS_1M("JSDialogs.CharacterCount.MainFrame",
+ message_length);
else
- UMA_HISTOGRAM_COUNTS("JSDialogs.CharacterCount.Subframe", message_length);
+ UMA_HISTOGRAM_COUNTS_1M("JSDialogs.CharacterCount.Subframe",
+ message_length);
// 10k ought to be enough for anyone.
const base::string16::size_type kMaxMessageSize = 10 * 1024;
@@ -2619,17 +2727,16 @@ bool RenderFrameImpl::RunJavaScriptDialog(JavaScriptDialogType type,
void RenderFrameImpl::DidFailProvisionalLoadInternal(
const WebURLError& error,
blink::WebHistoryCommitType commit_type,
- const base::Optional<std::string>& error_page_content) {
+ const base::Optional<std::string>& error_page_content,
+ std::unique_ptr<blink::WebNavigationParams> navigation_params,
+ std::unique_ptr<blink::WebDocumentLoader::ExtraData> document_state) {
TRACE_EVENT1("navigation,benchmark,rail",
"RenderFrameImpl::didFailProvisionalLoad", "id", routing_id_);
// Note: It is important this notification occur before DidStopLoading so the
// SSL manager can react to the provisional load failure before being
// notified the load stopped.
//
- for (auto& observer : render_view_->observers())
- observer.DidFailProvisionalLoad(frame_, error);
- for (auto& observer : observers_)
- observer.DidFailProvisionalLoad(error);
+ NotifyObserversOfFailedProvisionalLoad(error);
WebDocumentLoader* document_loader = frame_->GetProvisionalDocumentLoader();
if (!document_loader)
@@ -2646,8 +2753,8 @@ void RenderFrameImpl::DidFailProvisionalLoadInternal(
// Make sure we never show errors in view source mode.
frame_->EnableViewSourceMode(false);
- NavigationStateImpl* navigation_state = static_cast<NavigationStateImpl*>(
- DocumentState::FromDocumentLoader(document_loader)->navigation_state());
+ NavigationState* navigation_state =
+ NavigationState::FromDocumentLoader(document_loader);
// If this is a failed back/forward/reload navigation, then we need to do a
// 'replace' load. This is necessary to avoid messing up session history.
@@ -2658,42 +2765,30 @@ void RenderFrameImpl::DidFailProvisionalLoadInternal(
// If we failed on a browser initiated request, then make sure that our error
// page load is regarded as the same browser initiated request.
if (!navigation_state->IsContentInitiated()) {
- pending_navigation_params_.reset(new PendingNavigationParams(
+ document_state = BuildDocumentStateFromParams(
navigation_state->common_params(), navigation_state->request_params(),
- base::TimeTicks(), // not used for failed navigation.
- CommitNavigationCallback()));
- }
-
- // The |pending_navigation_params_| are reset in DidCreateDocumentLoader.
- // We might not have |pending_navigation_params_| here, if failing after
- // creating the DocumentLoader. This can happen if there's no byte in the
- // response and the network connection gets closed. In that case, the
- // provisional load does not commit and we get a DidFailProvisionalLoad.
- std::unique_ptr<DocumentState> document_state;
- std::unique_ptr<blink::WebNavigationParams> navigation_params;
- if (pending_navigation_params_) {
- document_state = BuildDocumentStateFromPending(
- pending_navigation_params_.get(), nullptr);
- // We might come here after we've already created
- // ServiceWorkerNetworkProvider in CommitNavigation, and if that's the case
- // we shouldn't reuse the same request_params (which confuses the
- // ServiceWorker backend due to double-creation for the same provider_id).
- // Code below will result in creating a SWNetworkProvider with an invalid
- // ID but it should be fine as it's only used for showing an error page.
- // TODO(ahemery): We should probably move the existing one down
- // into the failed page instead of recreating a new one.
+ base::TimeTicks(), // Not used for failed navigation.
+ CommitNavigationCallback(), nullptr);
navigation_params = BuildNavigationParams(
- pending_navigation_params_->common_params,
- pending_navigation_params_->request_params,
+ navigation_state->common_params(), navigation_state->request_params(),
BuildServiceWorkerNetworkProviderForNavigation(
nullptr /* request_params */,
nullptr /* controller_service_worker_info */));
}
+
LoadNavigationErrorPage(failed_request, error, replace, nullptr,
error_page_content, std::move(navigation_params),
std::move(document_state));
}
+void RenderFrameImpl::NotifyObserversOfFailedProvisionalLoad(
+ const blink::WebURLError& error) {
+ for (auto& observer : render_view_->observers())
+ observer.DidFailProvisionalLoad(frame_, error);
+ for (auto& observer : observers_)
+ observer.DidFailProvisionalLoad(error);
+}
+
void RenderFrameImpl::LoadNavigationErrorPage(
const WebURLRequest& failed_request,
const WebURLError& error,
@@ -2745,6 +2840,8 @@ void RenderFrameImpl::LoadNavigationErrorPageInternal(
: blink::WebFrameLoadType::kStandard;
const blink::WebHistoryItem& history_item =
history_entry ? history_entry->root() : blink::WebHistoryItem();
+ if (replace && frame_load_type == WebFrameLoadType::kStandard)
+ frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
// Failed navigations will always provide a |failed_request|. Error induced
// by the client/renderer side after a commit won't have a |failed_request|.
@@ -2759,10 +2856,10 @@ void RenderFrameImpl::LoadNavigationErrorPageInternal(
// should not inherit the cache mode from |failed_request|).
new_request.SetCacheMode(blink::mojom::FetchCacheMode::kNoStore);
- frame_->CommitDataNavigationWithRequest(
- new_request, error_html, "text/html", "UTF-8", error_url, replace,
- frame_load_type, history_item, is_client_redirect,
- std::move(navigation_params), std::move(navigation_data));
+ frame_->CommitDataNavigation(new_request, error_html, "text/html", "UTF-8",
+ error_url, frame_load_type, history_item,
+ is_client_redirect, std::move(navigation_params),
+ std::move(navigation_data));
}
void RenderFrameImpl::DidMeaningfulLayout(
@@ -2957,7 +3054,7 @@ void RenderFrameImpl::WhitelistContentOrigin(
}
void RenderFrameImpl::PluginDidStartLoading() {
- DidStartLoading(true);
+ DidStartLoading();
}
void RenderFrameImpl::PluginDidStopLoading() {
@@ -3029,20 +3126,6 @@ bool RenderFrameImpl::IsPasting() const {
return is_pasting_;
}
-// blink::mojom::EngagementClient implementation -------------------------------
-
-void RenderFrameImpl::SetEngagementLevel(const url::Origin& origin,
- blink::mojom::EngagementLevel level) {
- // Set the engagement level on |frame_| if its origin matches the one we have
- // been provided with.
- if (frame_ && url::Origin(frame_->GetSecurityOrigin()) == origin) {
- frame_->SetEngagementLevel(level);
- return;
- }
-
- engagement_level_ = std::make_pair(origin, level);
-}
-
// blink::mojom::FullscreenVideoElementHandler implementation ------------------
void RenderFrameImpl::RequestFullscreenVideoElement() {
WebElement video_element =
@@ -3145,15 +3228,6 @@ void RenderFrameImpl::CommitNavigation(
return;
}
- if (prefetch_shared_loader_factory_)
- prefetch_shared_loader_factory_->Detach();
- prefetch_loader_factory_ = std::move(prefetch_loader_factory);
- if (prefetch_loader_factory_) {
- prefetch_shared_loader_factory_ =
- base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- prefetch_loader_factory_.get());
- }
-
// If the request was initiated in the context of a user gesture then make
// sure that the navigation also executes in the context of a user gesture.
std::unique_ptr<blink::WebScopedUserGesture> gesture(
@@ -3167,7 +3241,8 @@ void RenderFrameImpl::CommitNavigation(
subresource_loader_factories);
SetupLoaderFactoryBundle(std::move(subresource_loader_factories),
- std::move(subresource_overrides));
+ std::move(subresource_overrides),
+ std::move(prefetch_loader_factory));
// Clear pending navigations which weren't sent to the browser because we
// did not get a didStartProvisionalLoad() notification for them.
@@ -3178,9 +3253,6 @@ void RenderFrameImpl::CommitNavigation(
if (request_params.is_view_source)
frame_->EnableViewSourceMode(true);
- pending_navigation_params_.reset(
- new PendingNavigationParams(common_params, request_params,
- base::TimeTicks::Now(), std::move(callback)));
PrepareFrameForCommit(common_params.url, request_params);
// We only save metrics of the main frame's main resource to the
@@ -3190,8 +3262,9 @@ void RenderFrameImpl::CommitNavigation(
const network::ResourceResponseHead* response_head = nullptr;
if (!frame_->Parent() && !frame_->IsViewSourceModeEnabled())
response_head = &head;
- std::unique_ptr<DocumentState> document_state(BuildDocumentStateFromPending(
- pending_navigation_params_.get(), response_head));
+ std::unique_ptr<DocumentState> document_state(BuildDocumentStateFromParams(
+ common_params, request_params, base::TimeTicks::Now(),
+ std::move(callback), response_head));
blink::WebFrameLoadType load_type = NavigationTypeToLoadType(
common_params.navigation_type, common_params.should_replace_current_entry,
@@ -3226,13 +3299,16 @@ void RenderFrameImpl::CommitNavigation(
should_load_data_url |= !request_params.data_url_as_string.empty();
#endif
if (is_main_frame_ && should_load_data_url) {
- LoadDataURL(common_params, request_params, frame_, load_type,
+ LoadDataURL(common_params, request_params, load_type,
item_for_history_navigation, is_client_redirect,
std::move(document_state));
} else {
WebURLRequest request = CreateURLRequestForCommit(
common_params, request_params, std::move(url_loader_client_endpoints),
head);
+ // Note: we cannot use base::AutoReset here, since |this| can be deleted
+ // in the next call and auto reset will introduce use-after-free bug.
+ committing_main_request_ = true;
frame_->CommitNavigation(
request, load_type, item_for_history_navigation, is_client_redirect,
devtools_navigation_token,
@@ -3247,7 +3323,7 @@ void RenderFrameImpl::CommitNavigation(
// otherwise it will result in a use-after-free bug.
if (!weak_this)
return;
-
+ committing_main_request_ = false;
RequestExtraData* extra_data =
static_cast<RequestExtraData*>(request.GetExtraData());
continue_navigation =
@@ -3260,9 +3336,6 @@ void RenderFrameImpl::CommitNavigation(
Send(new FrameHostMsg_DidStopLoading(routing_id_));
}
- // In case LoadRequest failed before DidCreateDocumentLoader was called.
- pending_navigation_params_.reset();
-
// Reset the source location now that the commit checks have been processed.
frame_->GetDocumentLoader()->ResetSourceLocation();
if (frame_->GetProvisionalDocumentLoader())
@@ -3306,12 +3379,8 @@ void RenderFrameImpl::CommitFailedNavigation(
common_params.url, frame_->Top()->GetSecurityOrigin().ToString().Utf8());
SetupLoaderFactoryBundle(std::move(subresource_loader_factories),
- base::nullopt /* subresource_overrides */);
-
- pending_navigation_params_.reset(new PendingNavigationParams(
- common_params, request_params,
- base::TimeTicks(), // Not used for failed navigation.
- std::move(callback)));
+ base::nullopt /* subresource_overrides */,
+ nullptr /* prefetch_loader_factory */);
// Send the provisional load failure.
WebURLError error(
@@ -3326,9 +3395,7 @@ void RenderFrameImpl::CommitFailedNavigation(
if (!ShouldDisplayErrorPageForFailedLoad(error_code, common_params.url)) {
// The browser expects this frame to be loading an error page. Inform it
// that the load stopped.
- std::move(pending_navigation_params_->commit_callback_)
- .Run(blink::mojom::CommitResult::Aborted);
- pending_navigation_params_.reset();
+ std::move(callback).Run(blink::mojom::CommitResult::Aborted);
Send(new FrameHostMsg_DidStopLoading(routing_id_));
browser_side_navigation_pending_ = false;
browser_side_navigation_pending_url_ = GURL();
@@ -3346,10 +3413,10 @@ void RenderFrameImpl::CommitFailedNavigation(
// either, as the frame has already been populated with something
// unrelated to this navigation failure. In that case, just send a stop
// IPC to the browser to unwind its state, and leave the frame as-is.
- std::move(pending_navigation_params_->commit_callback_)
- .Run(blink::mojom::CommitResult::Aborted);
- pending_navigation_params_.reset();
+ std::move(callback).Run(blink::mojom::CommitResult::Aborted);
Send(new FrameHostMsg_DidStopLoading(routing_id_));
+ } else {
+ std::move(callback).Run(blink::mojom::CommitResult::Ok);
}
browser_side_navigation_pending_ = false;
browser_side_navigation_pending_url_ = GURL();
@@ -3380,38 +3447,40 @@ void RenderFrameImpl::CommitFailedNavigation(
// otherwise it will result in a use-after-free bug.
base::WeakPtr<RenderFrameImpl> weak_this = weak_factory_.GetWeakPtr();
+ std::unique_ptr<blink::WebNavigationParams> navigation_params =
+ BuildNavigationParams(common_params, request_params,
+ BuildServiceWorkerNetworkProviderForNavigation(
+ &request_params, nullptr));
+ std::unique_ptr<DocumentState> navigation_data(BuildDocumentStateFromParams(
+ common_params, request_params, base::TimeTicks(), std::move(callback),
+ nullptr));
+
// For renderer initiated navigations, we send out a didFailProvisionalLoad()
// notification.
bool had_provisional_document_loader = frame_->GetProvisionalDocumentLoader();
if (request_params.nav_entry_id == 0) {
blink::WebHistoryCommitType commit_type =
replace ? blink::kWebHistoryInertCommit : blink::kWebStandardCommit;
- if (error_page_content.has_value()) {
- DidFailProvisionalLoadInternal(error, commit_type, error_page_content);
+
+ // Note: had_provisional_document_loader can be false in cases such as cross
+ // process failures, e.g. error pages.
+ if (had_provisional_document_loader) {
+ DidFailProvisionalLoadInternal(error, commit_type, error_page_content,
+ std::move(navigation_params),
+ std::move(navigation_data));
} else {
- // TODO(https://crbug.com/778824): We only have this branch because a
- // layout test expects DidFailProvisionalLoad() to be called directly,
- // rather than DidFailProvisionalLoadInternal(). Once the bug is fixed, we
- // should be able to call DidFailProvisionalLoadInternal() in all cases.
- DidFailProvisionalLoad(error, commit_type);
+ NotifyObserversOfFailedProvisionalLoad(error);
}
if (!weak_this)
return;
}
- // If we didn't call DidFailProvisionalLoad or there wasn't a
- // GetProvisionalDocumentLoader(), LoadNavigationErrorPage wasn't called, so
- // do it now.
+ // If we didn't call DidFailProvisionalLoad above, LoadNavigationErrorPage
+ // wasn't called, so do it now.
if (request_params.nav_entry_id != 0 || !had_provisional_document_loader) {
- std::unique_ptr<blink::WebNavigationParams> navigation_params =
- BuildNavigationParams(common_params, request_params,
- BuildServiceWorkerNetworkProviderForNavigation(
- &request_params, nullptr));
- std::unique_ptr<DocumentState> document_state(BuildDocumentStateFromPending(
- pending_navigation_params_.get(), nullptr));
LoadNavigationErrorPage(failed_request, error, replace, history_entry.get(),
error_page_content, std::move(navigation_params),
- std::move(document_state));
+ std::move(navigation_data));
if (!weak_this)
return;
}
@@ -3435,13 +3504,6 @@ void RenderFrameImpl::CommitSameDocumentNavigation(
common_params.has_user_gesture ? new blink::WebScopedUserGesture(frame_)
: nullptr);
- // TODO(ahemery): |pending_navigation_params_| below is solely used by
- // IsBrowserInitiated() in DecidePolicyForNavigation. Try and find a a way to
- // avoid having to create the entire structure just for this.
- pending_navigation_params_.reset(new PendingNavigationParams(
- common_params, request_params,
- base::TimeTicks(), // Not used for same-document navigation.
- CommitNavigationCallback()));
PrepareFrameForCommit(common_params.url, request_params);
blink::WebFrameLoadType load_type = NavigationTypeToLoadType(
@@ -3468,10 +3530,23 @@ void RenderFrameImpl::CommitSameDocumentNavigation(
base::WeakPtr<RenderFrameImpl> weak_this = weak_factory_.GetWeakPtr();
bool is_client_redirect =
!!(common_params.transition & ui::PAGE_TRANSITION_CLIENT_REDIRECT);
+ DocumentState* original_document_state =
+ DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
+ std::unique_ptr<DocumentState> document_state =
+ original_document_state->Clone();
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDocumentState(document_state.get());
+ internal_data->CopyFrom(
+ InternalDocumentStateData::FromDocumentState(original_document_state));
+ internal_data->set_navigation_state(NavigationState::CreateBrowserInitiated(
+ common_params, request_params,
+ base::TimeTicks(), // Not used for same-document navigation.
+ CommitNavigationCallback()));
+
// Load the request.
commit_status = frame_->CommitSameDocumentNavigation(
common_params.url, load_type, item_for_history_navigation,
- is_client_redirect);
+ is_client_redirect, std::move(document_state));
// The load of the URL can result in this frame being removed. Use a
// WeakPtr as an easy way to detect whether this has occured. If so, this
@@ -3489,8 +3564,6 @@ void RenderFrameImpl::CommitSameDocumentNavigation(
commit_status != blink::mojom::CommitResult::Ok) {
Send(new FrameHostMsg_DidStopLoading(routing_id_));
}
-
- pending_navigation_params_.reset();
}
void RenderFrameImpl::HandleRendererDebugURL(const GURL& url) {
@@ -3519,6 +3592,12 @@ void RenderFrameImpl::UpdateSubresourceLoaderFactories(
->UpdateThisAndAllClones(std::move(subresource_loaders));
}
+void RenderFrameImpl::BindDevToolsAgent(
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host,
+ blink::mojom::DevToolsAgentAssociatedRequest request) {
+ frame_->BindDevToolsAgent(host.PassHandle(), request.PassHandle());
+}
+
// mojom::HostZoom implementation ----------------------------------------------
void RenderFrameImpl::SetHostZoomLevel(const GURL& url, double zoom_level) {
@@ -3554,7 +3633,7 @@ bool RenderFrameImpl::IsPluginHandledExternally(
// externally.
int32_t tentative_element_instance_id =
BrowserPluginManager::Get()->GetNextInstanceID();
- return GetContentClient()->renderer()->IsPluginHandledByMimeHandlerView(
+ return GetContentClient()->renderer()->MaybeCreateMimeHandlerView(
this, plugin_element, GURL(url), suggested_mime_type.Utf8(),
tentative_element_instance_id);
#else
@@ -3618,14 +3697,10 @@ RenderFrameImpl::CreateApplicationCacheHost(
if (!frame_ || !frame_->View())
return nullptr;
- DocumentState* document_state =
+ NavigationState* navigation_state = NavigationState::FromDocumentLoader(
frame_->GetProvisionalDocumentLoader()
- ? DocumentState::FromDocumentLoader(
- frame_->GetProvisionalDocumentLoader())
- : DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
-
- NavigationStateImpl* navigation_state =
- static_cast<NavigationStateImpl*>(document_state->navigation_state());
+ ? frame_->GetProvisionalDocumentLoader()
+ : frame_->GetDocumentLoader());
return std::make_unique<RendererWebApplicationCacheHostImpl>(
RenderViewImpl::FromWebView(frame_->View()), client,
@@ -3664,11 +3739,6 @@ RenderFrameImpl::CreateWorkerFetchContext() {
service_worker_client_request = mojo::MakeRequest(&worker_client_ptr);
provider_context->RegisterWorkerClient(std::move(worker_client_ptr));
- // TODO(horo): Use this host pointer also when S13nServiceWorker is not
- // enabled once we support navigator.serviceWorker on dedicated workers:
- // crbug.com/371690. Currently we use this only to call
- // GetControllerServiceWorker() from the worker thread if S13nServiceWorker
- // is enabled.
if (blink::ServiceWorkerUtils::IsServicificationEnabled())
container_host_ptr_info = provider_context->CloneContainerHostPtrInfo();
}
@@ -3788,11 +3858,8 @@ void RenderFrameImpl::DidAccessInitialDocument() {
// no longer safe to show the pending URL of the main frame, since a URL spoof
// is now possible. (If the request has committed, the browser already knows.)
if (!has_accessed_initial_document_) {
- DocumentState* document_state =
- DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
- NavigationStateImpl* navigation_state =
- static_cast<NavigationStateImpl*>(document_state->navigation_state());
-
+ NavigationState* navigation_state =
+ NavigationState::FromDocumentLoader(frame_->GetDocumentLoader());
if (!navigation_state->request_committed()) {
Send(new FrameHostMsg_DidAccessInitialDocument(routing_id_));
}
@@ -3933,7 +4000,7 @@ void RenderFrameImpl::FrameDetached(DetachType type) {
// the RenderFrameImpl. In contrast, the main frame is owned by its
// containing RenderViewHost (so that they have the same lifetime), so only
// removal from the map is needed and no deletion.
- FrameMap::iterator it = g_frame_map.Get().find(frame_);
+ auto it = g_frame_map.Get().find(frame_);
CHECK(it != g_frame_map.Get().end());
CHECK_EQ(it->second, this);
g_frame_map.Get().erase(it);
@@ -4122,32 +4189,8 @@ void RenderFrameImpl::WillSendSubmitEvent(const blink::WebFormElement& form) {
observer.WillSendSubmitEvent(form);
}
-void RenderFrameImpl::WillSubmitForm(const blink::WebFormElement& form) {
- DocumentState* document_state =
- DocumentState::FromDocumentLoader(frame_->GetProvisionalDocumentLoader());
- NavigationStateImpl* navigation_state =
- static_cast<NavigationStateImpl*>(document_state->navigation_state());
- InternalDocumentStateData* internal_data =
- InternalDocumentStateData::FromDocumentState(document_state);
-
- if (ui::PageTransitionCoreTypeIs(navigation_state->GetTransitionType(),
- ui::PAGE_TRANSITION_LINK)) {
- navigation_state->set_transition_type(ui::PAGE_TRANSITION_FORM_SUBMIT);
- }
-
- // Save these to be processed when the ensuing navigation is committed.
- WebSearchableFormData web_searchable_form_data(form);
- internal_data->set_searchable_form_url(web_searchable_form_data.Url());
- internal_data->set_searchable_form_encoding(
- web_searchable_form_data.Encoding().Utf8());
-
- for (auto& observer : observers_)
- observer.WillSubmitForm(form);
-}
-
void RenderFrameImpl::DidCreateDocumentLoader(
blink::WebDocumentLoader* document_loader) {
- pending_navigation_params_.reset();
DocumentState* document_state =
DocumentState::FromDocumentLoader(document_loader);
if (!document_state) {
@@ -4162,7 +4205,8 @@ void RenderFrameImpl::DidCreateDocumentLoader(
void RenderFrameImpl::DidStartProvisionalLoad(
blink::WebDocumentLoader* document_loader,
- blink::WebURLRequest& request) {
+ blink::WebURLRequest& request,
+ mojo::ScopedMessagePipeHandle navigation_initiator_handle) {
// In fast/loader/stop-provisional-loads.html, we abort the load before this
// callback is invoked.
if (!document_loader)
@@ -4193,46 +4237,22 @@ void RenderFrameImpl::DidStartProvisionalLoad(
info.input_start = pending_navigation_info_->input_start;
pending_navigation_info_.reset(nullptr);
- BeginNavigation(info);
+ BeginNavigation(info, std::move(navigation_initiator_handle));
}
- DocumentState* document_state =
- DocumentState::FromDocumentLoader(document_loader);
- NavigationStateImpl* navigation_state = static_cast<NavigationStateImpl*>(
- document_state->navigation_state());
- bool is_top_most = !frame_->Parent();
- if (is_top_most) {
- auto navigation_gesture =
- WebUserGestureIndicator::IsProcessingUserGesture(frame_)
- ? NavigationGestureUser
- : NavigationGestureAuto;
- render_view_->set_navigation_gesture(navigation_gesture);
- } else if (document_loader->ReplacesCurrentHistoryItem()) {
- // Subframe navigations that don't add session history items must be
- // marked with AUTO_SUBFRAME. See also didFailProvisionalLoad for how we
- // handle loading of error pages.
- navigation_state->set_transition_type(ui::PAGE_TRANSITION_AUTO_SUBFRAME);
- }
-
- base::TimeTicks navigation_start =
- navigation_state->common_params().navigation_start;
- DCHECK(!navigation_start.is_null());
-
- for (auto& observer : observers_)
- observer.DidStartProvisionalLoad(document_loader);
-
- std::vector<GURL> redirect_chain;
- GetRedirectChain(document_loader, &redirect_chain);
-
- Send(new FrameHostMsg_DidStartProvisionalLoad(
- routing_id_, document_loader->GetRequest().Url(), redirect_chain,
- navigation_start));
+ NavigationState* navigation_state =
+ NavigationState::FromDocumentLoader(document_loader);
+ for (auto& observer : observers_) {
+ observer.DidStartProvisionalLoad(document_loader,
+ navigation_state->IsContentInitiated());
+ }
}
void RenderFrameImpl::DidFailProvisionalLoad(
const WebURLError& error,
blink::WebHistoryCommitType commit_type) {
- DidFailProvisionalLoadInternal(error, commit_type, base::nullopt);
+ DidFailProvisionalLoadInternal(error, commit_type, base::nullopt, nullptr,
+ nullptr);
}
void RenderFrameImpl::DidCommitProvisionalLoad(
@@ -4281,10 +4301,8 @@ void RenderFrameImpl::DidCommitProvisionalLoad(
committed_first_load_ = true;
}
- DocumentState* document_state =
- DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
- NavigationStateImpl* navigation_state =
- static_cast<NavigationStateImpl*>(document_state->navigation_state());
+ NavigationState* navigation_state =
+ NavigationState::FromDocumentLoader(frame_->GetDocumentLoader());
DCHECK(!navigation_state->WasWithinSameDocument());
const WebURLResponse& web_url_response =
frame_->GetDocumentLoader()->GetResponse();
@@ -4378,8 +4396,11 @@ void RenderFrameImpl::DidCommitProvisionalLoad(
media_permission_dispatcher_->OnNavigation();
navigation_state->RunCommitNavigationCallback(blink::mojom::CommitResult::Ok);
+
+ ui::PageTransition transition = GetTransitionType(frame_->GetDocumentLoader(),
+ frame_, true /* loading */);
DidCommitNavigationInternal(item, commit_type,
- false /* was_within_same_document */,
+ false /* was_within_same_document */, transition,
std::move(remote_interface_provider_request));
// Record time between receiving the message to commit the navigation until it
@@ -4388,7 +4409,7 @@ void RenderFrameImpl::DidCommitProvisionalLoad(
if (!navigation_state->time_commit_requested().is_null()) {
RecordReadyToCommitUntilCommitHistogram(
base::TimeTicks::Now() - navigation_state->time_commit_requested(),
- navigation_state->GetTransitionType());
+ transition);
}
// If we end up reusing this WebRequest (for example, due to a #ref click),
@@ -4574,6 +4595,8 @@ void RenderFrameImpl::DidHandleOnloadEvents() {
if (!frame_->Parent()) {
Send(new FrameHostMsg_DocumentOnLoadCompleted(routing_id_));
}
+ for (auto& observer : observers_)
+ observer.DidHandleOnloadEvents();
}
void RenderFrameImpl::DidFailLoad(const WebURLError& error,
@@ -4626,28 +4649,17 @@ void RenderFrameImpl::DidFinishSameDocumentNavigation(
TRACE_EVENT1("navigation,rail",
"RenderFrameImpl::didFinishSameDocumentNavigation", "id",
routing_id_);
- DocumentState* document_state =
- DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
-
- // If this was a browser-initiated navigation, then there could be pending
- // navigation params, so use them. Otherwise, just reset the document state
- // here, since if pending navigation params exist they are for some other
- // navigation <https://crbug.com/597239>.
- if (!pending_navigation_params_ || content_initiated) {
- document_state->set_navigation_state(
- NavigationStateImpl::CreateContentInitiated());
- } else {
- DCHECK(
- !pending_navigation_params_->common_params.navigation_start.is_null());
- document_state->set_navigation_state(CreateNavigationStateFromPending());
- pending_navigation_params_.reset();
- }
-
- static_cast<NavigationStateImpl*>(document_state->navigation_state())
- ->set_was_within_same_document(true);
+ InternalDocumentStateData* data =
+ InternalDocumentStateData::FromDocumentLoader(
+ frame_->GetDocumentLoader());
+ if (content_initiated)
+ data->set_navigation_state(NavigationState::CreateContentInitiated());
+ data->navigation_state()->set_was_within_same_document(true);
+ ui::PageTransition transition = GetTransitionType(frame_->GetDocumentLoader(),
+ frame_, true /* loading */);
DidCommitNavigationInternal(item, commit_type,
- true /* was_within_same_document */,
+ true /* was_within_same_document */, transition,
nullptr /* remote_interface_provider_request */);
}
@@ -4780,29 +4792,20 @@ bool RenderFrameImpl::RunModalBeforeUnloadDialog(bool is_reload) {
bool RenderFrameImpl::RunFileChooser(
const blink::WebFileChooserParams& params,
blink::WebFileChooserCompletion* chooser_completion) {
- FileChooserParams ipc_params;
- if (params.directory)
- ipc_params.mode = FileChooserParams::UploadFolder;
- else if (params.multi_select)
- ipc_params.mode = FileChooserParams::OpenMultiple;
- else if (params.save_as)
- ipc_params.mode = FileChooserParams::Save;
- else
- ipc_params.mode = FileChooserParams::Open;
+ blink::mojom::FileChooserParams ipc_params;
+ ipc_params.mode = params.mode;
ipc_params.title = params.title.Utf16();
ipc_params.accept_types.reserve(params.accept_types.size());
for (const auto& type : params.accept_types)
ipc_params.accept_types.push_back(type.Utf16());
ipc_params.need_local_path = params.need_local_path;
-#if defined(OS_ANDROID)
- ipc_params.capture = params.use_media_capture;
-#endif
+ ipc_params.use_media_capture = params.use_media_capture;
ipc_params.requestor = params.requestor;
return RunFileChooser(ipc_params, chooser_completion);
}
bool RenderFrameImpl::RunFileChooser(
- const FileChooserParams& params,
+ const blink::mojom::FileChooserParams& params,
blink::WebFileChooserCompletion* chooser_completion) {
// Do not open the file dialog in a hidden RenderFrame.
if (IsHidden())
@@ -4874,11 +4877,11 @@ void RenderFrameImpl::FrameRectsChanged(const blink::WebRect& frame_rect) {
}
void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request) {
- if (request.GetFrameType() !=
- network::mojom::RequestContextFrameType::kNone &&
- pending_navigation_params_) {
- // Skip the processing for the main resource, it has been done before
- // sending the request to the browser.
+ if (committing_main_request_ &&
+ request.GetFrameType() !=
+ network::mojom::RequestContextFrameType::kNone) {
+ // We should not process this request, as it was already processed
+ // as part of BeginNavigation.
return;
}
@@ -4891,14 +4894,11 @@ void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request) {
WebDocumentLoader* document_loader = provisional_document_loader
? provisional_document_loader
: frame_->GetDocumentLoader();
- DocumentState* document_state =
- DocumentState::FromDocumentLoader(document_loader);
- DCHECK(document_state);
InternalDocumentStateData* internal_data =
- InternalDocumentStateData::FromDocumentState(document_state);
- NavigationStateImpl* navigation_state =
- static_cast<NavigationStateImpl*>(document_state->navigation_state());
- ui::PageTransition transition_type = navigation_state->GetTransitionType();
+ InternalDocumentStateData::FromDocumentLoader(document_loader);
+ NavigationState* navigation_state = internal_data->navigation_state();
+ ui::PageTransition transition_type =
+ GetTransitionType(document_loader, frame_, false /* loading */);
if (provisional_document_loader &&
provisional_document_loader->IsClientRedirect()) {
transition_type = ui::PageTransitionFromInt(
@@ -4924,12 +4924,8 @@ void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request) {
// The request's extra data may indicate that we should set a custom user
// agent. This needs to be done here, after WebKit is through with setting the
- // user agent on its own. Similarly, it may indicate that we should set an
- // X-Requested-With header. This must be done here to avoid breaking CORS
- // checks.
- // There may also be a stream url associated with the request.
+ // user agent on its own.
WebString custom_user_agent;
- WebString requested_with;
std::unique_ptr<NavigationResponseOverrideParameters> response_override;
if (request.GetExtraData()) {
RequestExtraData* old_extra_data =
@@ -4942,14 +4938,6 @@ void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request) {
else
request.SetHTTPHeaderField("User-Agent", custom_user_agent);
}
-
- requested_with = old_extra_data->requested_with();
- if (!requested_with.IsNull()) {
- if (requested_with.IsEmpty())
- request.ClearHTTPHeaderField("X-Requested-With");
- else
- request.SetHTTPHeaderField("X-Requested-With", requested_with);
- }
response_override =
old_extra_data->TakeNavigationResponseOverrideOwnership();
}
@@ -4967,7 +4955,6 @@ void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request) {
auto* extra_data = static_cast<RequestExtraData*>(request.GetExtraData());
extra_data->set_visibility_state(VisibilityState());
extra_data->set_custom_user_agent(custom_user_agent);
- extra_data->set_requested_with(requested_with);
extra_data->set_render_frame_id(routing_id_);
extra_data->set_is_main_frame(!parent);
extra_data->set_allow_download(
@@ -5004,6 +4991,7 @@ void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request) {
// in the request lifetime, in LocalFrame::MaybeAllowImagePlaceholder(),
// so don't add the Client Lo-Fi bit to the request here.
request_previews_state &= ~(WebURLRequest::kClientLoFiOn);
+ request_previews_state &= ~(WebURLRequest::kLazyImageLoadDeferred);
if (request_previews_state == WebURLRequest::kPreviewsUnspecified)
request_previews_state = WebURLRequest::kPreviewsOff;
@@ -5353,8 +5341,15 @@ bool RenderFrameImpl::AllowContentInitiatedDataUrlNavigations(
}
void RenderFrameImpl::PostAccessibilityEvent(const blink::WebAXObject& obj,
- blink::WebAXEvent event) {
- HandleWebAccessibilityEvent(obj, event);
+ ax::mojom::Event event) {
+ if (render_accessibility_)
+ render_accessibility_->HandleWebAccessibilityEvent(obj, event);
+}
+
+void RenderFrameImpl::MarkWebAXObjectDirty(const blink::WebAXObject& obj,
+ bool subtree) {
+ if (render_accessibility_)
+ render_accessibility_->MarkWebAXObjectDirty(obj, subtree);
}
void RenderFrameImpl::HandleAccessibilityFindInPageResult(
@@ -5508,17 +5503,16 @@ const RenderFrameImpl* RenderFrameImpl::GetLocalRoot() const {
std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
RenderFrameImpl::MakeDidCommitProvisionalLoadParams(
- blink::WebHistoryCommitType commit_type) {
+ blink::WebHistoryCommitType commit_type,
+ ui::PageTransition transition) {
WebDocumentLoader* document_loader = frame_->GetDocumentLoader();
const WebURLRequest& request = document_loader->GetRequest();
const WebURLResponse& response = document_loader->GetResponse();
- DocumentState* document_state =
- DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
- NavigationStateImpl* navigation_state =
- static_cast<NavigationStateImpl*>(document_state->navigation_state());
InternalDocumentStateData* internal_data =
- InternalDocumentStateData::FromDocumentState(document_state);
+ InternalDocumentStateData::FromDocumentLoader(
+ frame_->GetDocumentLoader());
+ NavigationState* navigation_state = internal_data->navigation_state();
std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params =
std::make_unique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
@@ -5574,11 +5568,8 @@ RenderFrameImpl::MakeDidCommitProvisionalLoadParams(
params->should_update_history =
!document_loader->HasUnreachableURL() && response.HttpStatusCode() != 404;
- params->searchable_form_url = internal_data->searchable_form_url();
- params->searchable_form_encoding = internal_data->searchable_form_encoding();
-
- params->gesture = render_view_->navigation_gesture_;
- render_view_->navigation_gesture_ = NavigationGestureUnknown;
+ params->gesture = document_loader->HadUserGesture() ? NavigationGestureUser
+ : NavigationGestureAuto;
// Make navigation state a part of the DidCommitProvisionalLoad message so
// that committed entry has it at all times. Send a single HistoryItem for
@@ -5614,7 +5605,7 @@ RenderFrameImpl::MakeDidCommitProvisionalLoadParams(
params->contents_mime_type =
document_loader->GetResponse().MimeType().Utf8();
- params->transition = navigation_state->GetTransitionType();
+ params->transition = transition;
DCHECK(ui::PageTransitionIsMainFrame(params->transition));
// If the page contained a client redirect (meta refresh, document.loc...),
@@ -5652,7 +5643,7 @@ RenderFrameImpl::MakeDidCommitProvisionalLoadParams(
// Standard URLs must match the reported origin, when it is not unique.
// This check is very similar to RenderFrameHostImpl::CanCommitOrigin, but
// adapted to the renderer process side.
- if (!params->origin.unique() && params->url.IsStandard() &&
+ if (!params->origin.opaque() && params->url.IsStandard() &&
render_view_->GetWebkitPreferences().web_security_enabled) {
// Exclude file: URLs when settings allow them access any origin.
if (params->origin.scheme() != url::kFileScheme ||
@@ -5662,10 +5653,7 @@ RenderFrameImpl::MakeDidCommitProvisionalLoadParams(
<< " url:" << params->url << " origin:" << params->origin;
}
}
-
- WebURLResponseExtraDataImpl* extra_data = GetExtraDataFromResponse(response);
- if (extra_data)
- params->request_id = extra_data->request_id();
+ params->request_id = response.RequestId();
return params;
}
@@ -5681,8 +5669,7 @@ void RenderFrameImpl::UpdateZoomLevel() {
// Set zoom level, but don't do it for full-page plugin since they don't use
// the same zoom settings.
- HostZoomLevels::iterator host_zoom =
- host_zoom_levels_.find(GetLoadingUrl());
+ auto host_zoom = host_zoom_levels_.find(GetLoadingUrl());
if (render_view_->webview()->MainFrame()->IsWebLocalFrame() &&
render_view_->webview()
->MainFrame()
@@ -5713,10 +5700,8 @@ void RenderFrameImpl::UpdateZoomLevel() {
bool RenderFrameImpl::UpdateNavigationHistory(
const blink::WebHistoryItem& item,
blink::WebHistoryCommitType commit_type) {
- DocumentState* document_state =
- DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
- NavigationStateImpl* navigation_state =
- static_cast<NavigationStateImpl*>(document_state->navigation_state());
+ NavigationState* navigation_state =
+ NavigationState::FromDocumentLoader(frame_->GetDocumentLoader());
const RequestNavigationParams& request_params =
navigation_state->request_params();
@@ -5754,31 +5739,32 @@ bool RenderFrameImpl::UpdateNavigationHistory(
return is_new_navigation;
}
-void RenderFrameImpl::NotifyObserversOfNavigationCommit(bool is_new_navigation,
- bool is_same_document) {
+void RenderFrameImpl::NotifyObserversOfNavigationCommit(
+ bool is_new_navigation,
+ bool is_same_document,
+ ui::PageTransition transition) {
for (auto& observer : render_view_->observers_)
observer.DidCommitProvisionalLoad(frame_, is_new_navigation);
for (auto& observer : observers_)
- observer.DidCommitProvisionalLoad(is_new_navigation, is_same_document);
+ observer.DidCommitProvisionalLoad(is_same_document, transition);
}
void RenderFrameImpl::UpdateStateForCommit(
const blink::WebHistoryItem& item,
- blink::WebHistoryCommitType commit_type) {
- DocumentState* document_state =
- DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
- NavigationStateImpl* navigation_state =
- static_cast<NavigationStateImpl*>(document_state->navigation_state());
+ blink::WebHistoryCommitType commit_type,
+ ui::PageTransition transition) {
InternalDocumentStateData* internal_data =
- InternalDocumentStateData::FromDocumentState(document_state);
+ InternalDocumentStateData::FromDocumentLoader(
+ frame_->GetDocumentLoader());
+ NavigationState* navigation_state = internal_data->navigation_state();
// We need to update the last committed session history entry with state for
// the previous page. Do this before updating the current history item.
SendUpdateState();
bool is_new_navigation = UpdateNavigationHistory(item, commit_type);
- NotifyObserversOfNavigationCommit(is_new_navigation,
- navigation_state->WasWithinSameDocument());
+ NotifyObserversOfNavigationCommit(
+ is_new_navigation, navigation_state->WasWithinSameDocument(), transition);
if (internal_data->must_reset_scroll_and_scale_state()) {
render_view_->webview()->ResetScrollAndScaleState();
@@ -5801,13 +5787,6 @@ void RenderFrameImpl::UpdateStateForCommit(
// new navigation.
navigation_state->set_request_committed(true);
- // Set the correct engagement level on the frame, and wipe the cached origin
- // so this will not be reused accidentally.
- if (url::Origin(frame_->GetSecurityOrigin()) == engagement_level_.first) {
- frame_->SetEngagementLevel(engagement_level_.second);
- engagement_level_.first = url::Origin();
- }
-
// If we are a top frame navigation to another document we should clear any
// existing autoplay flags on the Page. This is because flags are stored at
// the page level so subframes would only add to them.
@@ -5827,11 +5806,12 @@ void RenderFrameImpl::DidCommitNavigationInternal(
const blink::WebHistoryItem& item,
blink::WebHistoryCommitType commit_type,
bool was_within_same_document,
+ ui::PageTransition transition,
service_manager::mojom::InterfaceProviderRequest
remote_interface_provider_request) {
DCHECK(!(was_within_same_document &&
remote_interface_provider_request.is_pending()));
- UpdateStateForCommit(item, commit_type);
+ UpdateStateForCommit(item, commit_type, transition);
// This invocation must precede any calls to allowScripts(), allowImages(), or
// allowPlugins() for the new page. This ensures that when these functions
@@ -5839,10 +5819,10 @@ void RenderFrameImpl::DidCommitNavigationInternal(
// process has already been informed of the provisional load committing.
if (was_within_same_document) {
GetFrameHost()->DidCommitSameDocumentNavigation(
- MakeDidCommitProvisionalLoadParams(commit_type));
+ MakeDidCommitProvisionalLoadParams(commit_type, transition));
} else {
GetFrameHost()->DidCommitProvisionalLoad(
- MakeDidCommitProvisionalLoadParams(commit_type),
+ MakeDidCommitProvisionalLoadParams(commit_type, transition),
std::move(remote_interface_provider_request));
}
}
@@ -5942,16 +5922,12 @@ bool RenderFrameImpl::SwapIn() {
// If this is the main frame going from a remote frame to a local frame,
// it needs to set RenderViewImpl's pointer for the main frame to itself,
- // ensure RenderWidget is no longer in swapped out mode, and call
- // AddRefProcess() to prevent the process from exiting. A matching
- // ReleaseProcess() call will be made if the RenderWidget ever becomes
- // swapped out again - see OnSwapOut().
+ // ensure RenderWidget is no longer in swapped out mode.
if (is_main_frame_) {
CHECK(!render_view_->main_render_frame_);
render_view_->main_render_frame_ = this;
if (render_view_->is_swapped_out()) {
render_view_->SetSwappedOut(false);
- RenderProcess::current()->AddRefProcess();
}
render_view_->UpdateWebViewWithDeviceScaleFactor();
}
@@ -5959,16 +5935,10 @@ bool RenderFrameImpl::SwapIn() {
return true;
}
-void RenderFrameImpl::DidStartLoading(bool to_different_document) {
+void RenderFrameImpl::DidStartLoading() {
+ // TODO(dgozman): consider removing this callback.
TRACE_EVENT1("navigation,rail", "RenderFrameImpl::didStartLoading",
"id", routing_id_);
- render_view_->FrameDidStartLoading(frame_);
-
- // The browser is responsible for knowing the start of all non-synchronous
- // navigations.
- // TODO(clamy): Remove this IPC.
- if (!to_different_document)
- Send(new FrameHostMsg_DidStartLoading(routing_id_, to_different_document));
}
void RenderFrameImpl::DidStopLoading() {
@@ -5982,7 +5952,6 @@ void RenderFrameImpl::DidStopLoading() {
SendUpdateFaviconURL();
- render_view_->FrameDidStopLoading(frame_);
Send(new FrameHostMsg_DidStopLoading(routing_id_));
}
@@ -5990,12 +5959,6 @@ void RenderFrameImpl::DidChangeLoadProgress(double load_progress) {
Send(new FrameHostMsg_DidChangeLoadProgress(routing_id_, load_progress));
}
-void RenderFrameImpl::HandleWebAccessibilityEvent(
- const blink::WebAXObject& obj, blink::WebAXEvent event) {
- if (render_accessibility_)
- render_accessibility_->HandleWebAccessibilityEvent(obj, event);
-}
-
void RenderFrameImpl::FocusedNodeChanged(const WebNode& node) {
has_scrolled_focused_editable_node_into_rect_ = false;
bool is_editable = false;
@@ -6086,8 +6049,11 @@ WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
// navigation.
if (!info.is_client_redirect) {
OpenURL(info, /*is_history_navigation_in_new_child=*/true);
- // Suppress the load in Blink but mark the frame as loading.
- return blink::kWebNavigationPolicyHandledByClientForInitialHistory;
+ // TODO(japhet): This case wants to flag the frame as loading and do
+ // nothing else. It'd be nice if it could go through the placeholder
+ // DocumentLoader path, too.
+ frame_->MarkAsLoading();
+ return blink::kWebNavigationPolicyIgnore;
} else {
// Client redirects during an initial history load should attempt to
// cancel the history navigation. They will create a provisional
@@ -6201,13 +6167,6 @@ WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
!weak_self) {
return blink::kWebNavigationPolicyIgnore;
}
-
- // |navigation_start| must be recorded immediately after dispatching the
- // beforeunload event.
- if (pending_navigation_params_) {
- pending_navigation_params_->common_params.navigation_start =
- base::TimeTicks::Now();
- }
}
// When an MHTML Archive is present, it should be used to serve iframe content
@@ -6217,6 +6176,10 @@ WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
!url.SchemeIs(url::kDataScheme);
if (info.default_policy == blink::kWebNavigationPolicyCurrentTab) {
+ if (!info.form.IsNull()) {
+ for (auto& observer : observers_)
+ observer.WillSubmitForm(info.form);
+ }
// If the navigation is not synchronous, send it to the browser. This
// includes navigations with no request being sent to the network stack.
if (!use_archive && IsURLHandledByNetworkStack(url)) {
@@ -6360,10 +6323,12 @@ void RenderFrameImpl::OnWriteMHTMLToDiskComplete(
main_thread_use_time));
}
+#ifndef STATIC_ASSERT_ENUM
#define STATIC_ASSERT_ENUM(a, b) \
static_assert(static_cast<int>(a) == static_cast<int>(b), \
"mismatching enums: " #a)
#undef STATIC_ASSERT_ENUM
+#endif
void RenderFrameImpl::OnEnableViewSourceMode() {
DCHECK(frame_);
@@ -6376,7 +6341,7 @@ void RenderFrameImpl::OnSuppressFurtherDialogs() {
}
void RenderFrameImpl::OnFileChooserResponse(
- const std::vector<content::FileChooserFileInfo>& files) {
+ const std::vector<blink::mojom::FileChooserFileInfoPtr>& files) {
// This could happen if we navigated to a different page before the user
// closed the chooser.
if (!file_chooser_completion_)
@@ -6388,23 +6353,23 @@ void RenderFrameImpl::OnFileChooserResponse(
size_t current_size = 0;
for (size_t i = 0; i < files.size(); ++i) {
blink::WebFileChooserCompletion::SelectedFileInfo selected_file;
- selected_file.path = blink::FilePathToWebString(files[i].file_path);
+ if (files[i]->is_file_system()) {
+ auto& fs_info = *files[i]->get_file_system();
+ selected_file.file_system_url = fs_info.url;
+ selected_file.length = fs_info.length;
+ selected_file.modification_time = fs_info.modification_time;
+ } else {
+ selected_file.file_path = files[i]->get_native_file()->file_path;
- // Exclude files whose paths can't be converted into WebStrings. Blink won't
- // be able to handle these, and the browser process would kill the renderer
- // when it claims to have chosen an empty file path.
- if (selected_file.path.IsEmpty())
- continue;
+ // Exclude files whose paths can't be converted into WebStrings. Blink
+ // won't be able to handle these, and the browser process would kill the
+ // renderer when it claims to have chosen an empty file path.
+ if (blink::FilePathToWebString(selected_file.file_path).IsEmpty())
+ continue;
- selected_file.display_name =
- blink::FilePathToWebString(base::FilePath(files[i].display_name));
- if (files[i].file_system_url.is_valid()) {
- selected_file.file_system_url = files[i].file_system_url;
- selected_file.length = files[i].length;
- selected_file.modification_time = files[i].modification_time.ToDoubleT();
- selected_file.is_directory = files[i].is_directory;
+ selected_file.display_name =
+ WebString::FromUTF16(files[i]->get_native_file()->display_name);
}
-
selected_files[current_size] = selected_file;
current_size++;
}
@@ -6438,7 +6403,7 @@ void RenderFrameImpl::OnMixedContentFound(
source_location.url = WebString::FromLatin1(params.source_location.url);
source_location.line_number = params.source_location.line_number;
source_location.column_number = params.source_location.column_number;
- auto request_context = static_cast<blink::WebURLRequest::RequestContext>(
+ auto request_context = static_cast<blink::mojom::RequestContextType>(
params.request_context_type);
frame_->MixedContentFound(params.main_resource_url, params.mixed_content_url,
request_context, params.was_allowed,
@@ -6523,23 +6488,16 @@ void RenderFrameImpl::OpenURL(const NavigationPolicyInfo& info,
params.triggering_event_info = info.triggering_event_info;
params.blob_url_token =
CloneBlobURLToken(info.blob_url_token.get()).PassHandle().release();
-
- if (IsBrowserInitiated(pending_navigation_params_.get())) {
- // This is necessary to preserve the should_replace_current_entry value on
- // cross-process redirects, in the event it was set by a previous process.
- WebDocumentLoader* document_loader = frame_->GetProvisionalDocumentLoader();
- DCHECK(document_loader);
- params.should_replace_current_entry =
- document_loader->ReplacesCurrentHistoryItem();
- } else {
- params.should_replace_current_entry = info.replaces_current_history_item &&
- render_view_->history_list_length_;
- }
- params.user_gesture =
- WebUserGestureIndicator::IsProcessingUserGesture(frame_);
+ params.should_replace_current_entry =
+ info.replaces_current_history_item && render_view_->history_list_length_;
+ params.user_gesture = info.has_user_gesture;
if (GetContentClient()->renderer()->AllowPopup())
params.user_gesture = true;
+ // TODO(csharrison,dgozman): FrameLoader::StartNavigation already consumes for
+ // all main frame navigations, except in the case where page A is navigating
+ // page B (e.g. using anchor targets). This edge case can go away when
+ // UserActivationV2 ships, which would make the conditional below redundant.
if (is_main_frame_ || policy == blink::kWebNavigationPolicyNewBackgroundTab ||
policy == blink::kWebNavigationPolicyNewForegroundTab ||
policy == blink::kWebNavigationPolicyNewWindow ||
@@ -6575,6 +6533,9 @@ WebURLRequest RenderFrameImpl::CreateURLRequestForCommit(
request.SetFrameType(IsTopLevelNavigation(frame_)
? network::mojom::RequestContextFrameType::kTopLevel
: network::mojom::RequestContextFrameType::kNested);
+ request.SetRequestorID(render_view_->GetRoutingID());
+ static_cast<RequestExtraData*>(request.GetExtraData())
+ ->set_render_frame_id(routing_id_);
#if defined(OS_ANDROID)
request.SetHasUserGesture(common_params.has_user_gesture);
@@ -6598,7 +6559,8 @@ ChildURLLoaderFactoryBundle* RenderFrameImpl::GetLoaderFactoryBundle() {
std::move(bundle_info));
} else {
SetupLoaderFactoryBundle(nullptr,
- base::nullopt /* subresource_overrides */);
+ base::nullopt /* subresource_overrides */,
+ nullptr /* prefetch_loader_factory */);
}
}
return loader_factories_.get();
@@ -6607,7 +6569,8 @@ ChildURLLoaderFactoryBundle* RenderFrameImpl::GetLoaderFactoryBundle() {
void RenderFrameImpl::SetupLoaderFactoryBundle(
std::unique_ptr<URLLoaderFactoryBundleInfo> info,
base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
- subresource_overrides) {
+ subresource_overrides,
+ network::mojom::URLLoaderFactoryPtr prefetch_loader_factory) {
RenderThreadImpl* render_thread = RenderThreadImpl::current();
loader_factories_ = base::MakeRefCounted<HostChildURLLoaderFactoryBundle>(
@@ -6626,6 +6589,10 @@ void RenderFrameImpl::SetupLoaderFactoryBundle(
std::make_unique<ChildURLLoaderFactoryBundleInfo>(std::move(info)),
std::move(subresource_overrides));
}
+ if (prefetch_loader_factory) {
+ loader_factories_->SetPrefetchLoaderFactory(
+ std::move(prefetch_loader_factory));
+ }
}
void RenderFrameImpl::UpdateEncoding(WebFrame* frame,
@@ -6779,7 +6746,9 @@ std::unique_ptr<base::DictionaryValue> GetDevToolsInitiator(
}
} // namespace
-void RenderFrameImpl::BeginNavigation(const NavigationPolicyInfo& info) {
+void RenderFrameImpl::BeginNavigation(
+ const NavigationPolicyInfo& info,
+ mojo::ScopedMessagePipeHandle navigation_initiator_handle) {
browser_side_navigation_pending_ = true;
browser_side_navigation_pending_url_ = info.url_request.Url();
@@ -6873,24 +6842,25 @@ void RenderFrameImpl::BeginNavigation(const NavigationPolicyInfo& info) {
mojom::NavigationClientAssociatedPtrInfo navigation_client_info;
if (IsPerNavigationMojoInterfaceEnabled()) {
WebDocumentLoader* document_loader = frame_->GetProvisionalDocumentLoader();
- DocumentState* document_state =
- DocumentState::FromDocumentLoader(document_loader);
- NavigationStateImpl* navigation_state =
- static_cast<NavigationStateImpl*>(document_state->navigation_state());
-
+ NavigationState* navigation_state =
+ NavigationState::FromDocumentLoader(document_loader);
BindNavigationClient(mojo::MakeRequest(&navigation_client_info));
navigation_state->set_navigation_client(std::move(navigation_client_impl_));
}
+
+ blink::mojom::NavigationInitiatorPtr initiator_ptr(
+ blink::mojom::NavigationInitiatorPtrInfo(
+ std::move(navigation_initiator_handle), 0));
+
GetFrameHost()->BeginNavigation(
MakeCommonNavigationParams(info, load_flags, info.input_start),
std::move(begin_navigation_params), std::move(blob_url_token),
- std::move(navigation_client_info));
+ std::move(navigation_client_info), std::move(initiator_ptr));
}
void RenderFrameImpl::LoadDataURL(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
- WebLocalFrame* frame,
blink::WebFrameLoadType load_type,
blink::WebHistoryItem item_for_history_navigation,
bool is_client_redirect,
@@ -6917,14 +6887,12 @@ void RenderFrameImpl::LoadDataURL(
const GURL base_url = common_params.base_url_for_data_url.is_empty()
? common_params.url
: common_params.base_url_for_data_url;
- bool replace = load_type == WebFrameLoadType::kReloadBypassingCache ||
- load_type == WebFrameLoadType::kReload;
- frame->CommitDataNavigation(
- WebData(data.c_str(), data.length()), WebString::FromUTF8(mime_type),
- WebString::FromUTF8(charset), base_url,
+ frame_->CommitDataNavigation(
+ WebURLRequest(base_url), WebData(data.c_str(), data.length()),
+ WebString::FromUTF8(mime_type), WebString::FromUTF8(charset),
// Needed so that history-url-only changes don't become reloads.
- common_params.history_url_for_data_url, replace, load_type,
+ common_params.history_url_for_data_url, load_type,
item_for_history_navigation, is_client_redirect,
BuildNavigationParams(
common_params, request_params,
@@ -6996,27 +6964,9 @@ GURL RenderFrameImpl::GetLoadingUrl() const {
return request.Url();
}
-
-NavigationState* RenderFrameImpl::CreateNavigationStateFromPending() {
- if (IsBrowserInitiated(pending_navigation_params_.get())) {
- return NavigationStateImpl::CreateBrowserInitiated(
- pending_navigation_params_->common_params,
- pending_navigation_params_->request_params,
- pending_navigation_params_->time_commit_requested,
- std::move(pending_navigation_params_->commit_callback_));
- }
- return NavigationStateImpl::CreateContentInitiated();
-}
-
media::MediaPermission* RenderFrameImpl::GetMediaPermission() {
- if (!media_permission_dispatcher_) {
- media_permission_dispatcher_.reset(new MediaPermissionDispatcher(
- base::Bind(
- &RenderFrameImpl::GetInterface<blink::mojom::PermissionService>,
- base::Unretained(this)),
- base::Bind(&RenderFrameImpl::IsEncryptedMediaEnabled,
- base::Unretained(this))));
- }
+ if (!media_permission_dispatcher_)
+ media_permission_dispatcher_.reset(new MediaPermissionDispatcher(this));
return media_permission_dispatcher_.get();
}
@@ -7058,9 +7008,6 @@ void RenderFrameImpl::HandlePepperImeCommit(const base::string16& text) {
#endif // ENABLE_PLUGINS
void RenderFrameImpl::RegisterMojoInterfaces() {
- GetAssociatedInterfaceRegistry()->AddInterface(
- base::Bind(&RenderFrameImpl::BindEngagement, weak_factory_.GetWeakPtr()));
-
GetAssociatedInterfaceRegistry()->AddInterface(base::Bind(
&RenderFrameImpl::BindAutoplayConfiguration, weak_factory_.GetWeakPtr()));
@@ -7105,15 +7052,6 @@ void RenderFrameImpl::RegisterMojoInterfaces() {
}
}
-template <typename Interface>
-void RenderFrameImpl::GetInterface(mojo::InterfaceRequest<Interface> request) {
- GetRemoteInterfaces()->GetInterface(std::move(request));
-}
-
-bool RenderFrameImpl::IsEncryptedMediaEnabled() const {
- return GetRendererPreferences().enable_encrypted_media;
-}
-
void RenderFrameImpl::OnHostZoomClientRequest(
mojom::HostZoomAssociatedRequest request) {
DCHECK(!host_zoom_binding_.is_bound());
diff --git a/chromium/content/renderer/render_frame_impl.h b/chromium/content/renderer/render_frame_impl.h
index 4f8775b0d90..db6a10d6020 100644
--- a/chromium/content/renderer/render_frame_impl.h
+++ b/chromium/content/renderer/render_frame_impl.h
@@ -45,9 +45,9 @@
#include "content/public/common/previews_state.h"
#include "content/public/common/referrer.h"
#include "content/public/common/renderer_preferences.h"
-#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "content/public/common/stop_find_action.h"
+#include "content/public/common/widget_type.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/websocket_handshake_throttle_provider.h"
#include "content/renderer/content_security_policy_util.h"
@@ -73,11 +73,12 @@
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
+#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
#include "third_party/blink/public/mojom/manifest/manifest_manager.mojom.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/platform/autoplay.mojom.h"
-#include "third_party/blink/public/platform/site_engagement.mojom.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom.h"
#include "third_party/blink/public/platform/web_effective_connection_type.h"
#include "third_party/blink/public/platform/web_focus_type.h"
#include "third_party/blink/public/platform/web_loading_behavior_flag.h"
@@ -93,7 +94,7 @@
#include "third_party/blink/public/web/web_meaningful_layout.h"
#include "third_party/blink/public/web/web_script_execution_callback.h"
#include "third_party/blink/public/web/web_triggering_event_info.h"
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
#include "ui/gfx/range/range.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -129,6 +130,10 @@ struct WebNavigationParams;
struct WebMediaPlayerAction;
struct WebImeTextSpan;
struct WebScrollIntoViewParams;
+
+namespace mojom {
+class FileChooserParams;
+}
} // namespace blink
namespace gfx {
@@ -141,7 +146,6 @@ class MediaPermission;
}
namespace network {
-class WeakWrapperSharedURLLoaderFactory;
struct ResourceResponseHead;
}
@@ -163,7 +167,6 @@ class HistoryEntry;
class ManifestManager;
class MediaPermissionDispatcher;
class MediaStreamDeviceObserver;
-class NavigationState;
class NavigationClient;
class PepperPluginInstanceImpl;
class PushMessagingClient;
@@ -179,17 +182,13 @@ class UserMediaClientImpl;
struct CSPViolationParams;
struct CommonNavigationParams;
struct CustomContextMenuContext;
-struct FileChooserFileInfo;
-struct FileChooserParams;
struct FrameOwnerProperties;
struct FrameReplicationState;
-struct PendingNavigationParams;
struct RequestNavigationParams;
struct ScreenInfo;
class CONTENT_EXPORT RenderFrameImpl
: public RenderFrame,
- blink::mojom::EngagementClient,
blink::mojom::AutoplayConfigurationClient,
mojom::Frame,
mojom::FrameNavigationControl,
@@ -272,8 +271,25 @@ class CONTENT_EXPORT RenderFrameImpl
};
using CreateRenderFrameImplFunction = RenderFrameImpl* (*)(CreateParams);
+ using CreateRenderWidgetForChildLocalRootFunction =
+ RenderWidget* (*)(int32_t,
+ CompositorDependencies*,
+ WidgetType,
+ const ScreenInfo&,
+ blink::WebDisplayMode display_mode,
+ bool,
+ bool,
+ bool);
+ using RenderWidgetForChildLocalRootInitializedCallback =
+ void (*)(RenderWidget*);
+
+ // LayoutTests override the creation of RenderFrames and RenderWidgets in
+ // order to inject their own (subclass) type and change behaviour inside the
+ // tests.
static void InstallCreateHook(
- CreateRenderFrameImplFunction create_render_frame_impl);
+ CreateRenderFrameImplFunction create_frame,
+ CreateRenderWidgetForChildLocalRootFunction create_widget,
+ RenderWidgetForChildLocalRootInitializedCallback widget_initialized);
// Looks up and returns the WebFrame corresponding to a given opener frame
// routing ID.
@@ -321,9 +337,7 @@ class CONTENT_EXPORT RenderFrameImpl
// TODO(nasko): Those are page-level methods at this time and come from
// WebViewClient. We should move them to be WebLocalFrameClient calls and put
// logic in the browser side to balance starts/stops.
- // |to_different_document| will be true unless the load is a fragment
- // navigation, or triggered by history.pushState/replaceState.
- void DidStartLoading(bool to_different_document) override;
+ void DidStartLoading() override;
void DidStopLoading() override;
void DidChangeLoadProgress(double load_progress) override;
@@ -342,7 +356,7 @@ class CONTENT_EXPORT RenderFrameImpl
bool in_frame_tree() { return in_frame_tree_; }
void HandleWebAccessibilityEvent(const blink::WebAXObject& obj,
- blink::WebAXEvent event);
+ ax::mojom::Event event);
// The focused node changed to |node|. If focus was lost from this frame,
// |node| will be null.
@@ -500,10 +514,6 @@ class CONTENT_EXPORT RenderFrameImpl
void SetAccessibilityModeForTest(ui::AXMode new_mode) override;
scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
- // blink::mojom::EngagementClient implementation:
- void SetEngagementLevel(const url::Origin& origin,
- blink::mojom::EngagementLevel level) override;
-
// blink::mojom::AutoplayConfigurationClient implementation:
void AddAutoplayFlags(const url::Origin& origin,
const int32_t flags) override;
@@ -553,6 +563,9 @@ class CONTENT_EXPORT RenderFrameImpl
void HandleRendererDebugURL(const GURL& url) override;
void UpdateSubresourceLoaderFactories(
std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders) override;
+ void BindDevToolsAgent(
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host,
+ blink::mojom::DevToolsAgentAssociatedRequest request) override;
// mojom::FullscreenVideoElementHandler implementation:
void RequestFullscreenVideoElement() override;
@@ -637,11 +650,12 @@ class CONTENT_EXPORT RenderFrameImpl
blink::WebNavigationPolicy DecidePolicyForNavigation(
const NavigationPolicyInfo& info) override;
void WillSendSubmitEvent(const blink::WebFormElement& form) override;
- void WillSubmitForm(const blink::WebFormElement& form) override;
void DidCreateDocumentLoader(
blink::WebDocumentLoader* document_loader) override;
- void DidStartProvisionalLoad(blink::WebDocumentLoader* document_loader,
- blink::WebURLRequest& request) override;
+ void DidStartProvisionalLoad(
+ blink::WebDocumentLoader* document_loader,
+ blink::WebURLRequest& request,
+ mojo::ScopedMessagePipeHandle navigation_initiator_handle) override;
void DidFailProvisionalLoad(const blink::WebURLError& error,
blink::WebHistoryCommitType commit_type) override;
void DidCommitProvisionalLoad(
@@ -729,7 +743,9 @@ class CONTENT_EXPORT RenderFrameImpl
bool AllowContentInitiatedDataUrlNavigations(
const blink::WebURL& url) override;
void PostAccessibilityEvent(const blink::WebAXObject& obj,
- blink::WebAXEvent event) override;
+ ax::mojom::Event event) override;
+ void MarkWebAXObjectDirty(const blink::WebAXObject& obj,
+ bool subtree) override;
void HandleAccessibilityFindInPageResult(int identifier,
int match_index,
const blink::WebNode& start_node,
@@ -770,9 +786,6 @@ class CONTENT_EXPORT RenderFrameImpl
blink::WebFrameSerializerClient::FrameSerializationStatus status)
override;
- // Binds to the site engagement service in the browser.
- void BindEngagement(blink::mojom::EngagementClientAssociatedRequest request);
-
// Binds to the fullscreen service in the browser.
void BindFullscreen(
mojom::FullscreenVideoElementHandlerAssociatedRequest request);
@@ -811,7 +824,7 @@ class CONTENT_EXPORT RenderFrameImpl
// Another RunFileChooser() for content::FileChooserParams.
// Returns true if the chooser was successfully requested. False means we
// didn't request anything.
- bool RunFileChooser(const FileChooserParams& params,
+ bool RunFileChooser(const blink::mojom::FileChooserParams& params,
blink::WebFileChooserCompletion* completion);
// Internal version of DidFailProvisionalLoad() that allows specifying
@@ -819,7 +832,11 @@ class CONTENT_EXPORT RenderFrameImpl
void DidFailProvisionalLoadInternal(
const blink::WebURLError& error,
blink::WebHistoryCommitType commit_type,
- const base::Optional<std::string>& error_page_content);
+ const base::Optional<std::string>& error_page_content,
+ std::unique_ptr<blink::WebNavigationParams> navigation_params,
+ std::unique_ptr<blink::WebDocumentLoader::ExtraData> document_state);
+
+ void NotifyObserversOfFailedProvisionalLoad(const blink::WebURLError& error);
bool handling_select_range() const { return handling_select_range_; }
@@ -963,8 +980,6 @@ class CONTENT_EXPORT RenderFrameImpl
class FrameURLLoaderFactory;
typedef std::map<GURL, double> HostZoomLevels;
- typedef std::pair<url::Origin, blink::mojom::EngagementLevel>
- EngagementOriginAndLevel;
// Creates a new RenderFrame. |render_view| is the RenderView object that this
// frame belongs to, and |interface_provider| is the RenderFrameHost's
@@ -1051,7 +1066,7 @@ class CONTENT_EXPORT RenderFrameImpl
void OnEnableViewSourceMode();
void OnSuppressFurtherDialogs();
void OnFileChooserResponse(
- const std::vector<content::FileChooserFileInfo>& files);
+ const std::vector<blink::mojom::FileChooserFileInfoPtr>& files);
void OnClearFocusedElement();
void OnBlinkFeatureUsageReport(const std::set<int>& features);
void OnMixedContentFound(const FrameMsg_MixedContentFound_Params& params);
@@ -1104,7 +1119,8 @@ class CONTENT_EXPORT RenderFrameImpl
void SetupLoaderFactoryBundle(
std::unique_ptr<URLLoaderFactoryBundleInfo> info,
base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
- subresource_overrides);
+ subresource_overrides,
+ network::mojom::URLLoaderFactoryPtr prefetch_loader_factory);
// Update current main frame's encoding and send it to browser window.
// Since we want to let users see the right encoding info from menu
@@ -1170,13 +1186,14 @@ class CONTENT_EXPORT RenderFrameImpl
const RequestNavigationParams& request_params);
// Sends a FrameHostMsg_BeginNavigation to the browser
- void BeginNavigation(const NavigationPolicyInfo& info);
+ void BeginNavigation(
+ const NavigationPolicyInfo& info,
+ mojo::ScopedMessagePipeHandle navigation_initiator_handle);
// Loads a data url.
void LoadDataURL(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
- blink::WebLocalFrame* frame,
blink::WebFrameLoadType load_type,
blink::WebHistoryItem item_for_history_navigation,
bool is_client_redirect,
@@ -1194,20 +1211,12 @@ class CONTENT_EXPORT RenderFrameImpl
// Returns the URL being loaded by the |frame_|'s request.
GURL GetLoadingUrl() const;
- // Returns a new NavigationState populated with the navigation information
- // saved in OnNavigate().
- NavigationState* CreateNavigationStateFromPending();
-
#if BUILDFLAG(ENABLE_PLUGINS)
void HandlePepperImeCommit(const base::string16& text);
#endif // ENABLE_PLUGINS
void RegisterMojoInterfaces();
- // Connect to an interface provided by the service registry.
- template <typename Interface>
- void GetInterface(mojo::InterfaceRequest<Interface> request);
-
void OnHostZoomClientRequest(mojom::HostZoomAssociatedRequest request);
void InitializeBlameContext(RenderFrameImpl* parent_frame);
@@ -1216,11 +1225,6 @@ class CONTENT_EXPORT RenderFrameImpl
void GetInterface(const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override;
- // Whether to allow the use of Encrypted Media Extensions (EME), except for
- // the use of Clear Key key systems, which is always allowed as required by
- // the spec.
- bool IsEncryptedMediaEnabled() const;
-
// Send |callback| our AndroidOverlay routing token when it arrives. We may
// call |callback| before returning.
void RequestOverlayRoutingToken(media::RoutingTokenCallback callback);
@@ -1239,7 +1243,8 @@ class CONTENT_EXPORT RenderFrameImpl
// Build DidCommitProvisionalLoad_Params based on the frame internal state.
std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
- MakeDidCommitProvisionalLoadParams(blink::WebHistoryCommitType commit_type);
+ MakeDidCommitProvisionalLoadParams(blink::WebHistoryCommitType commit_type,
+ ui::PageTransition transition);
// Updates the Zoom level of the render view to match current content.
void UpdateZoomLevel();
@@ -1253,12 +1258,14 @@ class CONTENT_EXPORT RenderFrameImpl
// Notify render_view_ observers that a commit happened.
void NotifyObserversOfNavigationCommit(bool is_new_navigation,
- bool is_same_document);
+ bool is_same_document,
+ ui::PageTransition transition);
// Updates the internal state following a navigation commit. This should be
// called before notifying the FrameHost of the commit.
void UpdateStateForCommit(const blink::WebHistoryItem& item,
- blink::WebHistoryCommitType commit_type);
+ blink::WebHistoryCommitType commit_type,
+ ui::PageTransition transition);
// Internal function used by same document navigation as well as cross
// document navigation that updates the state of the RenderFrameImpl and sends
@@ -1267,6 +1274,7 @@ class CONTENT_EXPORT RenderFrameImpl
const blink::WebHistoryItem& item,
blink::WebHistoryCommitType commit_type,
bool was_within_same_document,
+ ui::PageTransition transition,
service_manager::mojom::InterfaceProviderRequest
remote_interface_provider_request);
@@ -1389,11 +1397,6 @@ class CONTENT_EXPORT RenderFrameImpl
// parent that is a local frame.
scoped_refptr<RenderWidget> render_widget_;
- // Temporarily holds state pertaining to a navigation that has been initiated
- // until the NavigationState corresponding to the new navigation is created in
- // DidCreateDocumentLoader().
- std::unique_ptr<PendingNavigationParams> pending_navigation_params_;
-
// Keeps track of which future subframes the browser process has history items
// for during a history navigation, as well as whether those items are for
// about:blank. The renderer process should ask the browser for history items
@@ -1538,12 +1541,10 @@ class CONTENT_EXPORT RenderFrameImpl
#endif
HostZoomLevels host_zoom_levels_;
- EngagementOriginAndLevel engagement_level_;
using AutoplayOriginAndFlags = std::pair<url::Origin, int32_t>;
AutoplayOriginAndFlags autoplay_flags_;
- mojo::AssociatedBinding<blink::mojom::EngagementClient> engagement_binding_;
mojo::AssociatedBinding<blink::mojom::AutoplayConfigurationClient>
autoplay_configuration_binding_;
mojo::Binding<mojom::Frame> frame_binding_;
@@ -1611,12 +1612,6 @@ class CONTENT_EXPORT RenderFrameImpl
mojo::BindingSet<service_manager::mojom::InterfaceProvider>
interface_provider_bindings_;
- // Set on CommitNavigation when Network Service is enabled, and used
- // by FrameURLLoaderFactory for prefetch requests.
- network::mojom::URLLoaderFactoryPtr prefetch_loader_factory_;
- scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
- prefetch_shared_loader_factory_;
-
// URLLoaderFactory instances used for subresource loading.
// Depending on how the frame was created, |loader_factories_| could be:
// * |HostChildURLLoaderFactoryBundle| for standalone frames, or
@@ -1672,6 +1667,13 @@ class CONTENT_EXPORT RenderFrameImpl
int num_burst_download_requests_ = 0;
base::TimeTicks burst_download_start_time_;
+ // Set to true while we are committing a navigation and
+ // main request is being issued (the one which already got
+ // a response).
+ // TODO(dgozman): should be temporary until we stop using
+ // WebURLRequest for this.
+ bool committing_main_request_ = false;
+
// Set to true while we are replaying main resource response,
// which was captured in the browser, during navigation commit.
// TODO(dgozman): should be temporary until we stop using
diff --git a/chromium/content/renderer/render_frame_impl_browsertest.cc b/chromium/content/renderer/render_frame_impl_browsertest.cc
index 7debc6529b8..a95e495f7fd 100644
--- a/chromium/content/renderer/render_frame_impl_browsertest.cc
+++ b/chromium/content/renderer/render_frame_impl_browsertest.cc
@@ -18,7 +18,7 @@
#include "content/common/frame_messages.h"
#include "content/common/frame_owner_properties.h"
#include "content/common/renderer.mojom.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/previews_state.h"
#include "content/public/renderer/content_renderer_client.h"
@@ -28,7 +28,7 @@
#include "content/public/test/test_utils.h"
#include "content/renderer/loader/web_url_loader_impl.h"
#include "content/renderer/mojo/blink_interface_registry_impl.h"
-#include "content/renderer/navigation_state_impl.h"
+#include "content/renderer/navigation_state.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_frame_proxy.h"
#include "content/renderer/render_view_impl.h"
@@ -200,7 +200,7 @@ TEST_F(RenderFrameImplTest, FrameResize) {
visual_properties.browser_controls_shrink_blink_size = false;
visual_properties.is_fullscreen_granted = false;
- ViewMsg_SynchronizeVisualProperties resize_message(0, visual_properties);
+ WidgetMsg_SynchronizeVisualProperties resize_message(0, visual_properties);
frame_widget()->OnMessageReceived(resize_message);
EXPECT_EQ(frame_widget()->GetWebWidget()->Size(), blink::WebSize(size));
@@ -211,7 +211,7 @@ TEST_F(RenderFrameImplTest, FrameResize) {
TEST_F(RenderFrameImplTest, FrameWasShown) {
RenderFrameTestObserver observer(frame());
- ViewMsg_WasShown was_shown_message(0, true, base::TimeTicks());
+ WidgetMsg_WasShown was_shown_message(0, base::TimeTicks());
frame_widget()->OnMessageReceived(was_shown_message);
EXPECT_FALSE(frame_widget()->is_hidden());
@@ -241,7 +241,7 @@ TEST_F(RenderFrameImplTest, LocalChildFrameWasShown) {
RenderFrameTestObserver observer(grandchild);
- ViewMsg_WasShown was_shown_message(0, true, base::TimeTicks());
+ WidgetMsg_WasShown was_shown_message(0, base::TimeTicks());
frame_widget()->OnMessageReceived(was_shown_message);
EXPECT_FALSE(frame_widget()->is_hidden());
@@ -251,10 +251,10 @@ TEST_F(RenderFrameImplTest, LocalChildFrameWasShown) {
// Ensure that a RenderFrameImpl does not crash if the RenderView receives
// a WasShown message after the frame's widget has been closed.
TEST_F(RenderFrameImplTest, FrameWasShownAfterWidgetClose) {
- ViewMsg_Close close_message(0);
+ WidgetMsg_Close close_message(0);
frame_widget()->OnMessageReceived(close_message);
- ViewMsg_WasShown was_shown_message(0, true, base::TimeTicks());
+ WidgetMsg_WasShown was_shown_message(0, base::TimeTicks());
// Test passes if this does not crash.
RenderWidget* render_widget =
static_cast<RenderViewImpl*>(view_)->GetWidget();
@@ -275,17 +275,16 @@ TEST_F(RenderFrameImplTest, LoFiNotUpdatedOnSubframeCommits) {
// The main frame's and subframe's LoFi states should stay the same on
// same-document navigations.
frame()->DidFinishSameDocumentNavigation(item, blink::kWebStandardCommit,
- true);
+ false /* content_initiated */);
EXPECT_EQ(SERVER_LOFI_ON, frame()->GetPreviewsState());
GetMainRenderFrame()->DidFinishSameDocumentNavigation(
- item, blink::kWebStandardCommit, true);
+ item, blink::kWebStandardCommit, false /* content_initiated */);
EXPECT_EQ(SERVER_LOFI_ON, GetMainRenderFrame()->GetPreviewsState());
// The subframe's LoFi state should not be reset on commit.
- DocumentState* document_state = DocumentState::FromDocumentLoader(
+ NavigationState* navigation_state = NavigationState::FromDocumentLoader(
frame()->GetWebFrame()->GetDocumentLoader());
- static_cast<NavigationStateImpl*>(document_state->navigation_state())
- ->set_was_within_same_document(false);
+ navigation_state->set_was_within_same_document(false);
frame()->DidCommitProvisionalLoad(
item, blink::kWebStandardCommit,
@@ -293,10 +292,9 @@ TEST_F(RenderFrameImplTest, LoFiNotUpdatedOnSubframeCommits) {
EXPECT_EQ(SERVER_LOFI_ON, frame()->GetPreviewsState());
// The main frame's LoFi state should be reset to off on commit.
- document_state = DocumentState::FromDocumentLoader(
+ navigation_state = NavigationState::FromDocumentLoader(
GetMainRenderFrame()->GetWebFrame()->GetDocumentLoader());
- static_cast<NavigationStateImpl*>(document_state->navigation_state())
- ->set_was_within_same_document(false);
+ navigation_state->set_was_within_same_document(false);
// Calling didCommitProvisionalLoad is not representative of a full navigation
// but serves the purpose of testing the LoFi state logic.
@@ -337,17 +335,16 @@ TEST_F(RenderFrameImplTest, EffectiveConnectionType) {
// The main frame's and subframe's effective connection type should stay the
// same on same-document navigations.
frame()->DidFinishSameDocumentNavigation(item, blink::kWebStandardCommit,
- true);
+ false /* content_initiated */);
EXPECT_EQ(tests[i].type, frame()->GetEffectiveConnectionType());
GetMainRenderFrame()->DidFinishSameDocumentNavigation(
- item, blink::kWebStandardCommit, true);
+ item, blink::kWebStandardCommit, false /* content_initiated */);
EXPECT_EQ(tests[i].type, frame()->GetEffectiveConnectionType());
// The subframe's effective connection type should not be reset on commit.
- DocumentState* document_state = DocumentState::FromDocumentLoader(
+ NavigationState* navigation_state = NavigationState::FromDocumentLoader(
frame()->GetWebFrame()->GetDocumentLoader());
- static_cast<NavigationStateImpl*>(document_state->navigation_state())
- ->set_was_within_same_document(false);
+ navigation_state->set_was_within_same_document(false);
frame()->DidCommitProvisionalLoad(
item, blink::kWebStandardCommit,
@@ -355,10 +352,9 @@ TEST_F(RenderFrameImplTest, EffectiveConnectionType) {
EXPECT_EQ(tests[i].type, frame()->GetEffectiveConnectionType());
// The main frame's effective connection type should be reset on commit.
- document_state = DocumentState::FromDocumentLoader(
+ navigation_state = NavigationState::FromDocumentLoader(
GetMainRenderFrame()->GetWebFrame()->GetDocumentLoader());
- static_cast<NavigationStateImpl*>(document_state->navigation_state())
- ->set_was_within_same_document(false);
+ navigation_state->set_was_within_same_document(false);
GetMainRenderFrame()->DidCommitProvisionalLoad(
item, blink::kWebStandardCommit,
@@ -480,9 +476,9 @@ TEST_F(RenderFrameImplTest, ZoomLimit) {
// text finding, and then delete the frame immediately before the text finding
// returns any text match.
TEST_F(RenderFrameImplTest, NoCrashWhenDeletingFrameDuringFind) {
- blink::WebFindOptions options;
- options.force = true;
- frame()->GetWebFrame()->Find(1, "foo", options, false);
+ frame()->GetWebFrame()->FindForTesting(
+ 1, "foo", true /* match_case */, true /* forward */,
+ false /* find_next */, true /* force */, false /* wrap_within_frame */);
FrameMsg_Delete delete_message(0);
frame()->OnMessageReceived(delete_message);
@@ -821,13 +817,13 @@ class FrameHostTestInterfaceRequestIssuer : public RenderFrameObserver {
RequestTestInterfaceOnFrameEvent(kFrameEventWillCommitProvisionalLoad);
}
- void DidStartProvisionalLoad(
- blink::WebDocumentLoader* document_loader) override {}
+ void DidStartProvisionalLoad(blink::WebDocumentLoader* document_loader,
+ bool is_content_initiated) override {}
void DidFailProvisionalLoad(const blink::WebURLError& error) override {}
- void DidCommitProvisionalLoad(bool is_new_navigation,
- bool is_same_document_navigation) override {
+ void DidCommitProvisionalLoad(bool is_same_document_navigation,
+ ui::PageTransition transition) override {
RequestTestInterfaceOnFrameEvent(is_same_document_navigation
? kFrameEventDidCommitSameDocumentLoad
: kFrameEventDidCommitProvisionalLoad);
@@ -852,8 +848,8 @@ class FrameCommitWaiter : public RenderFrameObserver {
// RenderFrameObserver:
void OnDestruct() override {}
- void DidCommitProvisionalLoad(bool is_new_navigation,
- bool is_same_document_navigation) override {
+ void DidCommitProvisionalLoad(bool is_same_document_navigation,
+ ui::PageTransition transition) override {
did_commit_ = true;
run_loop_.Quit();
}
@@ -1232,8 +1228,7 @@ TEST_F(RenderFrameRemoteInterfacesTest, ReusedOnSameDocumentNavigation) {
GetMainRenderFrame()->TakeLastInterfaceProviderRequest();
FrameHostTestInterfaceRequestIssuer requester(GetMainRenderFrame());
- OnSameDocumentNavigation(GetMainFrame(), true /* is_new_navigation */,
- true /* is_contenet_initiated */);
+ OnSameDocumentNavigation(GetMainFrame(), true /* is_new_navigation */);
EXPECT_FALSE(
GetMainRenderFrame()->TakeLastInterfaceProviderRequest().is_pending());
diff --git a/chromium/content/renderer/render_frame_metadata_observer_impl.cc b/chromium/content/renderer/render_frame_metadata_observer_impl.cc
index c8de63db72b..b98aa7b0e6c 100644
--- a/chromium/content/renderer/render_frame_metadata_observer_impl.cc
+++ b/chromium/content/renderer/render_frame_metadata_observer_impl.cc
@@ -116,15 +116,15 @@ bool RenderFrameMetadataObserverImpl::ShouldSendRenderFrameMetadata(
rfm1.is_mobile_optimized != rfm2.is_mobile_optimized ||
rfm1.device_scale_factor != rfm2.device_scale_factor ||
rfm1.viewport_size_in_pixels != rfm2.viewport_size_in_pixels ||
+ rfm1.top_controls_height != rfm2.top_controls_height ||
+ rfm1.top_controls_shown_ratio != rfm2.top_controls_shown_ratio ||
rfm1.local_surface_id != rfm2.local_surface_id) {
*needs_activation_notification = true;
return true;
}
#if defined(OS_ANDROID)
- if (rfm1.top_controls_height != rfm2.top_controls_height ||
- rfm1.top_controls_shown_ratio != rfm2.top_controls_shown_ratio ||
- rfm1.bottom_controls_height != rfm2.bottom_controls_height ||
+ if (rfm1.bottom_controls_height != rfm2.bottom_controls_height ||
rfm1.bottom_controls_shown_ratio != rfm2.bottom_controls_shown_ratio ||
rfm1.min_page_scale_factor != rfm2.min_page_scale_factor ||
rfm1.max_page_scale_factor != rfm2.max_page_scale_factor ||
diff --git a/chromium/content/renderer/render_frame_proxy.cc b/chromium/content/renderer/render_frame_proxy.cc
index 954ea7fbf07..ade104d7e96 100644
--- a/chromium/content/renderer/render_frame_proxy.cc
+++ b/chromium/content/renderer/render_frame_proxy.cc
@@ -179,7 +179,7 @@ RenderFrameProxy* RenderFrameProxy::CreateFrameProxy(
// static
RenderFrameProxy* RenderFrameProxy::FromRoutingID(int32_t routing_id) {
RoutingIDProxyMap* proxies = g_routing_id_proxy_map.Pointer();
- RoutingIDProxyMap::iterator it = proxies->find(routing_id);
+ auto it = proxies->find(routing_id);
return it == proxies->end() ? NULL : it->second;
}
@@ -188,7 +188,7 @@ RenderFrameProxy* RenderFrameProxy::FromWebFrame(
blink::WebRemoteFrame* web_frame) {
// TODO(dcheng): Turn this into a DCHECK() if it doesn't crash on canary.
CHECK(web_frame);
- FrameProxyMap::iterator iter = g_frame_proxy_map.Get().find(web_frame);
+ auto iter = g_frame_proxy_map.Get().find(web_frame);
if (iter != g_frame_proxy_map.Get().end()) {
RenderFrameProxy* proxy = iter->second;
DCHECK_EQ(web_frame, proxy->web_frame());
@@ -249,7 +249,7 @@ void RenderFrameProxy::Init(blink::WebRemoteFrame* web_frame,
render_widget_->GetOriginalScreenInfo();
#if defined(USE_AURA)
- if (features::IsUsingWindowService()) {
+ if (features::IsMultiProcessMash()) {
RendererWindowTreeClient* renderer_window_tree_client =
RendererWindowTreeClient::Get(render_widget_->routing_id());
// It's possible a MusEmbeddedFrame has already been scheduled for creation
@@ -491,7 +491,7 @@ void RenderFrameProxy::OnViewChanged(
const FrameMsg_ViewChanged_Params& params) {
crashed_ = false;
// In mash the FrameSinkId comes from RendererWindowTreeClient.
- if (!features::IsUsingWindowService())
+ if (!features::IsMultiProcessMash())
frame_sink_id_ = *params.frame_sink_id;
// Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
@@ -730,7 +730,7 @@ void RenderFrameProxy::FrameDetached(DetachType type) {
// Remove the entry in the WebFrame->RenderFrameProxy map, as the |web_frame_|
// is no longer valid.
- FrameProxyMap::iterator it = g_frame_proxy_map.Get().find(web_frame_);
+ auto it = g_frame_proxy_map.Get().find(web_frame_);
CHECK(it != g_frame_proxy_map.Get().end());
CHECK_EQ(it->second, this);
g_frame_proxy_map.Get().erase(it);
@@ -875,15 +875,10 @@ base::UnguessableToken RenderFrameProxy::GetDevToolsFrameToken() {
}
#if defined(USE_AURA)
-void RenderFrameProxy::OnMusEmbeddedFrameSurfaceChanged(
- const viz::SurfaceInfo& surface_info) {
- OnFirstSurfaceActivation(surface_info);
-}
-
void RenderFrameProxy::OnMusEmbeddedFrameSinkIdAllocated(
const viz::FrameSinkId& frame_sink_id) {
// RendererWindowTreeClient should only call this when mus is hosting viz.
- DCHECK(features::IsUsingWindowService());
+ DCHECK(features::IsMultiProcessMash());
frame_sink_id_ = frame_sink_id;
// Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
// changes.
@@ -896,9 +891,12 @@ cc::Layer* RenderFrameProxy::GetLayer() {
}
void RenderFrameProxy::SetLayer(scoped_refptr<cc::Layer> layer,
- bool prevent_contents_opaque_changes) {
- if (web_frame())
- web_frame()->SetCcLayer(layer.get(), prevent_contents_opaque_changes);
+ bool prevent_contents_opaque_changes,
+ bool is_surface_layer) {
+ if (web_frame()) {
+ web_frame()->SetCcLayer(layer.get(), prevent_contents_opaque_changes,
+ is_surface_layer);
+ }
embedded_layer_ = std::move(layer);
}
diff --git a/chromium/content/renderer/render_frame_proxy.h b/chromium/content/renderer/render_frame_proxy.h
index 4715761b72d..ba9429c55db 100644
--- a/chromium/content/renderer/render_frame_proxy.h
+++ b/chromium/content/renderer/render_frame_proxy.h
@@ -265,8 +265,6 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
#if defined(USE_AURA)
// MusEmbeddedFrameDelegate
- void OnMusEmbeddedFrameSurfaceChanged(
- const viz::SurfaceInfo& surface_info) override;
void OnMusEmbeddedFrameSinkIdAllocated(
const viz::FrameSinkId& frame_sink_id) override;
#endif
@@ -274,7 +272,8 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
// ChildFrameCompositor:
cc::Layer* GetLayer() override;
void SetLayer(scoped_refptr<cc::Layer> layer,
- bool prevent_contents_opaque_changes) override;
+ bool prevent_contents_opaque_changes,
+ bool is_surface_layer) override;
SkBitmap* GetSadPageBitmap() override;
const viz::LocalSurfaceId& GetLocalSurfaceId() const;
diff --git a/chromium/content/renderer/render_process_impl.cc b/chromium/content/renderer/render_process_impl.cc
index 49973c56fcd..b9f38b029ac 100644
--- a/chromium/content/renderer/render_process_impl.cc
+++ b/chromium/content/renderer/render_process_impl.cc
@@ -131,12 +131,10 @@ RenderProcessImpl::RenderProcessImpl(
SetV8FlagIfHasSwitch(switches::kDisableJavaScriptHarmonyShipping,
"--noharmony-shipping");
SetV8FlagIfHasSwitch(switches::kJavaScriptHarmony, "--harmony");
- SetV8FlagIfFeature(features::kModuleScriptsDynamicImport,
- "--harmony-dynamic-import");
- SetV8FlagIfFeature(features::kModuleScriptsImportMetaUrl,
- "--harmony-import-meta");
- SetV8FlagIfFeature(features::kAsmJsToWebAssembly, "--validate-asm");
- SetV8FlagIfNotFeature(features::kAsmJsToWebAssembly, "--no-validate-asm");
+
+ constexpr char kModuleFlags[] =
+ "--harmony-dynamic-import --harmony-import-meta";
+ v8::V8::SetFlagsFromString(kModuleFlags, sizeof(kModuleFlags));
SetV8FlagIfFeature(features::kV8Orinoco, "--no-single-threaded-gc");
SetV8FlagIfNotFeature(features::kV8Orinoco, "--single-threaded-gc");
@@ -237,4 +235,12 @@ int RenderProcessImpl::GetEnabledBindings() const {
return enabled_bindings_;
}
+void RenderProcessImpl::AddRefProcess() {
+ NOTREACHED();
+}
+
+void RenderProcessImpl::ReleaseProcess() {
+ NOTREACHED();
+}
+
} // namespace content
diff --git a/chromium/content/renderer/render_process_impl.h b/chromium/content/renderer/render_process_impl.h
index 0776bb239e2..a81dcb1cf46 100644
--- a/chromium/content/renderer/render_process_impl.h
+++ b/chromium/content/renderer/render_process_impl.h
@@ -32,6 +32,14 @@ class RenderProcessImpl : public RenderProcess {
void AddBindings(int bindings) override;
int GetEnabledBindings() const override;
+ // Do not use these functions.
+ // The browser process is the only one responsible for knowing when to
+ // shutdown its renderer processes. Reference counting to keep this process
+ // alive is not used. To keep this process alive longer, see
+ // mojo::KeepAliveHandle and content::RenderProcessHostImpl.
+ void AddRefProcess() override;
+ void ReleaseProcess() override;
+
private:
RenderProcessImpl(std::unique_ptr<base::TaskScheduler::InitParams>
task_scheduler_init_params);
diff --git a/chromium/content/renderer/render_thread_impl.cc b/chromium/content/renderer/render_thread_impl.cc
index b36daaee097..f2d704c09e6 100644
--- a/chromium/content/renderer/render_thread_impl.cc
+++ b/chromium/content/renderer/render_thread_impl.cc
@@ -17,7 +17,6 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/discardable_memory_allocator.h"
-#include "base/memory/memory_coordinator_client_registry.h"
#include "base/memory/shared_memory.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_functions.h"
@@ -63,12 +62,12 @@
#include "content/common/dom_storage/dom_storage_messages.h"
#include "content/common/frame_messages.h"
#include "content/common/frame_owner_properties.h"
-#include "content/common/gpu_stream_constants.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_stream_constants.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/resource_usage_reporter.mojom.h"
#include "content/public/common/resource_usage_reporter_type_converters.h"
@@ -88,8 +87,6 @@
#include "content/renderer/dom_storage/webstoragearea_impl.h"
#include "content/renderer/dom_storage/webstoragenamespace_impl.h"
#include "content/renderer/effective_connection_type_helper.h"
-#include "content/renderer/fileapi/file_system_dispatcher.h"
-#include "content/renderer/fileapi/webfilesystem_impl.h"
#include "content/renderer/gpu/frame_swap_message_queue.h"
#include "content/renderer/indexed_db/indexed_db_dispatcher.h"
#include "content/renderer/input/widget_input_handler_manager.h"
@@ -149,7 +146,6 @@
#include "services/ws/public/cpp/gpu/gpu.h"
#include "services/ws/public/mojom/constants.mojom.h"
#include "skia/ext/skia_memory_dump_provider.h"
-#include "third_party/blink/public/platform/scheduler/child/webthread_base.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_cache.h"
#include "third_party/blink/public/platform/web_image_generator.h"
@@ -157,7 +153,6 @@
#include "third_party/blink/public/platform/web_network_state_notifier.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_frame.h"
@@ -217,9 +212,6 @@ namespace content {
namespace {
-const int64_t kInitialIdleHandlerDelayMs = 1000;
-const int64_t kLongIdleHandlerDelayMs = 30 * 1000;
-
#if defined(OS_ANDROID)
// Unique identifier for each output surface created.
uint32_t g_next_layer_tree_frame_sink_id = 1;
@@ -681,7 +673,8 @@ RenderThreadImpl::DeprecatedGetMainTaskRunner() {
RenderThreadImpl::RenderThreadImpl(
const InProcessChildThreadParams& params,
std::unique_ptr<blink::scheduler::WebThreadScheduler> scheduler)
- : ChildThreadImpl(Options::Builder()
+ : ChildThreadImpl(base::DoNothing(),
+ Options::Builder()
.InBrowserProcess(params)
.AutoStartServiceManagerConnection(false)
.ConnectToBrowser(true)
@@ -699,8 +692,10 @@ RenderThreadImpl::RenderThreadImpl(
// Multi-process mode.
RenderThreadImpl::RenderThreadImpl(
+ base::RepeatingClosure quit_closure,
std::unique_ptr<blink::scheduler::WebThreadScheduler> scheduler)
- : ChildThreadImpl(Options::Builder()
+ : ChildThreadImpl(std::move(quit_closure),
+ Options::Builder()
.AutoStartServiceManagerConnection(false)
.ConnectToBrowser(true)
.IPCTaskRunner(scheduler->IPCTaskRunner())
@@ -745,7 +740,7 @@ void RenderThreadImpl::Init() {
main_thread_runner(), GetConnector()));
gpu_ = ws::Gpu::Create(GetConnector(),
- features::IsUsingWindowService()
+ features::IsMultiProcessMash()
? ws::mojom::kServiceName
: mojom::kBrowserServiceName,
GetIOTaskRunner());
@@ -759,11 +754,8 @@ void RenderThreadImpl::Init() {
InitializeWebKit(registry.get());
// In single process the single process is all there is.
- webkit_shared_timer_suspended_ = false;
widget_count_ = 0;
hidden_widget_count_ = 0;
- idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs;
- idle_notifications_to_skip_ = 0;
appcache_dispatcher_.reset(
new AppCacheDispatcher(new AppCacheFrontendImpl()));
@@ -779,7 +771,8 @@ void RenderThreadImpl::Init() {
browser_plugin_manager_.reset(new BrowserPluginManager());
AddObserver(browser_plugin_manager_.get());
- peer_connection_tracker_.reset(new PeerConnectionTracker());
+ peer_connection_tracker_.reset(
+ new PeerConnectionTracker(main_thread_runner()));
AddObserver(peer_connection_tracker_.get());
p2p_socket_dispatcher_ = new P2PSocketDispatcher();
@@ -800,7 +793,7 @@ void RenderThreadImpl::Init() {
AddFilter(midi_message_filter_.get());
#if defined(USE_AURA)
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
CreateRenderWidgetWindowTreeClientFactory(GetServiceManagerConnection());
#endif
@@ -955,7 +948,7 @@ void RenderThreadImpl::Init() {
categorized_worker_pool_->Start(num_raster_threads);
discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr;
- if (features::IsUsingWindowService()) {
+ if (features::IsMultiProcessMash()) {
#if defined(USE_AURA)
GetServiceManagerConnection()->GetConnector()->BindInterface(
ws::mojom::kServiceName, &manager_ptr);
@@ -989,8 +982,6 @@ void RenderThreadImpl::Init() {
needs_to_record_first_active_paint_ = false;
was_backgrounded_time_ = base::TimeTicks::Min();
- base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
-
GetConnector()->BindInterface(mojom::kBrowserServiceName,
mojo::MakeRequest(&frame_sink_provider_));
@@ -1014,7 +1005,6 @@ RenderThreadImpl::~RenderThreadImpl() {
void RenderThreadImpl::Shutdown() {
ChildThreadImpl::Shutdown();
- WebFileSystemImpl::DeleteThreadSpecificInstance();
// In a multi-process mode, we immediately exit the renderer.
// Historically we had a graceful shutdown sequence here but it was
// 1) a waste of performance and 2) a source of lots of complicated
@@ -1170,25 +1160,14 @@ void RenderThreadImpl::SetResourceDispatcherDelegate(
}
void RenderThreadImpl::InitializeCompositorThread() {
- blink::WebThreadCreationParams params(
- blink::WebThreadType::kCompositorThread);
-#if defined(OS_ANDROID)
- params.thread_options.priority = base::ThreadPriority::DISPLAY;
-#endif
- compositor_thread_ =
- blink::scheduler::WebThreadBase::CreateCompositorThread(params);
- blink_platform_impl_->SetCompositorThread(compositor_thread_.get());
- compositor_task_runner_ = compositor_thread_->GetTaskRunner();
+ blink_platform_impl_->InitializeCompositorThread();
+ compositor_task_runner_ = blink_platform_impl_->CompositorThreadTaskRunner();
compositor_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(base::IgnoreResult(&ThreadRestrictions::SetIOAllowed),
false));
GetContentClient()->renderer()->PostCompositorThreadCreated(
compositor_task_runner_.get());
-#if defined(OS_LINUX)
- render_message_filter()->SetThreadPriority(compositor_thread_->ThreadId(),
- base::ThreadPriority::DISPLAY);
-#endif
}
scoped_refptr<base::SingleThreadTaskRunner>
@@ -1225,7 +1204,7 @@ void RenderThreadImpl::InitializeWebKit(
->renderer()
->SetRuntimeFeaturesDefaultsBeforeBlinkInitialization();
blink::Initialize(blink_platform_impl_.get(), registry,
- blink_platform_impl_->CurrentThread());
+ main_thread_scheduler_.get());
v8::Isolate* isolate = blink::MainThreadIsolate();
isolate->SetCreateHistogramFunction(CreateHistogram);
@@ -1242,11 +1221,7 @@ void RenderThreadImpl::InitializeWebKit(
RenderMediaClient::Initialize();
- idle_timer_.SetTaskRunner(GetWebMainThreadScheduler()->DefaultTaskRunner());
-
- if (GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) {
- ScheduleIdleHandler(kLongIdleHandlerDelayMs);
- } else {
+ if (!GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) {
// If we do not track widget visibility, then assume conservatively that
// the isolate is in background. This reduces memory usage.
isolate->IsolateInBackgroundNotification();
@@ -1303,67 +1278,6 @@ void RenderThreadImpl::RegisterExtension(v8::Extension* extension) {
WebScriptController::RegisterExtension(extension);
}
-void RenderThreadImpl::ScheduleIdleHandler(int64_t initial_delay_ms) {
- idle_notification_delay_in_ms_ = initial_delay_ms;
- idle_timer_.Stop();
- idle_timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(initial_delay_ms),
- this, &RenderThreadImpl::IdleHandler);
-}
-
-void RenderThreadImpl::IdleHandler() {
- bool run_in_foreground_tab = (widget_count_ > hidden_widget_count_) &&
- GetContentClient()->renderer()->
- RunIdleHandlerWhenWidgetsHidden();
- if (run_in_foreground_tab) {
- if (idle_notifications_to_skip_ > 0) {
- --idle_notifications_to_skip_;
- } else {
- ReleaseFreeMemory();
- }
- ScheduleIdleHandler(kLongIdleHandlerDelayMs);
- return;
- }
-
- ReleaseFreeMemory();
-
- // Continue the idle timer if the webkit shared timer is not suspended or
- // something is left to do.
- bool continue_timer = !webkit_shared_timer_suspended_;
-
- // Schedule next invocation. When the tab is originally hidden, an invocation
- // is scheduled for kInitialIdleHandlerDelayMs in
- // RenderThreadImpl::WidgetHidden in order to race to a minimal heap.
- // After that, idle calls can be much less frequent, so run at a maximum of
- // once every kLongIdleHandlerDelayMs.
- // Dampen the delay using the algorithm (if delay is in seconds):
- // delay = delay + 1 / (delay + 2)
- // Using floor(delay) has a dampening effect such as:
- // 30s, 30, 30, 31, 31, 31, 31, 32, 32, ...
- // If the delay is in milliseconds, the above formula is equivalent to:
- // delay_ms / 1000 = delay_ms / 1000 + 1 / (delay_ms / 1000 + 2)
- // which is equivalent to
- // delay_ms = delay_ms + 1000*1000 / (delay_ms + 2000).
- if (continue_timer) {
- ScheduleIdleHandler(
- std::max(kLongIdleHandlerDelayMs,
- idle_notification_delay_in_ms_ +
- 1000000 / (idle_notification_delay_in_ms_ + 2000)));
-
- } else {
- idle_timer_.Stop();
- }
-}
-
-int64_t RenderThreadImpl::GetIdleNotificationDelayInMs() const {
- return idle_notification_delay_in_ms_;
-}
-
-void RenderThreadImpl::SetIdleNotificationDelayInMs(
- int64_t idle_notification_delay_in_ms) {
- idle_notification_delay_in_ms_ = idle_notification_delay_in_ms;
-}
-
int RenderThreadImpl::PostTaskToAllWebWorkers(const base::Closure& closure) {
return WorkerThreadRegistry::Instance()->PostTaskToAllThreads(closure);
}
@@ -1374,10 +1288,6 @@ bool RenderThreadImpl::ResolveProxy(const GURL& url, std::string* proxy_list) {
return result;
}
-void RenderThreadImpl::PostponeIdleNotification() {
- idle_notifications_to_skip_ = 2;
-}
-
media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
DCHECK(IsMainThread());
@@ -1438,6 +1348,9 @@ media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
gpu_channel_host->gpu_info().supports_overlays);
#endif // defined(OS_WIN)
+ media::mojom::InterfaceFactoryPtr interface_factory;
+ GetConnector()->BindInterface(mojom::kBrowserServiceName, &interface_factory);
+
media::mojom::VideoEncodeAcceleratorProviderPtr vea_provider;
gpu_->CreateVideoEncodeAcceleratorProvider(mojo::MakeRequest(&vea_provider));
@@ -1445,7 +1358,8 @@ media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
std::move(gpu_channel_host), base::ThreadTaskRunnerHandle::Get(),
GetMediaThreadTaskRunner(), std::move(media_context_provider),
enable_video_gpu_memory_buffers, enable_media_stream_gpu_memory_buffers,
- enable_video_accelerator, vea_provider.PassInterface()));
+ enable_video_accelerator, interface_factory.PassInterface(),
+ vea_provider.PassInterface()));
gpu_factories_.back()->SetRenderingColorSpace(rendering_color_space_);
return gpu_factories_.back().get();
}
@@ -1563,6 +1477,10 @@ int32_t RenderThreadImpl::GetClientId() {
return client_id_;
}
+bool RenderThreadImpl::IsOnline() {
+ return online_status_;
+}
+
void RenderThreadImpl::SetRendererProcessType(
blink::scheduler::RendererProcessType type) {
main_thread_scheduler_->SetRendererProcessType(type);
@@ -1701,6 +1619,7 @@ void RenderThreadImpl::OnProcessFinalRelease() {
// caused race conditions, where the browser process was reusing renderer
// processes that were shutting down.
// See https://crbug.com/535246 or https://crbug.com/873541/#c8.
+ NOTREACHED();
}
bool RenderThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
@@ -1755,7 +1674,11 @@ void RenderThreadImpl::ProcessPurgeAndSuspend() {
if (!base::FeatureList::IsEnabled(features::kPurgeAndSuspend))
return;
- base::MemoryCoordinatorClientRegistry::GetInstance()->PurgeMemory();
+ if (base::MemoryPressureListener::AreNotificationsSuppressed())
+ return;
+
+ base::MemoryPressureListener::NotifyMemoryPressure(
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
needs_to_record_first_active_paint_ = true;
RendererMemoryMetrics memory_metrics;
@@ -1961,7 +1884,8 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
LayerTreeFrameSinkCallback callback,
mojom::RenderFrameMetadataObserverClientRequest
render_frame_metadata_observer_client_request,
- mojom::RenderFrameMetadataObserverPtr render_frame_metadata_observer_ptr) {
+ mojom::RenderFrameMetadataObserverPtr render_frame_metadata_observer_ptr,
+ const char* client_name) {
// Misconfigured bots (eg. crbug.com/780757) could run layout tests on a
// machine where gpu compositing doesn't work. Don't crash in that case.
if (layout_test_mode() && is_gpu_compositing_disabled_) {
@@ -1980,7 +1904,8 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
if (features::IsVizHitTestingDrawQuadEnabled()) {
params.hit_test_data_provider =
std::make_unique<viz::HitTestDataProviderDrawQuad>(
- true /* should_ask_for_child_region */);
+ true /* should_ask_for_child_region */,
+ true /* root_accepts_events */);
}
// The renderer runs animations and layout for animate_only BeginFrames.
@@ -1994,8 +1919,10 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
if (command_line.HasSwitch(switches::kDisableFrameRateLimit))
params.synthetic_begin_frame_source = CreateSyntheticBeginFrameSource();
+ params.client_name = client_name;
+
#if defined(USE_AURA)
- if (features::IsUsingWindowService()) {
+ if (features::IsMultiProcessMash()) {
if (!RendererWindowTreeClient::Get(routing_id)) {
std::move(callback).Run(nullptr);
return;
@@ -2227,12 +2154,12 @@ void RenderThreadImpl::SetUpEmbeddedWorkerChannelForServiceWorker(
void RenderThreadImpl::OnNetworkConnectionChanged(
net::NetworkChangeNotifier::ConnectionType type,
double max_bandwidth_mbps) {
- bool online = type != net::NetworkChangeNotifier::CONNECTION_NONE;
- WebNetworkStateNotifier::SetOnLine(online);
+ online_status_ = type != net::NetworkChangeNotifier::CONNECTION_NONE;
+ WebNetworkStateNotifier::SetOnLine(online_status_);
if (url_loader_throttle_provider_)
- url_loader_throttle_provider_->SetOnline(online);
+ url_loader_throttle_provider_->SetOnline(online_status_);
for (auto& observer : observers_)
- observer.NetworkStateChanged(online);
+ observer.NetworkStateChanged(online_status_);
WebNetworkStateNotifier::SetWebConnection(
NetConnectionTypeToWebConnectionType(type), max_bandwidth_mbps);
}
@@ -2255,7 +2182,6 @@ void RenderThreadImpl::SetWebKitSharedTimersSuspended(bool suspend) {
} else {
main_thread_scheduler_->ResumeTimersForAndroidWebView();
}
- webkit_shared_timer_suspended_ = suspend;
#else
NOTREACHED();
#endif
@@ -2315,30 +2241,6 @@ void RenderThreadImpl::OnMemoryPressure(
ReleaseFreeMemory();
}
-void RenderThreadImpl::OnMemoryStateChange(base::MemoryState state) {
- if (blink_platform_impl_) {
- blink::WebMemoryCoordinator::OnMemoryStateChange(
- static_cast<blink::MemoryState>(state));
- }
-}
-
-void RenderThreadImpl::OnPurgeMemory() {
- // Record amount of purged memory after 2 seconds. 2 seconds is arbitrary
- // but it works most cases.
- RendererMemoryMetrics metrics;
- if (!GetRendererMemoryMetrics(&metrics))
- return;
-
- GetWebMainThreadScheduler()->DefaultTaskRunner()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&RenderThreadImpl::RecordPurgeMemory,
- base::Unretained(this), std::move(metrics)),
- base::TimeDelta::FromSeconds(2));
-
- OnTrimMemoryImmediately();
- ReleaseFreeMemory();
-}
-
void RenderThreadImpl::RecordPurgeMemory(RendererMemoryMetrics before) {
RendererMemoryMetrics after;
if (!GetRendererMemoryMetrics(&after))
@@ -2451,7 +2353,6 @@ void RenderThreadImpl::OnRendererHidden() {
if (!GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden())
return;
main_thread_scheduler_->SetRendererHidden(true);
- ScheduleIdleHandler(kInitialIdleHandlerDelayMs);
}
void RenderThreadImpl::OnRendererVisible() {
@@ -2459,7 +2360,6 @@ void RenderThreadImpl::OnRendererVisible() {
if (!GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden())
return;
main_thread_scheduler_->SetRendererHidden(false);
- ScheduleIdleHandler(kLongIdleHandlerDelayMs);
}
void RenderThreadImpl::ReleaseFreeMemory() {
@@ -2513,17 +2413,6 @@ void RenderThreadImpl::OnSyncMemoryPressure(
v8_memory_pressure_level);
}
-// Note that this would be called only when memory_coordinator is enabled.
-// OnSyncMemoryPressure() is never called in that case.
-void RenderThreadImpl::OnTrimMemoryImmediately() {
- if (blink::MainThreadIsolate()) {
- blink::MainThreadIsolate()->MemoryPressureNotification(
- v8::MemoryPressureLevel::kCritical);
- blink::MemoryPressureNotificationToWorkerThreadIsolates(
- v8::MemoryPressureLevel::kCritical);
- }
-}
-
void RenderThreadImpl::OnRendererInterfaceRequest(
mojom::RendererAssociatedRequest request) {
DCHECK(!renderer_binding_.is_bound());
diff --git a/chromium/content/renderer/render_thread_impl.h b/chromium/content/renderer/render_thread_impl.h
index 61d79566e6b..59967453c9e 100644
--- a/chromium/content/renderer/render_thread_impl.h
+++ b/chromium/content/renderer/render_thread_impl.h
@@ -17,7 +17,6 @@
#include "base/cancelable_callback.h"
#include "base/macros.h"
-#include "base/memory/memory_coordinator_client.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/user_metrics_action.h"
@@ -29,7 +28,6 @@
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "content/child/child_thread_impl.h"
-#include "content/child/memory/child_memory_coordinator_impl.h"
#include "content/common/content_export.h"
#include "content/common/frame.mojom.h"
#include "content/common/frame_replication_state.h"
@@ -71,9 +69,6 @@
class SkBitmap;
namespace blink {
-namespace scheduler {
-class WebThreadBase;
-}
class WebMediaStreamCenter;
}
@@ -164,7 +159,6 @@ class CONTENT_EXPORT RenderThreadImpl
: public RenderThread,
public ChildThreadImpl,
public blink::scheduler::WebRAILModeObserver,
- public base::MemoryCoordinatorClient,
public mojom::Renderer,
public viz::mojom::CompositingModeWatcher,
public CompositorDependencies {
@@ -182,7 +176,8 @@ class CONTENT_EXPORT RenderThreadImpl
static scoped_refptr<base::SingleThreadTaskRunner>
DeprecatedGetMainTaskRunner();
- explicit RenderThreadImpl(
+ RenderThreadImpl(
+ base::RepeatingClosure quit_closure,
std::unique_ptr<blink::scheduler::WebThreadScheduler> scheduler);
RenderThreadImpl(
const InProcessChildThreadParams& params,
@@ -212,15 +207,11 @@ class CONTENT_EXPORT RenderThreadImpl
std::unique_ptr<base::SharedMemory> HostAllocateSharedMemoryBuffer(
size_t buffer_size) override;
void RegisterExtension(v8::Extension* extension) override;
- void ScheduleIdleHandler(int64_t initial_delay_ms) override;
- void IdleHandler() override;
- int64_t GetIdleNotificationDelayInMs() const override;
- void SetIdleNotificationDelayInMs(
- int64_t idle_notification_delay_in_ms) override;
int PostTaskToAllWebWorkers(const base::Closure& closure) override;
bool ResolveProxy(const GURL& url, std::string* proxy_list) override;
base::WaitableEvent* GetShutdownEvent() override;
int32_t GetClientId() override;
+ bool IsOnline() override;
void SetRendererProcessType(
blink::scheduler::RendererProcessType type) override;
blink::WebString GetUserAgent() const override;
@@ -284,7 +275,8 @@ class CONTENT_EXPORT RenderThreadImpl
LayerTreeFrameSinkCallback callback,
mojom::RenderFrameMetadataObserverClientRequest
render_frame_metadata_observer_client_request,
- mojom::RenderFrameMetadataObserverPtr render_frame_metadata_observer_ptr);
+ mojom::RenderFrameMetadataObserverPtr render_frame_metadata_observer_ptr,
+ const char* client_name);
blink::AssociatedInterfaceRegistry* GetAssociatedInterfaceRegistry();
@@ -319,6 +311,8 @@ class CONTENT_EXPORT RenderThreadImpl
return blink_platform_impl_.get();
}
+ // Returns the task runner on the compositor thread.
+ //
// Will be null if threaded compositing has not been enabled.
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner() const {
return compositor_task_runner_;
@@ -404,11 +398,6 @@ class CONTENT_EXPORT RenderThreadImpl
scoped_refptr<viz::RasterContextProvider>
SharedCompositorWorkerContextProvider();
- // Causes the idle handler to skip sending idle notifications
- // on the two next scheduled calls, so idle notifications are
- // not sent for at least one notification delay.
- void PostponeIdleNotification();
-
media::GpuVideoAcceleratorFactories* GetGpuFactories();
scoped_refptr<ws::ContextProviderCommandBuffer>
@@ -495,9 +484,6 @@ class CONTENT_EXPORT RenderThreadImpl
blink::mojom::StoragePartitionService* GetStoragePartitionService();
mojom::RendererHost* GetRendererHost();
- // ChildMemoryCoordinatorDelegate implementation.
- void OnTrimMemoryImmediately() override;
-
struct RendererMemoryMetrics {
size_t partition_alloc_kb;
size_t blink_gc_kb;
@@ -530,10 +516,6 @@ class CONTENT_EXPORT RenderThreadImpl
bool IsMainThread();
- // base::MemoryCoordinatorClient implementation:
- void OnMemoryStateChange(base::MemoryState state) override;
- void OnPurgeMemory() override;
-
void RecordPurgeMemory(RendererMemoryMetrics before);
void Init();
@@ -649,30 +631,16 @@ class CONTENT_EXPORT RenderThreadImpl
// The count of hidden RenderWidgets running through this thread.
int hidden_widget_count_;
- // The current value of the idle notification timer delay.
- int64_t idle_notification_delay_in_ms_;
-
- // The number of idle handler calls that skip sending idle notifications.
- int idle_notifications_to_skip_;
-
- bool webkit_shared_timer_suspended_;
-
blink::WebString user_agent_;
// Used to control layout test specific behavior.
std::unique_ptr<LayoutTestDependencies> layout_test_deps_;
- // Timer that periodically calls IdleHandler.
- base::RepeatingTimer idle_timer_;
-
// Sticky once true, indicates that compositing is done without Gpu, so
// resources given to the compositor or to the viz service should be
// software-based.
bool is_gpu_compositing_disabled_ = false;
- // May be null if overridden by ContentRendererClient.
- std::unique_ptr<blink::scheduler::WebThreadBase> compositor_thread_;
-
// Utility class to provide GPU functionalities to media.
// TODO(dcastagna): This should be just one scoped_ptr once
// http://crbug.com/580386 is fixed.
@@ -777,6 +745,7 @@ class CONTENT_EXPORT RenderThreadImpl
bool needs_to_record_first_active_paint_;
base::TimeTicks was_backgrounded_time_;
int process_foregrounded_count_;
+ bool online_status_ = true;
int32_t client_id_;
diff --git a/chromium/content/renderer/render_thread_impl_browsertest.cc b/chromium/content/renderer/render_thread_impl_browsertest.cc
index 93a88a7ea72..e6f7e1302d5 100644
--- a/chromium/content/renderer/render_thread_impl_browsertest.cc
+++ b/chromium/content/renderer/render_thread_impl_browsertest.cc
@@ -21,6 +21,7 @@
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
+#include "base/task/post_task.h"
#include "base/task/task_scheduler/task_scheduler.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/sequenced_task_runner_handle.h"
@@ -28,6 +29,7 @@
#include "content/app/mojo/mojo_init.h"
#include "content/common/in_process_child_thread_params.h"
#include "content/common/service_manager/child_connection.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
@@ -181,7 +183,7 @@ class RenderThreadImplBrowserTest : public testing::Test {
browser_threads_.reset(
new TestBrowserThreadBundle(TestBrowserThreadBundle::REAL_IO_THREAD));
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+ base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});
InitializeMojo();
mojo_ipc_support_.reset(new mojo::core::ScopedIPCSupport(
diff --git a/chromium/content/renderer/render_view_browsertest.cc b/chromium/content/renderer/render_view_browsertest.cc
index d22f9ea8f65..b38ef21ca05 100644
--- a/chromium/content/renderer/render_view_browsertest.cc
+++ b/chromium/content/renderer/render_view_browsertest.cc
@@ -26,7 +26,7 @@
#include "content/common/frame_owner_properties.h"
#include "content/common/frame_replication_state.h"
#include "content/common/renderer.mojom.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/web_ui_controller.h"
@@ -39,8 +39,6 @@
#include "content/public/common/url_utils.h"
#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "content/public/renderer/content_renderer_client.h"
-#include "content/public/renderer/document_state.h"
-#include "content/public/renderer/navigation_state.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/frame_load_waiter.h"
#include "content/public/test/render_view_test.h"
@@ -50,7 +48,7 @@
#include "content/renderer/history_entry.h"
#include "content/renderer/history_serialization.h"
#include "content/renderer/loader/request_extra_data.h"
-#include "content/renderer/navigation_state_impl.h"
+#include "content/renderer/navigation_state.h"
#include "content/renderer/render_frame_proxy.h"
#include "content/renderer/render_process.h"
#include "content/renderer/render_view_impl.h"
@@ -88,7 +86,7 @@
#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/public/web/web_window_features.h"
-#include "ui/accessibility/ax_modes.h"
+#include "ui/accessibility/ax_mode.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/dom/dom_code.h"
@@ -657,9 +655,6 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicy) {
WebUITestWebUIControllerFactory factory;
WebUIControllerFactory::RegisterFactory(&factory);
- DocumentState state;
- state.set_navigation_state(NavigationStateImpl::CreateContentInitiated());
-
// Navigations to normal HTTP URLs can be handled locally.
blink::WebURLRequest request(GURL("http://foo.com"));
request.SetFetchRequestMode(network::mojom::FetchRequestMode::kNavigate);
@@ -667,7 +662,7 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicy) {
network::mojom::FetchCredentialsMode::kInclude);
request.SetFetchRedirectMode(network::mojom::FetchRedirectMode::kManual);
request.SetFrameType(network::mojom::RequestContextFrameType::kTopLevel);
- request.SetRequestContext(blink::WebURLRequest::kRequestContextInternal);
+ request.SetRequestContext(blink::mojom::RequestContextType::INTERNAL);
blink::WebLocalFrameClient::NavigationPolicyInfo policy_info(request);
policy_info.navigation_type = blink::kWebNavigationTypeLinkClicked;
policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;
@@ -699,9 +694,6 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicy) {
}
TEST_F(RenderViewImplTest, DecideNavigationPolicyHandlesAllTopLevel) {
- DocumentState state;
- state.set_navigation_state(NavigationStateImpl::CreateContentInitiated());
-
RendererPreferences prefs = view()->renderer_preferences();
prefs.browser_handles_all_top_level_requests = true;
view()->OnSetRendererPrefs(prefs);
@@ -732,9 +724,6 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicyForWebUI) {
// Enable bindings to simulate a WebUI view.
view()->GetMainRenderFrame()->AllowBindings(BINDINGS_POLICY_WEB_UI);
- DocumentState state;
- state.set_navigation_state(NavigationStateImpl::CreateContentInitiated());
-
// Navigations to normal HTTP URLs will be sent to browser process.
blink::WebURLRequest request(GURL("http://foo.com"));
blink::WebLocalFrameClient::NavigationPolicyInfo policy_info(request);
@@ -1173,10 +1162,10 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
view()->UpdateTextInputState();
const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
EXPECT_TRUE(msg != nullptr);
- EXPECT_EQ(static_cast<uint32_t>(ViewHostMsg_TextInputStateChanged::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetHostMsg_TextInputStateChanged::ID),
msg->type());
- ViewHostMsg_TextInputStateChanged::Param params;
- ViewHostMsg_TextInputStateChanged::Read(msg, &params);
+ WidgetHostMsg_TextInputStateChanged::Param params;
+ WidgetHostMsg_TextInputStateChanged::Read(msg, &params);
TextInputState p = std::get<0>(params);
ui::TextInputType type = p.type;
ui::TextInputMode input_mode = p.mode;
@@ -1195,9 +1184,9 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
view()->UpdateTextInputState();
msg = render_thread_->sink().GetMessageAt(0);
EXPECT_TRUE(msg != nullptr);
- EXPECT_EQ(static_cast<uint32_t>(ViewHostMsg_TextInputStateChanged::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetHostMsg_TextInputStateChanged::ID),
msg->type());
- ViewHostMsg_TextInputStateChanged::Read(msg, &params);
+ WidgetHostMsg_TextInputStateChanged::Read(msg, &params);
p = std::get<0>(params);
type = p.type;
input_mode = p.mode;
@@ -1221,9 +1210,9 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
base::RunLoop().RunUntilIdle();
const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
EXPECT_TRUE(msg != nullptr);
- EXPECT_EQ(static_cast<uint32_t>(ViewHostMsg_TextInputStateChanged::ID),
+ EXPECT_EQ(static_cast<uint32_t>(WidgetHostMsg_TextInputStateChanged::ID),
msg->type());
- ViewHostMsg_TextInputStateChanged::Read(msg, &params);
+ WidgetHostMsg_TextInputStateChanged::Read(msg, &params);
p = std::get<0>(params);
type = p.type;
input_mode = p.mode;
@@ -1868,7 +1857,7 @@ TEST_F(RenderViewImplTest, MessageOrderInDidChangeSelection) {
for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
const uint32_t type = render_thread_->sink().GetMessageAt(i)->type();
- if (type == ViewHostMsg_TextInputStateChanged::ID) {
+ if (type == WidgetHostMsg_TextInputStateChanged::ID) {
is_input_type_called = true;
last_input_type = i;
} else if (type == FrameHostMsg_SelectionChanged::ID) {
@@ -2111,7 +2100,7 @@ TEST_F(RenderViewImplTest, ServiceWorkerNetworkProviderSetup) {
// See that subresource requests are also tagged with the provider's id.
EXPECT_EQ(frame(), RenderFrameImpl::FromWebFrame(GetMainFrame()));
blink::WebURLRequest request(GURL("http://foo.com"));
- request.SetRequestContext(blink::WebURLRequest::kRequestContextSubresource);
+ request.SetRequestContext(blink::mojom::RequestContextType::SUBRESOURCE);
blink::WebURLResponse redirect_response;
webprovider->WillSendRequest(request);
extra_data = static_cast<RequestExtraData*>(request.GetExtraData());
@@ -2143,11 +2132,11 @@ TEST_F(RenderViewImplTest, RendererNavigationStartTransmittedToBrowser) {
frame()->GetWebFrame()->LoadHTMLString(
"hello world", blink::WebURL(GURL("data:text/html,")));
- FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params =
- ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
- base::TimeTicks transmitted_start = std::get<2>(host_nav_params);
- EXPECT_FALSE(transmitted_start.is_null());
- EXPECT_LE(lower_bound_navigation_start, transmitted_start);
+ NavigationState* navigation_state = NavigationState::FromDocumentLoader(
+ frame()->GetWebFrame()->GetProvisionalDocumentLoader());
+ EXPECT_FALSE(navigation_state->common_params().navigation_start.is_null());
+ EXPECT_LE(lower_bound_navigation_start,
+ navigation_state->common_params().navigation_start);
}
// Checks that a browser-initiated navigation in an initial document that was
@@ -2158,9 +2147,10 @@ TEST_F(RenderViewImplTest, BrowserNavigationStart) {
auto common_params = MakeCommonNavigationParams(-TimeDelta::FromSeconds(1));
frame()->Navigate(common_params, RequestNavigationParams());
- FrameHostMsg_DidStartProvisionalLoad::Param nav_params =
- ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
- EXPECT_EQ(common_params.navigation_start, std::get<2>(nav_params));
+ NavigationState* navigation_state = NavigationState::FromDocumentLoader(
+ frame()->GetWebFrame()->GetProvisionalDocumentLoader());
+ EXPECT_EQ(common_params.navigation_start,
+ navigation_state->common_params().navigation_start);
}
// Sanity check for the Navigation Timing API |navigationStart| override. We
@@ -2194,9 +2184,10 @@ TEST_F(RenderViewImplTest, NavigationStartWhenInitialDocumentWasAccessed) {
auto common_params = MakeCommonNavigationParams(-TimeDelta::FromSeconds(1));
frame()->Navigate(common_params, RequestNavigationParams());
- FrameHostMsg_DidStartProvisionalLoad::Param nav_params =
- ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
- EXPECT_EQ(common_params.navigation_start, std::get<2>(nav_params));
+ NavigationState* navigation_state = NavigationState::FromDocumentLoader(
+ frame()->GetWebFrame()->GetProvisionalDocumentLoader());
+ EXPECT_EQ(common_params.navigation_start,
+ navigation_state->common_params().navigation_start);
}
TEST_F(RenderViewImplTest, NavigationStartForReload) {
@@ -2216,11 +2207,11 @@ TEST_F(RenderViewImplTest, NavigationStartForReload) {
// be fired during Navigate.
frame()->Navigate(common_params, RequestNavigationParams());
- FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params =
- ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
-
// The browser navigation_start is always used.
- EXPECT_EQ(common_params.navigation_start, std::get<2>(host_nav_params));
+ NavigationState* navigation_state = NavigationState::FromDocumentLoader(
+ frame()->GetWebFrame()->GetProvisionalDocumentLoader());
+ EXPECT_EQ(common_params.navigation_start,
+ navigation_state->common_params().navigation_start);
}
TEST_F(RenderViewImplTest, NavigationStartForSameProcessHistoryNavigation) {
@@ -2241,12 +2232,12 @@ TEST_F(RenderViewImplTest, NavigationStartForSameProcessHistoryNavigation) {
FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;
GoToOffsetWithParams(-1, back_state, common_params_back,
RequestNavigationParams());
- FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params =
- ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
+ NavigationState* navigation_state = NavigationState::FromDocumentLoader(
+ frame()->GetWebFrame()->GetDocumentLoader());
// The browser navigation_start is always used.
- EXPECT_EQ(common_params_back.navigation_start, std::get<2>(host_nav_params));
- render_thread_->sink().ClearMessages();
+ EXPECT_EQ(common_params_back.navigation_start,
+ navigation_state->common_params().navigation_start);
// Go forward.
CommonNavigationParams common_params_forward;
@@ -2257,10 +2248,10 @@ TEST_F(RenderViewImplTest, NavigationStartForSameProcessHistoryNavigation) {
FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;
GoToOffsetWithParams(1, forward_state, common_params_forward,
RequestNavigationParams());
- FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params2 =
- ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
+ navigation_state = NavigationState::FromDocumentLoader(
+ frame()->GetWebFrame()->GetDocumentLoader());
EXPECT_EQ(common_params_forward.navigation_start,
- std::get<2>(host_nav_params2));
+ navigation_state->common_params().navigation_start);
}
TEST_F(RenderViewImplTest, NavigationStartForCrossProcessHistoryNavigation) {
@@ -2278,9 +2269,10 @@ TEST_F(RenderViewImplTest, NavigationStartForCrossProcessHistoryNavigation) {
request_params.current_history_list_length = 1;
frame()->Navigate(common_params, request_params);
- FrameHostMsg_DidStartProvisionalLoad::Param host_nav_params =
- ProcessAndReadIPC<FrameHostMsg_DidStartProvisionalLoad>();
- EXPECT_EQ(std::get<2>(host_nav_params), common_params.navigation_start);
+ NavigationState* navigation_state = NavigationState::FromDocumentLoader(
+ frame()->GetWebFrame()->GetProvisionalDocumentLoader());
+ EXPECT_EQ(common_params.navigation_start,
+ navigation_state->common_params().navigation_start);
}
TEST_F(RenderViewImplTest, PreferredSizeZoomed) {
diff --git a/chromium/content/renderer/render_view_impl.cc b/chromium/content/renderer/render_view_impl.cc
index 215c4a750f0..bc72fadb307 100644
--- a/chromium/content/renderer/render_view_impl.cc
+++ b/chromium/content/renderer/render_view_impl.cc
@@ -41,7 +41,6 @@
#include "cc/paint/skia_paint_canvas.h"
#include "cc/trees/layer_tree_host.h"
#include "content/common/content_constants_internal.h"
-#include "content/common/dom_storage/dom_storage_namespace_ids.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/common/drag_messages.h"
#include "content/common/frame_messages.h"
@@ -64,7 +63,6 @@
#include "content/public/common/web_preferences.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/document_state.h"
-#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_view_observer.h"
#include "content/public/renderer/render_view_visitor.h"
#include "content/public/renderer/window_features_converter.h"
@@ -83,7 +81,6 @@
#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
-#include "content/renderer/navigation_state_impl.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_frame_proxy.h"
#include "content/renderer/render_process.h"
@@ -109,6 +106,7 @@
#include "ppapi/buildflags/buildflags.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/common/dom_storage/session_storage_namespace_id.h"
#include "third_party/blink/public/common/frame/user_activation_update_source.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
@@ -152,6 +150,7 @@
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_navigation_policy.h"
#include "third_party/blink/public/web/web_page_importance_signals.h"
+#include "third_party/blink/public/web/web_page_popup.h"
#include "third_party/blink/public/web/web_plugin.h"
#include "third_party/blink/public/web/web_plugin_action.h"
#include "third_party/blink/public/web/web_range.h"
@@ -381,8 +380,7 @@ UScriptCode GetScriptForWebSettings(UScriptCode scriptCode) {
void ApplyFontsFromMap(const ScriptFontFamilyMap& map,
SetFontFamilyWrapper setter,
WebSettings* settings) {
- for (ScriptFontFamilyMap::const_iterator it = map.begin(); it != map.end();
- ++it) {
+ for (auto it = map.begin(); it != map.end(); ++it) {
int32_t script = u_getPropertyValueEnum(UCHAR_SCRIPT, (it->first).c_str());
if (script >= 0 && script < USCRIPT_CODE_LIMIT) {
UScriptCode code = static_cast<UScriptCode>(script);
@@ -420,13 +418,31 @@ content::mojom::WindowContainerType WindowFeaturesToContainerType(
}
}
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+// Check content::BrowserControlsState, and cc::BrowserControlsState
+// are kept in sync.
+static_assert(int(BROWSER_CONTROLS_STATE_SHOWN) ==
+ int(cc::BrowserControlsState::kShown),
+ "mismatching enums: SHOWN");
+static_assert(int(BROWSER_CONTROLS_STATE_HIDDEN) ==
+ int(cc::BrowserControlsState::kHidden),
+ "mismatching enums: HIDDEN");
+static_assert(int(BROWSER_CONTROLS_STATE_BOTH) ==
+ int(cc::BrowserControlsState::kBoth),
+ "mismatching enums: BOTH");
+
+cc::BrowserControlsState ContentToCc(BrowserControlsState state) {
+ return static_cast<cc::BrowserControlsState>(state);
+}
+#endif
+
} // namespace
RenderViewImpl::RenderViewImpl(CompositorDependencies* compositor_deps,
const mojom::CreateViewParams& params)
: RenderWidget(params.main_frame_widget_routing_id,
compositor_deps,
- blink::kWebPopupTypeNone,
+ WidgetType::kFrame,
params.visual_properties.screen_info,
params.visual_properties.display_mode,
params.swapped_out,
@@ -438,6 +454,8 @@ RenderViewImpl::RenderViewImpl(CompositorDependencies* compositor_deps,
webkit_preferences_(params.web_preferences),
session_storage_namespace_id_(params.session_storage_namespace_id),
weak_ptr_factory_(this) {
+ DCHECK(!session_storage_namespace_id_.empty())
+ << "Session storage namespace must be populated.";
GetWidget()->set_owner_delegate(this);
RenderThread::Get()->AddRoute(routing_id_, this);
}
@@ -446,11 +464,8 @@ void RenderViewImpl::Initialize(
mojom::CreateViewParamsPtr params,
RenderWidget::ShowCallback show_callback,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- bool has_show_callback = !!show_callback;
#if defined(OS_ANDROID)
- // TODO(sgurun): crbug.com/325351 Needed only for android webview's deprecated
- // HandleNavigation codepath.
- was_created_by_renderer_ = has_show_callback;
+ bool has_show_callback = !!show_callback;
#endif
WebFrame* opener_frame =
@@ -471,9 +486,6 @@ void RenderViewImpl::Initialize(
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kStatsCollectionController))
- stats_collection_observer_.reset(new StatsCollectionObserver(this));
-
webview()->SetDisplayMode(GetWidget()->display_mode());
webview()->GetSettings()->SetThreadedScrollingEnabled(
!command_line.HasSwitch(switches::kDisableThreadedScrolling));
@@ -518,6 +530,10 @@ void RenderViewImpl::Initialize(
ApplyBlinkSettings(command_line, webview()->GetSettings());
+ // We have either a main frame or a proxy routing id.
+ DCHECK_NE(params->main_frame_routing_id != MSG_ROUTING_NONE,
+ params->proxy_routing_id != MSG_ROUTING_NONE);
+
if (params->main_frame_routing_id != MSG_ROUTING_NONE) {
CHECK(params->main_frame_interface_provider.is_valid());
service_manager::mojom::InterfaceProviderPtr main_frame_interface_provider(
@@ -529,12 +545,9 @@ void RenderViewImpl::Initialize(
GetWidget()->GetWebScreenInfo(), GetWidget()->compositor_deps(),
opener_frame, params->devtools_main_frame_token,
params->replicated_frame_state, params->has_committed_real_load);
- }
- // TODO(dcheng): Shouldn't these be mutually exclusive at this point? See
- // https://crbug.com/720116 where the browser is apparently sending both
- // routing IDs...
- if (params->proxy_routing_id != MSG_ROUTING_NONE) {
+ main_render_frame_->Initialize();
+ } else {
CHECK(params->swapped_out);
RenderFrameProxy::CreateFrameProxy(params->proxy_routing_id, GetRoutingID(),
opener_frame, MSG_ROUTING_NONE,
@@ -542,17 +555,6 @@ void RenderViewImpl::Initialize(
params->devtools_main_frame_token);
}
- if (main_render_frame_)
- main_render_frame_->Initialize();
-
- // If this RenderView's creation was initiated by an opener page in this
- // process, (e.g. window.open()), we won't be visible until we ask the opener,
- // via |show_callback|, to make us visible. Otherwise, we went through a
- // browser-initiated creation, and Show() won't be called. In this case, no
- // |show_callback| is given to inform that Show() won't be called.
- if (!has_show_callback)
- RenderWidget::set_did_show();
-
// TODO(davidben): Move this state from Blink into content.
if (params->window_was_created_with_opener)
webview()->SetOpenedByDOM();
@@ -560,12 +562,22 @@ void RenderViewImpl::Initialize(
UpdateWebViewWithDeviceScaleFactor();
OnSetRendererPrefs(params->renderer_preferences);
OnSynchronizeVisualProperties(params->visual_properties);
- RenderWidget::SetUpIdleUserDetector();
GetContentClient()->renderer()->RenderViewCreated(this);
page_zoom_level_ = 0;
nav_state_sync_timer_.SetTaskRunner(task_runner);
+
+#if defined(OS_ANDROID)
+ // TODO(sgurun): crbug.com/325351 Needed only for android webview's deprecated
+ // HandleNavigation codepath.
+ // Renderer-created RenderViews have a ShowCallback because they send a Show
+ // request (ViewHostMsg_ShowWidget, ViewHostMsg_ShowFullscreenWidget, or
+ // FrameHostMsg_ShowCreatedWindow) to the browser to attach them to the UI
+ // there. Browser-created RenderViews do not send a Show request to the
+ // browser, so have no such callback.
+ was_created_by_renderer_ = has_show_callback;
+#endif
}
RenderViewImpl::~RenderViewImpl() {
@@ -598,7 +610,7 @@ RenderViewImpl::~RenderViewImpl() {
/*static*/
RenderViewImpl* RenderViewImpl::FromWebView(WebView* webview) {
ViewMap* views = g_view_map.Pointer();
- ViewMap::iterator it = views->find(webview);
+ auto it = views->find(webview);
return it == views->end() ? NULL : it->second;
}
@@ -610,7 +622,7 @@ RenderView* RenderView::FromWebView(blink::WebView* webview) {
/*static*/
RenderViewImpl* RenderViewImpl::FromRoutingID(int32_t routing_id) {
RoutingIDViewMap* views = g_routing_id_view_map.Pointer();
- RoutingIDViewMap::iterator it = views->find(routing_id);
+ auto it = views->find(routing_id);
return it == views->end() ? NULL : it->second;
}
@@ -627,7 +639,7 @@ size_t RenderView::GetRenderViewCount() {
/*static*/
void RenderView::ForEach(RenderViewVisitor* visitor) {
ViewMap* views = g_view_map.Pointer();
- for (ViewMap::iterator it = views->begin(); it != views->end(); ++it) {
+ for (auto it = views->begin(); it != views->end(); ++it) {
if (!visitor->Visit(it->second))
return;
}
@@ -804,6 +816,9 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
settings->SetTextAutosizingEnabled(prefs.text_autosizing_enabled);
settings->SetDoubleTapToZoomEnabled(prefs.double_tap_to_zoom_enabled);
+ blink::WebNetworkStateNotifier::SetNetworkQualityWebHoldback(
+ static_cast<blink::WebEffectiveConnectionType>(
+ prefs.network_quality_estimator_web_holdback));
#if defined(OS_ANDROID)
settings->SetAllowCustomScrollbarInMainFrame(false);
@@ -904,8 +919,6 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
settings->SetSmoothScrollForFindEnabled(prefs.smooth_scroll_for_find_enabled);
settings->SetHideDownloadUI(prefs.hide_download_ui);
- WebRuntimeFeatures::EnableBackgroundVideoTrackOptimization(
- prefs.background_video_track_optimization_enabled);
WebRuntimeFeatures::EnableNewRemotePlaybackPipeline(
base::FeatureList::IsEnabled(media::kNewRemotePlaybackPipeline));
@@ -920,7 +933,7 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
settings->SetPictureInPictureEnabled(
prefs.picture_in_picture_enabled &&
MediaFactory::GetVideoSurfaceLayerMode() !=
- media::WebMediaPlayerParams::SurfaceLayerMode::kNever);
+ blink::WebMediaPlayer::SurfaceLayerMode::kNever);
settings->SetDataSaverHoldbackWebApi(
prefs.data_saver_holdback_web_api_enabled);
@@ -994,7 +1007,6 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
}
#if defined(OS_MACOSX)
- settings->SetDoubleTapToZoomEnabled(true);
web_view->SetMaximumLegibleScale(prefs.default_maximum_page_scale_factor);
#endif
@@ -1072,19 +1084,6 @@ void RenderViewImpl::SetActiveForWidget(bool active) {
webview()->SetIsActive(active);
}
-void RenderViewImpl::SetBackgroundOpaqueForWidget(bool opaque) {
- if (!frame_widget_)
- return;
-
- if (opaque) {
- frame_widget_->ClearBaseBackgroundColorOverride();
- frame_widget_->ClearBackgroundColorOverride();
- } else {
- frame_widget_->SetBaseBackgroundColorOverride(SK_ColorTRANSPARENT);
- frame_widget_->SetBackgroundColorOverride(SK_ColorTRANSPARENT);
- }
-}
-
bool RenderViewImpl::SupportsMultipleWindowsForWidget() {
return webkit_preferences_.supports_multiple_windows;
}
@@ -1107,8 +1106,6 @@ void RenderViewImpl::DidCloseWidget() {
g_view_map.Get().erase(webview_);
webview_ = nullptr;
g_routing_id_view_map.Get().erase(GetRoutingID());
- // TODO(ajwong): Does this message actually get sent?
- RenderThread::Get()->Send(new ViewHostMsg_Close_ACK(GetRoutingID()));
}
void RenderViewImpl::ApplyNewSizeForWidget(const gfx::Size& old_size,
@@ -1165,15 +1162,6 @@ void RenderViewImpl::DidChangeFocusForWidget() {
BrowserPluginManager::Get()->UpdateFocusState();
}
-GURL RenderViewImpl::GetURLForGraphicsContext3DForWidget() {
- DCHECK(webview());
- WebFrame* main_frame = webview()->MainFrame();
- if (main_frame && main_frame->IsWebLocalFrame())
- return GURL(main_frame->ToWebLocalFrame()->GetDocument().Url());
- else
- return GURL("chrome://gpu/RenderViewImpl::CreateGraphicsContext3D");
-}
-
void RenderViewImpl::DidCommitCompositorFrameForWidget() {
for (auto& observer : observers_)
observer.DidCommitCompositorFrame();
@@ -1216,33 +1204,6 @@ void RenderViewImpl::SetScreenMetricsEmulationParametersForWidget(
// IPC message handlers -----------------------------------------
-void RenderViewImpl::OnSelectWordAroundCaret() {
- // TODO(ajwong): Move this into RenderWidget. http://crbug.com/545684
- // Set default values for the ACK
- bool did_select = false;
- int start_adjust = 0;
- int end_adjust = 0;
-
- if (webview()) {
- WebLocalFrame* focused_frame = GetWebView()->FocusedFrame();
- if (focused_frame) {
- GetWidget()->SetHandlingInputEvent(true);
- blink::WebRange initial_range = focused_frame->SelectionRange();
- if (!initial_range.IsNull())
- did_select = focused_frame->SelectWordAroundCaret();
- if (did_select) {
- blink::WebRange adjusted_range = focused_frame->SelectionRange();
- start_adjust =
- adjusted_range.StartOffset() - initial_range.StartOffset();
- end_adjust = adjusted_range.EndOffset() - initial_range.EndOffset();
- }
- GetWidget()->SetHandlingInputEvent(false);
- }
- }
- Send(new ViewHostMsg_SelectWordAroundCaretAck(
- GetWidget()->routing_id(), did_select, start_adjust, end_adjust));
-}
-
void RenderViewImpl::OnUpdateTargetURLAck() {
// Check if there is a targeturl waiting to be sent.
if (target_url_status_ == TARGET_PENDING)
@@ -1347,7 +1308,6 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
OnDisableScrollbarsForSmallWindows)
IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
IPC_MESSAGE_HANDLER(ViewMsg_PluginActionAt, OnPluginActionAt)
- IPC_MESSAGE_HANDLER(ViewMsg_SelectWordAroundCaret, OnSelectWordAroundCaret)
// Page messages.
IPC_MESSAGE_HANDLER(PageMsg_UpdateWindowScreenRect,
@@ -1362,9 +1322,6 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(PageMsg_UpdateScreenInfo, OnUpdateScreenInfo)
IPC_MESSAGE_HANDLER(PageMsg_SetPageFrozen, SetPageFrozen)
-#if defined(OS_MACOSX)
- IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose)
-#endif
// Adding a new message? Add platform independent ones first, then put the
// platform specific ones at the end.
@@ -1401,7 +1358,8 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
params->window_container_type = WindowFeaturesToContainerType(features);
- params->session_storage_namespace_id = AllocateSessionStorageNamespaceId();
+ params->session_storage_namespace_id =
+ blink::AllocateSessionStorageNamespaceId();
params->clone_from_session_storage_namespace_id =
session_storage_namespace_id_;
if (base::FeatureList::IsEnabled(features::kMojoSessionStorage)) {
@@ -1485,6 +1443,8 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
view_params->main_frame_widget_routing_id = reply->main_frame_widget_route_id;
view_params->session_storage_namespace_id =
reply->cloned_session_storage_namespace_id;
+ DCHECK(!view_params->session_storage_namespace_id.empty())
+ << "Session storage namespace must be populated.";
view_params->swapped_out = false;
view_params->replicated_frame_state.frame_policy.sandbox_flags =
sandbox_flags;
@@ -1510,15 +1470,61 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
return view->webview();
}
-WebWidget* RenderViewImpl::CreatePopup(blink::WebLocalFrame* creator,
- blink::WebPopupType popup_type) {
- RenderWidget* popup_widget =
- RenderWidget::CreateForPopup(this, GetWidget()->compositor_deps(),
- popup_type, GetWidget()->screen_info());
- if (!popup_widget)
+WebWidget* RenderViewImpl::CreatePopup(blink::WebLocalFrame* creator) {
+ mojom::WidgetPtr widget_channel;
+ mojom::WidgetRequest widget_channel_request =
+ mojo::MakeRequest(&widget_channel);
+
+ // Do a synchronous IPC to obtain a routing ID.
+ int32_t widget_routing_id = MSG_ROUTING_NONE;
+ bool success =
+ RenderThreadImpl::current_render_message_filter()->CreateNewWidget(
+ GetRoutingID(), std::move(widget_channel), &widget_routing_id);
+ if (!success) {
+ // When the renderer is being killed the mojo message will fail.
return nullptr;
- popup_widget->ApplyEmulatedScreenMetricsForPopupWidget(GetWidget());
- return popup_widget->GetWebWidget();
+ }
+
+ RenderWidget::ShowCallback opener_callback = base::BindOnce(
+ &RenderViewImpl::ShowCreatedPopupWidget, weak_ptr_factory_.GetWeakPtr());
+
+ // The RenderWidget associated with the RenderView. This should be the
+ // RenderWidget for the main frame, but may be a zombie RenderWidget when
+ // the main frame is remote (we don't need a RenderWidget for it then).
+ // However for now (https://crbug.com/419087) we know it exists and grab
+ // state off it for the popup.
+ // TODO(crbug.com/419087): This should probably be using the local root's
+ // RenderWidget for the frame making the popup.
+ RenderWidget* view_render_widget = GetWidget();
+
+ auto popup_widget = base::MakeRefCounted<RenderWidget>(
+ widget_routing_id, view_render_widget->compositor_deps(),
+ WidgetType::kPopup, view_render_widget->screen_info(),
+ blink::kWebDisplayModeUndefined,
+ /*swapped_out=*/false,
+ /*hidden=*/false,
+ /*never_visible=*/false, std::move(widget_channel_request));
+
+ // The returned WebPagePopup is self-referencing, so the pointer here is not
+ // an owning pointer.
+ blink::WebPagePopup* popup_web_widget =
+ blink::WebPagePopup::Create(popup_widget.get());
+
+ // Adds a self-reference on the |popup_widget| so it will not be destroyed
+ // when leaving scope. The WebPagePopup takes responsibility for Close()ing
+ // and thus destroying the RenderWidget.
+ popup_widget->InitForPopup(std::move(opener_callback), popup_web_widget);
+ // TODO(crbug.com/419087): RenderWidget has some weird logic for picking a
+ // WebWidget which doesn't apply to this case. So we verify. This can go away
+ // when RenderWidget::GetWebWidget() is just a simple accessor.
+ DCHECK_EQ(popup_widget->GetWebWidget(), popup_web_widget);
+
+ // Devtools emulation, which may be currently applied to the
+ // |view_render_widget|, should also apply to the new popup. This doesn't
+ // happen automatically.
+ popup_widget->ApplyEmulatedScreenMetricsForPopupWidget(view_render_widget);
+
+ return popup_web_widget;
}
base::StringPiece RenderViewImpl::GetSessionStorageNamespaceId() {
@@ -1550,27 +1556,6 @@ bool RenderViewImpl::EnumerateChosenDirectory(
GetRoutingID(), id, blink::WebStringToFilePath(path)));
}
-void RenderViewImpl::FrameDidStartLoading(WebFrame* frame) {
- DCHECK_GE(frames_in_progress_, 0);
- if (frames_in_progress_ == 0) {
- for (auto& observer : observers_)
- observer.DidStartLoading();
- }
- frames_in_progress_++;
-}
-
-void RenderViewImpl::FrameDidStopLoading(WebFrame* frame) {
- // TODO(japhet): This should be a DCHECK, but the pdf plugin sometimes
- // calls DidStopLoading() without a matching DidStartLoading().
- if (frames_in_progress_ == 0)
- return;
- frames_in_progress_--;
- if (frames_in_progress_ == 0) {
- for (auto& observer : observers_)
- observer.DidStopLoading();
- }
-}
-
void RenderViewImpl::AttachWebFrameWidget(blink::WebFrameWidget* frame_widget) {
// The previous WebFrameWidget must already be detached by CloseForFrame().
DCHECK(!frame_widget_);
@@ -1712,7 +1697,8 @@ void RenderViewImpl::DidUpdateMainFrameLayout() {
needs_preferred_size_update_ = true;
}
-void RenderViewImpl::NavigateBackForwardSoon(int offset) {
+void RenderViewImpl::NavigateBackForwardSoon(int offset,
+ bool has_user_gesture) {
history_navigation_virtual_time_pauser_ =
RenderThreadImpl::current()
->GetWebMainThreadScheduler()
@@ -1720,7 +1706,8 @@ void RenderViewImpl::NavigateBackForwardSoon(int offset) {
"NavigateBackForwardSoon",
blink::WebScopedVirtualTimePauser::VirtualTaskDuration::kInstant);
history_navigation_virtual_time_pauser_.PauseVirtualTime();
- Send(new ViewHostMsg_GoToEntryAtOffset(GetRoutingID(), offset));
+ Send(new ViewHostMsg_GoToEntryAtOffset(GetRoutingID(), offset,
+ has_user_gesture));
}
void RenderViewImpl::DidCommitProvisionalHistoryLoad() {
@@ -1770,6 +1757,33 @@ const std::string& RenderViewImpl::GetAcceptLanguages() const {
return renderer_preferences_.accept_languages;
}
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+
+void RenderViewImpl::UpdateBrowserControlsState(
+ BrowserControlsState constraints,
+ BrowserControlsState current,
+ bool animate) {
+ if (GetWebWidget()) {
+ GetWebWidget()->UpdateBrowserControlsState(ContentToCc(constraints),
+ ContentToCc(current), animate);
+ }
+
+ top_controls_constraints_ = constraints;
+}
+
+void RenderViewImpl::didScrollWithKeyboard(const blink::WebSize& delta) {
+ if (delta.height == 0)
+ return;
+
+ BrowserControlsState current = delta.height < 0
+ ? BROWSER_CONTROLS_STATE_SHOWN
+ : BROWSER_CONTROLS_STATE_HIDDEN;
+
+ UpdateBrowserControlsState(top_controls_constraints_, current, true);
+}
+
+#endif
+
void RenderViewImpl::ConvertViewportToWindowViaWidget(blink::WebRect* rect) {
WidgetClient()->ConvertViewportToWindow(rect);
}
@@ -1980,17 +1994,6 @@ void RenderViewImpl::OnClosePage() {
Send(new ViewHostMsg_ClosePage_ACK(GetRoutingID()));
}
-#if defined(OS_MACOSX)
-void RenderViewImpl::OnClose() {
- if (GetWidget()->closing())
- RenderThread::Get()->Send(new ViewHostMsg_Close_ACK(GetRoutingID()));
- // This method is protected for OS_MACOSX only, because the message gets sent
- // to the RenderViewImpl instead of to the RenderWidget.
- // TODO(danakj): Move this message to RenderWidget?
- RenderWidget::OnClose();
-}
-#endif
-
void RenderViewImpl::OnMoveOrResizeStarted() {
if (webview())
webview()->HidePopups();
diff --git a/chromium/content/renderer/render_view_impl.h b/chromium/content/renderer/render_view_impl.h
index fc982820b97..6e08aba4a3c 100644
--- a/chromium/content/renderer/render_view_impl.h
+++ b/chromium/content/renderer/render_view_impl.h
@@ -27,8 +27,6 @@
#include "cc/input/browser_controls_state.h"
#include "content/common/content_export.h"
#include "content/common/frame_message_enums.h"
-#include "content/common/navigation_gesture.h"
-#include "content/common/view_message_enums.h"
#include "content/public/common/browser_controls_state.h"
#include "content/public/common/drop_data.h"
#include "content/public/common/page_zoom.h"
@@ -40,7 +38,6 @@
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_widget.h"
#include "content/renderer/render_widget_owner_delegate.h"
-#include "content/renderer/stats_collection_observer.h"
#include "ipc/ipc_platform_file.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "third_party/blink/public/platform/web_input_event.h"
@@ -79,21 +76,30 @@ class RendererDateTimePicker;
class RenderViewImplTest;
class RenderViewObserver;
class RenderViewTest;
-struct FileChooserParams;
namespace mojom {
class CreateViewParams;
}
+// RenderViewImpl (the implementation of RenderView) is the renderer process
+// object that owns the blink frame tree.
//
-// RenderView is an object that manages a WebView object, and provides a
-// communication interface with an embedding application process.
+// Each top-level web container has a frame tree, and thus a RenderViewImpl.
+// Typically such a container is a browser tab, or a tab-less window. It can
+// also be other cases such as a background page or extension.
//
-// DEPRECATED: RenderViewImpl is being removed as part of the SiteIsolation
-// project. New code should be added to RenderFrameImpl instead.
+// Under site isolation, frames in the main frame's tree may be moved out
+// to a separate frame tree (possibly in another process), leaving remote
+// placeholders behind. Each such frame tree also includes a RenderViewImpl as
+// the owner of it. Thus a tab may have multiple RenderViewImpls, one for the
+// main frame, and one for each other frame tree generated.
//
-// For context, please see https://crbug.com/467770 and
-// https://www.chromium.org/developers/design-documents/site-isolation.
+// The RenderViewImpl manages a WebView object from blink, which hosts the
+// web page and a blink frame tree. If the main frame (root of the tree) is
+// a local frame for this view, then it also manages a RenderWidget for the
+// main frame.
+//
+// TODO(419087): That RenderWidget should be managed by the main frame itself.
class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
public blink::WebViewClient,
public RenderWidgetOwnerDelegate,
@@ -147,30 +153,10 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
void AddObserver(RenderViewObserver* observer);
void RemoveObserver(RenderViewObserver* observer);
- // Returns the StatsCollectionObserver associated with this view, or NULL
- // if one wasn't created;
- StatsCollectionObserver* GetStatsCollectionObserver() {
- return stats_collection_observer_.get();
- }
-
- // Adds the given file chooser request to the file_chooser_completion_ queue
- // (see that var for more) and requests the chooser be displayed if there are
- // no other waiting items in the queue.
- //
- // Returns true if the chooser was successfully scheduled. False means we
- // didn't schedule anything.
- bool ScheduleFileChooser(const FileChooserParams& params,
- blink::WebFileChooserCompletion* completion);
-
#if defined(OS_ANDROID)
void DismissDateTimeDialog();
#endif
- bool is_loading() const { return frames_in_progress_ != 0; }
-
- void FrameDidStartLoading(blink::WebFrame* frame);
- void FrameDidStopLoading(blink::WebFrame* frame);
-
// Sets the zoom level and notifies observers.
void SetZoomLevel(double zoom_level);
@@ -226,8 +212,7 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
blink::WebNavigationPolicy policy,
bool suppress_opener,
blink::WebSandboxFlags sandbox_flags) override;
- blink::WebWidget* CreatePopup(blink::WebLocalFrame* creator,
- blink::WebPopupType popup_type) override;
+ blink::WebWidget* CreatePopup(blink::WebLocalFrame* creator) override;
base::StringPiece GetSessionStorageNamespaceId() override;
void PrintPage(blink::WebLocalFrame* frame) override;
bool EnumerateChosenDirectory(
@@ -247,7 +232,7 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
bool CanUpdateLayout() override;
void DidUpdateMainFrameLayout() override;
blink::WebString AcceptLanguages() override;
- void NavigateBackForwardSoon(int offset) override;
+ void NavigateBackForwardSoon(int offset, bool has_user_gesture) override;
int HistoryBackListCount() override;
int HistoryForwardListCount() override;
void ZoomLimitsChanged(double minimum_level, double maximum_level) override;
@@ -266,7 +251,6 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
// date and time input fields using MULTIPLE_FIELDS_UI
bool OpenDateTimeChooser(const blink::WebDateTimeChooserParams&,
blink::WebDateTimeChooserCompletion*) override;
- virtual void didScrollWithKeyboard(const blink::WebSize& delta);
#endif
// RenderView implementation -------------------------------------------------
@@ -287,10 +271,11 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
const std::string& value) override;
void ClearEditCommands() override;
const std::string& GetAcceptLanguages() const override;
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
void UpdateBrowserControlsState(BrowserControlsState constraints,
BrowserControlsState current,
bool animate) override;
+ virtual void didScrollWithKeyboard(const blink::WebSize& delta);
#endif
void ConvertViewportToWindowViaWidget(blink::WebRect* rect) override;
gfx::RectF ElementBoundsInWindow(const blink::WebElement& element) override;
@@ -392,7 +377,6 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
bool RenderWidgetWillHandleMouseEventForWidget(
const blink::WebMouseEvent& event) override;
void SetActiveForWidget(bool active) override;
- void SetBackgroundOpaqueForWidget(bool opaque) override;
bool SupportsMultipleWindowsForWidget() override;
void DidHandleGestureEventForWidget(
const blink::WebGestureEvent& event) override;
@@ -408,7 +392,6 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
void ScrollFocusedNodeIntoViewForWidget() override;
void DidReceiveSetFocusEventForWidget() override;
void DidChangeFocusForWidget() override;
- GURL GetURLForGraphicsContext3DForWidget() override;
void DidCommitCompositorFrameForWidget() override;
void DidCompletePageScaleAnimationForWidget() override;
void ResizeWebWidgetForWidget(
@@ -448,9 +431,6 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
void OnAllowScriptToClose(bool script_can_close);
void OnCancelDownload(int32_t download_id);
void OnClosePage();
-#if defined(OS_MACOSX)
- void OnClose();
-#endif
void OnDeterminePageLanguage();
void OnDisableScrollbarsForSmallWindows(
@@ -470,7 +450,6 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
void OnUpdateTargetURLAck();
void OnUpdateWebPreferences(const WebPreferences& prefs);
void OnSetPageScale(float page_scale_factor);
- void OnSelectWordAroundCaret();
void OnAudioStateChanged(bool is_audio_playing);
void OnPausePageScheduledTasks(bool paused);
@@ -519,13 +498,6 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
return observers_;
}
- NavigationGesture navigation_gesture() {
- return navigation_gesture_;
- }
- void set_navigation_gesture(NavigationGesture gesture) {
- navigation_gesture_ = gesture;
- }
-
// Platform specific theme preferences if any are updated here.
#if defined(OS_WIN)
void UpdateThemePrefs();
@@ -581,10 +553,6 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
// Loading state -------------------------------------------------------------
- // The gesture that initiated the current navigation.
- // TODO(nasko): Move to RenderFrame, as this is per-frame state.
- NavigationGesture navigation_gesture_ = NavigationGestureUnknown;
-
// Timer used to delay the updating of nav state (see
// StartNavStateSyncTimerIfNecessary).
base::OneShotTimer nav_state_sync_timer_;
@@ -605,12 +573,6 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
// process.
int history_list_length_ = 0;
- // Counter to track how many frames have sent start notifications but not stop
- // notifications.
- // TODO(avi): Remove this once FrameDidStartLoading/FrameDidStopLoading are
- // gone.
- int frames_in_progress_ = 0;
-
// UI state ------------------------------------------------------------------
// The state of our target_url transmissions. When we receive a request to
@@ -642,7 +604,7 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
// The next target URL we want to send to the browser.
GURL pending_target_url_;
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
// Cache the old browser controls state constraints. Used when updating
// current value only without altering the constraints.
BrowserControlsState top_controls_constraints_ = BROWSER_CONTROLS_STATE_BOTH;
@@ -693,10 +655,6 @@ class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
// is fine.
base::ObserverList<RenderViewObserver>::Unchecked observers_;
- // NOTE: stats_collection_observer_ should be the last members because their
- // constructors call the AddObservers method of RenderViewImpl.
- std::unique_ptr<StatsCollectionObserver> stats_collection_observer_;
-
blink::WebScopedVirtualTimePauser history_navigation_virtual_time_pauser_;
// ---------------------------------------------------------------------------
diff --git a/chromium/content/renderer/render_view_impl_android.cc b/chromium/content/renderer/render_view_impl_android.cc
deleted file mode 100644
index f6835cd2ef5..00000000000
--- a/chromium/content/renderer/render_view_impl_android.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/render_view_impl.h"
-
-#include "base/command_line.h"
-#include "cc/trees/layer_tree_host.h"
-#include "content/common/view_messages.h"
-#include "content/renderer/gpu/layer_tree_view.h"
-#include "third_party/blink/public/web/web_view.h"
-
-namespace content {
-
-// Check content::BrowserControlsState, and cc::BrowserControlsState
-// are kept in sync.
-static_assert(int(BROWSER_CONTROLS_STATE_SHOWN) ==
- int(cc::BrowserControlsState::kShown),
- "mismatching enums: SHOWN");
-static_assert(int(BROWSER_CONTROLS_STATE_HIDDEN) ==
- int(cc::BrowserControlsState::kHidden),
- "mismatching enums: HIDDEN");
-static_assert(int(BROWSER_CONTROLS_STATE_BOTH) ==
- int(cc::BrowserControlsState::kBoth),
- "mismatching enums: BOTH");
-
-cc::BrowserControlsState ContentToCc(BrowserControlsState state) {
- return static_cast<cc::BrowserControlsState>(state);
-}
-
-void RenderViewImpl::UpdateBrowserControlsState(
- BrowserControlsState constraints,
- BrowserControlsState current,
- bool animate) {
- if (GetWebWidget()) {
- GetWebWidget()->UpdateBrowserControlsState(ContentToCc(constraints),
- ContentToCc(current), animate);
- }
-
- top_controls_constraints_ = constraints;
-}
-
-void RenderViewImpl::didScrollWithKeyboard(const blink::WebSize& delta) {
- if (delta.height == 0)
- return;
-
- BrowserControlsState current = delta.height < 0
- ? BROWSER_CONTROLS_STATE_SHOWN
- : BROWSER_CONTROLS_STATE_HIDDEN;
-
- UpdateBrowserControlsState(top_controls_constraints_, current, true);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/render_widget.cc b/chromium/content/renderer/render_widget.cc
index 6d0580d5b0b..06378122ec8 100644
--- a/chromium/content/renderer/render_widget.cc
+++ b/chromium/content/renderer/render_widget.cc
@@ -45,6 +45,7 @@
#include "content/common/tab_switching_time_callback.h"
#include "content/common/text_input_state.h"
#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
@@ -61,7 +62,6 @@
#include "content/renderer/gpu/frame_swap_message_queue.h"
#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/gpu/queue_message_swap_promise.h"
-#include "content/renderer/idle_user_detector.h"
#include "content/renderer/ime_event_guard.h"
#include "content/renderer/input/main_thread_event_queue.h"
#include "content/renderer/input/widget_input_handler_manager.h"
@@ -95,7 +95,6 @@
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/public/web/web_autofill_client.h"
#include "third_party/blink/public/web/web_device_emulation_params.h"
#include "third_party/blink/public/web/web_frame_widget.h"
@@ -159,7 +158,6 @@ using blink::WebNavigationPolicy;
using blink::WebNode;
using blink::WebPagePopup;
using blink::WebPoint;
-using blink::WebPopupType;
using blink::WebRange;
using blink::WebRect;
using blink::WebSize;
@@ -184,6 +182,8 @@ const base::Feature kUnpremultiplyAndDitherLowBitDepthTiles = {
typedef std::map<std::string, ui::TextInputMode> TextInputModeMap;
static const int kInvalidNextPreviousFlagsValue = -1;
+static const char* kOOPIF = "OOPIF";
+static const char* kRenderer = "Renderer";
class WebWidgetLockTarget : public content::MouseLockDispatcher::LockTarget {
public:
@@ -298,9 +298,7 @@ WebDragData DropDataToWebDragData(const DropData& drop_data) {
item_list.push_back(item);
}
- for (std::vector<ui::FileInfo>::const_iterator it =
- drop_data.filenames.begin();
- it != drop_data.filenames.end();
+ for (auto it = drop_data.filenames.begin(); it != drop_data.filenames.end();
++it) {
WebDragData::Item item;
item.storage_type = WebDragData::Item::kStorageTypeFilename;
@@ -310,10 +308,8 @@ WebDragData DropDataToWebDragData(const DropData& drop_data) {
item_list.push_back(item);
}
- for (std::vector<DropData::FileSystemFileInfo>::const_iterator it =
- drop_data.file_system_files.begin();
- it != drop_data.file_system_files.end();
- ++it) {
+ for (auto it = drop_data.file_system_files.begin();
+ it != drop_data.file_system_files.end(); ++it) {
WebDragData::Item item;
item.storage_type = WebDragData::Item::kStorageTypeFileSystemFile;
item.file_system_url = it->url;
@@ -337,12 +333,6 @@ WebDragData DropDataToWebDragData(const DropData& drop_data) {
return result;
}
-content::RenderWidget::CreateRenderWidgetFunction g_create_render_widget =
- nullptr;
-
-content::RenderWidget::RenderWidgetInitializedCallback
- g_render_widget_initialized = nullptr;
-
ui::TextInputType ConvertWebTextInputType(blink::WebTextInputType type) {
// Check the type is in the range representable by ui::TextInputType.
DCHECK_LE(type, static_cast<int>(ui::TEXT_INPUT_TYPE_MAX))
@@ -388,22 +378,20 @@ static bool PreferCompositingToLCDText(CompositorDependencies* compositor_deps,
// RenderWidget ---------------------------------------------------------------
-RenderWidget::RenderWidget(
- int32_t widget_routing_id,
- CompositorDependencies* compositor_deps,
- blink::WebPopupType popup_type,
- const ScreenInfo& screen_info,
- blink::WebDisplayMode display_mode,
- bool swapped_out,
- bool hidden,
- bool never_visible,
- mojom::WidgetRequest widget_request)
+RenderWidget::RenderWidget(int32_t widget_routing_id,
+ CompositorDependencies* compositor_deps,
+ WidgetType widget_type,
+ const ScreenInfo& screen_info,
+ blink::WebDisplayMode display_mode,
+ bool swapped_out,
+ bool hidden,
+ bool never_visible,
+ mojom::WidgetRequest widget_request)
: routing_id_(widget_routing_id),
compositor_deps_(compositor_deps),
webwidget_internal_(nullptr),
owner_delegate_(nullptr),
auto_resize_mode_(false),
- did_show_(false),
is_hidden_(hidden),
compositor_never_visible_(never_visible),
is_fullscreen_granted_(false),
@@ -418,7 +406,7 @@ RenderWidget::RenderWidget(
next_previous_flags_(kInvalidNextPreviousFlagsValue),
can_compose_inline_(true),
composition_range_(gfx::Range::InvalidRange()),
- popup_type_(popup_type),
+ widget_type_(widget_type),
pending_window_rect_count_(0),
screen_info_(screen_info),
monitor_composition_info_(false),
@@ -437,10 +425,6 @@ RenderWidget::RenderWidget(
widget_binding_(this, std::move(widget_request)),
weak_ptr_factory_(this) {
DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
- // TODO(nasko, alexmos): ref count the process based on the lifetime of
- // RenderFrames rather than RenderWidgets.
- if (!swapped_out)
- RenderProcess::current()->AddRefProcess();
DCHECK(RenderThread::Get());
// In tests there may not be a RenderThreadImpl.
@@ -452,7 +436,7 @@ RenderWidget::RenderWidget(
}
#if defined(USE_AURA)
RendererWindowTreeClient::CreateIfNecessary(routing_id_);
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
RendererWindowTreeClient::Get(routing_id_)->SetVisible(!is_hidden_);
#endif
@@ -471,9 +455,6 @@ RenderWidget::~RenderWidget() {
if (input_event_queue_)
input_event_queue_->ClearClient();
- // If we are swapped out, we have released already.
- if (!is_swapped_out_ && RenderProcess::current())
- RenderProcess::current()->ReleaseProcess();
#if defined(USE_AURA)
// It is possible for a RenderWidget to be destroyed before it was embedded
// in a mus window. The RendererWindowTreeClient will leak in such cases. So
@@ -483,115 +464,25 @@ RenderWidget::~RenderWidget() {
}
// static
-void RenderWidget::InstallCreateHook(
- CreateRenderWidgetFunction create_render_widget,
- RenderWidgetInitializedCallback render_widget_initialized) {
- CHECK(!g_create_render_widget && !g_render_widget_initialized);
- g_create_render_widget = create_render_widget;
- g_render_widget_initialized = render_widget_initialized;
-}
-
-// static
RenderWidget* RenderWidget::FromRoutingID(int32_t routing_id) {
RoutingIDWidgetMap* widgets = g_routing_id_widget_map.Pointer();
- RoutingIDWidgetMap::iterator it = widgets->find(routing_id);
+ auto it = widgets->find(routing_id);
return it == widgets->end() ? NULL : it->second;
}
-// static
-RenderWidget* RenderWidget::CreateForPopup(
- RenderViewImpl* opener,
- CompositorDependencies* compositor_deps,
- blink::WebPopupType popup_type,
- const ScreenInfo& screen_info) {
- mojom::WidgetPtr widget_channel;
- mojom::WidgetRequest widget_channel_request =
- mojo::MakeRequest(&widget_channel);
-
- // Do a synchronous IPC to obtain a routing ID.
- int32_t routing_id = MSG_ROUTING_NONE;
- if (!RenderThreadImpl::current_render_message_filter()->CreateNewWidget(
- opener->GetRoutingID(), popup_type, std::move(widget_channel),
- &routing_id)) {
- return nullptr;
- }
-
- scoped_refptr<RenderWidget> widget(
- new RenderWidget(routing_id, compositor_deps, popup_type, screen_info,
- blink::kWebDisplayModeUndefined, false, false, false,
- std::move(widget_channel_request)));
- ShowCallback opener_callback = base::BindOnce(
- &RenderViewImpl::ShowCreatedPopupWidget, opener->GetWeakPtr());
- widget->Init(std::move(opener_callback),
- RenderWidget::CreateWebWidget(widget.get()));
- DCHECK(!widget->HasOneRef()); // RenderWidget::Init() adds a reference.
- return widget.get();
-}
-
-// static
-RenderWidget* RenderWidget::CreateForFrame(
- int widget_routing_id,
- bool hidden,
- const ScreenInfo& screen_info,
- CompositorDependencies* compositor_deps,
- blink::WebLocalFrame* frame) {
- CHECK_NE(widget_routing_id, MSG_ROUTING_NONE);
- RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame);
- // For the mainframe, the RenderWidget is attached to the RenderView.
- // TODO(ajwong): Remove this when the widget is always attached to a frame.
- // https://crbug.com/545684
- if (!frame->Parent()) {
- RenderViewImpl* view =
- static_cast<RenderViewImpl*>(render_frame->GetRenderView());
- // Use the WidgetClient() from the RenderViewImpl, rather than getting its
- // RenderWidget directly. Layout tests may inject a different
- // WebWidgetClient on the RenderViewImpl that intercepts calls before they
- // get to the RenderWidget.
- view->AttachWebFrameWidget(
- RenderWidget::CreateWebFrameWidget(view->WidgetClient(), frame));
- view->GetWidget()->UpdateWebViewWithDeviceScaleFactor();
- return view->GetWidget();
- }
- scoped_refptr<RenderWidget> widget(
- g_create_render_widget
- ? g_create_render_widget(widget_routing_id, compositor_deps,
- blink::kWebPopupTypeNone, screen_info,
- blink::kWebDisplayModeUndefined, false,
- hidden, false)
- : new RenderWidget(widget_routing_id, compositor_deps,
- blink::kWebPopupTypeNone, screen_info,
- blink::kWebDisplayModeUndefined, false, hidden,
- false));
- widget->for_oopif_ = true;
- // Init increments the reference count on |widget|, keeping it alive after
- // this function returns.
- widget->Init(base::NullCallback(),
- RenderWidget::CreateWebFrameWidget(widget.get(), frame));
- widget->UpdateWebViewWithDeviceScaleFactor();
-
- if (g_render_widget_initialized)
- g_render_widget_initialized(widget.get());
- return widget.get();
-}
-
-// static
-blink::WebFrameWidget* RenderWidget::CreateWebFrameWidget(
- blink::WebWidgetClient* widget_client,
- blink::WebLocalFrame* frame) {
- return blink::WebFrameWidget::Create(widget_client, frame);
+void RenderWidget::InitForPopup(ShowCallback show_callback,
+ blink::WebPagePopup* web_page_popup) {
+ // Init() increments the reference count on |this|, making it
+ // self-referencing.
+ Init(std::move(show_callback), web_page_popup);
}
-// static
-blink::WebWidget* RenderWidget::CreateWebWidget(RenderWidget* render_widget) {
- switch (render_widget->popup_type_) {
- case blink::kWebPopupTypeNone: // Nothing to create.
- break;
- case blink::kWebPopupTypePage:
- return WebPagePopup::Create(render_widget);
- default:
- NOTREACHED();
- }
- return nullptr;
+void RenderWidget::InitForChildLocalRoot(
+ blink::WebFrameWidget* web_frame_widget) {
+ for_oopif_ = true;
+ // Init() increments the reference count on |this|, making it
+ // self-referencing.
+ Init(base::NullCallback(), web_frame_widget);
}
void RenderWidget::CloseForFrame() {
@@ -612,20 +503,38 @@ void RenderWidget::Init(ShowCallback show_callback, WebWidget* web_widget) {
DCHECK(!webwidget_internal_);
DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
+ RenderThreadImpl* render_thread_impl = RenderThreadImpl::current();
+
input_handler_ = std::make_unique<RenderWidgetInputHandler>(this, this);
- RenderThreadImpl* render_thread_impl = RenderThreadImpl::current();
+ LayerTreeView* layer_tree_view = InitializeLayerTreeView();
+ web_widget->SetLayerTreeView(layer_tree_view);
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler = nullptr;
+ if (render_thread_impl)
+ main_thread_scheduler = render_thread_impl->GetWebMainThreadScheduler();
blink::scheduler::WebThreadScheduler* compositor_thread_scheduler =
blink::scheduler::WebThreadScheduler::CompositorThreadScheduler();
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_input_task_runner;
+ // The |compositor_thread_scheduler| can be null in tests without a compositor
+ // thread.
+ if (compositor_thread_scheduler) {
+ // When the RenderWidget is for a frame (ie for a local root) then it uses
+ // the compositor thread task runner. When it is for a popup or other such
+ // widgets, it does not.
+ // TODO(danakj): The |web_widget| given here should become a WebFrameWidget
+ // in the case the RenderWidget is for a RenderViewImpl, but currently the
+ // WebFrameWidget gets attached after RenderWidget init. So we have to check
+ // IsWebView() as well.
+ if (web_widget->IsWebFrameWidget() || web_widget->IsWebView()) {
+ compositor_input_task_runner =
+ compositor_thread_scheduler->InputTaskRunner();
+ }
+ }
widget_input_handler_manager_ = WidgetInputHandlerManager::Create(
- weak_ptr_factory_.GetWeakPtr(),
- compositor_thread_scheduler && layer_tree_view_
- ? compositor_thread_scheduler->InputTaskRunner()
- : nullptr,
- render_thread_impl ? render_thread_impl->GetWebMainThreadScheduler()
- : nullptr);
+ weak_ptr_factory_.GetWeakPtr(), std::move(compositor_input_task_runner),
+ main_thread_scheduler);
show_callback_ = std::move(show_callback);
@@ -636,7 +545,7 @@ void RenderWidget::Init(ShowCallback show_callback, WebWidget* web_widget) {
RenderThread::Get()->AddRoute(routing_id_, this);
// Take a reference on behalf of the RenderThread. This will be balanced
- // when we receive ViewMsg_Close.
+ // when we receive WidgetMsg_Close.
AddRef();
if (RenderThreadImpl::current()) {
RenderThreadImpl::current()->WidgetCreated();
@@ -645,10 +554,6 @@ void RenderWidget::Init(ShowCallback show_callback, WebWidget* web_widget) {
}
}
-void RenderWidget::SetUpIdleUserDetector() {
- idle_user_detector_ = std::make_unique<IdleUserDetector>();
-}
-
void RenderWidget::ApplyEmulatedScreenMetricsForPopupWidget(
RenderWidget* origin_widget) {
RenderWidgetScreenMetricsEmulator* emulator =
@@ -694,30 +599,30 @@ bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderWidget, message)
- IPC_MESSAGE_HANDLER(ViewMsg_ShowContextMenu, OnShowContextMenu)
- IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose)
- IPC_MESSAGE_HANDLER(ViewMsg_SynchronizeVisualProperties,
+ IPC_MESSAGE_HANDLER(WidgetMsg_ShowContextMenu, OnShowContextMenu)
+ IPC_MESSAGE_HANDLER(WidgetMsg_Close, OnClose)
+ IPC_MESSAGE_HANDLER(WidgetMsg_SynchronizeVisualProperties,
OnSynchronizeVisualProperties)
- IPC_MESSAGE_HANDLER(ViewMsg_EnableDeviceEmulation,
+ IPC_MESSAGE_HANDLER(WidgetMsg_EnableDeviceEmulation,
OnEnableDeviceEmulation)
- IPC_MESSAGE_HANDLER(ViewMsg_DisableDeviceEmulation,
+ IPC_MESSAGE_HANDLER(WidgetMsg_DisableDeviceEmulation,
OnDisableDeviceEmulation)
- IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden)
- IPC_MESSAGE_HANDLER(ViewMsg_WasShown, OnWasShown)
- IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
- IPC_MESSAGE_HANDLER(ViewMsg_SetBackgroundOpaque, OnSetBackgroundOpaque)
- IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection)
- IPC_MESSAGE_HANDLER(ViewMsg_SetBounds_ACK, OnRequestSetBoundsAck)
- IPC_MESSAGE_HANDLER(ViewMsg_UpdateScreenRects, OnUpdateScreenRects)
- IPC_MESSAGE_HANDLER(ViewMsg_ForceRedraw, OnForceRedraw)
- IPC_MESSAGE_HANDLER(ViewMsg_SetViewportIntersection,
+ IPC_MESSAGE_HANDLER(WidgetMsg_WasHidden, OnWasHidden)
+ IPC_MESSAGE_HANDLER(WidgetMsg_WasShown, OnWasShown)
+ IPC_MESSAGE_HANDLER(WidgetMsg_SetActive, OnSetActive)
+ IPC_MESSAGE_HANDLER(WidgetMsg_SetBackgroundOpaque, OnSetBackgroundOpaque)
+ IPC_MESSAGE_HANDLER(WidgetMsg_SetTextDirection, OnSetTextDirection)
+ IPC_MESSAGE_HANDLER(WidgetMsg_SetBounds_ACK, OnRequestSetBoundsAck)
+ IPC_MESSAGE_HANDLER(WidgetMsg_UpdateScreenRects, OnUpdateScreenRects)
+ IPC_MESSAGE_HANDLER(WidgetMsg_ForceRedraw, OnForceRedraw)
+ IPC_MESSAGE_HANDLER(WidgetMsg_SetViewportIntersection,
OnSetViewportIntersection)
- IPC_MESSAGE_HANDLER(ViewMsg_SetIsInert, OnSetIsInert)
- IPC_MESSAGE_HANDLER(ViewMsg_SetInheritedEffectiveTouchAction,
+ IPC_MESSAGE_HANDLER(WidgetMsg_SetIsInert, OnSetIsInert)
+ IPC_MESSAGE_HANDLER(WidgetMsg_SetInheritedEffectiveTouchAction,
OnSetInheritedEffectiveTouchAction)
- IPC_MESSAGE_HANDLER(ViewMsg_UpdateRenderThrottlingStatus,
+ IPC_MESSAGE_HANDLER(WidgetMsg_UpdateRenderThrottlingStatus,
OnUpdateRenderThrottlingStatus)
- IPC_MESSAGE_HANDLER(ViewMsg_WaitForNextFrameForTests,
+ IPC_MESSAGE_HANDLER(WidgetMsg_WaitForNextFrameForTests,
OnWaitNextFrameForTests)
IPC_MESSAGE_HANDLER(DragMsg_TargetDragEnter, OnDragTargetDragEnter)
IPC_MESSAGE_HANDLER(DragMsg_TargetDragOver, OnDragTargetDragOver)
@@ -880,7 +785,7 @@ void RenderWidget::OnEnableDeviceEmulation(
visual_properties.is_fullscreen_granted = is_fullscreen_granted_;
visual_properties.display_mode = display_mode_;
screen_metrics_emulator_.reset(new RenderWidgetScreenMetricsEmulator(
- this, params, visual_properties, view_screen_rect_,
+ this, params, visual_properties, widget_screen_rect_,
window_screen_rect_));
screen_metrics_emulator_->Apply();
} else {
@@ -900,8 +805,7 @@ void RenderWidget::OnWasHidden() {
observer.WasHidden();
}
-void RenderWidget::OnWasShown(bool needs_repainting,
- base::TimeTicks show_request_timestamp) {
+void RenderWidget::OnWasShown(base::TimeTicks show_request_timestamp) {
TRACE_EVENT0("renderer", "RenderWidget::OnWasShown");
// During shutdown we can just ignore this message.
if (!GetWebWidget())
@@ -913,9 +817,6 @@ void RenderWidget::OnWasShown(bool needs_repainting,
for (auto& observer : render_frames_)
observer.WasShown();
- if (!needs_repainting)
- return;
-
if (layer_tree_view_ && !show_request_timestamp.is_null()) {
layer_tree_view_->layer_tree_host()->RequestPresentationTimeForNextFrame(
CreateTabSwitchingTimeRecorder(show_request_timestamp));
@@ -939,7 +840,7 @@ void RenderWidget::OnForceRedraw(int snapshot_id) {
void RenderWidget::DidPresentForceDrawFrame(
int snapshot_id,
const gfx::PresentationFeedback& feedback) {
- Send(new ViewHostMsg_ForceRedrawComplete(routing_id(), snapshot_id));
+ Send(new WidgetHostMsg_ForceRedrawComplete(routing_id(), snapshot_id));
}
viz::FrameSinkId RenderWidget::GetFrameSinkIdAtPoint(const gfx::Point& point,
@@ -956,8 +857,6 @@ void RenderWidget::HandleInputEvent(
nullptr, base::nullopt);
return;
}
- if (idle_user_detector_)
- idle_user_detector_->ActivityDetected();
input_handler_->HandleInputEvent(input_event, latency_info,
std::move(callback));
}
@@ -987,8 +886,24 @@ void RenderWidget::OnSetActive(bool active) {
}
void RenderWidget::OnSetBackgroundOpaque(bool opaque) {
- if (owner_delegate_)
- owner_delegate_->SetBackgroundOpaqueForWidget(opaque);
+ // Background opaque-ness modification is only supported for the main frame.
+ // The |owner_delegate_| is used as proxy for this RenderWidget being attached
+ // to the main frame.
+ if (!owner_delegate_)
+ return;
+
+ blink::WebWidget* web_widget = GetWebWidget();
+ // This is true since we only do this for RenderWidgets attached to the main
+ // frame.
+ DCHECK(web_widget->IsWebFrameWidget());
+ auto* web_frame_widget = static_cast<blink::WebFrameWidget*>(web_widget);
+ if (opaque) {
+ web_frame_widget->ClearBaseBackgroundColorOverride();
+ web_frame_widget->ClearBackgroundColorOverride();
+ } else {
+ web_frame_widget->SetBaseBackgroundColorOverride(SK_ColorTRANSPARENT);
+ web_frame_widget->SetBackgroundColorOverride(SK_ColorTRANSPARENT);
+ }
}
void RenderWidget::OnSetFocus(bool enable) {
@@ -1020,17 +935,11 @@ void RenderWidget::SetNeedsMainFrame() {
///////////////////////////////////////////////////////////////////////////////
// LayerTreeViewDelegate
-void RenderWidget::ApplyViewportDeltas(
- const gfx::Vector2dF& inner_delta,
- const gfx::Vector2dF& outer_delta,
- const gfx::Vector2dF& elastic_overscroll_delta,
- float page_scale,
- float top_controls_delta) {
+void RenderWidget::ApplyViewportChanges(
+ const cc::ApplyViewportChangesArgs& args) {
if (!GetWebWidget())
return;
- GetWebWidget()->ApplyViewportDeltas(inner_delta, outer_delta,
- elastic_overscroll_delta, page_scale,
- top_controls_delta);
+ GetWebWidget()->ApplyViewportChanges(args);
}
void RenderWidget::RecordWheelAndTouchScrollingCount(
@@ -1070,9 +979,15 @@ void RenderWidget::RequestNewLayerTreeFrameSink(
std::move(client_info));
layer_tree_view_->SetRenderFrameObserver(
std::move(render_frame_metadata_observer));
+ GURL url = GetWebWidget()->GetURLForDebugTrace();
+ // The |url| is not always available, fallback to a fixed string.
+ if (url.is_empty())
+ url = GURL("chrome://gpu/RenderWidget::RequestNewLayerTreeFrameSink");
+ const char* client_name = for_oopif_ ? kOOPIF : kRenderer;
RenderThreadImpl::current()->RequestNewLayerTreeFrameSink(
- routing_id_, frame_swap_message_queue_, GetURLForGraphicsContext3D(),
- std::move(callback), std::move(client_request), std::move(ptr));
+ routing_id_, frame_swap_message_queue_, std::move(url),
+ std::move(callback), std::move(client_request), std::move(ptr),
+ client_name);
}
void RenderWidget::DidCommitAndDrawCompositorFrame() {
@@ -1085,6 +1000,8 @@ void RenderWidget::DidCommitAndDrawCompositorFrame() {
// Notify subclasses that we initiated the paint operation.
DidInitiatePaint();
+
+ Send(new ViewHostMsg_DidCommitAndDrawCompositorFrame(routing_id_));
}
void RenderWidget::DidCommitCompositorFrame() {
@@ -1097,9 +1014,6 @@ void RenderWidget::DidCompletePageScaleAnimation() {
owner_delegate_->DidCompletePageScaleAnimationForWidget();
}
-void RenderWidget::DidReceiveCompositorFrameAck() {
-}
-
bool RenderWidget::IsClosing() const {
// TODO(ajwong): There is oddly 2 closing states. This API is used by
// LayerTreeView only as part of the LayerTreeViewDelegate interface and
@@ -1127,19 +1041,14 @@ void RenderWidget::RequestScheduleAnimation() {
ScheduleAnimation();
}
-void RenderWidget::UpdateVisualState(VisualStateUpdate requested_update) {
+void RenderWidget::UpdateVisualState() {
if (!GetWebWidget())
return;
- bool pre_paint_only = requested_update == VisualStateUpdate::kPrePaint;
- WebWidget::LifecycleUpdate lifecycle_update =
- pre_paint_only ? WebWidget::LifecycleUpdate::kPrePaint
- : WebWidget::LifecycleUpdate::kAll;
-
- GetWebWidget()->UpdateLifecycle(lifecycle_update);
+ GetWebWidget()->UpdateLifecycle(WebWidget::LifecycleUpdate::kAll);
GetWebWidget()->SetSuppressFrameRequestsWorkaroundFor704763Only(false);
- if (first_update_visual_state_after_hidden_ && !pre_paint_only) {
+ if (first_update_visual_state_after_hidden_) {
RecordTimeToFirstActivePaint();
first_update_visual_state_after_hidden_ = false;
}
@@ -1161,6 +1070,13 @@ void RenderWidget::RecordTimeToFirstActivePaint() {
}
}
+void RenderWidget::RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) {
+ if (!GetWebWidget())
+ return;
+
+ GetWebWidget()->RecordEndOfFrameMetrics(frame_begin_time);
+}
+
void RenderWidget::WillBeginCompositorFrame() {
TRACE_EVENT0("gpu", "RenderWidget::willBeginCompositorFrame");
@@ -1303,7 +1219,7 @@ void RenderWidget::UpdateTextInputStateInternal(bool show_virtual_keyboard,
if (next_previous_flags_ == kInvalidNextPreviousFlagsValue) {
// Due to a focus change, values will be reset by the frame.
// That case we only need fresh NEXT/PREVIOUS information.
- // Also we won't send ViewHostMsg_TextInputStateChanged if next/previous
+ // Also we won't send WidgetHostMsg_TextInputStateChanged if next/previous
// focusable status is changed.
if (auto* controller = GetInputMethodController()) {
next_previous_flags_ =
@@ -1328,7 +1244,7 @@ void RenderWidget::UpdateTextInputStateInternal(bool show_virtual_keyboard,
// show_virtual_keyboard.
params.show_ime_if_needed = show_virtual_keyboard;
params.reply_to_request = reply_to_request;
- Send(new ViewHostMsg_TextInputStateChanged(routing_id(), params));
+ Send(new WidgetHostMsg_TextInputStateChanged(routing_id(), params));
text_input_info_ = new_info;
text_input_type_ = new_type;
@@ -1479,61 +1395,18 @@ void RenderWidget::SetScreenMetricsEmulationParameters(
params);
}
-void RenderWidget::SetScreenRects(const gfx::Rect& view_screen_rect,
+void RenderWidget::SetScreenRects(const gfx::Rect& widget_screen_rect,
const gfx::Rect& window_screen_rect) {
- view_screen_rect_ = view_screen_rect;
+ widget_screen_rect_ = widget_screen_rect;
window_screen_rect_ = window_screen_rect;
}
///////////////////////////////////////////////////////////////////////////////
// WebWidgetClient
-blink::WebLayerTreeView* RenderWidget::InitializeLayerTreeView() {
- DCHECK(!host_closing_);
-
- layer_tree_view_ = std::make_unique<LayerTreeView>(
- this, compositor_deps_->GetCompositorMainThreadTaskRunner(),
- compositor_deps_->GetCompositorImplThreadTaskRunner(),
- compositor_deps_->GetTaskGraphRunner(),
- compositor_deps_->GetWebMainThreadScheduler());
- layer_tree_view_->Initialize(
- GenerateLayerTreeSettings(compositor_deps_, for_oopif_,
- screen_info_.rect.size(),
- screen_info_.device_scale_factor),
- compositor_deps_->CreateUkmRecorderFactory());
-
- UpdateSurfaceAndScreenInfo(local_surface_id_from_parent_,
- compositor_viewport_pixel_size_, screen_info_);
- layer_tree_view_->SetRasterColorSpace(
- screen_info_.color_space.GetRasterColorSpace());
- layer_tree_view_->SetContentSourceId(current_content_source_id_);
- // For background pages and certain tests, we don't want to trigger
- // LayerTreeFrameSink creation.
- bool should_generate_frame_sink =
- !compositor_never_visible_ && RenderThreadImpl::current();
- if (!should_generate_frame_sink)
- layer_tree_view_->SetNeverVisible();
-
- StartCompositor();
- DCHECK_NE(MSG_ROUTING_NONE, routing_id_);
- layer_tree_view_->SetFrameSinkId(
- viz::FrameSinkId(RenderThread::Get()->GetClientId(), routing_id_));
-
- RenderThreadImpl* render_thread = RenderThreadImpl::current();
- if (render_thread) {
- input_event_queue_ = new MainThreadEventQueue(
- this, render_thread->GetWebMainThreadScheduler()->InputTaskRunner(),
- render_thread->GetWebMainThreadScheduler(), should_generate_frame_sink);
- }
-
- UpdateURLForCompositorUkm();
-
- return layer_tree_view_.get();
-}
-
void RenderWidget::IntrinsicSizingInfoChanged(
const blink::WebIntrinsicSizingInfo& sizing_info) {
- Send(new ViewHostMsg_IntrinsicSizingInfoChanged(routing_id_, sizing_info));
+ Send(new WidgetHostMsg_IntrinsicSizingInfoChanged(routing_id_, sizing_info));
}
void RenderWidget::WillCloseLayerTreeView() {
@@ -1602,20 +1475,20 @@ void RenderWidget::DidChangeCursor(const WebCursorInfo& cursor_info) {
// Only send a SetCursor message if we need to make a change.
if (!current_cursor_.IsEqual(cursor)) {
current_cursor_ = cursor;
- Send(new ViewHostMsg_SetCursor(routing_id_, cursor));
+ Send(new WidgetHostMsg_SetCursor(routing_id_, cursor));
}
}
void RenderWidget::AutoscrollStart(const blink::WebFloatPoint& point) {
- Send(new ViewHostMsg_AutoscrollStart(routing_id_, point));
+ Send(new WidgetHostMsg_AutoscrollStart(routing_id_, point));
}
void RenderWidget::AutoscrollFling(const blink::WebFloatSize& velocity) {
- Send(new ViewHostMsg_AutoscrollFling(routing_id_, velocity));
+ Send(new WidgetHostMsg_AutoscrollFling(routing_id_, velocity));
}
void RenderWidget::AutoscrollEnd() {
- Send(new ViewHostMsg_AutoscrollEnd(routing_id_));
+ Send(new WidgetHostMsg_AutoscrollEnd(routing_id_));
}
// We are supposed to get a single call to Show for a newly created RenderWidget
@@ -1626,23 +1499,20 @@ void RenderWidget::AutoscrollEnd() {
// created RenderWidget (i.e., as a blocked popup or as a new tab).
//
void RenderWidget::Show(WebNavigationPolicy policy) {
- if (did_show_) {
+ if (!show_callback_) {
if (owner_delegate_) {
// When SupportsMultipleWindows is disabled, popups are reusing
- // the same view. In some scenarios, this makes blink to call Show()
- // twice. But otherwise, if it is enabled, we should not visit Show() more
- // than once.
+ // the view's RenderWidget. In some scenarios, this makes blink to call
+ // Show() twice. But otherwise, if it is enabled, we should not visit
+ // Show() more than once.
DCHECK(!owner_delegate_->SupportsMultipleWindowsForWidget());
+ return;
} else {
- DCHECK(!did_show_) << "received extraneous Show call";
+ NOTREACHED() << "received extraneous Show call";
}
- return;
}
DCHECK(routing_id_ != MSG_ROUTING_NONE);
- DCHECK(show_callback_);
-
- did_show_ = true;
// The opener is responsible for actually showing this widget.
std::move(show_callback_).Run(this, policy, initial_rect_);
@@ -1653,9 +1523,51 @@ void RenderWidget::Show(WebNavigationPolicy policy) {
SetPendingWindowRect(initial_rect_);
}
+LayerTreeView* RenderWidget::InitializeLayerTreeView() {
+ TRACE_EVENT0("blink", "RenderWidget::InitializeLayerTreeView");
+ DCHECK(!host_closing_);
+
+ layer_tree_view_ = std::make_unique<LayerTreeView>(
+ this, compositor_deps_->GetCompositorMainThreadTaskRunner(),
+ compositor_deps_->GetCompositorImplThreadTaskRunner(),
+ compositor_deps_->GetTaskGraphRunner(),
+ compositor_deps_->GetWebMainThreadScheduler());
+ layer_tree_view_->Initialize(
+ GenerateLayerTreeSettings(compositor_deps_, for_oopif_,
+ screen_info_.rect.size(),
+ screen_info_.device_scale_factor),
+ compositor_deps_->CreateUkmRecorderFactory());
+
+ UpdateSurfaceAndScreenInfo(local_surface_id_from_parent_,
+ compositor_viewport_pixel_size_, screen_info_);
+ layer_tree_view_->SetRasterColorSpace(
+ screen_info_.color_space.GetRasterColorSpace());
+ layer_tree_view_->SetContentSourceId(current_content_source_id_);
+ // For background pages and certain tests, we don't want to trigger
+ // LayerTreeFrameSink creation.
+ bool should_generate_frame_sink =
+ !compositor_never_visible_ && RenderThreadImpl::current();
+ if (!should_generate_frame_sink)
+ layer_tree_view_->SetNeverVisible();
+
+ StartCompositor();
+ DCHECK_NE(MSG_ROUTING_NONE, routing_id_);
+ layer_tree_view_->SetFrameSinkId(
+ viz::FrameSinkId(RenderThread::Get()->GetClientId(), routing_id_));
+
+ RenderThreadImpl* render_thread = RenderThreadImpl::current();
+ if (render_thread) {
+ input_event_queue_ = base::MakeRefCounted<MainThreadEventQueue>(
+ this, render_thread->GetWebMainThreadScheduler()->InputTaskRunner(),
+ render_thread->GetWebMainThreadScheduler(), should_generate_frame_sink);
+ }
+
+ return layer_tree_view_.get();
+}
+
void RenderWidget::DoDeferredClose() {
WillCloseLayerTreeView();
- Send(new ViewHostMsg_Close(routing_id_));
+ Send(new WidgetHostMsg_Close(routing_id_));
}
void RenderWidget::NotifyOnClose() {
@@ -1691,6 +1603,8 @@ void RenderWidget::Close() {
layer_tree_view_.reset();
if (owner_delegate_)
owner_delegate_->DidCloseWidget();
+ // Note the ACK is a control message going to the RenderProcessHost.
+ RenderThread::Get()->Send(new WidgetHostMsg_Close_ACK(routing_id()));
}
void RenderWidget::CloseWebWidget() {
@@ -1781,29 +1695,43 @@ WebRect RenderWidget::WindowRect() {
}
WebRect RenderWidget::ViewRect() {
- WebRect rect = view_screen_rect_;
+ WebRect rect = widget_screen_rect_;
ScreenRectToEmulatedIfNeeded(&rect);
return rect;
}
void RenderWidget::SetToolTipText(const blink::WebString& text,
WebTextDirection hint) {
- Send(new ViewHostMsg_SetTooltipText(routing_id_, text.Utf16(), hint));
+ Send(new WidgetHostMsg_SetTooltipText(routing_id_, text.Utf16(), hint));
}
void RenderWidget::SetWindowRect(const WebRect& rect_in_screen) {
+ // This path is for the renderer to change the on-screen position/size of
+ // the widget by changing its window rect. This is not possible for
+ // RenderWidgets whose position/size are controlled by layout from another
+ // frame tree (ie. child local root frames, informed by |for_oopif_|), as
+ // the window rect can only be set by the browser.
+ if (for_oopif_)
+ return;
+
WebRect window_rect = rect_in_screen;
EmulatedToScreenRectIfNeeded(&window_rect);
- if (!resizing_mode_selector_->is_synchronous_mode()) {
- if (did_show_) {
- Send(new ViewHostMsg_RequestSetBounds(routing_id_, window_rect));
- SetPendingWindowRect(window_rect);
- } else {
- initial_rect_ = window_rect;
- }
- } else {
+ if (resizing_mode_selector_->is_synchronous_mode()) {
+ // This is a layout-test-only path. At one point, it was planned to be
+ // removed. See https://crbug.com/309760.
SetWindowRectSynchronously(window_rect);
+ return;
+ }
+
+ if (show_callback_) {
+ // The widget is not shown yet. Delay the |window_rect| being sent to the
+ // browser until Show() is called so it can be sent with that IPC, once the
+ // browser is ready for the info.
+ initial_rect_ = window_rect;
+ } else {
+ Send(new WidgetHostMsg_RequestSetBounds(routing_id_, window_rect));
+ SetPendingWindowRect(window_rect);
}
}
@@ -1813,9 +1741,9 @@ void RenderWidget::SetPendingWindowRect(const WebRect& rect) {
// Popups don't get size updates back from the browser so just store the set
// values.
- if (popup_type_ != blink::kWebPopupTypeNone) {
+ if (widget_type_ != WidgetType::kFrame) {
window_screen_rect_ = rect;
- view_screen_rect_ = rect;
+ widget_screen_rect_ = rect;
}
}
@@ -1977,10 +1905,14 @@ void RenderWidget::SetWindowRectSynchronously(
layer_tree_view_->RequestNewLocalSurfaceId();
SynchronizeVisualProperties(visual_properties);
- view_screen_rect_ = new_window_rect;
+ widget_screen_rect_ = new_window_rect;
window_screen_rect_ = new_window_rect;
- if (!did_show_)
+ if (show_callback_) {
+ // Tests may call here directly to control the window rect. If
+ // Show() did not happen yet, the rect is stored to be passed to the
+ // browser when the RenderWidget requests Show().
initial_rect_ = new_window_rect;
+ }
}
void RenderWidget::UpdateCaptureSequenceNumber(
@@ -2001,15 +1933,15 @@ void RenderWidget::OnSetTextDirection(WebTextDirection direction) {
frame->SetTextDirection(direction);
}
-void RenderWidget::OnUpdateScreenRects(const gfx::Rect& view_screen_rect,
+void RenderWidget::OnUpdateScreenRects(const gfx::Rect& widget_screen_rect,
const gfx::Rect& window_screen_rect) {
if (screen_metrics_emulator_) {
- screen_metrics_emulator_->OnUpdateScreenRects(view_screen_rect,
+ screen_metrics_emulator_->OnUpdateScreenRects(widget_screen_rect,
window_screen_rect);
} else {
- SetScreenRects(view_screen_rect, window_screen_rect);
+ SetScreenRects(widget_screen_rect, window_screen_rect);
}
- Send(new ViewHostMsg_UpdateScreenRects_ACK(routing_id()));
+ Send(new WidgetHostMsg_UpdateScreenRects_ACK(routing_id()));
}
void RenderWidget::OnSetViewportIntersection(
@@ -2017,7 +1949,7 @@ void RenderWidget::OnSetViewportIntersection(
const gfx::Rect& compositor_visible_rect,
bool occluded_or_obscured) {
if (auto* frame_widget = GetFrameWidget()) {
- DCHECK_EQ(popup_type_, WebPopupType::kWebPopupTypeNone);
+ DCHECK_EQ(widget_type_, WidgetType::kFrame);
compositor_visible_rect_ = compositor_visible_rect;
frame_widget->SetRemoteViewportIntersection(viewport_intersection,
occluded_or_obscured);
@@ -2027,7 +1959,7 @@ void RenderWidget::OnSetViewportIntersection(
void RenderWidget::OnSetIsInert(bool inert) {
if (auto* frame_widget = GetFrameWidget()) {
- DCHECK_EQ(popup_type_, WebPopupType::kWebPopupTypeNone);
+ DCHECK_EQ(widget_type_, WidgetType::kFrame);
frame_widget->SetIsInert(inert);
}
}
@@ -2035,7 +1967,7 @@ void RenderWidget::OnSetIsInert(bool inert) {
void RenderWidget::OnSetInheritedEffectiveTouchAction(
cc::TouchAction touch_action) {
if (auto* frame_widget = GetFrameWidget()) {
- DCHECK_EQ(popup_type_, WebPopupType::kWebPopupTypeNone);
+ DCHECK_EQ(widget_type_, WidgetType::kFrame);
frame_widget->SetInheritedEffectiveTouchAction(touch_action);
}
}
@@ -2043,7 +1975,7 @@ void RenderWidget::OnSetInheritedEffectiveTouchAction(
void RenderWidget::OnUpdateRenderThrottlingStatus(bool is_throttled,
bool subtree_throttled) {
if (auto* frame_widget = GetFrameWidget()) {
- DCHECK_EQ(popup_type_, WebPopupType::kWebPopupTypeNone);
+ DCHECK_EQ(widget_type_, WidgetType::kFrame);
frame_widget->UpdateRenderThrottlingStatus(is_throttled, subtree_throttled);
}
}
@@ -2230,12 +2162,6 @@ void RenderWidget::OnOrientationChange() {
}
}
-GURL RenderWidget::GetURLForGraphicsContext3D() {
- if (owner_delegate_)
- return owner_delegate_->GetURLForGraphicsContext3DForWidget();
- return GURL();
-}
-
void RenderWidget::SetHidden(bool hidden) {
if (is_hidden_ == hidden)
return;
@@ -2245,7 +2171,7 @@ void RenderWidget::SetHidden(bool hidden) {
is_hidden_ = hidden;
#if defined(USE_AURA)
- if (features::IsUsingWindowService())
+ if (features::IsMultiProcessMash())
RendererWindowTreeClient::Get(routing_id_)->SetVisible(!hidden);
#endif
@@ -2340,7 +2266,7 @@ void RenderWidget::UpdateSelectionBounds() {
!blink::WebRuntimeFeatures::IsCompositedSelectionUpdateEnabled();
#endif
if (send_ipc) {
- ViewHostMsg_SelectionBounds_Params params;
+ WidgetHostMsg_SelectionBounds_Params params;
params.is_anchor_first = false;
GetSelectionBounds(&params.anchor_rect, &params.focus_rect);
if (selection_anchor_rect_ != params.anchor_rect ||
@@ -2352,7 +2278,7 @@ void RenderWidget::UpdateSelectionBounds() {
params.anchor_dir);
params.is_anchor_first = focused_frame->IsSelectionAnchorFirst();
}
- Send(new ViewHostMsg_SelectionBoundsChanged(routing_id_, params));
+ Send(new WidgetHostMsg_SelectionBoundsChanged(routing_id_, params));
}
}
@@ -2369,7 +2295,7 @@ void RenderWidget::DidAutoResize(const gfx::Size& new_size) {
if (resizing_mode_selector_->is_synchronous_mode()) {
gfx::Rect new_pos(WindowRect().x, WindowRect().y, size_.width(),
size_.height());
- view_screen_rect_ = new_pos;
+ widget_screen_rect_ = new_pos;
window_screen_rect_ = new_pos;
}
@@ -2512,7 +2438,7 @@ void RenderWidget::DidHandleGestureEvent(const WebGestureEvent& event,
blink::WebTextInputType text_input_type =
controller ? controller->TextInputType() : blink::kWebTextInputTypeNone;
- Send(new ViewHostMsg_FocusedNodeTouched(
+ Send(new WidgetHostMsg_FocusedNodeTouched(
routing_id_, text_input_type != blink::kWebTextInputTypeNone));
}
#endif
@@ -2862,6 +2788,9 @@ cc::LayerTreeSettings RenderWidget::GenerateLayerTreeSettings(
settings.always_request_presentation_time =
cmd.HasSwitch(cc::switches::kAlwaysRequestPresentationTime);
+
+ settings.send_compositor_frame_ack = false;
+
return settings;
}
@@ -3027,9 +2956,11 @@ void RenderWidget::UnregisterBrowserPlugin(BrowserPlugin* browser_plugin) {
browser_plugins_.RemoveObserver(browser_plugin);
}
-void RenderWidget::OnWaitNextFrameForTests(int routing_id) {
+void RenderWidget::OnWaitNextFrameForTests(
+ int main_frame_thread_observer_routing_id) {
// Sends an ACK to the browser process during the next compositor frame.
- QueueMessage(new ViewHostMsg_WaitForNextFrameForTests_ACK(routing_id));
+ QueueMessage(new WidgetHostMsg_WaitForNextFrameForTests_ACK(
+ main_frame_thread_observer_routing_id));
}
const ScreenInfo& RenderWidget::GetWebScreenInfo() const {
@@ -3226,20 +3157,6 @@ void RenderWidget::DisableAutoResizeForTesting(const gfx::Size& new_size) {
OnSynchronizeVisualProperties(visual_properties);
}
-void RenderWidget::UpdateURLForCompositorUkm() {
- DCHECK(layer_tree_view_);
- blink::WebFrameWidget* frame_widget = GetFrameWidget();
- if (!frame_widget)
- return;
-
- auto* render_frame = RenderFrameImpl::FromWebFrame(frame_widget->LocalRoot());
- if (!render_frame->IsMainFrame())
- return;
-
- layer_tree_view_->SetURLForUkm(
- render_frame->GetWebFrame()->GetDocument().Url());
-}
-
blink::WebLocalFrame* RenderWidget::GetFocusedWebLocalFrameInWidget() const {
if (auto* frame_widget = GetFrameWidget())
return frame_widget->FocusedWebLocalFrameInWidget();
diff --git a/chromium/content/renderer/render_widget.h b/chromium/content/renderer/render_widget.h
index 15031b62b93..5a2c8e08be4 100644
--- a/chromium/content/renderer/render_widget.h
+++ b/chromium/content/renderer/render_widget.h
@@ -37,6 +37,7 @@
#include "content/common/widget.mojom.h"
#include "content/public/common/drop_data.h"
#include "content/public/common/screen_info.h"
+#include "content/public/common/widget_type.h"
#include "content/renderer/devtools/render_widget_screen_metrics_emulator_delegate.h"
#include "content/renderer/gpu/layer_tree_view_delegate.h"
#include "content/renderer/input/main_thread_event_queue.h"
@@ -55,7 +56,6 @@
#include "third_party/blink/public/platform/web_referrer_policy.h"
#include "third_party/blink/public/platform/web_text_input_info.h"
#include "third_party/blink/public/web/web_ime_text_span.h"
-#include "third_party/blink/public/web/web_popup_type.h"
#include "third_party/blink/public/web/web_text_direction.h"
#include "third_party/blink/public/web/web_widget.h"
#include "third_party/blink/public/web/web_widget_client.h"
@@ -68,8 +68,6 @@
#include "ui/gfx/range/range.h"
#include "ui/surface/transport_dib.h"
-class GURL;
-
namespace IPC {
class SyncMessageFilter;
}
@@ -89,6 +87,7 @@ struct WebPoint;
} // namespace blink
namespace cc {
+struct ApplyViewportChangesArgs;
class SwapPromise;
}
@@ -106,7 +105,6 @@ class BrowserPlugin;
class CompositorDependencies;
class ExternalPopupMenu;
class FrameSwapMessageQueue;
-class IdleUserDetector;
class ImeEventGuard;
class LayerTreeView;
class MainThreadEventQueue;
@@ -152,35 +150,31 @@ class CONTENT_EXPORT RenderWidget
TTFAP_5MIN_AFTER_BACKGROUNDED,
};
- // Creates a new RenderWidget for a popup. |opener| is the RenderView that
- // this widget lives inside.
- static RenderWidget* CreateForPopup(RenderViewImpl* opener,
- CompositorDependencies* compositor_deps,
- blink::WebPopupType popup_type,
- const ScreenInfo& screen_info);
-
- // Creates a new RenderWidget that will be attached to a RenderFrame.
- static RenderWidget* CreateForFrame(int widget_routing_id,
- bool hidden,
- const ScreenInfo& screen_info,
- CompositorDependencies* compositor_deps,
- blink::WebLocalFrame* frame);
-
- // Used by content_layouttest_support to hook into the creation of
- // RenderWidgets.
- using CreateRenderWidgetFunction =
- RenderWidget* (*)(int32_t,
- CompositorDependencies*,
- blink::WebPopupType,
- const ScreenInfo&,
- blink::WebDisplayMode display_mode,
- bool,
- bool,
- bool);
- using RenderWidgetInitializedCallback = void (*)(RenderWidget*);
- static void InstallCreateHook(
- CreateRenderWidgetFunction create_render_widget,
- RenderWidgetInitializedCallback render_widget_initialized_callback);
+ // An Init*() method must be called after creating a RenderWidget, which will
+ // make the RenderWidget self-referencing. Then it can be deleted by calling
+ // Close().
+ RenderWidget(int32_t widget_routing_id,
+ CompositorDependencies* compositor_deps,
+ WidgetType widget_type,
+ const ScreenInfo& screen_info,
+ blink::WebDisplayMode display_mode,
+ bool swapped_out,
+ bool hidden,
+ bool never_visible,
+ mojom::WidgetRequest widget_request = nullptr);
+
+ // Initialize a new RenderWidget for a popup. The |show_callback| is called
+ // when RenderWidget::Show() happens. This method increments the reference
+ // count on the RenderWidget, making it self-referencing, which can be
+ // released by calling Close().
+ void InitForPopup(ShowCallback show_callback,
+ blink::WebPagePopup* web_page_popup);
+
+ // Initialize a new RenderWidget that will be attached to a RenderFrame (via
+ // the WebFrameWidget), for a frame that is a local root, but not the main
+ // frame. This method increments the reference count on the RenderWidget,
+ // making it self-referencing, which can be released by calling Close().
+ void InitForChildLocalRoot(blink::WebFrameWidget* web_frame_widget);
void set_owner_delegate(RenderWidgetOwnerDelegate* owner_delegate) {
DCHECK(!owner_delegate_);
@@ -262,11 +256,7 @@ class CONTENT_EXPORT RenderWidget
bool Send(IPC::Message* msg) override;
// LayerTreeViewDelegate
- void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
- const gfx::Vector2dF& outer_delta,
- const gfx::Vector2dF& elastic_overscroll_delta,
- float page_scale,
- float top_controls_delta) override;
+ void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) override;
void RecordWheelAndTouchScrollingCount(bool has_scrolled_by_wheel,
bool has_scrolled_by_touch) override;
void BeginMainFrame(base::TimeTicks frame_time) override;
@@ -275,10 +265,10 @@ class CONTENT_EXPORT RenderWidget
void DidCommitAndDrawCompositorFrame() override;
void DidCommitCompositorFrame() override;
void DidCompletePageScaleAnimation() override;
- void DidReceiveCompositorFrameAck() override;
+ void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override;
bool IsClosing() const override;
void RequestScheduleAnimation() override;
- void UpdateVisualState(VisualStateUpdate requested_update) override;
+ void UpdateVisualState() override;
void WillBeginCompositorFrame() override;
std::unique_ptr<cc::SwapPromise> RequestCopyOfOutputForLayoutTest(
std::unique_ptr<viz::CopyOutputRequest> request) override;
@@ -307,11 +297,10 @@ class CONTENT_EXPORT RenderWidget
void SetScreenMetricsEmulationParameters(
bool enabled,
const blink::WebDeviceEmulationParams& params) override;
- void SetScreenRects(const gfx::Rect& view_screen_rect,
+ void SetScreenRects(const gfx::Rect& widget_screen_rect,
const gfx::Rect& window_screen_rect) override;
// blink::WebWidgetClient
- blink::WebLayerTreeView* InitializeLayerTreeView() override;
void IntrinsicSizingInfoChanged(
const blink::WebIntrinsicSizingInfo&) override;
void DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type) override;
@@ -533,40 +522,15 @@ class CONTENT_EXPORT RenderWidget
base::WeakPtr<RenderWidget> AsWeakPtr();
protected:
- RenderWidget(int32_t widget_routing_id,
- CompositorDependencies* compositor_deps,
- blink::WebPopupType popup_type,
- const ScreenInfo& screen_info,
- blink::WebDisplayMode display_mode,
- bool swapped_out,
- bool hidden,
- bool never_visible,
- mojom::WidgetRequest widget_request = nullptr);
-
- // Avoid making RenderWidget other than as a refptr.
~RenderWidget() override;
- static blink::WebFrameWidget* CreateWebFrameWidget(
- blink::WebWidgetClient* widget_client,
- blink::WebLocalFrame* frame);
-
- // Creates a WebWidget based on the popup type.
- static blink::WebWidget* CreateWebWidget(RenderWidget* render_widget);
-
// Called by Create() functions and subclasses to finish initialization.
// |show_callback| will be invoked once WebWidgetClient::Show() occurs, and
// should be null if Show() won't be triggered for this widget.
void Init(ShowCallback show_callback, blink::WebWidget* web_widget);
- // Initialization methods used by the RenderViewImpl subclass.
- //
- // Idle user detector is optionally set up and destroyed during
- // initialization/teardown.
- void SetUpIdleUserDetector();
// Update the web view's device scale factor.
void UpdateWebViewWithDeviceScaleFactor();
- // Informs that Show() will not happen.
- void set_did_show() { did_show_ = true; }
// Close the underlying WebWidget and stop the compositor.
virtual void Close();
@@ -574,19 +538,9 @@ class CONTENT_EXPORT RenderWidget
// Notify subclasses that we initiated the paint operation.
virtual void DidInitiatePaint() {}
- // Gets the current URL or a placeholder constant for creating 3d contexts and
- // attributing them back to a URL.
- virtual GURL GetURLForGraphicsContext3D();
-
// RenderWidget IPC message handler that can be overridden by subclasses.
virtual void OnSynchronizeVisualProperties(const VisualProperties& params);
-#if defined(OS_MACOSX)
- // On MacOSX this message arrives on RenderViewImpl instead of here, and it
- // needs to be able to call back to the normal message handler here.
- void OnClose();
-#endif
-
private:
// Friend RefCounted so that the dtor can be non-public. Using this class
// without ref-counting is an error.
@@ -606,6 +560,8 @@ class CONTENT_EXPORT RenderWidget
static scoped_refptr<base::SingleThreadTaskRunner> GetCleanupTaskRunner();
+ LayerTreeView* InitializeLayerTreeView();
+
void DoDeferredClose();
void NotifyOnClose();
@@ -629,15 +585,12 @@ class CONTENT_EXPORT RenderWidget
const std::vector<const blink::WebInputEvent*>& coalesced_events,
const ui::LatencyInfo& latency_info,
InputEventDispatchType dispatch_type);
-#if !defined(OS_MACOSX)
void OnClose();
-#endif
void OnCreatingNewAck();
void OnEnableDeviceEmulation(const blink::WebDeviceEmulationParams& params);
void OnDisableDeviceEmulation();
void OnWasHidden();
- void OnWasShown(bool needs_repainting,
- base::TimeTicks show_request_timestamp);
+ void OnWasShown(base::TimeTicks show_request_timestamp);
void OnCreateVideoAck(int32_t video_id);
void OnUpdateVideoAck(int32_t video_id);
void OnRequestSetBoundsAck();
@@ -647,7 +600,7 @@ class CONTENT_EXPORT RenderWidget
void OnSetTextDirection(blink::WebTextDirection direction);
void OnGetFPS();
- void OnUpdateScreenRects(const gfx::Rect& view_screen_rect,
+ void OnUpdateScreenRects(const gfx::Rect& widget_screen_rect,
const gfx::Rect& window_screen_rect);
void OnSetViewportIntersection(const gfx::Rect& viewport_intersection,
const gfx::Rect& compositor_visible_rect,
@@ -738,10 +691,6 @@ class CONTENT_EXPORT RenderWidget
void ScreenRectToEmulatedIfNeeded(blink::WebRect* window_rect) const;
void EmulatedToScreenRectIfNeeded(blink::WebRect* window_rect) const;
- bool CreateWidget(int32_t opener_id,
- blink::WebPopupType popup_type,
- int32_t* routing_id);
-
void UpdateSurfaceAndScreenInfo(
const viz::LocalSurfaceId& new_local_surface_id,
const gfx::Size& new_compositor_viewport_pixel_size,
@@ -786,12 +735,6 @@ class CONTENT_EXPORT RenderWidget
#endif
void RecordTimeToFirstActivePaint();
- // Updates the URL used by the compositor for keying UKM metrics.
- // Note that this uses the main frame's URL and only if its available in the
- // current process. In the case where it is not available, no metrics will be
- // recorded.
- void UpdateURLForCompositorUkm();
-
// This method returns the WebLocalFrame which is currently focused and
// belongs to the frame tree associated with this RenderWidget.
blink::WebLocalFrame* GetFocusedWebLocalFrameInWidget() const;
@@ -846,9 +789,6 @@ class CONTENT_EXPORT RenderWidget
// The maximum size to use for auto-resize.
gfx::Size max_size_for_auto_resize_;
- // Set to true if we should ignore RenderWidget::Show calls.
- bool did_show_;
-
// Indicates that we shouldn't bother generated paint events.
bool is_hidden_;
@@ -907,7 +847,7 @@ class CONTENT_EXPORT RenderWidget
gfx::Range composition_range_;
// The kind of popup this widget represents, NONE if not a popup.
- blink::WebPopupType popup_type_;
+ WidgetType widget_type_;
// While we are waiting for the browser to update window sizes, we track the
// pending size temporarily.
@@ -915,7 +855,7 @@ class CONTENT_EXPORT RenderWidget
gfx::Rect pending_window_rect_;
// The screen rects of the view and the window that contains it.
- gfx::Rect view_screen_rect_;
+ gfx::Rect widget_screen_rect_;
gfx::Rect window_screen_rect_;
scoped_refptr<WidgetInputHandlerManager> widget_input_handler_manager_;
@@ -1019,9 +959,6 @@ class CONTENT_EXPORT RenderWidget
scoped_refptr<MainThreadEventQueue> input_event_queue_;
mojo::Binding<mojom::Widget> widget_binding_;
- // IdleUserDetector is setup optionally on RenderWidget by its creator, so may
- // be null.
- std::unique_ptr<IdleUserDetector> idle_user_detector_;
gfx::Rect compositor_visible_rect_;
diff --git a/chromium/content/renderer/render_widget_fullscreen_pepper.cc b/chromium/content/renderer/render_widget_fullscreen_pepper.cc
index 28ce36b09a4..738b93ef255 100644
--- a/chromium/content/renderer/render_widget_fullscreen_pepper.cc
+++ b/chromium/content/renderer/render_widget_fullscreen_pepper.cc
@@ -12,6 +12,7 @@
#include "build/build_config.h"
#include "cc/paint/paint_canvas.h"
#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "content/renderer/gpu/layer_tree_view.h"
@@ -116,11 +117,12 @@ FullscreenMouseLockDispatcher::~FullscreenMouseLockDispatcher() {
}
void FullscreenMouseLockDispatcher::SendLockMouseRequest() {
- widget_->Send(new ViewHostMsg_LockMouse(widget_->routing_id(), false, true));
+ widget_->Send(
+ new WidgetHostMsg_LockMouse(widget_->routing_id(), false, true));
}
void FullscreenMouseLockDispatcher::SendUnlockMouseRequest() {
- widget_->Send(new ViewHostMsg_UnlockMouse(widget_->routing_id()));
+ widget_->Send(new WidgetHostMsg_UnlockMouse(widget_->routing_id()));
}
// WebWidget that simply wraps the pepper plugin.
@@ -128,13 +130,18 @@ void FullscreenMouseLockDispatcher::SendUnlockMouseRequest() {
// necessary.
class PepperWidget : public WebWidget {
public:
- explicit PepperWidget(RenderWidgetFullscreenPepper* widget)
- : widget_(widget) {
- }
+ explicit PepperWidget(RenderWidgetFullscreenPepper* widget,
+ const blink::WebURL& local_main_frame_url)
+ : widget_(widget), local_main_frame_url_(local_main_frame_url) {}
virtual ~PepperWidget() {}
// WebWidget API
+ void SetLayerTreeView(blink::WebLayerTreeView*) override {
+ // Does nothing, as the LayerTreeView can be accessed from the RenderWidget
+ // directly.
+ }
+
void Close() override { delete this; }
WebSize Size() override { return size_; }
@@ -241,9 +248,12 @@ class PepperWidget : public WebWidget {
: WebInputEventResult::kNotHandled;
}
+ blink::WebURL GetURLForDebugTrace() override { return local_main_frame_url_; }
+
private:
RenderWidgetFullscreenPepper* widget_;
WebSize size_;
+ blink::WebURL local_main_frame_url_;
DISALLOW_COPY_AND_ASSIGN(PepperWidget);
};
@@ -256,16 +266,16 @@ RenderWidgetFullscreenPepper* RenderWidgetFullscreenPepper::Create(
RenderWidget::ShowCallback show_callback,
CompositorDependencies* compositor_deps,
PepperPluginInstanceImpl* plugin,
- const GURL& active_url,
+ const blink::WebURL& local_main_frame_url,
const ScreenInfo& screen_info,
mojom::WidgetRequest widget_request) {
DCHECK_NE(MSG_ROUTING_NONE, routing_id);
DCHECK(show_callback);
scoped_refptr<RenderWidgetFullscreenPepper> widget(
new RenderWidgetFullscreenPepper(routing_id, compositor_deps, plugin,
- active_url, screen_info,
- std::move(widget_request)));
- widget->Init(std::move(show_callback), new PepperWidget(widget.get()));
+ screen_info, std::move(widget_request)));
+ widget->Init(std::move(show_callback),
+ new PepperWidget(widget.get(), local_main_frame_url));
widget->AddRef();
return widget.get();
}
@@ -274,19 +284,17 @@ RenderWidgetFullscreenPepper::RenderWidgetFullscreenPepper(
int32_t routing_id,
CompositorDependencies* compositor_deps,
PepperPluginInstanceImpl* plugin,
- const GURL& active_url,
const ScreenInfo& screen_info,
mojom::WidgetRequest widget_request)
: RenderWidget(routing_id,
compositor_deps,
- blink::kWebPopupTypeNone,
+ WidgetType::kFrame,
screen_info,
blink::kWebDisplayModeUndefined,
false,
false,
false,
std::move(widget_request)),
- active_url_(active_url),
plugin_(plugin),
layer_(nullptr),
mouse_lock_dispatcher_(new FullscreenMouseLockDispatcher(this)) {}
@@ -321,7 +329,7 @@ void RenderWidgetFullscreenPepper::Destroy() {
// away.
SetLayer(nullptr);
- Send(new ViewHostMsg_Close(routing_id()));
+ Send(new WidgetHostMsg_Close(routing_id()));
Release();
}
@@ -338,8 +346,6 @@ void RenderWidgetFullscreenPepper::SetLayer(cc::Layer* layer) {
layer_tree_view()->ClearRootLayer();
return;
}
- if (!layer_tree_view())
- InitializeLayerTreeView();
UpdateLayerBounds();
layer_->SetIsDrawable(true);
layer_tree_view()->SetRootLayer(layer_);
@@ -348,11 +354,9 @@ void RenderWidgetFullscreenPepper::SetLayer(cc::Layer* layer) {
bool RenderWidgetFullscreenPepper::OnMessageReceived(const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderWidgetFullscreenPepper, msg)
- IPC_MESSAGE_FORWARD(ViewMsg_LockMouse_ACK,
- mouse_lock_dispatcher_.get(),
+ IPC_MESSAGE_FORWARD(WidgetMsg_LockMouse_ACK, mouse_lock_dispatcher_.get(),
MouseLockDispatcher::OnLockMouseACK)
- IPC_MESSAGE_FORWARD(ViewMsg_MouseLockLost,
- mouse_lock_dispatcher_.get(),
+ IPC_MESSAGE_FORWARD(WidgetMsg_MouseLockLost, mouse_lock_dispatcher_.get(),
MouseLockDispatcher::OnMouseLockLost)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -383,10 +387,6 @@ void RenderWidgetFullscreenPepper::OnSynchronizeVisualProperties(
UpdateLayerBounds();
}
-GURL RenderWidgetFullscreenPepper::GetURLForGraphicsContext3D() {
- return active_url_;
-}
-
void RenderWidgetFullscreenPepper::UpdateLayerBounds() {
if (!layer_)
return;
diff --git a/chromium/content/renderer/render_widget_fullscreen_pepper.h b/chromium/content/renderer/render_widget_fullscreen_pepper.h
index 548bc9913a6..c6b17e50c6b 100644
--- a/chromium/content/renderer/render_widget_fullscreen_pepper.h
+++ b/chromium/content/renderer/render_widget_fullscreen_pepper.h
@@ -35,7 +35,7 @@ class RenderWidgetFullscreenPepper : public RenderWidget,
RenderWidget::ShowCallback show_callback,
CompositorDependencies* compositor_deps,
PepperPluginInstanceImpl* plugin,
- const GURL& active_url,
+ const blink::WebURL& local_main_frame_url,
const ScreenInfo& screen_info,
mojom::WidgetRequest widget_request);
@@ -61,7 +61,6 @@ class RenderWidgetFullscreenPepper : public RenderWidget,
RenderWidgetFullscreenPepper(int32_t routing_id,
CompositorDependencies* compositor_deps,
PepperPluginInstanceImpl* plugin,
- const GURL& active_url,
const ScreenInfo& screen_info,
mojom::WidgetRequest widget_request);
~RenderWidgetFullscreenPepper() override;
@@ -72,15 +71,9 @@ class RenderWidgetFullscreenPepper : public RenderWidget,
void OnSynchronizeVisualProperties(
const VisualProperties& visual_properties) override;
- // RenderWidget overrides.
- GURL GetURLForGraphicsContext3D() override;
-
private:
void UpdateLayerBounds();
- // URL that is responsible for this widget, passed to ggl::CreateViewContext.
- GURL active_url_;
-
// The plugin instance this widget wraps.
PepperPluginInstanceImpl* plugin_;
diff --git a/chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc b/chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc
index e05ea432aa5..bac8dc5749d 100644
--- a/chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc
+++ b/chromium/content/renderer/render_widget_mouse_lock_dispatcher.cc
@@ -4,7 +4,7 @@
#include "content/renderer/render_widget_mouse_lock_dispatcher.h"
-#include "content/common/view_messages.h"
+#include "content/common/widget_messages.h"
#include "content/renderer/render_view_impl.h"
#include "ipc/ipc_message.h"
#include "third_party/blink/public/web/web_frame.h"
@@ -29,21 +29,21 @@ void RenderWidgetMouseLockDispatcher::SendLockMouseRequest() {
bool user_gesture =
blink::WebUserGestureIndicator::IsProcessingUserGesture(web_local_frame);
- render_widget_->Send(new ViewHostMsg_LockMouse(render_widget_->routing_id(),
- user_gesture, false));
+ render_widget_->Send(new WidgetHostMsg_LockMouse(render_widget_->routing_id(),
+ user_gesture, false));
}
void RenderWidgetMouseLockDispatcher::SendUnlockMouseRequest() {
render_widget_->Send(
- new ViewHostMsg_UnlockMouse(render_widget_->routing_id()));
+ new WidgetHostMsg_UnlockMouse(render_widget_->routing_id()));
}
bool RenderWidgetMouseLockDispatcher::OnMessageReceived(
const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(RenderWidgetMouseLockDispatcher, message)
- IPC_MESSAGE_HANDLER(ViewMsg_LockMouse_ACK, OnLockMouseACK)
- IPC_MESSAGE_FORWARD(ViewMsg_MouseLockLost,
+ IPC_MESSAGE_HANDLER(WidgetMsg_LockMouse_ACK, OnLockMouseACK)
+ IPC_MESSAGE_FORWARD(WidgetMsg_MouseLockLost,
static_cast<MouseLockDispatcher*>(this),
MouseLockDispatcher::OnMouseLockLost)
IPC_MESSAGE_UNHANDLED(handled = false)
diff --git a/chromium/content/renderer/render_widget_owner_delegate.h b/chromium/content/renderer/render_widget_owner_delegate.h
index 2365a3944fe..35393e71fa2 100644
--- a/chromium/content/renderer/render_widget_owner_delegate.h
+++ b/chromium/content/renderer/render_widget_owner_delegate.h
@@ -33,9 +33,6 @@ class CONTENT_EXPORT RenderWidgetOwnerDelegate {
// See comment in RenderWidgetHost::SetActive().
virtual void SetActiveForWidget(bool active) = 0;
- // See comment in RenderWidgetHostImpl::SetBackgroundOpaque().
- virtual void SetBackgroundOpaqueForWidget(bool opaque) = 0;
-
// Returns whether multiple windows are allowed for the widget. If true, then
// Show() may be called more than once.
virtual bool SupportsMultipleWindowsForWidget() = 0;
@@ -86,9 +83,6 @@ class CONTENT_EXPORT RenderWidgetOwnerDelegate {
// Called after RenderWidget changes focus.
virtual void DidChangeFocusForWidget() = 0;
- // Called to get the current URL if it exists or a hardcoded fallback.
- virtual GURL GetURLForGraphicsContext3DForWidget() = 0;
-
// Called when the RenderWidget handles
// LayerTreeViewDelegate::DidCommitCompositorFrame().
virtual void DidCommitCompositorFrameForWidget() = 0;
diff --git a/chromium/content/renderer/render_widget_unittest.cc b/chromium/content/renderer/render_widget_unittest.cc
index 98c17ad635c..9e33f3d236f 100644
--- a/chromium/content/renderer/render_widget_unittest.cc
+++ b/chromium/content/renderer/render_widget_unittest.cc
@@ -129,7 +129,13 @@ class MockHandledEventCallback {
DISALLOW_COPY_AND_ASSIGN(MockHandledEventCallback);
};
-class MockWebWidget : public blink::WebWidget {
+class StubWebWidget : public blink::WebWidget {
+ public:
+ void SetLayerTreeView(blink::WebLayerTreeView*) override {}
+ blink::WebURL GetURLForDebugTrace() override { return {}; }
+};
+
+class MockWebWidget : public StubWebWidget {
public:
MOCK_METHOD0(DispatchBufferedTouchEvents, blink::WebInputEventResult());
MOCK_METHOD1(
@@ -144,7 +150,7 @@ class InteractiveRenderWidget : public RenderWidget {
explicit InteractiveRenderWidget(CompositorDependencies* compositor_deps)
: RenderWidget(++next_routing_id_,
compositor_deps,
- blink::kWebPopupTypeNone,
+ WidgetType::kFrame,
ScreenInfo(),
blink::kWebDisplayModeUndefined,
false,
@@ -356,8 +362,6 @@ TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
// Tests that if a RenderWidget is auto-resized, it requests a new
// viz::LocalSurfaceId to be allocated on the impl thread.
TEST_F(RenderWidgetUnittest, AutoResizeAllocatedLocalSurfaceId) {
- widget()->InitializeLayerTreeView();
-
viz::ParentLocalSurfaceIdAllocator allocator;
// Enable auto-resize.
@@ -389,14 +393,13 @@ class PopupRenderWidget : public RenderWidget {
explicit PopupRenderWidget(CompositorDependencies* compositor_deps)
: RenderWidget(routing_id_++,
compositor_deps,
- blink::kWebPopupTypePage,
+ WidgetType::kPopup,
ScreenInfo(),
blink::kWebDisplayModeUndefined,
false,
false,
false) {
Init(RenderWidget::ShowCallback(), mock_webwidget());
- did_show_ = true;
}
IPC::TestSink* sink() { return &sink_; }
@@ -468,7 +471,6 @@ class StubRenderWidgetOwnerDelegate : public RenderWidgetOwnerDelegate {
return false;
}
void SetActiveForWidget(bool active) override {}
- void SetBackgroundOpaqueForWidget(bool opaque) override {}
bool SupportsMultipleWindowsForWidget() override { return true; }
void DidHandleGestureEventForWidget(
const blink::WebGestureEvent& event) override {}
@@ -484,7 +486,6 @@ class StubRenderWidgetOwnerDelegate : public RenderWidgetOwnerDelegate {
void ScrollFocusedNodeIntoViewForWidget() override {}
void DidReceiveSetFocusEventForWidget() override {}
void DidChangeFocusForWidget() override {}
- GURL GetURLForGraphicsContext3DForWidget() override { return {}; }
void DidCommitCompositorFrameForWidget() override {}
void DidCompletePageScaleAnimationForWidget() override {}
void ResizeWebWidgetForWidget(
diff --git a/chromium/content/renderer/renderer_blink_platform_impl.cc b/chromium/content/renderer/renderer_blink_platform_impl.cc
index 4a594bd98bc..907fd2f4f85 100644
--- a/chromium/content/renderer/renderer_blink_platform_impl.cc
+++ b/chromium/content/renderer/renderer_blink_platform_impl.cc
@@ -16,7 +16,6 @@
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
-#include "base/memory/memory_coordinator_client_registry.h"
#include "base/memory/shared_memory.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
@@ -32,10 +31,9 @@
#include "content/child/child_process.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/frame_messages.h"
-#include "content/common/gpu_stream_constants.h"
-#include "content/common/render_message_filter.mojom.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/gpu_stream_constants.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/common/webplugininfo.h"
@@ -47,8 +45,6 @@
#include "content/renderer/dom_storage/local_storage_namespace.h"
#include "content/renderer/dom_storage/session_web_storage_namespace_impl.h"
#include "content/renderer/dom_storage/webstoragenamespace_impl.h"
-#include "content/renderer/file_info_util.h"
-#include "content/renderer/fileapi/webfilesystem_impl.h"
#include "content/renderer/image_capture/image_capture_frame_grabber.h"
#include "content/renderer/indexed_db/webidbfactory_impl.h"
#include "content/renderer/loader/child_url_loader_factory_bundle.h"
@@ -83,6 +79,7 @@
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/platform_handle.h"
+#include "net/base/features.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -101,13 +98,11 @@
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_audio_latency_hint.h"
#include "third_party/blink/public/platform/web_blob_registry.h"
-#include "third_party/blink/public/platform/web_file_info.h"
#include "third_party/blink/public/platform/web_media_recorder_handler.h"
#include "third_party/blink/public/platform/web_media_stream_center.h"
#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
#include "third_party/blink/public/platform/web_security_origin.h"
-#include "third_party/blink/public/platform/web_thread.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/platform/web_url_loader_factory.h"
#include "third_party/blink/public/platform/web_url_request.h"
@@ -130,7 +125,7 @@
#include "base/synchronization/lock.h"
#include "content/child/child_process_sandbox_support_impl_linux.h"
-#include "third_party/blink/public/platform/linux/web_fallback_font.h"
+#include "third_party/blink/public/platform/linux/out_of_process_font.h"
#include "third_party/blink/public/platform/linux/web_sandbox_support.h"
#include "third_party/icu/source/common/unicode/utf16.h"
#endif
@@ -146,8 +141,6 @@ using blink::WebAudioLatencyHint;
using blink::WebBlobRegistry;
using blink::WebCanvasCaptureHandler;
using blink::WebDatabaseObserver;
-using blink::WebFileInfo;
-using blink::WebFileSystem;
using blink::WebIDBFactory;
using blink::WebImageCaptureFrameGrabber;
using blink::WebMediaPlayer;
@@ -222,7 +215,10 @@ class RendererBlinkPlatformImpl::SandboxSupport
void GetFallbackFontForCharacter(
blink::WebUChar32 character,
const char* preferred_locale,
- blink::WebFallbackFont* fallbackFont) override;
+ blink::OutOfProcessFont* fallbackFont) override;
+ void MatchFontByPostscriptNameOrFullFontName(
+ const char* font_unique_name,
+ blink::OutOfProcessFont* fallback_font) override;
void GetWebFontRenderStyleForStrike(const char* family,
int size,
bool is_bold,
@@ -235,7 +231,7 @@ class RendererBlinkPlatformImpl::SandboxSupport
// unicode code points. It needs this information frequently so we cache it
// here.
base::Lock unicode_font_families_mutex_;
- std::map<int32_t, blink::WebFallbackFont> unicode_font_families_;
+ std::map<int32_t, blink::OutOfProcessFont> unicode_font_families_;
sk_sp<font_service::FontLoader> font_loader_;
#endif
};
@@ -249,8 +245,6 @@ RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
RenderThreadImpl::current()
? RenderThreadImpl::current()->GetIOTaskRunner()
: nullptr),
- compositor_thread_(nullptr),
- main_thread_(main_thread_scheduler->CreateMainThread()),
sudden_termination_disables_(0),
is_locked_to_site_(false),
default_task_runner_(main_thread_scheduler->DefaultTaskRunner()),
@@ -294,16 +288,17 @@ RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
GetInterfaceProvider()->GetInterface(
mojo::MakeRequest(&web_database_host_info_));
+ GetInterfaceProvider()->GetInterface(
+ mojo::MakeRequest(&code_cache_host_info_));
}
RendererBlinkPlatformImpl::~RendererBlinkPlatformImpl() {
- WebFileSystemImpl::DeleteThreadSpecificInstance();
main_thread_scheduler_->SetTopLevelBlameContext(nullptr);
}
void RendererBlinkPlatformImpl::Shutdown() {
#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA)
- // SandboxSupport contains a map of WebFallbackFont objects, which hold
+ // SandboxSupport contains a map of OutOfProcessFont objects, which hold
// WebStrings and WebVectors, which become invalidated when blink is shut
// down. Hence, we need to clear that map now, just before blink::shutdown()
// is called.
@@ -381,17 +376,14 @@ RendererBlinkPlatformImpl::CreateNetworkURLLoaderFactory() {
return url_loader_factory;
}
-void RendererBlinkPlatformImpl::SetCompositorThread(
- blink::scheduler::WebThreadBase* compositor_thread) {
- compositor_thread_ = compositor_thread;
- if (compositor_thread_)
- WaitUntilWebThreadTLSUpdate(compositor_thread_);
-}
-
-blink::WebThread* RendererBlinkPlatformImpl::CurrentThread() {
- if (main_thread_->IsCurrentThread())
- return main_thread_.get();
- return BlinkPlatformImpl::CurrentThread();
+void RendererBlinkPlatformImpl::SetDisplayThreadPriority(
+ base::PlatformThreadId thread_id) {
+#if defined(OS_LINUX)
+ if (RenderThreadImpl* render_thread = RenderThreadImpl::current()) {
+ render_thread->render_message_filter()->SetThreadPriority(
+ thread_id, base::ThreadPriority::DISPLAY);
+ }
+#endif
}
blink::BlameContext* RendererBlinkPlatformImpl::GetTopLevelBlameContext() {
@@ -455,30 +447,37 @@ blink::WebString RendererBlinkPlatformImpl::UserAgent() {
return render_thread->GetUserAgent();
}
-void RendererBlinkPlatformImpl::CacheMetadata(const blink::WebURL& url,
- base::Time response_time,
- const char* data,
- size_t size) {
- // Let the browser know we generated cacheable metadata for this resource. The
- // browser may cache it and return it on subsequent responses to speed
- // the processing of this resource.
- std::vector<uint8_t> copy(data, data + size);
- RenderThreadImpl::current()
- ->render_message_filter()
- ->DidGenerateCacheableMetadata(url, response_time, copy);
+void RendererBlinkPlatformImpl::CacheMetadata(
+ blink::mojom::CodeCacheType cache_type,
+ const blink::WebURL& url,
+ base::Time response_time,
+ const char* data,
+ size_t size) {
+ // Only cache WebAssembly if we have isolated code caches.
+ // TODO(bbudge) Remove this check when isolated code caches are on by default.
+ if (cache_type == blink::mojom::CodeCacheType::kJavascript ||
+ base::FeatureList::IsEnabled(net::features::kIsolatedCodeCache)) {
+ // Let the browser know we generated cacheable metadata for this resource.
+ // The browser may cache it and return it on subsequent responses to speed
+ // the processing of this resource.
+ std::vector<uint8_t> copy(data, data + size);
+ GetCodeCacheHost().DidGenerateCacheableMetadata(cache_type, url,
+ response_time, copy);
+ }
}
void RendererBlinkPlatformImpl::FetchCachedCode(
+ blink::mojom::CodeCacheType cache_type,
const GURL& url,
base::OnceCallback<void(base::Time, const std::vector<uint8_t>&)>
callback) {
- RenderThreadImpl::current()->render_message_filter()->FetchCachedCode(
- url, std::move(callback));
+ GetCodeCacheHost().FetchCachedCode(cache_type, url, std::move(callback));
}
-void RendererBlinkPlatformImpl::ClearCodeCacheEntry(const GURL& url) {
- RenderThreadImpl::current()->render_message_filter()->ClearCodeCacheEntry(
- url);
+void RendererBlinkPlatformImpl::ClearCodeCacheEntry(
+ blink::mojom::CodeCacheType cache_type,
+ const GURL& url) {
+ GetCodeCacheHost().ClearCodeCacheEntry(cache_type, url);
}
void RendererBlinkPlatformImpl::CacheMetadataInCacheStorage(
@@ -492,11 +491,9 @@ void RendererBlinkPlatformImpl::CacheMetadataInCacheStorage(
// CacheStorage. The browser may cache it and return it on subsequent
// responses to speed the processing of this resource.
std::vector<uint8_t> copy(data, data + size);
- RenderThreadImpl::current()
- ->render_message_filter()
- ->DidGenerateCacheableMetadataInCacheStorage(
- url, response_time, copy, cacheStorageOrigin,
- cacheStorageCacheName.Utf8());
+ GetCodeCacheHost().DidGenerateCacheableMetadataInCacheStorage(
+ url, response_time, copy, cacheStorageOrigin,
+ cacheStorageCacheName.Utf8());
}
WebString RendererBlinkPlatformImpl::DefaultLocale() {
@@ -523,18 +520,6 @@ void RendererBlinkPlatformImpl::SuddenTerminationChanged(bool enabled) {
thread->GetRendererHost()->SuddenTerminationChanged(enabled);
}
-void RendererBlinkPlatformImpl::AddRefProcess() {
- ChildProcess::current()->AddRefProcess();
-}
-
-void RendererBlinkPlatformImpl::ReleaseRefProcess() {
- ChildProcess::current()->ReleaseProcess();
-}
-
-blink::WebThread* RendererBlinkPlatformImpl::CompositorThread() const {
- return compositor_thread_;
-}
-
std::unique_ptr<WebStorageNamespace>
RendererBlinkPlatformImpl::CreateLocalStorageNamespace() {
if (!local_storage_cached_areas_) {
@@ -590,10 +575,6 @@ RendererBlinkPlatformImpl::CreateIdbFactory() {
//------------------------------------------------------------------------------
-WebFileSystem* RendererBlinkPlatformImpl::FileSystem() {
- return WebFileSystemImpl::ThreadSpecificInstance(default_task_runner_.get());
-}
-
WebString RendererBlinkPlatformImpl::FileSystemCreateOriginIdentifier(
const blink::WebSecurityOrigin& origin) {
return WebString::FromUTF8(
@@ -615,9 +596,9 @@ bool RendererBlinkPlatformImpl::SandboxSupport::LoadFont(CTFontRef src_font,
void RendererBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter(
blink::WebUChar32 character,
const char* preferred_locale,
- blink::WebFallbackFont* fallbackFont) {
+ blink::OutOfProcessFont* fallbackFont) {
base::AutoLock lock(unicode_font_families_mutex_);
- const std::map<int32_t, blink::WebFallbackFont>::const_iterator iter =
+ const std::map<int32_t, blink::OutOfProcessFont>::const_iterator iter =
unicode_font_families_.find(character);
if (iter != unicode_font_families_.end()) {
fallbackFont->name = iter->second.name;
@@ -635,6 +616,14 @@ void RendererBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter(
unicode_font_families_.insert(std::make_pair(character, *fallbackFont));
}
+void RendererBlinkPlatformImpl::SandboxSupport::
+ MatchFontByPostscriptNameOrFullFontName(
+ const char* font_unique_name,
+ blink::OutOfProcessFont* fallback_font) {
+ content::MatchFontByPostscriptNameOrFullFontName(
+ font_loader_, font_unique_name, fallback_font);
+}
+
void RendererBlinkPlatformImpl::SandboxSupport::GetWebFontRenderStyleForStrike(
const char* family,
int size,
@@ -1193,11 +1182,13 @@ void RendererBlinkPlatformImpl::WorkerContextCreated(
//------------------------------------------------------------------------------
void RendererBlinkPlatformImpl::RequestPurgeMemory() {
- // TODO(tasak|bashi): We should use ChildMemoryCoordinator here, but
- // ChildMemoryCoordinator isn't always available as it's only initialized
- // when kMemoryCoordinatorV0 is enabled.
- // Use ChildMemoryCoordinator when memory coordinator is always enabled.
- base::MemoryCoordinatorClientRegistry::GetInstance()->PurgeMemory();
+ base::MemoryPressureListener::NotifyMemoryPressure(
+ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
+}
+
+void RendererBlinkPlatformImpl::SetMemoryPressureNotificationsSuppressed(
+ bool suppressed) {
+ base::MemoryPressureListener::SetNotificationsSuppressed(suppressed);
}
void RendererBlinkPlatformImpl::InitializeWebDatabaseHostIfNeeded() {
@@ -1214,4 +1205,14 @@ blink::mojom::WebDatabaseHost& RendererBlinkPlatformImpl::GetWebDatabaseHost() {
return **web_database_host_;
}
+blink::mojom::CodeCacheHost& RendererBlinkPlatformImpl::GetCodeCacheHost() {
+ if (!code_cache_host_) {
+ code_cache_host_ = blink::mojom::ThreadSafeCodeCacheHostPtr::Create(
+ std::move(code_cache_host_info_),
+ base::CreateSequencedTaskRunnerWithTraits(
+ {base::WithBaseSyncPrimitives()}));
+ }
+ return **code_cache_host_;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/renderer_blink_platform_impl.h b/chromium/content/renderer/renderer_blink_platform_impl.h
index b3bde113adb..4ec814fd92c 100644
--- a/chromium/content/renderer/renderer_blink_platform_impl.h
+++ b/chromium/content/renderer/renderer_blink_platform_impl.h
@@ -25,6 +25,7 @@
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h"
+#include "third_party/blink/public/mojom/loader/code_cache.mojom.h"
#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h"
#include "third_party/blink/public/platform/modules/webdatabase/web_database.mojom.h"
@@ -37,7 +38,6 @@
namespace blink {
namespace scheduler {
class WebThreadScheduler;
-class WebThreadBase;
}
class WebCanvasCaptureHandler;
class WebGraphicsContext3DProvider;
@@ -83,15 +83,18 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
bool IsLinkVisited(unsigned long long linkHash) override;
blink::WebPrescientNetworking* PrescientNetworking() override;
blink::WebString UserAgent() override;
- void CacheMetadata(const blink::WebURL&,
+ void CacheMetadata(blink::mojom::CodeCacheType cache_type,
+ const blink::WebURL&,
base::Time,
const char*,
size_t) override;
void FetchCachedCode(
+ blink::mojom::CodeCacheType cache_type,
const GURL&,
base::OnceCallback<void(base::Time, const std::vector<uint8_t>&)>)
override;
- void ClearCodeCacheEntry(const GURL&) override;
+ void ClearCodeCacheEntry(blink::mojom::CodeCacheType cache_type,
+ const GURL&) override;
void CacheMetadataInCacheStorage(
const blink::WebURL&,
base::Time,
@@ -101,9 +104,6 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
const blink::WebString& cacheStorageCacheName) override;
blink::WebString DefaultLocale() override;
void SuddenTerminationChanged(bool enabled) override;
- void AddRefProcess() override;
- void ReleaseRefProcess() override;
- blink::WebThread* CompositorThread() const override;
std::unique_ptr<blink::WebStorageNamespace> CreateLocalStorageNamespace()
override;
std::unique_ptr<blink::WebStorageNamespace> CreateSessionStorageNamespace(
@@ -126,7 +126,6 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
bool IsLockedToSite() const override;
std::unique_ptr<blink::WebIDBFactory> CreateIdbFactory() override;
- blink::WebFileSystem* FileSystem() override;
blink::WebString FileSystemCreateOriginIdentifier(
const blink::WebSecurityOrigin& origin) override;
@@ -199,7 +198,7 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
blink::WebString ConvertIDNToUnicode(const blink::WebString& host) override;
service_manager::Connector* GetConnector() override;
blink::InterfaceProvider* GetInterfaceProvider() override;
- blink::WebThread* CurrentThread() override;
+ void SetDisplayThreadPriority(base::PlatformThreadId thread_id) override;
blink::BlameContext* GetTopLevelBlameContext() override;
void RecordRappor(const char* metric,
const blink::WebString& sample) override;
@@ -225,6 +224,7 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
std::unique_ptr<blink::WebURLLoaderFactory> CreateDefaultURLLoaderFactory()
override;
std::unique_ptr<blink::CodeCacheLoader> CreateCodeCacheLoader() override;
+
std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory(
mojo::ScopedMessagePipeHandle url_loader_factory_handle) override;
std::unique_ptr<blink::WebURLLoaderFactory> WrapSharedURLLoaderFactory(
@@ -232,6 +232,7 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
std::unique_ptr<blink::WebDataConsumerHandle> CreateDataConsumerHandle(
mojo::ScopedDataPipeConsumerHandle handle) override;
void RequestPurgeMemory() override;
+ void SetMemoryPressureNotificationsSuppressed(bool suppressed) override;
// Returns non-null.
// It is invalid to call this in an incomplete env where
@@ -239,11 +240,6 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
scoped_refptr<ChildURLLoaderFactoryBundle>
CreateDefaultURLLoaderFactoryBundle();
- // This class does *not* own the compositor thread. It is the responsibility
- // of the caller to ensure that the compositor thread is cleared before it is
- // destructed.
- void SetCompositorThread(blink::scheduler::WebThreadBase* compositor_thread);
-
PossiblyAssociatedInterfacePtr<network::mojom::URLLoaderFactory>
CreateNetworkURLLoaderFactory();
@@ -264,9 +260,9 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
// Return the mojo interface for making WebDatabaseHost calls.
blink::mojom::WebDatabaseHost& GetWebDatabaseHost();
- blink::scheduler::WebThreadBase* compositor_thread_;
+ // Return the mojo interface for making CodeCache calls.
+ blink::mojom::CodeCacheHost& GetCodeCacheHost();
- std::unique_ptr<blink::WebThread> main_thread_;
std::unique_ptr<service_manager::Connector> connector_;
scoped_refptr<base::SingleThreadTaskRunner> io_runner_;
@@ -303,6 +299,9 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
blink::mojom::WebDatabaseHostPtrInfo web_database_host_info_;
scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr> web_database_host_;
+ blink::mojom::CodeCacheHostPtrInfo code_cache_host_info_;
+ scoped_refptr<blink::mojom::ThreadSafeCodeCacheHostPtr> code_cache_host_;
+
#if defined(OS_LINUX)
sk_sp<font_service::FontLoader> font_loader_;
#endif
diff --git a/chromium/content/renderer/renderer_main.cc b/chromium/content/renderer/renderer_main.cc
index 9e76e271b65..1ddd7147cef 100644
--- a/chromium/content/renderer/renderer_main.cc
+++ b/chromium/content/renderer/renderer_main.cc
@@ -167,7 +167,7 @@ int RendererMain(const MainFunctionParams& parameters) {
InitializeWebRtcModule();
{
- bool run_loop = true;
+ bool should_run_loop = true;
bool need_sandbox =
!command_line.HasSwitch(service_manager::switches::kNoSandbox);
@@ -176,7 +176,7 @@ int RendererMain(const MainFunctionParams& parameters) {
// except Windows and Mac.
// TODO(markus): Check if it is OK to remove ifdefs for Windows and Mac.
if (need_sandbox) {
- run_loop = platform.EnableSandbox();
+ should_run_loop = platform.EnableSandbox();
need_sandbox = false;
}
#endif
@@ -184,20 +184,22 @@ int RendererMain(const MainFunctionParams& parameters) {
std::unique_ptr<RenderProcess> render_process = RenderProcessImpl::Create();
// It's not a memory leak since RenderThread has the same lifetime
// as a renderer process.
- new RenderThreadImpl(std::move(main_thread_scheduler));
+ base::RunLoop run_loop;
+ new RenderThreadImpl(run_loop.QuitClosure(),
+ std::move(main_thread_scheduler));
if (need_sandbox)
- run_loop = platform.EnableSandbox();
+ should_run_loop = platform.EnableSandbox();
base::HighResolutionTimerManager hi_res_timer_manager;
- if (run_loop) {
+ if (should_run_loop) {
#if defined(OS_MACOSX)
if (pool)
pool->Recycle();
#endif
TRACE_EVENT_ASYNC_BEGIN0("toplevel", "RendererMain.START_MSG_LOOP", 0);
- base::RunLoop().Run();
+ run_loop.Run();
TRACE_EVENT_ASYNC_END0("toplevel", "RendererMain.START_MSG_LOOP", 0);
}
diff --git a/chromium/content/renderer/renderer_main_platform_delegate_mac.mm b/chromium/content/renderer/renderer_main_platform_delegate_mac.mm
index e2122fb5fe9..b7142c2871f 100644
--- a/chromium/content/renderer/renderer_main_platform_delegate_mac.mm
+++ b/chromium/content/renderer/renderer_main_platform_delegate_mac.mm
@@ -24,23 +24,22 @@
#include "services/service_manager/sandbox/mac/sandbox_mac.h"
extern "C" {
-void CGSSetDenyWindowServerConnections(bool);
-void CGSShutdownServerConnections();
+CGError CGSSetDenyWindowServerConnections(bool);
};
namespace content {
namespace {
-// This disconnects from the window server, and then indicates that Chrome
-// should continue execution without access to launchservicesd.
-void DisconnectWindowServer() {
- // Now disconnect from WindowServer, after all objects have been warmed up.
- // Shutting down the connection requires connecting to WindowServer,
- // so do this before actually engaging the sandbox. This may cause two log
- // messages to be printed to the system logger on certain OS versions.
- CGSSetDenyWindowServerConnections(true);
- CGSShutdownServerConnections();
+// This tells Core Graphics not to attempt to connect to the WindowServer (and
+// verifies there are no existing open connections), and then indicates that
+// Chrome should continue execution without access to launchservicesd.
+void DisableSystemServices() {
+ // Tell the WindowServer that we don't want to make any future connections.
+ // This will return Success as long as there are no open connections, which
+ // is what we want.
+ CGError result = CGSSetDenyWindowServerConnections(true);
+ CHECK_EQ(result, kCGErrorSuccess);
sandbox::DisableLaunchServices();
}
@@ -146,12 +145,12 @@ void RendererMainPlatformDelegate::PlatformUninitialize() {
bool RendererMainPlatformDelegate::EnableSandbox() {
bool sandbox_initialized = sandbox::Seatbelt::IsSandboxed();
- // If the sandbox is already engaged, just disconnect from the window server.
+ // If the sandbox is already engaged, just disable system services.
if (sandbox_initialized) {
- DisconnectWindowServer();
+ DisableSystemServices();
} else {
sandbox_initialized =
- InitializeSandbox(base::BindOnce(&DisconnectWindowServer));
+ InitializeSandbox(base::BindOnce(&DisableSystemServices));
}
// The sandbox is now engaged. Make sure that the renderer has not connected
diff --git a/chromium/content/renderer/renderer_webcookiejar_impl.cc b/chromium/content/renderer/renderer_webcookiejar_impl.cc
index d5e0ef88c30..07f2dccb100 100644
--- a/chromium/content/renderer/renderer_webcookiejar_impl.cc
+++ b/chromium/content/renderer/renderer_webcookiejar_impl.cc
@@ -23,8 +23,7 @@ void RendererWebCookieJarImpl::SetCookie(const WebURL& url,
std::string value_utf8 =
value.Utf8(WebString::UTF8ConversionMode::kStrictReplacingErrorsWithFFFD);
RenderThreadImpl::current()->render_frame_message_filter()->SetCookie(
- sender_->GetRoutingID(), url, site_for_cookies, value_utf8,
- base::DoNothing());
+ sender_->GetRoutingID(), url, site_for_cookies, value_utf8);
}
WebString RendererWebCookieJarImpl::Cookies(const WebURL& url,
diff --git a/chromium/content/renderer/service_worker/controller_service_worker_connector.h b/chromium/content/renderer/service_worker/controller_service_worker_connector.h
index 066a87c7fce..49a66adfdbd 100644
--- a/chromium/content/renderer/service_worker/controller_service_worker_connector.h
+++ b/chromium/content/renderer/service_worker/controller_service_worker_connector.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_RENDERER_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_CONNECTOR_H_
#define CONTENT_RENDERER_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_CONNECTOR_H_
+#include <string>
+
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
@@ -97,16 +99,11 @@ class CONTENT_EXPORT ControllerServiceWorkerConnector
mojo::BindingSet<mojom::ControllerServiceWorkerConnector> bindings_;
- // Keeps the mojo end to the browser process on its own.
- // Non-null only for the service worker clients that are workers (i.e., only
- // when created for dedicated workers or shared workers).
+ // Connection to the container host in the browser process.
mojom::ServiceWorkerContainerHostPtr container_host_ptr_;
- // Connection to the ControllerServiceWorker. The consumer of this connection
- // should not need to know which process this is connected to.
- // (Currently this is connected to BrowserSideControllerServiceWorker,
- // but will eventually be directly connected to the controller service worker
- // in the renderer process)
+ // Connection to the controller service worker, which lives in a renderer
+ // process that's not necessarily the same as this connector.
mojom::ControllerServiceWorkerPtr controller_service_worker_;
base::ObserverList<Observer>::Unchecked observer_list_;
diff --git a/chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.cc b/chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
index d54d88dd273..66b5e227e99 100644
--- a/chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
+++ b/chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
@@ -13,9 +13,7 @@
#include "content/public/common/content_client.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/service_worker/service_worker_context_client.h"
-#include "content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h"
#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_installed_scripts_manager.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/public/platform/web_security_origin.h"
@@ -25,12 +23,6 @@
namespace content {
-EmbeddedWorkerInstanceClientImpl::WorkerWrapper::WorkerWrapper(
- std::unique_ptr<blink::WebEmbeddedWorker> worker)
- : worker_(std::move(worker)) {}
-
-EmbeddedWorkerInstanceClientImpl::WorkerWrapper::~WorkerWrapper() = default;
-
// static
void EmbeddedWorkerInstanceClientImpl::Create(
scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner,
@@ -42,17 +34,17 @@ void EmbeddedWorkerInstanceClientImpl::Create(
}
void EmbeddedWorkerInstanceClientImpl::WorkerContextDestroyed() {
- DCHECK(wrapper_);
+ DCHECK(worker_);
TRACE_EVENT0("ServiceWorker",
"EmbeddedWorkerInstanceClientImpl::WorkerContextDestroyed");
// Destroys |this|.
- wrapper_.reset();
+ worker_.reset();
}
void EmbeddedWorkerInstanceClientImpl::StartWorker(
mojom::EmbeddedWorkerStartParamsPtr params) {
DCHECK(ChildThreadImpl::current());
- DCHECK(!wrapper_);
+ DCHECK(!worker_);
TRACE_EVENT0("ServiceWorker",
"EmbeddedWorkerInstanceClientImpl::StartWorker");
auto start_timing = mojom::EmbeddedWorkerStartTiming::New();
@@ -88,41 +80,38 @@ void EmbeddedWorkerInstanceClientImpl::StartWorker(
UMA_HISTOGRAM_ENUMERATION(
"ServiceWorker.EmbeddedWorkerInstanceClient.StartWorker", metric,
StartWorkerHistogramEnum::NUM_TYPES);
- wrapper_ = StartWorkerContext(std::move(params), std::move(client),
- std::move(cache_storage),
- std::move(interface_provider),
- std::move(privacy_preferences));
+ worker_ = StartWorkerContext(
+ std::move(params), std::move(client), std::move(cache_storage),
+ std::move(interface_provider), std::move(privacy_preferences));
}
void EmbeddedWorkerInstanceClientImpl::StopWorker() {
// StopWorker must be called after StartWorker is called.
DCHECK(ChildThreadImpl::current());
- DCHECK(wrapper_);
+ DCHECK(worker_);
TRACE_EVENT0("ServiceWorker", "EmbeddedWorkerInstanceClientImpl::StopWorker");
- wrapper_->worker()->TerminateWorkerContext();
+ worker_->TerminateWorkerContext();
}
void EmbeddedWorkerInstanceClientImpl::ResumeAfterDownload() {
- DCHECK(wrapper_);
- DCHECK(wrapper_->worker());
- wrapper_->worker()->ResumeAfterDownload();
+ DCHECK(worker_);
+ worker_->ResumeAfterDownload();
}
void EmbeddedWorkerInstanceClientImpl::AddMessageToConsole(
blink::WebConsoleMessage::Level level,
const std::string& message) {
- DCHECK(wrapper_);
- DCHECK(wrapper_->worker());
- wrapper_->worker()->AddMessageToConsole(
+ DCHECK(worker_);
+ worker_->AddMessageToConsole(
blink::WebConsoleMessage(level, blink::WebString::FromUTF8(message)));
}
void EmbeddedWorkerInstanceClientImpl::BindDevToolsAgent(
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host,
blink::mojom::DevToolsAgentAssociatedRequest request) {
- DCHECK(wrapper_);
- DCHECK(wrapper_->worker());
- wrapper_->worker()->BindDevToolsAgent(request.PassHandle());
+ DCHECK(worker_);
+ worker_->BindDevToolsAgent(host.PassHandle(), request.PassHandle());
}
EmbeddedWorkerInstanceClientImpl::EmbeddedWorkerInstanceClientImpl(
@@ -143,32 +132,41 @@ void EmbeddedWorkerInstanceClientImpl::OnError() {
temporal_self_.reset();
}
-std::unique_ptr<EmbeddedWorkerInstanceClientImpl::WorkerWrapper>
+std::unique_ptr<blink::WebEmbeddedWorker>
EmbeddedWorkerInstanceClientImpl::StartWorkerContext(
mojom::EmbeddedWorkerStartParamsPtr params,
std::unique_ptr<ServiceWorkerContextClient> context_client,
blink::mojom::CacheStoragePtrInfo cache_storage,
service_manager::mojom::InterfaceProviderPtrInfo interface_provider,
blink::PrivacyPreferences privacy_preferences) {
- std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManager> manager;
+ std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManagerParams>
+ installed_scripts_manager_params;
// |installed_scripts_info| is null if scripts should be served by net layer,
// when the worker is not installed, or the worker is launched for checking
// the update.
if (params->installed_scripts_info) {
- manager = WebServiceWorkerInstalledScriptsManagerImpl::Create(
- std::move(params->installed_scripts_info), io_thread_runner_);
+ installed_scripts_manager_params = std::make_unique<
+ blink::WebServiceWorkerInstalledScriptsManagerParams>();
+ installed_scripts_manager_params->installed_scripts_urls =
+ std::move(params->installed_scripts_info->installed_urls);
+ installed_scripts_manager_params->manager_request =
+ params->installed_scripts_info->manager_request.PassMessagePipe();
+ installed_scripts_manager_params->manager_host_ptr =
+ params->installed_scripts_info->manager_host_ptr.PassHandle();
+ DCHECK(installed_scripts_manager_params->manager_request.is_valid());
+ DCHECK(installed_scripts_manager_params->manager_host_ptr.is_valid());
}
- auto wrapper =
- std::make_unique<WorkerWrapper>(blink::WebEmbeddedWorker::Create(
- std::move(context_client), std::move(manager),
- params->content_settings_proxy.PassHandle(),
- cache_storage.PassHandle(), interface_provider.PassHandle()));
+ auto worker = blink::WebEmbeddedWorker::Create(
+ std::move(context_client), std::move(installed_scripts_manager_params),
+ params->content_settings_proxy.PassHandle(), cache_storage.PassHandle(),
+ interface_provider.PassHandle());
blink::WebEmbeddedWorkerStartData start_data;
start_data.script_url = params->script_url;
start_data.user_agent =
blink::WebString::FromUTF8(GetContentClient()->GetUserAgent());
+ start_data.script_type = params->script_type;
start_data.wait_for_debugger_mode =
params->wait_for_debugger
? blink::WebEmbeddedWorkerStartData::kWaitForDebugger
@@ -182,8 +180,8 @@ EmbeddedWorkerInstanceClientImpl::StartWorkerContext(
: blink::WebEmbeddedWorkerStartData::kDontPauseAfterDownload;
start_data.privacy_preferences = std::move(privacy_preferences);
- wrapper->worker()->StartWorkerContext(start_data);
- return wrapper;
+ worker->StartWorkerContext(start_data);
+ return worker;
}
} // namespace content
diff --git a/chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.h b/chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.h
index 4544a991922..0e4a6072bb0 100644
--- a/chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.h
+++ b/chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.h
@@ -10,7 +10,6 @@
#include "base/containers/id_map.h"
#include "base/single_thread_task_runner.h"
#include "content/child/child_thread_impl.h"
-#include "content/child/scoped_child_process_reference.h"
#include "content/common/service_worker/embedded_worker.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "third_party/blink/public/common/privacy_preferences.h"
@@ -73,20 +72,6 @@ class EmbeddedWorkerInstanceClientImpl
void StopWorker() override;
private:
- // A thin wrapper of WebEmbeddedWorker which also adds and releases process
- // references automatically.
- class WorkerWrapper {
- public:
- explicit WorkerWrapper(std::unique_ptr<blink::WebEmbeddedWorker> worker);
- ~WorkerWrapper();
-
- blink::WebEmbeddedWorker* worker() { return worker_.get(); }
-
- private:
- ScopedChildProcessReference process_ref_;
- std::unique_ptr<blink::WebEmbeddedWorker> worker_;
- };
-
EmbeddedWorkerInstanceClientImpl(
scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner,
mojom::EmbeddedWorkerInstanceClientRequest request);
@@ -97,12 +82,13 @@ class EmbeddedWorkerInstanceClientImpl
void AddMessageToConsole(blink::WebConsoleMessage::Level level,
const std::string& message) override;
void BindDevToolsAgent(
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host,
blink::mojom::DevToolsAgentAssociatedRequest request) override;
// Handler of connection error bound to |binding_|.
void OnError();
- std::unique_ptr<WorkerWrapper> StartWorkerContext(
+ std::unique_ptr<blink::WebEmbeddedWorker> StartWorkerContext(
mojom::EmbeddedWorkerStartParamsPtr params,
std::unique_ptr<ServiceWorkerContextClient> context_client,
blink::mojom::CacheStoragePtrInfo cache_storage,
@@ -116,7 +102,7 @@ class EmbeddedWorkerInstanceClientImpl
std::unique_ptr<EmbeddedWorkerInstanceClientImpl> temporal_self_;
// nullptr means the worker is not running.
- std::unique_ptr<WorkerWrapper> wrapper_;
+ std::unique_ptr<blink::WebEmbeddedWorker> worker_;
scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner_;
diff --git a/chromium/content/renderer/service_worker/service_worker_context_client.cc b/chromium/content/renderer/service_worker/service_worker_context_client.cc
index 51440106f6f..42bedc75eba 100644
--- a/chromium/content/renderer/service_worker/service_worker_context_client.cc
+++ b/chromium/content/renderer/service_worker/service_worker_context_client.cc
@@ -43,8 +43,6 @@
#include "content/renderer/service_worker/service_worker_timeout_timer.h"
#include "content/renderer/service_worker/service_worker_type_converters.h"
#include "content/renderer/service_worker/service_worker_type_util.h"
-#include "content/renderer/service_worker/web_service_worker_impl.h"
-#include "content/renderer/service_worker/web_service_worker_provider_impl.h"
#include "content/renderer/service_worker/web_service_worker_registration_impl.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
@@ -54,7 +52,7 @@
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "storage/common/blob_storage/blob_handle.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
@@ -70,7 +68,7 @@
#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
#include "third_party/blink/public/platform/modules/payments/web_payment_handler_response.h"
#include "third_party/blink/public/platform/modules/payments/web_payment_request_event_data.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_client_query_options.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_clients_info.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h"
@@ -147,9 +145,10 @@ class WebServiceWorkerNetworkProviderImpl
private:
static bool IsScriptRequest(const WebURLRequest& request) {
auto request_context = request.GetRequestContext();
- return request_context == WebURLRequest::kRequestContextServiceWorker ||
- request_context == WebURLRequest::kRequestContextScript ||
- request_context == WebURLRequest::kRequestContextImport;
+ return request_context ==
+ blink::mojom::RequestContextType::SERVICE_WORKER ||
+ request_context == blink::mojom::RequestContextType::SCRIPT ||
+ request_context == blink::mojom::RequestContextType::IMPORT;
}
std::unique_ptr<ServiceWorkerNetworkProvider> provider_;
@@ -159,16 +158,25 @@ class StreamHandleListener
: public blink::WebServiceWorkerStreamHandle::Listener {
public:
StreamHandleListener(
- blink::mojom::ServiceWorkerStreamCallbackPtr callback_ptr)
- : callback_ptr_(std::move(callback_ptr)) {}
+ blink::mojom::ServiceWorkerStreamCallbackPtr callback_ptr,
+ std::unique_ptr<ServiceWorkerTimeoutTimer::StayAwakeToken> token)
+ : callback_ptr_(std::move(callback_ptr)), token_(std::move(token)) {}
~StreamHandleListener() override {}
- void OnAborted() override { callback_ptr_->OnAborted(); }
- void OnCompleted() override { callback_ptr_->OnCompleted(); }
+ void OnAborted() override {
+ callback_ptr_->OnAborted();
+ token_.reset();
+ }
+
+ void OnCompleted() override {
+ callback_ptr_->OnCompleted();
+ token_.reset();
+ }
private:
blink::mojom::ServiceWorkerStreamCallbackPtr callback_ptr_;
+ std::unique_ptr<ServiceWorkerTimeoutTimer::StayAwakeToken> token_;
};
bool IsOutOfProcessNetworkService() {
@@ -178,9 +186,9 @@ bool IsOutOfProcessNetworkService() {
switches::kSingleProcess);
}
-WebURLRequest::RequestContext GetBlinkRequestContext(
- RequestContextType request_context_type) {
- return static_cast<WebURLRequest::RequestContext>(request_context_type);
+blink::mojom::RequestContextType GetBlinkRequestContext(
+ blink::mojom::RequestContextType request_context_type) {
+ return static_cast<blink::mojom::RequestContextType>(request_context_type);
}
blink::WebServiceWorkerClientInfo ToWebServiceWorkerClientInfo(
@@ -207,7 +215,7 @@ blink::WebBackgroundFetchRegistration ToWebBackgroundFetchRegistration(
blink::WebString::FromUTF8(registration.developer_id),
blink::WebString::FromUTF8(registration.unique_id),
registration.upload_total, registration.uploaded,
- registration.download_total, registration.downloaded, registration.state,
+ registration.download_total, registration.downloaded, registration.result,
registration.failure_reason);
}
@@ -290,10 +298,11 @@ void ToWebServiceWorkerRequest(const network::ResourceRequest& request,
static_cast<ResourceType>(request.resource_type)));
web_request->SetCredentialsMode(request.fetch_credentials_mode);
web_request->SetCacheMode(
- ServiceWorkerFetchRequest::GetCacheModeFromLoadFlags(request.load_flags));
+ ServiceWorkerUtils::GetCacheModeFromLoadFlags(request.load_flags));
web_request->SetRedirectMode(request.fetch_redirect_mode);
- web_request->SetRequestContext(GetBlinkRequestContext(
- static_cast<RequestContextType>(request.fetch_request_context_type)));
+ web_request->SetRequestContext(
+ GetBlinkRequestContext(static_cast<blink::mojom::RequestContextType>(
+ request.fetch_request_context_type)));
web_request->SetFrameType(request.fetch_frame_type);
web_request->SetClientId(blink::WebString::FromUTF8(client_id));
web_request->SetIsReload(ui::PageTransitionCoreTypeIs(
@@ -306,6 +315,8 @@ void ToWebServiceWorkerRequest(const network::ResourceRequest& request,
web_request->SetKeepalive(request.keepalive);
web_request->SetIsHistoryNavigation(request.transition_type &
ui::PAGE_TRANSITION_FORWARD_BACK);
+ if (request.fetch_window_id)
+ web_request->SetWindowId(*request.fetch_window_id);
}
// Finds an event callback keyed by |event_id| from |map|, and runs the callback
@@ -332,7 +343,8 @@ template <typename MapType, typename... Args>
base::OnceCallback<void(int /* event_id */)> CreateAbortCallback(MapType* map,
Args... args) {
return base::BindOnce(
- [](MapType* map, Args... args, base::Time dispatched_time, int event_id) {
+ [](MapType* map, Args... args, base::TimeTicks dispatched_time,
+ int event_id) {
auto iter = map->find(event_id);
DCHECK(iter != map->end());
std::move(iter->second)
@@ -340,109 +352,7 @@ base::OnceCallback<void(int /* event_id */)> CreateAbortCallback(MapType* map,
std::forward<Args>(args)..., dispatched_time);
map->erase(iter);
},
- map, std::forward<Args>(args)..., base::Time::Now());
-}
-
-void DidGetClients(
- std::unique_ptr<blink::WebServiceWorkerClientsCallbacks> callbacks,
- std::vector<blink::mojom::ServiceWorkerClientInfoPtr> clients) {
- blink::WebServiceWorkerClientsInfo info;
- blink::WebVector<blink::WebServiceWorkerClientInfo> web_clients(
- clients.size());
- for (size_t i = 0; i < clients.size(); ++i)
- web_clients[i] = ToWebServiceWorkerClientInfo(std::move(clients[i]));
- info.clients.Swap(web_clients);
- callbacks->OnSuccess(info);
-}
-
-void DidClaimClients(
- std::unique_ptr<blink::WebServiceWorkerClientsClaimCallbacks> callbacks,
- blink::mojom::ServiceWorkerErrorType error,
- const base::Optional<std::string>& error_msg) {
- if (error != blink::mojom::ServiceWorkerErrorType::kNone) {
- callbacks->OnError(blink::WebServiceWorkerError(
- error, blink::WebString::FromUTF8(*error_msg)));
- return;
- }
- DCHECK(!error_msg);
- callbacks->OnSuccess();
-}
-
-void DidGetClient(
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks,
- blink::mojom::ServiceWorkerClientInfoPtr client) {
- std::unique_ptr<blink::WebServiceWorkerClientInfo> web_client;
- if (client) {
- web_client = std::make_unique<blink::WebServiceWorkerClientInfo>(
- ToWebServiceWorkerClientInfo(std::move(client)));
- }
- callbacks->OnSuccess(std::move(web_client));
-}
-
-void DidSkipWaiting(
- std::unique_ptr<blink::WebServiceWorkerSkipWaitingCallbacks> callbacks,
- bool success) {
- // OnError() should not be called here since per spec the promise returned by
- // skipWaiting() can never reject.
- if (!success)
- return;
- callbacks->OnSuccess();
-}
-
-void DidOpenWindow(
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks,
- bool success,
- blink::mojom::ServiceWorkerClientInfoPtr client,
- const base::Optional<std::string>& error_msg) {
- if (!success) {
- DCHECK(!client);
- callbacks->OnError(blink::WebServiceWorkerError(
- blink::mojom::ServiceWorkerErrorType::kNavigation,
- blink::WebString::FromUTF8(*error_msg)));
- return;
- }
-
- std::unique_ptr<blink::WebServiceWorkerClientInfo> web_client;
- if (client) {
- web_client = std::make_unique<blink::WebServiceWorkerClientInfo>(
- ToWebServiceWorkerClientInfo(std::move(client)));
- }
- callbacks->OnSuccess(std::move(web_client));
-}
-
-void DidFocusClient(
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks,
- blink::mojom::ServiceWorkerClientInfoPtr client) {
- if (!client) {
- callbacks->OnError(blink::WebServiceWorkerError(
- blink::mojom::ServiceWorkerErrorType::kNotFound,
- "The client was not found."));
- return;
- }
- auto web_client = std::make_unique<blink::WebServiceWorkerClientInfo>(
- ToWebServiceWorkerClientInfo(std::move(client)));
- callbacks->OnSuccess(std::move(web_client));
-}
-
-void DidNavigateClient(
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks,
- bool success,
- blink::mojom::ServiceWorkerClientInfoPtr client,
- const base::Optional<std::string>& error_msg) {
- if (!success) {
- DCHECK(!client);
- callbacks->OnError(blink::WebServiceWorkerError(
- blink::mojom::ServiceWorkerErrorType::kNavigation,
- blink::WebString::FromUTF8(*error_msg)));
- return;
- }
-
- std::unique_ptr<blink::WebServiceWorkerClientInfo> web_client;
- if (client) {
- web_client = std::make_unique<blink::WebServiceWorkerClientInfo>(
- ToWebServiceWorkerClientInfo(std::move(client)));
- }
- callbacks->OnSuccess(std::move(web_client));
+ map, std::forward<Args>(args)..., base::TimeTicks::Now());
}
} // namespace
@@ -459,15 +369,8 @@ struct ServiceWorkerContextClient::WorkerContextData {
DCHECK(thread_checker.CalledOnValidThread());
}
- // Map from version id to JavaScript ServiceWorker object.
- std::map<int64_t, WebServiceWorkerImpl*> workers_;
-
mojo::Binding<mojom::ServiceWorker> service_worker_binding;
- // Bound by the first Mojo call received on the service worker thread
- // ServiceWorker::InitializeGlobalScope().
- blink::mojom::ServiceWorkerHostAssociatedPtr service_worker_host;
-
// Maps for inflight event callbacks.
// These are mapped from an event id issued from ServiceWorkerTimeoutTimer to
// the Mojo callback to notify the end of the event.
@@ -572,7 +475,7 @@ class ServiceWorkerContextClient::NavigationPreloadRequest final
false /* report_security_info */,
-1 /* request_id */);
client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_),
- nullptr);
+ mojo::ScopedDataPipeConsumerHandle());
// This will delete |this|.
client->OnNavigationPreloadComplete(
fetch_event_id_, response_head.response_start,
@@ -632,7 +535,7 @@ class ServiceWorkerContextClient::NavigationPreloadRequest final
// without OnStartLoadingResponseBody().
DCHECK(!body_.is_valid());
client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_),
- nullptr);
+ mojo::ScopedDataPipeConsumerHandle());
}
// This will delete |this|.
client->OnNavigationPreloadComplete(
@@ -649,9 +552,8 @@ class ServiceWorkerContextClient::NavigationPreloadRequest final
if (!client)
return;
- client->OnNavigationPreloadResponse(
- fetch_event_id_, std::move(response_),
- std::make_unique<WebDataConsumerHandleImpl>(std::move(body_)));
+ client->OnNavigationPreloadResponse(fetch_event_id_, std::move(response_),
+ std::move(body_));
}
void ReportErrorToClient(const std::string& message,
@@ -755,66 +657,6 @@ ServiceWorkerContextClient::ServiceWorkerContextClient(
ServiceWorkerContextClient::~ServiceWorkerContextClient() {}
-scoped_refptr<WebServiceWorkerImpl>
-ServiceWorkerContextClient::GetOrCreateServiceWorkerObject(
- blink::mojom::ServiceWorkerObjectInfoPtr info) {
- if (!info)
- return nullptr;
-
- auto found = context_->workers_.find(info->version_id);
- if (found != context_->workers_.end()) {
- return found->second;
- }
-
- return WebServiceWorkerImpl::CreateForServiceWorkerGlobalScope(
- std::move(info));
-}
-
-void ServiceWorkerContextClient::GetClient(
- const blink::WebString& id,
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks) {
- DCHECK(callbacks);
- context_->service_worker_host->GetClient(
- id.Utf8(), base::BindOnce(&DidGetClient, std::move(callbacks)));
-}
-
-void ServiceWorkerContextClient::GetClients(
- const blink::WebServiceWorkerClientQueryOptions& weboptions,
- std::unique_ptr<blink::WebServiceWorkerClientsCallbacks> callbacks) {
- DCHECK(callbacks);
- auto options = blink::mojom::ServiceWorkerClientQueryOptions::New(
- weboptions.include_uncontrolled, weboptions.client_type);
- context_->service_worker_host->GetClients(
- std::move(options), base::BindOnce(&DidGetClients, std::move(callbacks)));
-}
-
-void ServiceWorkerContextClient::OpenNewTab(
- const blink::WebURL& url,
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks) {
- DCHECK(callbacks);
- context_->service_worker_host->OpenNewTab(
- url, base::BindOnce(&DidOpenWindow, std::move(callbacks)));
-}
-
-void ServiceWorkerContextClient::OpenPaymentHandlerWindow(
- const blink::WebURL& url,
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks) {
- DCHECK(callbacks);
- context_->service_worker_host->OpenPaymentHandlerWindow(
- url, base::BindOnce(&DidOpenWindow, std::move(callbacks)));
-}
-
-void ServiceWorkerContextClient::SetCachedMetadata(const blink::WebURL& url,
- const char* data,
- size_t size) {
- context_->service_worker_host->SetCachedMetadata(
- url, std::vector<uint8_t>(data, data + size));
-}
-
-void ServiceWorkerContextClient::ClearCachedMetadata(const blink::WebURL& url) {
- context_->service_worker_host->ClearCachedMetadata(url);
-}
-
void ServiceWorkerContextClient::WorkerReadyForInspection() {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
(*instance_host_)->OnReadyForInspection();
@@ -888,13 +730,13 @@ void ServiceWorkerContextClient::WorkerContextStarted(
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "EVALUATE_SCRIPT", this);
}
-void ServiceWorkerContextClient::WillEvaluateClassicScript() {
+void ServiceWorkerContextClient::WillEvaluateScript() {
DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
start_timing_->script_evaluation_start_time = base::TimeTicks::Now();
(*instance_host_)->OnScriptEvaluationStart();
}
-void ServiceWorkerContextClient::DidEvaluateClassicScript(bool success) {
+void ServiceWorkerContextClient::DidEvaluateScript(bool success) {
DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
start_timing_->script_evaluation_end_time = base::TimeTicks::Now();
@@ -999,7 +841,7 @@ void ServiceWorkerContextClient::ReportConsoleMessage(
void ServiceWorkerContextClient::DidHandleActivateEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1("ServiceWorker",
"ServiceWorkerContextClient::DidHandleActivateEvent",
TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope,
@@ -1008,13 +850,13 @@ void ServiceWorkerContextClient::DidHandleActivateEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->activate_event_callbacks,
context_->timeout_timer.get(), request_id, status,
- base::Time::FromDoubleT(event_dispatch_time));
+ event_dispatch_time);
}
void ServiceWorkerContextClient::DidHandleBackgroundFetchAbortEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker",
"ServiceWorkerContextClient::DidHandleBackgroundFetchAbortEvent",
@@ -1024,13 +866,13 @@ void ServiceWorkerContextClient::DidHandleBackgroundFetchAbortEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->background_fetch_abort_event_callbacks,
context_->timeout_timer.get(), request_id, status,
- base::Time::FromDoubleT(event_dispatch_time));
+ event_dispatch_time);
}
void ServiceWorkerContextClient::DidHandleBackgroundFetchClickEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker",
"ServiceWorkerContextClient::DidHandleBackgroundFetchClickEvent",
@@ -1040,13 +882,13 @@ void ServiceWorkerContextClient::DidHandleBackgroundFetchClickEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->background_fetch_click_event_callbacks,
context_->timeout_timer.get(), request_id, status,
- base::Time::FromDoubleT(event_dispatch_time));
+ event_dispatch_time);
}
void ServiceWorkerContextClient::DidHandleBackgroundFetchFailEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker",
"ServiceWorkerContextClient::DidHandleBackgroundFetchFailEvent",
@@ -1056,13 +898,13 @@ void ServiceWorkerContextClient::DidHandleBackgroundFetchFailEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->background_fetch_fail_event_callbacks,
context_->timeout_timer.get(), request_id, status,
- base::Time::FromDoubleT(event_dispatch_time));
+ event_dispatch_time);
}
void ServiceWorkerContextClient::DidHandleBackgroundFetchSuccessEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker",
"ServiceWorkerContextClient::DidHandleBackgroundFetchSuccessEvent",
@@ -1072,13 +914,13 @@ void ServiceWorkerContextClient::DidHandleBackgroundFetchSuccessEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->background_fetched_event_callbacks,
context_->timeout_timer.get(), request_id, status,
- base::Time::FromDoubleT(event_dispatch_time));
+ event_dispatch_time);
}
void ServiceWorkerContextClient::DidHandleCookieChangeEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker", "ServiceWorkerContextClient::DidHandleCookieChangeEvent",
TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope,
@@ -1087,13 +929,13 @@ void ServiceWorkerContextClient::DidHandleCookieChangeEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->cookie_change_event_callbacks,
context_->timeout_timer.get(), request_id, status,
- base::Time::FromDoubleT(event_dispatch_time));
+ event_dispatch_time);
}
void ServiceWorkerContextClient::DidHandleExtendableMessageEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker",
"ServiceWorkerContextClient::DidHandleExtendableMessageEvent",
@@ -1103,13 +945,13 @@ void ServiceWorkerContextClient::DidHandleExtendableMessageEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->message_event_callbacks,
context_->timeout_timer.get(), request_id, status,
- base::Time::FromDoubleT(event_dispatch_time));
+ event_dispatch_time);
}
void ServiceWorkerContextClient::DidHandleInstallEvent(
int event_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1("ServiceWorker",
"ServiceWorkerContextClient::DidHandleInstallEvent",
TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope,
@@ -1118,13 +960,13 @@ void ServiceWorkerContextClient::DidHandleInstallEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->install_event_callbacks,
context_->timeout_timer.get(), event_id, status,
- proxy_->HasFetchEventHandler(),
- base::Time::FromDoubleT(event_dispatch_time));
+ proxy_->HasFetchEventHandler(), event_dispatch_time);
}
void ServiceWorkerContextClient::RespondToFetchEventWithNoResponse(
int fetch_event_id,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time) {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker",
"ServiceWorkerContextClient::RespondToFetchEventWithNoResponse",
@@ -1135,14 +977,20 @@ void ServiceWorkerContextClient::RespondToFetchEventWithNoResponse(
const blink::mojom::ServiceWorkerFetchResponseCallbackPtr& response_callback =
context_->fetch_response_callbacks[fetch_event_id];
DCHECK(response_callback.is_bound());
- response_callback->OnFallback(base::Time::FromDoubleT(event_dispatch_time));
+
+ auto timing = blink::mojom::ServiceWorkerFetchEventTiming::New();
+ timing->dispatch_event_time = event_dispatch_time;
+ timing->respond_with_settled_time = respond_with_settled_time;
+
+ response_callback->OnFallback(std::move(timing));
context_->fetch_response_callbacks.erase(fetch_event_id);
}
void ServiceWorkerContextClient::RespondToFetchEvent(
int fetch_event_id,
const blink::WebServiceWorkerResponse& web_response,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time) {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker", "ServiceWorkerContextClient::RespondToFetchEvent",
TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope,
@@ -1154,8 +1002,11 @@ void ServiceWorkerContextClient::RespondToFetchEvent(
const blink::mojom::ServiceWorkerFetchResponseCallbackPtr& response_callback =
context_->fetch_response_callbacks[fetch_event_id];
- response_callback->OnResponse(std::move(response),
- base::Time::FromDoubleT(event_dispatch_time));
+ auto timing = blink::mojom::ServiceWorkerFetchEventTiming::New();
+ timing->dispatch_event_time = event_dispatch_time;
+ timing->respond_with_settled_time = respond_with_settled_time;
+
+ response_callback->OnResponse(std::move(response), std::move(timing));
context_->fetch_response_callbacks.erase(fetch_event_id);
}
@@ -1163,7 +1014,8 @@ void ServiceWorkerContextClient::RespondToFetchEventWithResponseStream(
int fetch_event_id,
const blink::WebServiceWorkerResponse& web_response,
blink::WebServiceWorkerStreamHandle* web_body_as_stream,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time) {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker",
"ServiceWorkerContextClient::RespondToFetchEventWithResponseStream",
@@ -1182,19 +1034,23 @@ void ServiceWorkerContextClient::RespondToFetchEventWithResponseStream(
body_as_stream->stream = web_body_as_stream->DrainStreamDataPipe();
DCHECK(body_as_stream->stream.is_valid());
- web_body_as_stream->SetListener(
- std::make_unique<StreamHandleListener>(std::move(callback_ptr)));
+ web_body_as_stream->SetListener(std::make_unique<StreamHandleListener>(
+ std::move(callback_ptr),
+ context_->timeout_timer->CreateStayAwakeToken()));
+
+ auto timing = blink::mojom::ServiceWorkerFetchEventTiming::New();
+ timing->dispatch_event_time = event_dispatch_time;
+ timing->respond_with_settled_time = respond_with_settled_time;
response_callback->OnResponseStream(
- std::move(response), std::move(body_as_stream),
- base::Time::FromDoubleT(event_dispatch_time));
+ std::move(response), std::move(body_as_stream), std::move(timing));
context_->fetch_response_callbacks.erase(fetch_event_id);
}
void ServiceWorkerContextClient::DidHandleFetchEvent(
int event_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
// This TRACE_EVENT is used for perf benchmark to confirm if all of fetch
// events have completed. (crbug.com/736697)
TRACE_EVENT_WITH_FLOW1("ServiceWorker",
@@ -1205,7 +1061,7 @@ void ServiceWorkerContextClient::DidHandleFetchEvent(
ServiceWorkerUtils::MojoEnumToString(status));
if (RunEventCallback(&context_->fetch_event_callbacks,
context_->timeout_timer.get(), event_id, status,
- base::Time::FromDoubleT(event_dispatch_time))) {
+ event_dispatch_time)) {
context_->fetch_response_callbacks.erase(event_id);
}
}
@@ -1213,7 +1069,7 @@ void ServiceWorkerContextClient::DidHandleFetchEvent(
void ServiceWorkerContextClient::DidHandleNotificationClickEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker",
"ServiceWorkerContextClient::DidHandleNotificationClickEvent",
@@ -1223,13 +1079,13 @@ void ServiceWorkerContextClient::DidHandleNotificationClickEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->notification_click_event_callbacks,
context_->timeout_timer.get(), request_id, status,
- base::Time::FromDoubleT(event_dispatch_time));
+ event_dispatch_time);
}
void ServiceWorkerContextClient::DidHandleNotificationCloseEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker",
"ServiceWorkerContextClient::DidHandleNotificationCloseEvent",
@@ -1239,13 +1095,13 @@ void ServiceWorkerContextClient::DidHandleNotificationCloseEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->notification_close_event_callbacks,
context_->timeout_timer.get(), request_id, status,
- base::Time::FromDoubleT(event_dispatch_time));
+ event_dispatch_time);
}
void ServiceWorkerContextClient::DidHandlePushEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1("ServiceWorker",
"ServiceWorkerContextClient::DidHandlePushEvent",
TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope,
@@ -1254,13 +1110,13 @@ void ServiceWorkerContextClient::DidHandlePushEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->push_event_callbacks,
context_->timeout_timer.get(), request_id, status,
- base::Time::FromDoubleT(event_dispatch_time));
+ event_dispatch_time);
}
void ServiceWorkerContextClient::DidHandleSyncEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1("ServiceWorker",
"ServiceWorkerContextClient::DidHandleSyncEvent",
TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope,
@@ -1269,13 +1125,13 @@ void ServiceWorkerContextClient::DidHandleSyncEvent(
ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->sync_event_callbacks,
context_->timeout_timer.get(), request_id, status,
- base::Time::FromDoubleT(event_dispatch_time));
+ event_dispatch_time);
}
void ServiceWorkerContextClient::RespondToAbortPaymentEvent(
int event_id,
bool payment_aborted,
- double dispatch_event_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker", "ServiceWorkerContextClient::RespondToAbortPaymentEvent",
TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope,
@@ -1284,15 +1140,15 @@ void ServiceWorkerContextClient::RespondToAbortPaymentEvent(
DCHECK(base::ContainsKey(context_->abort_payment_result_callbacks, event_id));
const payments::mojom::PaymentHandlerResponseCallbackPtr& result_callback =
context_->abort_payment_result_callbacks[event_id];
- result_callback->OnResponseForAbortPayment(
- payment_aborted, base::Time::FromDoubleT(dispatch_event_time));
+ result_callback->OnResponseForAbortPayment(payment_aborted,
+ event_dispatch_time);
context_->abort_payment_result_callbacks.erase(event_id);
}
void ServiceWorkerContextClient::DidHandleAbortPaymentEvent(
int event_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker", "ServiceWorkerContextClient::DidHandleAbortPaymentEvent",
TRACE_ID_WITH_SCOPE(kServiceWorkerContextClientScope,
@@ -1301,7 +1157,7 @@ void ServiceWorkerContextClient::DidHandleAbortPaymentEvent(
ServiceWorkerUtils::MojoEnumToString(status));
if (RunEventCallback(&context_->abort_payment_event_callbacks,
context_->timeout_timer.get(), event_id, status,
- base::Time::FromDoubleT(dispatch_event_time))) {
+ event_dispatch_time)) {
context_->abort_payment_result_callbacks.erase(event_id);
}
}
@@ -1309,7 +1165,7 @@ void ServiceWorkerContextClient::DidHandleAbortPaymentEvent(
void ServiceWorkerContextClient::RespondToCanMakePaymentEvent(
int event_id,
bool can_make_payment,
- double dispatch_event_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker",
"ServiceWorkerContextClient::RespondToCanMakePaymentEvent",
@@ -1320,15 +1176,15 @@ void ServiceWorkerContextClient::RespondToCanMakePaymentEvent(
base::ContainsKey(context_->can_make_payment_result_callbacks, event_id));
const payments::mojom::PaymentHandlerResponseCallbackPtr& result_callback =
context_->can_make_payment_result_callbacks[event_id];
- result_callback->OnResponseForCanMakePayment(
- can_make_payment, base::Time::FromDoubleT(dispatch_event_time));
+ result_callback->OnResponseForCanMakePayment(can_make_payment,
+ event_dispatch_time);
context_->can_make_payment_result_callbacks.erase(event_id);
}
void ServiceWorkerContextClient::DidHandleCanMakePaymentEvent(
int event_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker",
"ServiceWorkerContextClient::DidHandleCanMakePaymentEvent",
@@ -1338,7 +1194,7 @@ void ServiceWorkerContextClient::DidHandleCanMakePaymentEvent(
ServiceWorkerUtils::MojoEnumToString(status));
if (RunEventCallback(&context_->can_make_payment_event_callbacks,
context_->timeout_timer.get(), event_id, status,
- base::Time::FromDoubleT(dispatch_event_time))) {
+ event_dispatch_time)) {
context_->can_make_payment_result_callbacks.erase(event_id);
}
}
@@ -1346,7 +1202,7 @@ void ServiceWorkerContextClient::DidHandleCanMakePaymentEvent(
void ServiceWorkerContextClient::RespondToPaymentRequestEvent(
int payment_request_id,
const blink::WebPaymentHandlerResponse& web_response,
- double dispatch_event_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker",
"ServiceWorkerContextClient::RespondToPaymentRequestEvent",
@@ -1361,15 +1217,15 @@ void ServiceWorkerContextClient::RespondToPaymentRequestEvent(
payments::mojom::PaymentHandlerResponse::New();
response->method_name = web_response.method_name.Utf8();
response->stringified_details = web_response.stringified_details.Utf8();
- response_callback->OnResponseForPaymentRequest(
- std::move(response), base::Time::FromDoubleT(dispatch_event_time));
+ response_callback->OnResponseForPaymentRequest(std::move(response),
+ event_dispatch_time);
context_->payment_response_callbacks.erase(payment_request_id);
}
void ServiceWorkerContextClient::DidHandlePaymentRequestEvent(
int payment_request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) {
+ base::TimeTicks event_dispatch_time) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker",
"ServiceWorkerContextClient::DidHandlePaymentRequestEvent",
@@ -1379,7 +1235,7 @@ void ServiceWorkerContextClient::DidHandlePaymentRequestEvent(
ServiceWorkerUtils::MojoEnumToString(status));
if (RunEventCallback(&context_->payment_request_event_callbacks,
context_->timeout_timer.get(), payment_request_id,
- status, base::Time::FromDoubleT(event_dispatch_time))) {
+ status, event_dispatch_time)) {
context_->payment_response_callbacks.erase(payment_request_id);
}
}
@@ -1430,54 +1286,6 @@ ServiceWorkerContextClient::CreateServiceWorkerFetchContext(
std::move(preference_watcher_request_));
}
-std::unique_ptr<blink::WebServiceWorkerProvider>
-ServiceWorkerContextClient::CreateServiceWorkerProvider() {
- DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
- DCHECK(provider_context_);
-
- return std::make_unique<WebServiceWorkerProviderImpl>(
- provider_context_.get());
-}
-
-void ServiceWorkerContextClient::PostMessageToClient(
- const blink::WebString& uuid,
- blink::TransferableMessage message) {
- context_->service_worker_host->PostMessageToClient(uuid.Utf8(),
- std::move(message));
-}
-
-void ServiceWorkerContextClient::Focus(
- const blink::WebString& uuid,
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks) {
- DCHECK(callbacks);
- context_->service_worker_host->FocusClient(
- uuid.Utf8(), base::BindOnce(&DidFocusClient, std::move(callbacks)));
-}
-
-void ServiceWorkerContextClient::Navigate(
- const blink::WebString& uuid,
- const blink::WebURL& url,
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks) {
- DCHECK(callbacks);
- context_->service_worker_host->NavigateClient(
- uuid.Utf8(), url,
- base::BindOnce(&DidNavigateClient, std::move(callbacks)));
-}
-
-void ServiceWorkerContextClient::SkipWaiting(
- std::unique_ptr<blink::WebServiceWorkerSkipWaitingCallbacks> callbacks) {
- DCHECK(callbacks);
- context_->service_worker_host->SkipWaiting(
- base::BindOnce(&DidSkipWaiting, std::move(callbacks)));
-}
-
-void ServiceWorkerContextClient::Claim(
- std::unique_ptr<blink::WebServiceWorkerClientsClaimCallbacks> callbacks) {
- DCHECK(callbacks);
- context_->service_worker_host->ClaimClients(
- base::BindOnce(&DidClaimClients, std::move(callbacks)));
-}
-
void ServiceWorkerContextClient::DispatchOrQueueFetchEvent(
blink::mojom::DispatchFetchEventParamsPtr params,
blink::mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
@@ -1581,6 +1389,11 @@ void ServiceWorkerContextClient::SendWorkerStarted(
blink::mojom::ServiceWorkerStartStatus status) {
DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
+ if (GetContentClient()->renderer()) { // nullptr in unit_tests.
+ GetContentClient()->renderer()->DidStartServiceWorkerContextOnWorkerThread(
+ service_worker_version_id_, service_worker_scope_, script_url_);
+ }
+
(*instance_host_)
->OnStarted(status, WorkerThread::GetCurrentId(),
std::move(start_timing_));
@@ -1683,8 +1496,7 @@ void ServiceWorkerContextClient::InitializeGlobalScope(
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info) {
DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
// Connect to the blink::mojom::ServiceWorkerHost.
- DCHECK(!context_->service_worker_host);
- context_->service_worker_host.Bind(std::move(service_worker_host));
+ proxy_->BindServiceWorkerHost(service_worker_host.PassHandle());
// Set ServiceWorkerGlobalScope#registration.
DCHECK_NE(registration_info->registration_id,
blink::mojom::kInvalidServiceWorkerRegistrationId);
@@ -1735,11 +1547,10 @@ void ServiceWorkerContextClient::DispatchExtendableMessageEvent(
DCHECK_NE(event->source_info_for_service_worker->version_id,
blink::mojom::kInvalidServiceWorkerVersionId);
- scoped_refptr<WebServiceWorkerImpl> worker = GetOrCreateServiceWorkerObject(
- std::move(event->source_info_for_service_worker));
proxy_->DispatchExtendableMessageEvent(
request_id, std::move(event->message), event->source_origin,
- WebServiceWorkerImpl::CreateHandle(worker));
+ event->source_info_for_service_worker
+ .To<blink::WebServiceWorkerObjectInfo>());
}
void ServiceWorkerContextClient::
@@ -1767,11 +1578,10 @@ void ServiceWorkerContextClient::
DCHECK_NE(event->source_info_for_service_worker->version_id,
blink::mojom::kInvalidServiceWorkerVersionId);
- scoped_refptr<WebServiceWorkerImpl> worker = GetOrCreateServiceWorkerObject(
- std::move(event->source_info_for_service_worker));
proxy_->DispatchExtendableMessageEvent(
request_id, std::move(event->message), event->source_origin,
- WebServiceWorkerImpl::CreateHandle(worker));
+ event->source_info_for_service_worker
+ .To<blink::WebServiceWorkerObjectInfo>());
}
// S13nServiceWorker
@@ -1812,7 +1622,7 @@ void ServiceWorkerContextClient::DispatchFetchEvent(
void ServiceWorkerContextClient::DispatchNotificationClickEvent(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
DispatchNotificationClickEventCallback callback) {
@@ -1838,7 +1648,7 @@ void ServiceWorkerContextClient::DispatchNotificationClickEvent(
void ServiceWorkerContextClient::DispatchNotificationCloseEvent(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
DispatchNotificationCloseEventCallback callback) {
int request_id = context_->timeout_timer->StartEvent(
CreateAbortCallback(&context_->notification_close_event_callbacks));
@@ -1920,7 +1730,7 @@ void ServiceWorkerContextClient::SetIdleTimerDelayToZero() {
void ServiceWorkerContextClient::OnNavigationPreloadResponse(
int fetch_event_id,
std::unique_ptr<blink::WebURLResponse> response,
- std::unique_ptr<blink::WebDataConsumerHandle> data_consumer_handle) {
+ mojo::ScopedDataPipeConsumerHandle data_pipe) {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker",
"ServiceWorkerContextClient::OnNavigationPreloadResponse",
@@ -1928,7 +1738,7 @@ void ServiceWorkerContextClient::OnNavigationPreloadResponse(
TRACE_ID_LOCAL(fetch_event_id)),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
proxy_->OnNavigationPreloadResponse(fetch_event_id, std::move(response),
- std::move(data_consumer_handle));
+ std::move(data_pipe));
}
void ServiceWorkerContextClient::OnNavigationPreloadError(
@@ -2007,23 +1817,6 @@ void ServiceWorkerContextClient::StopWorker() {
embedded_worker_client_->StopWorker();
}
-void ServiceWorkerContextClient::AddServiceWorkerObject(
- int64_t version_id,
- WebServiceWorkerImpl* worker) {
- DCHECK(!base::ContainsKey(context_->workers_, version_id));
- context_->workers_[version_id] = worker;
-}
-
-void ServiceWorkerContextClient::RemoveServiceWorkerObject(int64_t version_id) {
- DCHECK(base::ContainsKey(context_->workers_, version_id));
- context_->workers_.erase(version_id);
-}
-
-bool ServiceWorkerContextClient::ContainsServiceWorkerObjectForTesting(
- int64_t version_id) {
- return base::ContainsKey(context_->workers_, version_id);
-}
-
base::WeakPtr<ServiceWorkerContextClient>
ServiceWorkerContextClient::GetWeakPtr() {
DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
diff --git a/chromium/content/renderer/service_worker/service_worker_context_client.h b/chromium/content/renderer/service_worker/service_worker_context_client.h
index f5770f23a2d..2357eccf7ee 100644
--- a/chromium/content/renderer/service_worker/service_worker_context_client.h
+++ b/chromium/content/renderer/service_worker/service_worker_context_client.h
@@ -45,23 +45,19 @@ class TaskRunner;
}
namespace blink {
-class WebDataConsumerHandle;
-struct WebServiceWorkerClientQueryOptions;
+struct PlatformNotificationData;
class WebServiceWorkerContextProxy;
-class WebServiceWorkerProvider;
class WebServiceWorkerResponse;
class WebURLResponse;
}
namespace content {
-struct PlatformNotificationData;
class EmbeddedWorkerInstanceClientImpl;
class HostChildURLLoaderFactoryBundle;
class ServiceWorkerNetworkProvider;
class ServiceWorkerProviderContext;
class ServiceWorkerTimeoutTimer;
-class WebServiceWorkerImpl;
class WebWorkerFetchContext;
// ServiceWorkerContextClient is a "client" of a service worker execution
@@ -105,36 +101,15 @@ class CONTENT_EXPORT ServiceWorkerContextClient
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
~ServiceWorkerContextClient() override;
- // Returns the service worker object described by |info|. Creates a new object
- // if needed, or else returns the existing one.
- scoped_refptr<WebServiceWorkerImpl> GetOrCreateServiceWorkerObject(
- blink::mojom::ServiceWorkerObjectInfoPtr info);
-
// WebServiceWorkerContextClient overrides.
- void GetClient(
- const blink::WebString& client_id,
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks>) override;
- void GetClients(
- const blink::WebServiceWorkerClientQueryOptions&,
- std::unique_ptr<blink::WebServiceWorkerClientsCallbacks>) override;
- void OpenNewTab(
- const blink::WebURL&,
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks>) override;
- void OpenPaymentHandlerWindow(
- const blink::WebURL&,
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks>) override;
- void SetCachedMetadata(const blink::WebURL&,
- const char* data,
- size_t size) override;
- void ClearCachedMetadata(const blink::WebURL&) override;
void WorkerReadyForInspection() override;
void WorkerContextFailedToStart() override;
void FailedToLoadInstalledScript() override;
void WorkerScriptLoaded() override;
void WorkerContextStarted(
blink::WebServiceWorkerContextProxy* proxy) override;
- void WillEvaluateClassicScript() override;
- void DidEvaluateClassicScript(bool success) override;
+ void WillEvaluateScript() override;
+ void DidEvaluateScript(bool success) override;
void DidInitializeWorkerContext(v8::Local<v8::Context> context) override;
void WillDestroyWorkerContext(v8::Local<v8::Context> context) override;
void WorkerContextDestroyed() override;
@@ -150,99 +125,90 @@ class CONTENT_EXPORT ServiceWorkerContextClient
const blink::WebString& source_url) override;
void DidHandleActivateEvent(int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandleBackgroundFetchAbortEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandleBackgroundFetchClickEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandleBackgroundFetchFailEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandleBackgroundFetchSuccessEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandleCookieChangeEvent(int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandleExtendableMessageEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandleInstallEvent(int event_id,
blink::mojom::ServiceWorkerEventStatus status,
- double event_dispatch_time) override;
- void RespondToFetchEventWithNoResponse(int fetch_event_id,
- double event_dispatch_time) override;
+ base::TimeTicks event_dispatch_time) override;
+ void RespondToFetchEventWithNoResponse(
+ int fetch_event_id,
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time) override;
void RespondToFetchEvent(int fetch_event_id,
const blink::WebServiceWorkerResponse& response,
- double event_dispatch_time) override;
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time) override;
void RespondToFetchEventWithResponseStream(
int fetch_event_id,
const blink::WebServiceWorkerResponse& response,
blink::WebServiceWorkerStreamHandle* web_body_as_stream,
- double event_dispatch_time) override;
+ base::TimeTicks event_dispatch_time,
+ base::TimeTicks respond_with_settled_time) override;
void DidHandleFetchEvent(int fetch_event_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandleNotificationClickEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandleNotificationCloseEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandlePushEvent(int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandleSyncEvent(int request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void RespondToAbortPaymentEvent(int event_id,
bool payment_aborted,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandleAbortPaymentEvent(int event_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
- void RespondToCanMakePaymentEvent(int event_id,
- bool can_make_payment,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
+ void RespondToCanMakePaymentEvent(
+ int event_id,
+ bool can_make_payment,
+ base::TimeTicks event_dispatch_time) override;
void DidHandleCanMakePaymentEvent(
int event_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void RespondToPaymentRequestEvent(
int payment_request_id,
const blink::WebPaymentHandlerResponse& response,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
void DidHandlePaymentRequestEvent(
int payment_request_id,
blink::mojom::ServiceWorkerEventStatus status,
- double dispatch_event_time) override;
+ base::TimeTicks event_dispatch_time) override;
std::unique_ptr<blink::WebServiceWorkerNetworkProvider>
CreateServiceWorkerNetworkProvider() override;
std::unique_ptr<blink::WebWorkerFetchContext> CreateServiceWorkerFetchContext(
blink::WebServiceWorkerNetworkProvider*) override;
- std::unique_ptr<blink::WebServiceWorkerProvider> CreateServiceWorkerProvider()
- override;
- void PostMessageToClient(const blink::WebString& uuid,
- blink::TransferableMessage message) override;
- void Focus(const blink::WebString& uuid,
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks>) override;
- void Navigate(
- const blink::WebString& uuid,
- const blink::WebURL&,
- std::unique_ptr<blink::WebServiceWorkerClientCallbacks>) override;
- void SkipWaiting(std::unique_ptr<blink::WebServiceWorkerSkipWaitingCallbacks>
- callbacks) override;
- void Claim(std::unique_ptr<blink::WebServiceWorkerClientsClaimCallbacks>
- callbacks) override;
// Dispatches the fetch event if the worker is running normally, and queues it
// instead if the worker has already requested to be terminated by the
@@ -262,7 +228,6 @@ class CONTENT_EXPORT ServiceWorkerContextClient
class NavigationPreloadRequest;
friend class ControllerServiceWorkerImpl;
friend class ServiceWorkerContextClientTest;
- friend class WebServiceWorkerImpl;
FRIEND_TEST_ALL_PREFIXES(
ServiceWorkerContextClientTest,
DispatchOrQueueFetchEvent_RequestedTerminationAndDie);
@@ -311,13 +276,13 @@ class CONTENT_EXPORT ServiceWorkerContextClient
DispatchFetchEventCallback callback) override;
void DispatchNotificationClickEvent(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
DispatchNotificationClickEventCallback callback) override;
void DispatchNotificationCloseEvent(
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
DispatchNotificationCloseEventCallback callback) override;
void DispatchPushEvent(const base::Optional<std::string>& payload,
DispatchPushEventCallback callback) override;
@@ -346,13 +311,13 @@ class CONTENT_EXPORT ServiceWorkerContextClient
void OnNotificationClickEvent(
int request_id,
const std::string& notification_id,
- const PlatformNotificationData& notification_data,
+ const blink::PlatformNotificationData& notification_data,
int action_index,
const base::NullableString16& reply);
void OnNotificationCloseEvent(
int request_id,
const std::string& notification_id,
- const PlatformNotificationData& notification_data);
+ const blink::PlatformNotificationData& notification_data);
void OnFocusClientResponse(
int request_id,
@@ -365,7 +330,7 @@ class CONTENT_EXPORT ServiceWorkerContextClient
void OnNavigationPreloadResponse(
int fetch_event_id,
std::unique_ptr<blink::WebURLResponse> response,
- std::unique_ptr<blink::WebDataConsumerHandle> data_consumer_handle);
+ mojo::ScopedDataPipeConsumerHandle data_pipe);
// Called when the navigation preload request completed. Either
// OnNavigationPreloadComplete() or OnNavigationPreloadError() must be
// called to release the preload related resources.
@@ -398,11 +363,6 @@ class CONTENT_EXPORT ServiceWorkerContextClient
// Stops the worker context. Called on the main thread.
void StopWorker();
- // Keeps the mapping from version id to ServiceWorker object.
- void AddServiceWorkerObject(int64_t version_id, WebServiceWorkerImpl* worker);
- void RemoveServiceWorkerObject(int64_t version_id);
- bool ContainsServiceWorkerObjectForTesting(int64_t version_id);
-
base::WeakPtr<ServiceWorkerContextClient> GetWeakPtr();
static void ResetThreadSpecificInstanceForTesting();
diff --git a/chromium/content/renderer/service_worker/service_worker_context_client_unittest.cc b/chromium/content/renderer/service_worker/service_worker_context_client_unittest.cc
index 273452c5a13..bc666cd5438 100644
--- a/chromium/content/renderer/service_worker/service_worker_context_client_unittest.cc
+++ b/chromium/content/renderer/service_worker/service_worker_context_client_unittest.cc
@@ -20,14 +20,13 @@
#include "content/renderer/service_worker/embedded_worker_instance_client_impl.h"
#include "content/renderer/service_worker/service_worker_timeout_timer.h"
#include "content/renderer/service_worker/service_worker_type_util.h"
-#include "content/renderer/service_worker/web_service_worker_impl.h"
#include "content/renderer/worker_thread_registry.h"
#include "mojo/public/cpp/bindings/associated_binding_set.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_request.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
@@ -66,12 +65,14 @@ class MockWebServiceWorkerContextProxy
public:
~MockWebServiceWorkerContextProxy() override = default;
- void ReadyToEvaluateScript() override {}
+ void BindServiceWorkerHost(
+ mojo::ScopedInterfaceEndpointHandle service_worker_host) override {}
void SetRegistration(
std::unique_ptr<blink::WebServiceWorkerRegistration::Handle> handle)
override {
registration_handle_ = std::move(handle);
}
+ void ReadyToEvaluateScript() override {}
bool HasFetchEventHandler() override { return false; }
void DispatchFetchEvent(int fetch_event_id,
const blink::WebServiceWorkerRequest& web_request,
@@ -117,7 +118,7 @@ class MockWebServiceWorkerContextProxy
int event_id,
blink::TransferableMessage message,
const blink::WebSecurityOrigin& source_origin,
- std::unique_ptr<blink::WebServiceWorker::Handle>) override {
+ blink::WebServiceWorkerObjectInfo) override {
NOTREACHED();
}
void DispatchInstallEvent(int event_id) override { NOTREACHED(); }
@@ -156,7 +157,7 @@ class MockWebServiceWorkerContextProxy
void OnNavigationPreloadResponse(
int fetch_event_id,
std::unique_ptr<blink::WebURLResponse>,
- std::unique_ptr<blink::WebDataConsumerHandle>) override {
+ mojo::ScopedDataPipeConsumerHandle) override {
NOTREACHED();
}
void OnNavigationPreloadError(
@@ -290,7 +291,8 @@ class ServiceWorkerContextClientTest : public testing::Test {
registration_info->registration_id = 100; // dummy
registration_info->options =
blink::mojom::ServiceWorkerRegistrationOptions::New(
- kScope, blink::mojom::ServiceWorkerUpdateViaCache::kAll);
+ kScope, blink::mojom::ScriptType::kClassic,
+ blink::mojom::ServiceWorkerUpdateViaCache::kAll);
out_pipes->registration_host_request =
mojo::MakeRequest(&registration_info->host_ptr_info);
registration_info->request = mojo::MakeRequest(&out_pipes->registration);
@@ -300,11 +302,6 @@ class ServiceWorkerContextClientTest : public testing::Test {
return context_client;
}
- bool ContainsServiceWorkerObject(ServiceWorkerContextClient* context_client,
- int64_t version_id) {
- return context_client->ContainsServiceWorkerObjectForTesting(version_id);
- }
-
scoped_refptr<base::TestMockTimeTaskRunner> task_runner() const {
return task_runner_;
}
@@ -332,7 +329,7 @@ TEST_F(ServiceWorkerContextClientTest, DispatchFetchEvent) {
MockWebServiceWorkerContextProxy mock_proxy;
std::unique_ptr<ServiceWorkerContextClient> context_client =
CreateContextClient(&pipes, &mock_proxy);
- context_client->DidEvaluateClassicScript(true /* success */);
+ context_client->DidEvaluateScript(true /* success */);
task_runner()->RunUntilIdle();
EXPECT_TRUE(mock_proxy.fetch_events().empty());
@@ -347,7 +344,7 @@ TEST_F(ServiceWorkerContextClientTest, DispatchFetchEvent) {
pipes.service_worker->DispatchFetchEvent(
std::move(params), std::move(fetch_callback_ptr),
base::BindOnce(
- [](blink::mojom::ServiceWorkerEventStatus, base::Time) {}));
+ [](blink::mojom::ServiceWorkerEventStatus, base::TimeTicks) {}));
task_runner()->RunUntilIdle();
ASSERT_EQ(1u, mock_proxy.fetch_events().size());
@@ -370,7 +367,7 @@ TEST_F(ServiceWorkerContextClientTest, DispatchFetchEvent_Headers) {
MockWebServiceWorkerContextProxy mock_proxy;
std::unique_ptr<ServiceWorkerContextClient> context_client =
CreateContextClient(&pipes, &mock_proxy);
- context_client->DidEvaluateClassicScript(true /* success */);
+ context_client->DidEvaluateScript(true /* success */);
task_runner()->RunUntilIdle();
EXPECT_TRUE(mock_proxy.fetch_events().empty());
@@ -387,7 +384,7 @@ TEST_F(ServiceWorkerContextClientTest, DispatchFetchEvent_Headers) {
pipes.service_worker->DispatchFetchEvent(
std::move(params), std::move(fetch_callback_ptr),
base::BindOnce(
- [](blink::mojom::ServiceWorkerEventStatus, base::Time) {}));
+ [](blink::mojom::ServiceWorkerEventStatus, base::TimeTicks) {}));
task_runner()->RunUntilIdle();
ASSERT_EQ(1u, mock_proxy.fetch_events().size());
@@ -412,7 +409,7 @@ TEST_F(ServiceWorkerContextClientTest,
MockWebServiceWorkerContextProxy mock_proxy;
std::unique_ptr<ServiceWorkerContextClient> context_client =
CreateContextClient(&pipes, &mock_proxy);
- context_client->DidEvaluateClassicScript(true /* success */);
+ context_client->DidEvaluateScript(true /* success */);
task_runner()->RunUntilIdle();
EXPECT_TRUE(mock_proxy.fetch_events().empty());
@@ -434,7 +431,7 @@ TEST_F(ServiceWorkerContextClientTest,
context_client->DispatchOrQueueFetchEvent(
std::move(params), std::move(fetch_callback_ptr),
base::BindOnce(
- [](blink::mojom::ServiceWorkerEventStatus, base::Time) {}));
+ [](blink::mojom::ServiceWorkerEventStatus, base::TimeTicks) {}));
task_runner()->RunUntilIdle();
EXPECT_FALSE(context_client->RequestedTermination());
@@ -450,7 +447,7 @@ TEST_F(ServiceWorkerContextClientTest,
MockWebServiceWorkerContextProxy mock_proxy;
std::unique_ptr<ServiceWorkerContextClient> context_client =
CreateContextClient(&pipes, &mock_proxy);
- context_client->DidEvaluateClassicScript(true /* success */);
+ context_client->DidEvaluateScript(true /* success */);
task_runner()->RunUntilIdle();
EXPECT_TRUE(mock_proxy.fetch_events().empty());
@@ -482,7 +479,7 @@ TEST_F(ServiceWorkerContextClientTest,
pipes.controller->DispatchFetchEvent(
std::move(params), std::move(fetch_callback_ptr),
base::BindOnce(
- [](blink::mojom::ServiceWorkerEventStatus, base::Time) {}));
+ [](blink::mojom::ServiceWorkerEventStatus, base::TimeTicks) {}));
task_runner()->RunUntilIdle();
}
EXPECT_TRUE(mock_proxy.fetch_events().empty());
@@ -498,7 +495,7 @@ TEST_F(ServiceWorkerContextClientTest,
MockWebServiceWorkerContextProxy mock_proxy;
std::unique_ptr<ServiceWorkerContextClient> context_client =
CreateContextClient(&pipes, &mock_proxy);
- context_client->DidEvaluateClassicScript(true /* success */);
+ context_client->DidEvaluateScript(true /* success */);
task_runner()->RunUntilIdle();
EXPECT_TRUE(mock_proxy.fetch_events().empty());
bool is_idle = false;
@@ -533,7 +530,7 @@ TEST_F(ServiceWorkerContextClientTest,
pipes.controller->DispatchFetchEvent(
std::move(params), std::move(fetch_callback_ptr),
base::BindOnce(
- [](blink::mojom::ServiceWorkerEventStatus, base::Time) {}));
+ [](blink::mojom::ServiceWorkerEventStatus, base::TimeTicks) {}));
task_runner()->RunUntilIdle();
}
EXPECT_TRUE(mock_proxy.fetch_events().empty());
@@ -550,7 +547,7 @@ TEST_F(ServiceWorkerContextClientTest,
pipes.service_worker->DispatchFetchEvent(
std::move(params), std::move(fetch_callback_ptr),
base::BindOnce(
- [](blink::mojom::ServiceWorkerEventStatus, base::Time) {}));
+ [](blink::mojom::ServiceWorkerEventStatus, base::TimeTicks) {}));
task_runner()->RunUntilIdle();
}
EXPECT_FALSE(context_client->RequestedTermination());
@@ -563,58 +560,4 @@ TEST_F(ServiceWorkerContextClientTest,
static_cast<GURL>(mock_proxy.fetch_events()[1].second.Url()));
}
-TEST_F(ServiceWorkerContextClientTest, GetOrCreateServiceWorkerObject) {
- ContextClientPipes pipes;
- MockWebServiceWorkerContextProxy mock_proxy;
- std::unique_ptr<ServiceWorkerContextClient> context_client =
- CreateContextClient(&pipes, &mock_proxy);
- scoped_refptr<WebServiceWorkerImpl> worker1;
- scoped_refptr<WebServiceWorkerImpl> worker2;
- const int64_t version_id = 200;
- auto mock_service_worker_object_host =
- std::make_unique<MockServiceWorkerObjectHost>(version_id);
- ASSERT_EQ(0, mock_service_worker_object_host->GetBindingCount());
-
- // Should return a worker object newly created with the 1st given |info|.
- {
- blink::mojom::ServiceWorkerObjectInfoPtr info =
- mock_service_worker_object_host->CreateObjectInfo();
- // ServiceWorkerObjectHost Mojo connection has been added.
- EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount());
- EXPECT_FALSE(ContainsServiceWorkerObject(context_client.get(), version_id));
- worker1 = context_client->GetOrCreateServiceWorkerObject(std::move(info));
- EXPECT_TRUE(worker1);
- EXPECT_TRUE(ContainsServiceWorkerObject(context_client.get(), version_id));
- // |worker1| is holding the 1st blink::mojom::ServiceWorkerObjectHost Mojo
- // connection to |mock_service_worker_object_host|.
- EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount());
- }
-
- // Should return the same worker object and release the 2nd given |info|.
- {
- blink::mojom::ServiceWorkerObjectInfoPtr info =
- mock_service_worker_object_host->CreateObjectInfo();
- EXPECT_EQ(2, mock_service_worker_object_host->GetBindingCount());
- worker2 = context_client->GetOrCreateServiceWorkerObject(std::move(info));
- EXPECT_EQ(worker1, worker2);
- task_runner()->RunUntilIdle();
- // The 2nd ServiceWorkerObjectHost Mojo connection in |info| has been
- // dropped.
- EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount());
- }
-
- // The dtor decrements the refcounts.
- worker1 = nullptr;
- worker2 = nullptr;
- task_runner()->RunUntilIdle();
- EXPECT_FALSE(ContainsServiceWorkerObject(context_client.get(), version_id));
- // The 1st ServiceWorkerObjectHost Mojo connection got broken.
- EXPECT_EQ(0, mock_service_worker_object_host->GetBindingCount());
-
- // Should return nullptr when given nullptr.
- scoped_refptr<WebServiceWorkerImpl> invalid_worker =
- context_client->GetOrCreateServiceWorkerObject(nullptr);
- EXPECT_FALSE(invalid_worker);
-}
-
} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_network_provider.cc b/chromium/content/renderer/service_worker/service_worker_network_provider.cc
index 64b0d8bcec7..d9fa10dd9f9 100644
--- a/chromium/content/renderer/service_worker/service_worker_network_provider.cc
+++ b/chromium/content/renderer/service_worker/service_worker_network_provider.cc
@@ -78,6 +78,14 @@ class WebServiceWorkerNetworkProviderForFrame
blink::mojom::ControllerServiceWorkerMode::kNoController) {
request.SetSkipServiceWorker(true);
}
+
+ // Inject this frame's fetch window id into the request. This is really only
+ // needed for subresource requests in S13nServiceWorker. For main resource
+ // requests or non-S13nSW case, the browser process sets the id on the
+ // request when dispatching the fetch event to the service worker. But it
+ // doesn't hurt to set it always.
+ if (provider_->context())
+ request.SetFetchWindowId(provider_->context()->fetch_request_window_id());
}
int ProviderID() const override { return provider_->provider_id(); }
@@ -207,13 +215,14 @@ ServiceWorkerNetworkProvider::CreateForSharedWorker(
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_info,
+ mojom::ControllerServiceWorkerInfoPtr controller_info,
scoped_refptr<network::SharedURLLoaderFactory> fallback_loader_factory) {
// S13nServiceWorker: |info| holds info about the precreated provider host.
if (info) {
DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
return base::WrapUnique(new ServiceWorkerNetworkProvider(
std::move(info), std::move(script_loader_factory_info),
- std::move(fallback_loader_factory)));
+ std::move(controller_info), std::move(fallback_loader_factory)));
}
return base::WrapUnique(new ServiceWorkerNetworkProvider(
@@ -317,12 +326,13 @@ ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_info,
+ mojom::ControllerServiceWorkerInfoPtr controller_info,
scoped_refptr<network::SharedURLLoaderFactory> fallback_loader_factory) {
context_ = base::MakeRefCounted<ServiceWorkerProviderContext>(
info->provider_id,
blink::mojom::ServiceWorkerProviderType::kForSharedWorker,
std::move(info->client_request), std::move(info->host_ptr_info),
- nullptr /* controller */, std::move(fallback_loader_factory));
+ std::move(controller_info), std::move(fallback_loader_factory));
if (script_loader_factory_info.is_valid())
script_loader_factory_.Bind(std::move(script_loader_factory_info));
}
diff --git a/chromium/content/renderer/service_worker/service_worker_network_provider.h b/chromium/content/renderer/service_worker/service_worker_network_provider.h
index 01457653fb7..ea98eb70e7f 100644
--- a/chromium/content/renderer/service_worker/service_worker_network_provider.h
+++ b/chromium/content/renderer/service_worker/service_worker_network_provider.h
@@ -86,10 +86,15 @@ class CONTENT_EXPORT ServiceWorkerNetworkProvider {
// Creates a ServiceWorkerNetworkProvider for a shared worker (as a
// non-document service worker client).
+ //
+ // For NetworkService (PlzWorker):
+ // |controller_info| contains the endpoint and object info that is needed to
+ // set up the controller service worker for the client.
static std::unique_ptr<ServiceWorkerNetworkProvider> CreateForSharedWorker(
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_info,
+ mojom::ControllerServiceWorkerInfoPtr controller_info,
scoped_refptr<network::SharedURLLoaderFactory> fallback_loader_factory);
// Creates a ServiceWorkerNetworkProvider for a "controller" (i.e.
@@ -142,6 +147,7 @@ class CONTENT_EXPORT ServiceWorkerNetworkProvider {
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_info,
+ mojom::ControllerServiceWorkerInfoPtr controller_info,
scoped_refptr<network::SharedURLLoaderFactory> fallback_loader_factory);
// This is for controllers, used in CreateForController.
diff --git a/chromium/content/renderer/service_worker/service_worker_provider_context.cc b/chromium/content/renderer/service_worker/service_worker_provider_context.cc
index 697f3e36a08..7c50913dad6 100644
--- a/chromium/content/renderer/service_worker/service_worker_provider_context.cc
+++ b/chromium/content/renderer/service_worker/service_worker_provider_context.cc
@@ -18,7 +18,6 @@
#include "content/public/common/service_names.mojom.h"
#include "content/renderer/service_worker/controller_service_worker_connector.h"
#include "content/renderer/service_worker/service_worker_subresource_loader.h"
-#include "content/renderer/service_worker/web_service_worker_impl.h"
#include "content/renderer/service_worker/web_service_worker_registration_impl.h"
#include "content/renderer/worker_thread_registry.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
@@ -174,6 +173,12 @@ const std::string& ServiceWorkerProviderContext::client_id() const {
return state_for_client_->client_id;
}
+const base::UnguessableToken&
+ServiceWorkerProviderContext::fetch_request_window_id() const {
+ DCHECK(state_for_client_);
+ return state_for_client_->fetch_request_window_id;
+}
+
void ServiceWorkerProviderContext::SetWebServiceWorkerProvider(
base::WeakPtr<WebServiceWorkerProviderImpl> provider) {
DCHECK(state_for_client_);
@@ -204,8 +209,8 @@ ServiceWorkerProviderContext::CloneContainerHostPtrInfo() {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
DCHECK(state_for_client_);
mojom::ServiceWorkerContainerHostPtrInfo container_host_ptr_info;
- // TODO(kinuko): rename this, now this can be used for non-worker clients.
- container_host_->CloneForWorker(mojo::MakeRequest(&container_host_ptr_info));
+ container_host_->CloneContainerHost(
+ mojo::MakeRequest(&container_host_ptr_info));
return container_host_ptr_info;
}
@@ -226,24 +231,6 @@ ServiceWorkerProviderContext::GetOrCreateServiceWorkerRegistrationObject(
std::move(info), weak_factory_.GetWeakPtr());
}
-scoped_refptr<WebServiceWorkerImpl>
-ServiceWorkerProviderContext::GetOrCreateServiceWorkerObject(
- blink::mojom::ServiceWorkerObjectInfoPtr info) {
- DCHECK_EQ(blink::mojom::ServiceWorkerProviderType::kForWindow,
- provider_type_);
- DCHECK(state_for_client_);
- if (!info)
- return nullptr;
-
- auto found = state_for_client_->workers_.find(info->version_id);
- if (found != state_for_client_->workers_.end()) {
- return found->second;
- }
-
- return WebServiceWorkerImpl::CreateForServiceWorkerClient(
- std::move(info), weak_factory_.GetWeakPtr());
-}
-
void ServiceWorkerProviderContext::OnNetworkProviderDestroyed() {
container_host_.reset();
}
@@ -300,6 +287,9 @@ void ServiceWorkerProviderContext::SetController(
state->client_id == controller_info->client_id);
state->client_id = controller_info->client_id;
+ if (controller_info->fetch_request_window_id)
+ state->fetch_request_window_id = *controller_info->fetch_request_window_id;
+
DCHECK((controller_info->mode ==
blink::mojom::ControllerServiceWorkerMode::kNoController &&
!state->controller) ||
@@ -351,7 +341,7 @@ void ServiceWorkerProviderContext::SetController(
}
// The WebServiceWorkerProviderImpl might not exist yet because the document
- // has not yet been created (as WebServiceWorkerImpl is created for a
+ // has not yet been created (as WebServiceWorkerProviderImpl is created for a
// ServiceWorkerContainer). In that case, once it's created it will still get
// the controller from |this| via WebServiceWorkerProviderImpl::SetClient().
if (state->web_service_worker_provider) {
@@ -396,27 +386,6 @@ bool ServiceWorkerProviderContext::
return base::ContainsKey(state_for_client_->registrations_, registration_id);
}
-void ServiceWorkerProviderContext::AddServiceWorkerObject(
- int64_t version_id,
- WebServiceWorkerImpl* worker) {
- DCHECK(state_for_client_);
- DCHECK(!base::ContainsKey(state_for_client_->workers_, version_id));
- state_for_client_->workers_[version_id] = worker;
-}
-
-void ServiceWorkerProviderContext::RemoveServiceWorkerObject(
- int64_t version_id) {
- DCHECK(state_for_client_);
- DCHECK(base::ContainsKey(state_for_client_->workers_, version_id));
- state_for_client_->workers_.erase(version_id);
-}
-
-bool ServiceWorkerProviderContext::ContainsServiceWorkerObjectForTesting(
- int64_t version_id) {
- DCHECK(state_for_client_);
- return base::ContainsKey(state_for_client_->workers_, version_id);
-}
-
void ServiceWorkerProviderContext::CountFeature(
blink::mojom::WebFeature feature) {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
diff --git a/chromium/content/renderer/service_worker/service_worker_provider_context.h b/chromium/content/renderer/service_worker/service_worker_provider_context.h
index e8515eb57cb..ab671a1ebf6 100644
--- a/chromium/content/renderer/service_worker/service_worker_provider_context.h
+++ b/chromium/content/renderer/service_worker/service_worker_provider_context.h
@@ -41,7 +41,6 @@ namespace service_worker_provider_context_unittest {
class ServiceWorkerProviderContextTest;
} // namespace service_worker_provider_context_unittest
-class WebServiceWorkerImpl;
class WebServiceWorkerRegistrationImpl;
struct ServiceWorkerProviderContextDeleter;
@@ -101,23 +100,6 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
int provider_id() const { return provider_id_; }
- // For service worker execution contexts. Sets the registration for
- // ServiceWorkerGlobalScope#registration. Unlike
- // TakeRegistrationForServiceWorkerGlobalScope(), called on the main thread.
- // SetRegistrationForServiceWorkerGlobalScope() is called during the setup for
- // service worker startup, so it is guaranteed to be called before
- // TakeRegistrationForServiceWorkerGlobalScope().
- void SetRegistrationForServiceWorkerGlobalScope(
- blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration);
-
- // For service worker execution contexts. Used for initializing
- // ServiceWorkerGlobalScope#registration. Called on the worker thread.
- // This takes the registration that was passed to
- // SetRegistrationForServiceWorkerScope(), then creates a new
- // WebServiceWorkerRegistrationImpl instance and returns it.
- scoped_refptr<WebServiceWorkerRegistrationImpl>
- TakeRegistrationForServiceWorkerGlobalScope();
-
// For service worker clients. Returns version id of the controller service
// worker object (ServiceWorkerContainer#controller).
int64_t GetControllerVersionId() const;
@@ -141,6 +123,10 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
// The Client#id value of the client.
const std::string& client_id() const;
+ // For service worker clients that are windows. See |fetch_request_window_id|
+ // in network::ResourceRequest.
+ const base::UnguessableToken& fetch_request_window_id() const;
+
// For service worker clients. Sets a weak pointer back to the
// WebServiceWorkerProviderImpl (which corresponds to ServiceWorkerContainer
// in JavaScript) which has a strong reference to |this|. This allows us to
@@ -156,11 +142,8 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
mojom::ServiceWorkerWorkerClientRegistryRequest request) override;
// S13nServiceWorker:
- // For service worker clients. Creates a ServiceWorkerContainerHostPtrInfo
- // which can be bound to a ServiceWorkerContainerHostPtr in a (dedicated or
- // shared) worker thread. WebWorkerFetchContextImpl will use the host pointer
- // to get the controller service worker by GetControllerServiceWorker() and
- // send FetchEvents to the service worker.
+ // For service worker clients. Returns a ServiceWorkerContainerHostPtrInfo
+ // to this client's container host.
mojom::ServiceWorkerContainerHostPtrInfo CloneContainerHostPtrInfo();
// For service worker clients. Returns the registration object described by
@@ -169,11 +152,6 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
GetOrCreateServiceWorkerRegistrationObject(
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info);
- // For service worker clients. Returns the service worker object described by
- // |info|. Creates a new object if needed, or else returns the existing one.
- scoped_refptr<WebServiceWorkerImpl> GetOrCreateServiceWorkerObject(
- blink::mojom::ServiceWorkerObjectInfoPtr info);
-
// Called when ServiceWorkerNetworkProvider is destructed. This function
// severs the Mojo binding to the browser-side ServiceWorkerProviderHost. The
// reason ServiceWorkerNetworkProvider is special compared to the other
@@ -206,7 +184,6 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
ServiceWorkerProviderContextDeleter>;
friend class service_worker_provider_context_unittest::
ServiceWorkerProviderContextTest;
- friend class WebServiceWorkerImpl;
friend class WebServiceWorkerRegistrationImpl;
friend struct ServiceWorkerProviderContextDeleter;
@@ -234,12 +211,6 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
bool ContainsServiceWorkerRegistrationObjectForTesting(
int64_t registration_id);
- // For service worker clients. Keeps the mapping from version id to
- // ServiceWorker object.
- void AddServiceWorkerObject(int64_t version_id, WebServiceWorkerImpl* worker);
- void RemoveServiceWorkerObject(int64_t version_id);
- bool ContainsServiceWorkerObjectForTesting(int64_t version_id);
-
// S13nServiceWorker:
// For service worker clients.
// A convenient utility method to tell if a subresource loader factory
diff --git a/chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc b/chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc
index 0e34a0da26b..408a323665b 100644
--- a/chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc
+++ b/chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc
@@ -21,7 +21,6 @@
#include "content/public/common/content_features.h"
#include "content/public/common/resource_type.h"
#include "content/renderer/service_worker/controller_service_worker_connector.h"
-#include "content/renderer/service_worker/web_service_worker_impl.h"
#include "content/renderer/service_worker/web_service_worker_registration_impl.h"
#include "mojo/public/cpp/bindings/associated_binding_set.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
@@ -36,6 +35,7 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_registration_proxy.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_feature.mojom.h"
@@ -168,14 +168,13 @@ class MockWebServiceWorkerProviderClientImpl
~MockWebServiceWorkerProviderClientImpl() override {}
- void SetController(std::unique_ptr<blink::WebServiceWorker::Handle> handle,
+ void SetController(blink::WebServiceWorkerObjectInfo info,
bool should_notify_controller_change) override {
was_set_controller_called_ = true;
}
- void DispatchMessageEvent(
- std::unique_ptr<blink::WebServiceWorker::Handle> handle,
- blink::TransferableMessage message) override {
+ void DispatchMessageEvent(blink::WebServiceWorkerObjectInfo info,
+ blink::TransferableMessage message) override {
was_dispatch_message_event_called_ = true;
}
@@ -199,6 +198,44 @@ class MockWebServiceWorkerProviderClientImpl
std::set<blink::mojom::WebFeature> used_features_;
};
+// This class holds {installing,waiting,active} service worker object infos and
+// simulates the service worker objects management logic of Blink code: For any
+// incoming object info, if there does already exist an object info with the
+// same version id, drop this incoming one.
+class MockWebServiceWorkerRegistrationProxy
+ : public blink::WebServiceWorkerRegistrationProxy {
+ public:
+ ~MockWebServiceWorkerRegistrationProxy() override = default;
+
+ void DispatchUpdateFoundEvent() override {}
+ void SetInstalling(blink::WebServiceWorkerObjectInfo info) override {
+ if (info.version_id == blink::mojom::kInvalidServiceWorkerVersionId ||
+ (installing_ && installing_->version_id == info.version_id))
+ return;
+ installing_ =
+ std::make_unique<blink::WebServiceWorkerObjectInfo>(std::move(info));
+ }
+ void SetWaiting(blink::WebServiceWorkerObjectInfo info) override {
+ if (info.version_id == blink::mojom::kInvalidServiceWorkerVersionId ||
+ (waiting_ && waiting_->version_id == info.version_id))
+ return;
+ waiting_ =
+ std::make_unique<blink::WebServiceWorkerObjectInfo>(std::move(info));
+ }
+ void SetActive(blink::WebServiceWorkerObjectInfo info) override {
+ if (info.version_id == blink::mojom::kInvalidServiceWorkerVersionId ||
+ (active_ && active_->version_id == info.version_id))
+ return;
+ active_ =
+ std::make_unique<blink::WebServiceWorkerObjectInfo>(std::move(info));
+ }
+
+ private:
+ std::unique_ptr<blink::WebServiceWorkerObjectInfo> installing_;
+ std::unique_ptr<blink::WebServiceWorkerObjectInfo> waiting_;
+ std::unique_ptr<blink::WebServiceWorkerObjectInfo> active_;
+};
+
// S13nServiceWorker: a fake URLLoaderFactory implementation that basically
// does nothing but records the requests.
class FakeURLLoaderFactory final : public network::mojom::URLLoaderFactory {
@@ -261,7 +298,7 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
fetch_event_count_++;
fetch_event_request_ = params->request;
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time());
+ base::TimeTicks());
if (fetch_event_callback_)
std::move(fetch_event_callback_).Run();
}
@@ -318,7 +355,7 @@ class FakeServiceWorkerContainerHost
mojom::ControllerServiceWorkerPurpose purpose) override {
NOTIMPLEMENTED();
}
- void CloneForWorker(
+ void CloneContainerHost(
mojom::ServiceWorkerContainerHostRequest request) override {
bindings_.AddBinding(this, std::move(request));
}
@@ -365,11 +402,6 @@ class ServiceWorkerProviderContextTest : public testing::Test {
registration_id);
}
- bool ContainsServiceWorker(ServiceWorkerProviderContext* provider_context,
- int64_t version_id) {
- return provider_context->ContainsServiceWorkerObjectForTesting(version_id);
- }
-
void FlushControllerConnector(
ServiceWorkerProviderContext* provider_context) {
provider_context->state_for_client_->controller_connector.FlushForTesting();
@@ -815,6 +847,8 @@ TEST_F(ServiceWorkerProviderContextTest, GetOrCreateRegistration) {
registration_id);
ASSERT_EQ(0, mock_registration_object_host->GetBindingCount());
+ auto registration_proxy =
+ std::make_unique<MockWebServiceWorkerRegistrationProxy>();
{
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info =
mock_registration_object_host->CreateObjectInfo(
@@ -836,6 +870,7 @@ TEST_F(ServiceWorkerProviderContextTest, GetOrCreateRegistration) {
EXPECT_TRUE(ContainsRegistration(provider_context.get(), registration_id));
EXPECT_EQ(registration_id, registration1->RegistrationId());
EXPECT_EQ(1, mock_registration_object_host->GetBindingCount());
+ registration1->SetProxy(registration_proxy.get());
}
{
@@ -870,6 +905,7 @@ TEST_F(ServiceWorkerProviderContextTest, GetOrCreateRegistration) {
// The registration dtor decrements the refcounts.
registration1 = nullptr;
registration2 = nullptr;
+ registration_proxy = nullptr;
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(ContainsRegistration(provider_context.get(), registration_id));
// The 1st ServiceWorkerRegistrationObjectHost Mojo connection got broken.
@@ -880,60 +916,5 @@ TEST_F(ServiceWorkerProviderContextTest, GetOrCreateRegistration) {
EXPECT_EQ(0, installing_host->GetBindingCount());
}
-TEST_F(ServiceWorkerProviderContextTest, GetOrCreateServiceWorker) {
- scoped_refptr<WebServiceWorkerImpl> worker1;
- scoped_refptr<WebServiceWorkerImpl> worker2;
- // Set up ServiceWorkerProviderContext for client contexts.
- const int kProviderId = 10;
- auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>(
- kProviderId, blink::mojom::ServiceWorkerProviderType::kForWindow, nullptr,
- nullptr, nullptr /* controller_info */, nullptr /* loader_factory*/);
- const int64_t version_id = 200;
- auto mock_service_worker_object_host =
- std::make_unique<MockServiceWorkerObjectHost>(version_id);
- ASSERT_EQ(0, mock_service_worker_object_host->GetBindingCount());
-
- // Should return a worker object newly created with the 1st given |info|.
- {
- blink::mojom::ServiceWorkerObjectInfoPtr info =
- mock_service_worker_object_host->CreateObjectInfo();
- // ServiceWorkerObjectHost Mojo connection has been added.
- EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount());
- ASSERT_FALSE(ContainsServiceWorker(provider_context.get(), version_id));
- worker1 = provider_context->GetOrCreateServiceWorkerObject(std::move(info));
- EXPECT_TRUE(worker1);
- EXPECT_TRUE(ContainsServiceWorker(provider_context.get(), version_id));
- // |worker1| is holding the 1st blink::mojom::ServiceWorkerObjectHost Mojo
- // connection to |mock_service_worker_object_host|.
- EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount());
- }
-
- // Should return the same worker object and release the 2nd given |info|.
- {
- blink::mojom::ServiceWorkerObjectInfoPtr info =
- mock_service_worker_object_host->CreateObjectInfo();
- EXPECT_EQ(2, mock_service_worker_object_host->GetBindingCount());
- worker2 = provider_context->GetOrCreateServiceWorkerObject(std::move(info));
- EXPECT_EQ(worker1, worker2);
- base::RunLoop().RunUntilIdle();
- // The 2nd ServiceWorkerObjectHost Mojo connection in |info| has been
- // dropped.
- EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount());
- }
-
- // The dtor decrements the refcounts.
- worker1 = nullptr;
- worker2 = nullptr;
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(ContainsServiceWorker(provider_context.get(), version_id));
- // The 1st ServiceWorkerObjectHost Mojo connection got broken.
- EXPECT_EQ(0, mock_service_worker_object_host->GetBindingCount());
-
- // Should return nullptr when given nullptr.
- scoped_refptr<WebServiceWorkerImpl> invalid_worker =
- provider_context->GetOrCreateServiceWorkerObject(nullptr);
- EXPECT_FALSE(invalid_worker);
-}
-
} // namespace service_worker_provider_context_unittest
} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_provider_state_for_client.h b/chromium/content/renderer/service_worker/service_worker_provider_state_for_client.h
index dd93d3c3fe9..157c7f04b99 100644
--- a/chromium/content/renderer/service_worker/service_worker_provider_state_for_client.h
+++ b/chromium/content/renderer/service_worker/service_worker_provider_state_for_client.h
@@ -17,7 +17,6 @@
#include "content/common/service_worker/controller_service_worker.mojom.h"
#include "content/common/service_worker/service_worker_container.mojom.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
-#include "content/renderer/service_worker/web_service_worker_impl.h"
#include "content/renderer/service_worker/web_service_worker_provider_impl.h"
#include "content/renderer/service_worker/web_service_worker_registration_impl.h"
#include "mojo/public/cpp/bindings/binding_set.h"
@@ -52,6 +51,8 @@ struct ServiceWorkerProviderStateForClient {
// The Client#id value of the client.
std::string client_id;
+ base::UnguessableToken fetch_request_window_id;
+
blink::mojom::ControllerServiceWorkerMode controller_mode =
blink::mojom::ControllerServiceWorkerMode::kNoController;
@@ -95,10 +96,6 @@ struct ServiceWorkerProviderStateForClient {
// For service worker clients. Map from registration id to JavaScript
// ServiceWorkerRegistration object.
std::map<int64_t, WebServiceWorkerRegistrationImpl*> registrations_;
-
- // For service worker clients. Map from version id to JavaScript ServiceWorker
- // object.
- std::map<int64_t, WebServiceWorkerImpl*> workers_;
};
} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_subresource_loader.cc b/chromium/content/renderer/service_worker/service_worker_subresource_loader.cc
index 09349114c3c..241a229784e 100644
--- a/chromium/content/renderer/service_worker/service_worker_subresource_loader.cc
+++ b/chromium/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -25,6 +25,8 @@
#include "net/url_request/url_request.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/blink/public/common/blob/blob_utils.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/service_worker/service_worker_type_converters.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/blink/public/mojom/service_worker/dispatch_fetch_event_params.mojom.h"
@@ -156,9 +158,12 @@ ServiceWorkerSubresourceLoader::ServiceWorkerSubresourceLoader(
url_loader_client_(std::move(client)),
url_loader_binding_(this, std::move(request)),
response_callback_binding_(this),
+ body_as_blob_size_(blink::BlobUtils::kUnknownSize),
controller_connector_(std::move(controller_connector)),
controller_connector_observer_(this),
fetch_request_restarted_(false),
+ blob_reading_complete_(false),
+ side_data_reading_complete_(false),
routing_id_(routing_id),
request_id_(request_id),
options_(options),
@@ -200,11 +205,6 @@ void ServiceWorkerSubresourceLoader::StartRequest(
fetch_request_restarted_ = false;
response_head_.service_worker_start_time = base::TimeTicks::Now();
- // TODO(horo): Reset |service_worker_ready_time| when the the connection to
- // the service worker is revived.
- response_head_.service_worker_ready_time = base::TimeTicks::Now();
- response_head_.load_timing.send_start = base::TimeTicks::Now();
- response_head_.load_timing.send_end = base::TimeTicks::Now();
DispatchFetchEvent();
}
@@ -214,6 +214,14 @@ void ServiceWorkerSubresourceLoader::DispatchFetchEvent() {
mojom::ControllerServiceWorker* controller =
controller_connector_->GetControllerServiceWorker(
mojom::ControllerServiceWorkerPurpose::FETCH_SUB_RESOURCE);
+
+ // GetControllerServiceWorker() makes sure that the connection to the
+ // service worker is established, which means that the service worker
+ // has started if it wasn't running.
+ response_head_.service_worker_ready_time = base::TimeTicks::Now();
+ response_head_.load_timing.send_start = base::TimeTicks::Now();
+ response_head_.load_timing.send_end = base::TimeTicks::Now();
+
TRACE_EVENT1("ServiceWorker",
"ServiceWorkerSubresourceLoader::DispatchFetchEvent",
"controller", (controller ? "exists" : "does not exist"));
@@ -260,13 +268,13 @@ void ServiceWorkerSubresourceLoader::DispatchFetchEvent() {
controller->DispatchFetchEvent(
std::move(params), std::move(response_callback_ptr),
base::BindOnce(&ServiceWorkerSubresourceLoader::OnFetchEventFinished,
- weak_factory_.GetWeakPtr(), base::Time::Now()));
+ weak_factory_.GetWeakPtr(), base::TimeTicks::Now()));
}
void ServiceWorkerSubresourceLoader::OnFetchEventFinished(
- base::Time request_dispatch_time,
+ base::TimeTicks request_dispatch_time,
blink::mojom::ServiceWorkerEventStatus status,
- base::Time actual_dispatch_time) {
+ base::TimeTicks actual_dispatch_time) {
TRACE_EVENT_WITH_FLOW1("ServiceWorker",
"ServiceWorkerSubresourceLoader::OnFetchEventFinished",
this, TRACE_EVENT_FLAG_FLOW_IN, "status",
@@ -340,7 +348,7 @@ void ServiceWorkerSubresourceLoader::SettleFetchEventDispatch(
void ServiceWorkerSubresourceLoader::OnResponse(
blink::mojom::FetchAPIResponsePtr response,
- base::Time dispatch_event_time) {
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) {
TRACE_EVENT_WITH_FLOW0("ServiceWorker",
"ServiceWorkerSubresourceLoader::OnResponse", this,
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
@@ -351,7 +359,7 @@ void ServiceWorkerSubresourceLoader::OnResponse(
void ServiceWorkerSubresourceLoader::OnResponseStream(
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- base::Time dispatch_event_time) {
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker", "ServiceWorkerSubresourceLoader::OnResponseStream", this,
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
@@ -360,13 +368,14 @@ void ServiceWorkerSubresourceLoader::OnResponseStream(
}
void ServiceWorkerSubresourceLoader::OnFallback(
- base::Time dispatch_event_time) {
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) {
SettleFetchEventDispatch(blink::ServiceWorkerStatusCode::kOk);
// When the request mode is CORS or CORS-with-forced-preflight and the origin
// of the request URL is different from the security origin of the document,
// we can't simply fallback to the network here. It is because the CORS
// preflight logic is implemented in Blink. So we return a "fallback required"
// response to Blink.
+ // TODO(falken): Remove this mechanism after OOB-CORS ships.
if ((resource_request_.fetch_request_mode ==
network::mojom::FetchRequestMode::kCORS ||
resource_request_.fetch_request_mode ==
@@ -377,6 +386,11 @@ void ServiceWorkerSubresourceLoader::OnFallback(
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker", "ServiceWorkerSubresourceLoader::OnFallback", this,
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ // Add "Service Worker Fallback Required" which DevTools knows means to not
+ // show the response in the Network tab as it's just an internal
+ // implementation mechanism.
+ response_head_.headers = base::MakeRefCounted<net::HttpResponseHeaders>(
+ "HTTP/1.1 400 Service Worker Fallback Required");
response_head_.was_fetched_via_service_worker = true;
response_head_.was_fallback_required_by_service_worker = true;
CommitResponseHeaders();
@@ -430,7 +444,7 @@ void ServiceWorkerSubresourceLoader::StartResponse(
// Handle a redirect response. ComputeRedirectInfo returns non-null redirect
// info if the given response is a redirect.
redirect_info_ = ServiceWorkerLoaderHelpers::ComputeRedirectInfo(
- resource_request_, response_head_, false /* token_binding_negotiated */);
+ resource_request_, response_head_);
if (redirect_info_) {
if (redirect_limit_-- == 0) {
CommitCompleted(net::ERR_TOO_MANY_REDIRECTS);
@@ -461,10 +475,26 @@ void ServiceWorkerSubresourceLoader::StartResponse(
if (response->blob) {
DCHECK(!body_as_stream);
DCHECK(response->blob->blob.is_valid());
+
body_as_blob_.Bind(std::move(response->blob->blob));
+ body_as_blob_size_ = response->blob->size;
+
+ // If parallel reading is enabled, then start reading the body blob
+ // immediately. This will allow the body to start buffering in the
+ // pipe while the side data is read.
+ mojo::ScopedDataPipeConsumerHandle data_pipe;
+ if (base::FeatureList::IsEnabled(
+ blink::features::kServiceWorkerParallelSideDataReading)) {
+ int error = StartBlobReading(&data_pipe);
+ if (error != net::OK) {
+ CommitCompleted(error);
+ return;
+ }
+ }
+
body_as_blob_->ReadSideData(base::BindOnce(
&ServiceWorkerSubresourceLoader::OnBlobSideDataReadingComplete,
- base::Unretained(this)));
+ weak_factory_.GetWeakPtr(), std::move(data_pipe)));
return;
}
@@ -487,12 +517,17 @@ void ServiceWorkerSubresourceLoader::CommitCompleted(int error_code) {
DCHECK_LT(status_, Status::kCompleted);
DCHECK(url_loader_client_.is_bound());
+ body_as_blob_.reset();
stream_waiter_.reset();
status_ = Status::kCompleted;
network::URLLoaderCompletionStatus status;
status.error_code = error_code;
status.completion_time = base::TimeTicks::Now();
url_loader_client_->OnComplete(status);
+
+ // Invalidate weak pointers to prevent callbacks after commit. This can
+ // occur if an error code is encountered which forces an early commit.
+ weak_factory_.InvalidateWeakPtrs();
}
// ServiceWorkerSubresourceLoader: URLLoader implementation -----------------
@@ -544,7 +579,27 @@ void ServiceWorkerSubresourceLoader::PauseReadingBodyFromNet() {}
void ServiceWorkerSubresourceLoader::ResumeReadingBodyFromNet() {}
+int ServiceWorkerSubresourceLoader::StartBlobReading(
+ mojo::ScopedDataPipeConsumerHandle* body_pipe) {
+ TRACE_EVENT_WITH_FLOW0(
+ "ServiceWorker", "ServiceWorkerSubresourceLoader::StartBlobReading", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ DCHECK(body_pipe);
+ DCHECK(!blob_reading_complete_);
+
+ base::TimeDelta delay =
+ base::TimeTicks::Now() - response_head_.response_start;
+ UMA_HISTOGRAM_TIMES("ServiceWorker.SubresourceStartBlobReadingDelay", delay);
+
+ return ServiceWorkerLoaderHelpers::ReadBlobResponseBody(
+ &body_as_blob_, body_as_blob_size_,
+ base::BindOnce(&ServiceWorkerSubresourceLoader::OnBlobReadingComplete,
+ weak_factory_.GetWeakPtr()),
+ body_pipe);
+}
+
void ServiceWorkerSubresourceLoader::OnBlobSideDataReadingComplete(
+ mojo::ScopedDataPipeConsumerHandle data_pipe,
const base::Optional<std::vector<uint8_t>>& metadata) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker",
@@ -552,28 +607,57 @@ void ServiceWorkerSubresourceLoader::OnBlobSideDataReadingComplete(
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "metadata size",
(metadata ? metadata->size() : 0));
DCHECK(url_loader_client_);
+ DCHECK(body_as_blob_);
+ DCHECK(!side_data_reading_complete_);
+ side_data_reading_complete_ = true;
+
if (metadata.has_value())
url_loader_client_->OnReceiveCachedMetadata(metadata.value());
- mojo::ScopedDataPipeConsumerHandle data_pipe;
- int error = ServiceWorkerLoaderHelpers::ReadBlobResponseBody(
- &body_as_blob_, resource_request_.headers,
- base::BindOnce(&ServiceWorkerSubresourceLoader::OnBlobReadingComplete,
- weak_factory_.GetWeakPtr()),
- &data_pipe);
- if (error != net::OK) {
- CommitCompleted(error);
- return;
+
+ // If parallel reading is disabled then we need to start reading the blob.
+ if (!data_pipe.is_valid()) {
+ DCHECK(!base::FeatureList::IsEnabled(
+ blink::features::kServiceWorkerParallelSideDataReading));
+ int error = StartBlobReading(&data_pipe);
+ if (error != net::OK) {
+ CommitCompleted(error);
+ return;
+ }
}
+
+ base::TimeDelta delay =
+ base::TimeTicks::Now() - response_head_.response_start;
+ UMA_HISTOGRAM_TIMES(
+ "ServiceWorker.SubresourceNotifyStartLoadingResponseBodyDelay", delay);
+
+ DCHECK(data_pipe.is_valid());
url_loader_client_->OnStartLoadingResponseBody(std::move(data_pipe));
- // We continue in OnBlobReadingComplete().
+
+ // If the blob reading completed before the side data reading, then we
+ // must manually finalize the blob reading now.
+ if (blob_reading_complete_) {
+ // This should only be possible if parallel reading is enabled.
+ DCHECK(base::FeatureList::IsEnabled(
+ blink::features::kServiceWorkerParallelSideDataReading));
+ OnBlobReadingComplete(net::OK);
+ }
+
+ // Otherwise we asyncly continue in OnBlobReadingComplete().
}
void ServiceWorkerSubresourceLoader::OnBlobReadingComplete(int net_error) {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker", "ServiceWorkerSubresourceLoader::OnBlobReadingComplete",
this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ DCHECK(body_as_blob_);
+ blob_reading_complete_ = true;
+ // If the side data has not completed reading yet, then we need to delay
+ // calling CommitCompleted. This method will be called again from
+ // OnBlobSideDataReadingComplete(). Only delay for successful reads, though.
+ // Abort immediately on error.
+ if (!side_data_reading_complete_ && net_error == net::OK)
+ return;
CommitCompleted(net_error);
- body_as_blob_.reset();
}
// ServiceWorkerSubresourceLoaderFactory ------------------------------------
diff --git a/chromium/content/renderer/service_worker/service_worker_subresource_loader.h b/chromium/content/renderer/service_worker/service_worker_subresource_loader.h
index b17ef54f371..9cb935a0eed 100644
--- a/chromium/content/renderer/service_worker/service_worker_subresource_loader.h
+++ b/chromium/content/renderer/service_worker/service_worker_subresource_loader.h
@@ -66,22 +66,24 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
void StartRequest(const network::ResourceRequest& resource_request);
void DispatchFetchEvent();
- void OnFetchEventFinished(base::Time request_dispatch_time,
+ void OnFetchEventFinished(base::TimeTicks request_dispatch_time,
blink::mojom::ServiceWorkerEventStatus status,
- base::Time dispatch_event_time);
+ base::TimeTicks dispatch_event_time);
// Called when this loader no longer needs to restart dispatching the fetch
// event on failure. Null |status| means the event dispatch was not attempted.
void SettleFetchEventDispatch(
base::Optional<blink::ServiceWorkerStatusCode> status);
// blink::mojom::ServiceWorkerFetchResponseCallback overrides:
- void OnResponse(blink::mojom::FetchAPIResponsePtr response,
- base::Time dispatch_event_time) override;
+ void OnResponse(
+ blink::mojom::FetchAPIResponsePtr response,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) override;
void OnResponseStream(
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- base::Time dispatch_event_time) override;
- void OnFallback(base::Time dispatch_event_time) override;
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) override;
+ void OnFallback(
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing) override;
void StartResponse(blink::mojom::FetchAPIResponsePtr response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream);
@@ -97,7 +99,9 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
void PauseReadingBodyFromNet() override;
void ResumeReadingBodyFromNet() override;
+ int StartBlobReading(mojo::ScopedDataPipeConsumerHandle* body_pipe);
void OnBlobSideDataReadingComplete(
+ mojo::ScopedDataPipeConsumerHandle data_pipe,
const base::Optional<std::vector<uint8_t>>& metadata);
void OnBlobReadingComplete(int net_error);
@@ -119,6 +123,7 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
response_callback_binding_;
// The blob needs to be held while it's read to keep it alive.
blink::mojom::BlobPtr body_as_blob_;
+ uint64_t body_as_blob_size_;
scoped_refptr<ControllerServiceWorkerConnector> controller_connector_;
@@ -129,6 +134,8 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
ServiceWorkerSubresourceLoader>
controller_connector_observer_;
bool fetch_request_restarted_;
+ bool blob_reading_complete_;
+ bool side_data_reading_complete_;
// These are given by the constructor (as the params for
// URLLoaderFactory::CreateLoaderAndStart).
@@ -175,9 +182,8 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoaderFactory
// default URLLoaderFactory for network fallback. This should be the
// URLLoaderFactory that directly goes to network without going through
// any custom URLLoader factories.
- // |task_runner| is the runner where this loader runs. (We need to pass
- // this around because calling base::SequencedTaskRunnerHandle is
- // prohibited in the renderer :()
+ // |task_runner| is the runner where this loader runs. In production it runs,
+ // on a background thread.
static void Create(
scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
scoped_refptr<network::SharedURLLoaderFactory> fallback_factory,
diff --git a/chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc b/chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
index 67f4b12700e..b4b4ab522d2 100644
--- a/chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
+++ b/chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
@@ -4,8 +4,14 @@
#include "content/renderer/service_worker/service_worker_subresource_loader.h"
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "content/common/service_worker/service_worker_container.mojom.h"
@@ -128,6 +134,10 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
response->status_text = "OK";
response->response_type = network::mojom::FetchResponseType::kDefault;
response->blob = std::move(blob_body);
+ if (response->blob) {
+ response->headers.emplace("Content-Length",
+ base::NumberToString(response->blob->size));
+ }
return response;
}
@@ -181,16 +191,26 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
redirect_location_header_ = redirect_location_header;
}
+ // Tells this controller to respond to fetch events with a blob response body.
void RespondWithBlob(base::Optional<std::vector<uint8_t>> metadata,
std::string body) {
response_mode_ = ResponseMode::kBlob;
blob_body_ = blink::mojom::SerializedBlob::New();
blob_body_->uuid = "dummy-blob-uuid";
+ blob_body_->size = body.size();
mojo::MakeStrongBinding(
std::make_unique<FakeBlob>(std::move(metadata), std::move(body)),
mojo::MakeRequest(&blob_body_->blob));
}
+ // Tells this controller to respond to fetch events with a 206 partial
+ // response, returning a blob composed of the requested bytes of |body|
+ // according to the request headers.
+ void RespondWithBlobRange(std::string body) {
+ response_mode_ = ResponseMode::kBlobRange;
+ blob_range_body_ = body;
+ }
+
void ReadRequestBody(std::string* out_string) {
ASSERT_TRUE(request_body_);
std::vector<network::DataElement>* elements =
@@ -233,45 +253,93 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
switch (response_mode_) {
case ResponseMode::kDefault:
- response_callback->OnResponse(OkResponse(nullptr /* blob_body */),
- base::Time::Now());
+ response_callback->OnResponse(
+ OkResponse(nullptr /* blob_body */),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(callback).Run(
- blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
+ blink::mojom::ServiceWorkerEventStatus::COMPLETED,
+ base::TimeTicks());
break;
case ResponseMode::kAbort:
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::ABORTED,
- base::Time());
+ base::TimeTicks());
break;
case ResponseMode::kStream:
- response_callback->OnResponseStream(OkResponse(nullptr /* blob_body */),
- std::move(stream_handle_),
- base::Time::Now());
+ response_callback->OnResponseStream(
+ OkResponse(nullptr /* blob_body */), std::move(stream_handle_),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(callback).Run(
- blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
+ blink::mojom::ServiceWorkerEventStatus::COMPLETED,
+ base::TimeTicks());
break;
case ResponseMode::kBlob:
- response_callback->OnResponse(OkResponse(std::move(blob_body_)),
- base::Time::Now());
+ response_callback->OnResponse(
+ OkResponse(std::move(blob_body_)),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(callback).Run(
- blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
+ blink::mojom::ServiceWorkerEventStatus::COMPLETED,
+ base::TimeTicks());
break;
+
+ case ResponseMode::kBlobRange: {
+ // Parse the Range header.
+ std::string range_header;
+ std::vector<net::HttpByteRange> ranges;
+ ASSERT_TRUE(params->request.headers.GetHeader(
+ net::HttpRequestHeaders::kRange, &range_header));
+ ASSERT_TRUE(net::HttpUtil::ParseRangeHeader(range_header, &ranges));
+ ASSERT_EQ(1u, ranges.size());
+ ASSERT_TRUE(ranges[0].ComputeBounds(blob_range_body_.size()));
+ const net::HttpByteRange& range = ranges[0];
+
+ // Build a Blob composed of the requested bytes from |blob_range_body_|.
+ size_t start = static_cast<size_t>(range.first_byte_position());
+ size_t end = static_cast<size_t>(range.last_byte_position());
+ size_t size = end - start + 1;
+ std::string body = blob_range_body_.substr(start, size);
+ auto blob = blink::mojom::SerializedBlob::New();
+ blob->uuid = "dummy-blob-uuid";
+ blob->size = size;
+ mojo::MakeStrongBinding(std::make_unique<FakeBlob>(base::nullopt, body),
+ mojo::MakeRequest(&blob->blob));
+
+ // Respond with a 206 response.
+ auto response = OkResponse(std::move(blob));
+ response->status_code = 206;
+ response->headers.emplace(
+ "Content-Range", base::StringPrintf("bytes %zu-%zu/%zu", start, end,
+ blob_range_body_.size()));
+ response_callback->OnResponse(
+ std::move(response),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerEventStatus::COMPLETED,
+ base::TimeTicks::Now());
+ break;
+ }
+
case ResponseMode::kFallbackResponse:
- response_callback->OnFallback(base::Time::Now());
+ response_callback->OnFallback(
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(callback).Run(
blink::mojom::ServiceWorkerEventStatus::COMPLETED,
- base::Time::Now());
+ base::TimeTicks::Now());
break;
case ResponseMode::kErrorResponse:
- response_callback->OnResponse(ErrorResponse(), base::Time::Now());
+ response_callback->OnResponse(
+ ErrorResponse(),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(callback).Run(
blink::mojom::ServiceWorkerEventStatus::REJECTED,
- base::Time::Now());
+ base::TimeTicks::Now());
break;
case ResponseMode::kRedirectResponse: {
response_callback->OnResponse(
- RedirectResponse(redirect_location_header_), base::Time::Now());
+ RedirectResponse(redirect_location_header_),
+ blink::mojom::ServiceWorkerFetchEventTiming::New());
std::move(callback).Run(
- blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
+ blink::mojom::ServiceWorkerEventStatus::COMPLETED,
+ base::TimeTicks());
break;
}
}
@@ -300,6 +368,7 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
kAbort,
kStream,
kBlob,
+ kBlobRange,
kFallbackResponse,
kErrorResponse,
kRedirectResponse
@@ -319,6 +388,9 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
// For ResponseMode::kBlob.
blink::mojom::SerializedBlobPtr blob_body_;
+ // For ResponseMode::kBlobRange.
+ std::string blob_range_body_;
+
// For ResponseMode::kRedirectResponse
std::string redirect_location_header_;
@@ -367,7 +439,7 @@ class FakeServiceWorkerContainerHost
return;
fake_controller_->Clone(std::move(request));
}
- void CloneForWorker(
+ void CloneContainerHost(
mojom::ServiceWorkerContainerHostRequest request) override {
bindings_.AddBinding(this, std::move(request));
}
@@ -422,7 +494,8 @@ class ServiceWorkerSubresourceLoaderTest : public ::testing::Test {
network::mojom::URLLoaderFactoryPtr CreateSubresourceLoaderFactory() {
if (!connector_) {
mojom::ServiceWorkerContainerHostPtrInfo host_ptr_info;
- fake_container_host_.CloneForWorker(mojo::MakeRequest(&host_ptr_info));
+ fake_container_host_.CloneContainerHost(
+ mojo::MakeRequest(&host_ptr_info));
connector_ = base::MakeRefCounted<ControllerServiceWorkerConnector>(
std::move(host_ptr_info), nullptr /*controller_ptr*/,
"" /*client_id*/);
@@ -518,6 +591,30 @@ class ServiceWorkerSubresourceLoaderTest : public ::testing::Test {
// cover this case in fetch-event.https.html.
}
+ // Performs a range request using |range_header| and returns the resulting
+ // client after completion.
+ std::unique_ptr<network::TestURLLoaderClient> DoRangeRequest(
+ const std::string& range_header) {
+ network::mojom::URLLoaderFactoryPtr factory =
+ CreateSubresourceLoaderFactory();
+ network::ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/big-file"));
+ request.headers.SetHeader("Range", range_header);
+ network::mojom::URLLoaderPtr loader;
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ StartRequest(factory, request, &loader, &client);
+ client->RunUntilComplete();
+ return client;
+ }
+
+ std::string TakeResponseBody(network::TestURLLoaderClient* client) {
+ std::string body;
+ EXPECT_TRUE(client->response_body().is_valid());
+ EXPECT_TRUE(
+ mojo::BlockingCopyToString(client->response_body_release(), &body));
+ return body;
+ }
+
TestBrowserThreadBundle thread_bundle_;
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
scoped_refptr<ControllerServiceWorkerConnector> connector_;
@@ -869,6 +966,7 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, BlobResponse) {
const network::ResourceResponseHead& info = client->response_head();
ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());
+ EXPECT_EQ(33, info.content_length);
// Test the cached metadata.
client->RunUntilCachedMetadataReceived();
@@ -1167,6 +1265,10 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, CORSFallbackResponse) {
info.was_fetched_via_service_worker);
EXPECT_EQ(test.expected_was_fallback_required_by_service_worker,
info.was_fallback_required_by_service_worker);
+ if (info.was_fallback_required_by_service_worker) {
+ EXPECT_EQ("HTTP/1.1 400 Service Worker Fallback Required",
+ info.headers->GetStatusLine());
+ }
}
}
@@ -1190,5 +1292,73 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, FallbackWithRequestBody_DataPipe) {
RunFallbackWithRequestBodyTest(std::move(request_body), kData);
}
+// Test a range request that the service worker responds to with a 200
+// (non-ranged) response. The client should get the entire response as-is from
+// the service worker.
+TEST_F(ServiceWorkerSubresourceLoaderTest, RangeRequest_200Response) {
+ // Construct the Blob to respond with.
+ const std::string kResponseBody = "Here is sample text for the Blob.";
+ fake_controller_.RespondWithBlob(base::nullopt, kResponseBody);
+
+ // Perform the request.
+ std::unique_ptr<network::TestURLLoaderClient> client =
+ DoRangeRequest("bytes=5-13");
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+
+ // Test the response.
+ const network::ResourceResponseHead& info = client->response_head();
+ ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());
+ EXPECT_EQ(33, info.content_length);
+ EXPECT_FALSE(info.headers->HasHeader("Content-Range"));
+ EXPECT_EQ(kResponseBody, TakeResponseBody(client.get()));
+}
+
+// Test a range request that the service worker responds to with a 206 ranged
+// response. The client should get the partial response as-is from the service
+// worker.
+TEST_F(ServiceWorkerSubresourceLoaderTest, RangeRequest_206Response) {
+ // Tell the controller to respond with a 206 response.
+ const std::string kResponseBody = "Here is sample text for the Blob.";
+ fake_controller_.RespondWithBlobRange(kResponseBody);
+
+ // Perform the request.
+ std::unique_ptr<network::TestURLLoaderClient> client =
+ DoRangeRequest("bytes=5-13");
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+
+ // Test the response.
+ const network::ResourceResponseHead& info = client->response_head();
+ EXPECT_EQ(206, info.headers->response_code());
+ std::string range;
+ ASSERT_TRUE(info.headers->GetNormalizedHeader("Content-Range", &range));
+ EXPECT_EQ("bytes 5-13/33", range);
+ EXPECT_EQ(9, info.content_length);
+ EXPECT_EQ("is sample", TakeResponseBody(client.get()));
+}
+
+// Test a range request that the service worker responds to with a 206 ranged
+// response. The requested range has an unbounded end. The client should get the
+// partial response as-is from the service worker.
+TEST_F(ServiceWorkerSubresourceLoaderTest,
+ RangeRequest_UnboundedRight_206Response) {
+ // Tell the controller to respond with a 206 response.
+ const std::string kResponseBody = "Here is sample text for the Blob.";
+ fake_controller_.RespondWithBlobRange(kResponseBody);
+
+ // Perform the request.
+ std::unique_ptr<network::TestURLLoaderClient> client =
+ DoRangeRequest("bytes=5-");
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+
+ // Test the response.
+ const network::ResourceResponseHead& info = client->response_head();
+ EXPECT_EQ(206, info.headers->response_code());
+ std::string range;
+ ASSERT_TRUE(info.headers->GetNormalizedHeader("Content-Range", &range));
+ EXPECT_EQ("bytes 5-32/33", range);
+ EXPECT_EQ(28, info.content_length);
+ EXPECT_EQ("is sample text for the Blob.", TakeResponseBody(client.get()));
+}
+
} // namespace service_worker_subresource_loader_unittest
} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_timeout_timer.cc b/chromium/content/renderer/service_worker/service_worker_timeout_timer.cc
index 624664d316f..eb640fea50b 100644
--- a/chromium/content/renderer/service_worker/service_worker_timeout_timer.cc
+++ b/chromium/content/renderer/service_worker/service_worker_timeout_timer.cc
@@ -31,6 +31,26 @@ constexpr base::TimeDelta ServiceWorkerTimeoutTimer::kIdleDelay;
constexpr base::TimeDelta ServiceWorkerTimeoutTimer::kEventTimeout;
constexpr base::TimeDelta ServiceWorkerTimeoutTimer::kUpdateInterval;
+ServiceWorkerTimeoutTimer::StayAwakeToken::StayAwakeToken(
+ base::WeakPtr<ServiceWorkerTimeoutTimer> timer)
+ : timer_(std::move(timer)) {
+ DCHECK(timer_);
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
+ timer_->num_of_stay_awake_tokens_++;
+}
+
+ServiceWorkerTimeoutTimer::StayAwakeToken::~StayAwakeToken() {
+ // If |timer_| has already been destroyed, it means the worker thread has
+ // already been killed.
+ if (!timer_)
+ return;
+ DCHECK_GT(timer_->num_of_stay_awake_tokens_, 0);
+ timer_->num_of_stay_awake_tokens_--;
+
+ if (!timer_->HasInflightEvent())
+ timer_->OnNoInflightEvent();
+}
+
ServiceWorkerTimeoutTimer::ServiceWorkerTimeoutTimer(
base::RepeatingClosure idle_callback)
: ServiceWorkerTimeoutTimer(std::move(idle_callback),
@@ -39,7 +59,9 @@ ServiceWorkerTimeoutTimer::ServiceWorkerTimeoutTimer(
ServiceWorkerTimeoutTimer::ServiceWorkerTimeoutTimer(
base::RepeatingClosure idle_callback,
const base::TickClock* tick_clock)
- : idle_callback_(std::move(idle_callback)), tick_clock_(tick_clock) {
+ : idle_callback_(std::move(idle_callback)),
+ tick_clock_(tick_clock),
+ weak_factory_(this) {
// |idle_callback_| will be invoked if no event happens in |kIdleDelay|.
idle_time_ = tick_clock_->NowTicks() + kIdleDelay;
timer_.Start(FROM_HERE, kUpdateInterval,
@@ -91,10 +113,17 @@ void ServiceWorkerTimeoutTimer::EndEvent(int event_id) {
DCHECK(iter != id_event_map_.end());
inflight_events_.erase(iter->second);
id_event_map_.erase(iter);
- if (!HasInflightEvent()) {
- idle_time_ = tick_clock_->NowTicks() + kIdleDelay;
- MaybeTriggerIdleTimer();
- }
+
+ if (!HasInflightEvent())
+ OnNoInflightEvent();
+}
+
+std::unique_ptr<ServiceWorkerTimeoutTimer::StayAwakeToken>
+ServiceWorkerTimeoutTimer::CreateStayAwakeToken() {
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled())
+ return nullptr;
+ return std::make_unique<ServiceWorkerTimeoutTimer::StayAwakeToken>(
+ weak_factory_.GetWeakPtr());
}
void ServiceWorkerTimeoutTimer::PushPendingTask(
@@ -133,9 +162,8 @@ void ServiceWorkerTimeoutTimer::UpdateStatus() {
// If the worker is now idle, set the |idle_time_| and possibly trigger the
// idle callback.
if (!HasInflightEvent() && idle_time_.is_null()) {
- idle_time_ = tick_clock_->NowTicks() + kIdleDelay;
- if (MaybeTriggerIdleTimer())
- return;
+ OnNoInflightEvent();
+ return;
}
if (!idle_time_.is_null() && idle_time_ < now) {
@@ -154,8 +182,15 @@ bool ServiceWorkerTimeoutTimer::MaybeTriggerIdleTimer() {
return true;
}
+void ServiceWorkerTimeoutTimer::OnNoInflightEvent() {
+ DCHECK(!HasInflightEvent());
+ idle_time_ = tick_clock_->NowTicks() + kIdleDelay;
+ MaybeTriggerIdleTimer();
+}
+
bool ServiceWorkerTimeoutTimer::HasInflightEvent() const {
- return !inflight_events_.empty() || running_pending_tasks_;
+ return !inflight_events_.empty() || running_pending_tasks_ ||
+ num_of_stay_awake_tokens_ > 0;
}
ServiceWorkerTimeoutTimer::EventInfo::EventInfo(
diff --git a/chromium/content/renderer/service_worker/service_worker_timeout_timer.h b/chromium/content/renderer/service_worker/service_worker_timeout_timer.h
index c068ac32ddf..fcfefc1c075 100644
--- a/chromium/content/renderer/service_worker/service_worker_timeout_timer.h
+++ b/chromium/content/renderer/service_worker/service_worker_timeout_timer.h
@@ -10,6 +10,7 @@
#include "base/callback.h"
#include "base/containers/queue.h"
+#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "content/common/content_export.h"
@@ -44,6 +45,17 @@ namespace content {
// Does nothing except calls the abort callbacks upon destruction.
class CONTENT_EXPORT ServiceWorkerTimeoutTimer {
public:
+ // A token to keep the timeout timer from going into the idle state if any of
+ // them are alive.
+ class CONTENT_EXPORT StayAwakeToken {
+ public:
+ explicit StayAwakeToken(base::WeakPtr<ServiceWorkerTimeoutTimer> timer);
+ ~StayAwakeToken();
+
+ private:
+ base::WeakPtr<ServiceWorkerTimeoutTimer> timer_;
+ };
+
explicit ServiceWorkerTimeoutTimer(base::RepeatingClosure idle_callback);
// For testing.
ServiceWorkerTimeoutTimer(base::RepeatingClosure idle_callback,
@@ -64,6 +76,10 @@ class CONTENT_EXPORT ServiceWorkerTimeoutTimer {
base::TimeDelta timeout);
void EndEvent(int event_id);
+ // Creates a StayAwakeToken to ensure that the idle timer won't be triggered
+ // while any of these are alive.
+ std::unique_ptr<StayAwakeToken> CreateStayAwakeToken();
+
// Pushes a task which is expected to run after any event starts again to a
// pending task queue. The tasks will run at the next StartEvent() call.
// PushPendingTask() should be called if the idle timeout occurred
@@ -100,6 +116,10 @@ class CONTENT_EXPORT ServiceWorkerTimeoutTimer {
// the idle callback is called.
bool MaybeTriggerIdleTimer();
+ // Sets the |idle_time_| and maybe calls |idle_callback_| immediately if the
+ // timeout delay is set to zero.
+ void OnNoInflightEvent();
+
// Returns true if there are running events.
bool HasInflightEvent() const;
@@ -150,11 +170,16 @@ class CONTENT_EXPORT ServiceWorkerTimeoutTimer {
// invoke |idle_callback_| when running |pending_tasks_|.
bool running_pending_tasks_ = false;
+ // The number of the living StayAwakeToken. See also class comments.
+ int num_of_stay_awake_tokens_ = 0;
+
// |timer_| invokes UpdateEventStatus() periodically.
base::RepeatingTimer timer_;
// |tick_clock_| outlives |this|.
const base::TickClock* const tick_clock_;
+
+ base::WeakPtrFactory<ServiceWorkerTimeoutTimer> weak_factory_;
};
} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc b/chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
index c03a3c47b85..d4ae1c3b454 100644
--- a/chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
+++ b/chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
@@ -71,6 +71,8 @@ base::OnceClosure CreateDispatchingEventTask(
} // namespace
+using StayAwakeToken = ServiceWorkerTimeoutTimer::StayAwakeToken;
+
class ServiceWorkerTimeoutTimerTest : public testing::Test {
protected:
void SetUp() override {
@@ -116,7 +118,7 @@ TEST_F(ServiceWorkerTimeoutTimerTest, IdleTimer) {
// Nothing happens since there is an inflight event.
EXPECT_FALSE(is_idle);
- int event_id_2 = timer.StartEvent(std::move(do_nothing_callback));
+ int event_id_2 = timer.StartEvent(do_nothing_callback);
task_runner()->FastForwardBy(kIdleInterval);
// Nothing happens since there are two inflight events.
EXPECT_FALSE(is_idle);
@@ -130,6 +132,25 @@ TEST_F(ServiceWorkerTimeoutTimerTest, IdleTimer) {
task_runner()->FastForwardBy(kIdleInterval);
// |idle_callback| should be fired.
EXPECT_TRUE(is_idle);
+
+ is_idle = false;
+ int event_id_3 = timer.StartEvent(do_nothing_callback);
+ task_runner()->FastForwardBy(kIdleInterval);
+ // Nothing happens since there is an inflight event.
+ EXPECT_FALSE(is_idle);
+
+ std::unique_ptr<StayAwakeToken> token = timer.CreateStayAwakeToken();
+ timer.EndEvent(event_id_3);
+ task_runner()->FastForwardBy(kIdleInterval);
+ // Nothing happens since there is a living StayAwakeToken.
+ EXPECT_FALSE(is_idle);
+
+ token.reset();
+ // |idle_callback| isn't triggered immendiately.
+ EXPECT_FALSE(is_idle);
+ task_runner()->FastForwardBy(kIdleInterval);
+ // |idle_callback| should be fired.
+ EXPECT_TRUE(is_idle);
}
TEST_F(ServiceWorkerTimeoutTimerTest, EventTimer) {
@@ -317,6 +338,25 @@ TEST_F(ServiceWorkerTimeoutTimerTest, SetIdleTimerDelayToZero) {
// exist.
EXPECT_TRUE(is_idle);
}
+
+ {
+ bool is_idle = false;
+ ServiceWorkerTimeoutTimer timer(CreateReceiverWithCalledFlag(&is_idle),
+ task_runner()->GetMockTickClock());
+ std::unique_ptr<StayAwakeToken> token_1 = timer.CreateStayAwakeToken();
+ std::unique_ptr<StayAwakeToken> token_2 = timer.CreateStayAwakeToken();
+ timer.SetIdleTimerDelayToZero();
+ // Nothing happens since there are two living tokens.
+ EXPECT_FALSE(is_idle);
+
+ token_1.reset();
+ // Nothing happens since there is an living token.
+ EXPECT_FALSE(is_idle);
+
+ token_2.reset();
+ // EndEvent() immediately triggers the idle callback when no tokens exist.
+ EXPECT_TRUE(is_idle);
+ }
}
TEST_F(ServiceWorkerTimeoutTimerTest, NonS13nServiceWorker) {
diff --git a/chromium/content/renderer/service_worker/service_worker_type_converters.cc b/chromium/content/renderer/service_worker/service_worker_type_converters.cc
index 1e0b86ac99a..9484643c220 100644
--- a/chromium/content/renderer/service_worker/service_worker_type_converters.cc
+++ b/chromium/content/renderer/service_worker/service_worker_type_converters.cc
@@ -5,6 +5,8 @@
#include "content/renderer/service_worker/service_worker_type_converters.h"
#include "base/logging.h"
+#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
+#include "mojo/public/cpp/bindings/associated_interface_request.h"
namespace mojo {
@@ -126,4 +128,20 @@ TypeConverter<blink::WebPaymentDetailsModifier,
return output;
}
+blink::WebServiceWorkerObjectInfo
+TypeConverter<blink::WebServiceWorkerObjectInfo,
+ blink::mojom::ServiceWorkerObjectInfoPtr>::
+ Convert(const blink::mojom::ServiceWorkerObjectInfoPtr& input) {
+ if (!input) {
+ return blink::WebServiceWorkerObjectInfo(
+ blink::mojom::kInvalidServiceWorkerVersionId,
+ blink::mojom::ServiceWorkerState::kUnknown, blink::WebURL(),
+ mojo::ScopedInterfaceEndpointHandle() /* host_ptr_info */,
+ mojo::ScopedInterfaceEndpointHandle() /* request */);
+ }
+ return blink::WebServiceWorkerObjectInfo(
+ input->version_id, input->state, input->url,
+ input->host_ptr_info.PassHandle(), input->request.PassHandle());
+}
+
} // namespace mojo
diff --git a/chromium/content/renderer/service_worker/service_worker_type_converters.h b/chromium/content/renderer/service_worker/service_worker_type_converters.h
index 1e7f290e928..e60b78d705b 100644
--- a/chromium/content/renderer/service_worker/service_worker_type_converters.h
+++ b/chromium/content/renderer/service_worker/service_worker_type_converters.h
@@ -9,8 +9,10 @@
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/payments/payment_app.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/platform/modules/payments/web_can_make_payment_event_data.h"
#include "third_party/blink/public/platform/modules/payments/web_payment_request_event_data.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_object_info.h"
#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h"
namespace mojo {
@@ -56,6 +58,13 @@ struct TypeConverter<blink::WebPaymentDetailsModifier,
const payments::mojom::PaymentDetailsModifierPtr& input);
};
+template <>
+struct TypeConverter<blink::WebServiceWorkerObjectInfo,
+ blink::mojom::ServiceWorkerObjectInfoPtr> {
+ static blink::WebServiceWorkerObjectInfo Convert(
+ const blink::mojom::ServiceWorkerObjectInfoPtr& input);
+};
+
} // namespace
#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_TYPE_CONVERTERS_H_
diff --git a/chromium/content/renderer/service_worker/thread_safe_script_container.cc b/chromium/content/renderer/service_worker/thread_safe_script_container.cc
deleted file mode 100644
index 6f6e038c95c..00000000000
--- a/chromium/content/renderer/service_worker/thread_safe_script_container.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/service_worker/thread_safe_script_container.h"
-
-#include "base/stl_util.h"
-
-namespace content {
-
-ThreadSafeScriptContainer::ThreadSafeScriptContainer()
- : lock_(), waiting_cv_(&lock_), are_all_data_added_(false) {}
-
-void ThreadSafeScriptContainer::AddOnIOThread(const GURL& url,
- std::unique_ptr<Data> data) {
- base::AutoLock lock(lock_);
- script_data_[url] = std::move(data);
- if (url == waiting_url_)
- waiting_cv_.Signal();
-}
-
-ThreadSafeScriptContainer::ScriptStatus
-ThreadSafeScriptContainer::GetStatusOnWorkerThread(const GURL& url) {
- base::AutoLock lock(lock_);
- auto it = script_data_.find(url);
- if (it == script_data_.end())
- return ScriptStatus::kPending;
- if (!it->second)
- return ScriptStatus::kTaken;
- if (!it->second->IsValid())
- return ScriptStatus::kFailed;
- return ScriptStatus::kReceived;
-}
-
-void ThreadSafeScriptContainer::ResetOnWorkerThread(const GURL& url) {
- base::AutoLock lock(lock_);
- script_data_.erase(url);
-}
-
-bool ThreadSafeScriptContainer::WaitOnWorkerThread(const GURL& url) {
- base::AutoLock lock(lock_);
- DCHECK(waiting_url_.is_empty())
- << "The script container is unexpectedly shared among worker threads.";
- waiting_url_ = url;
- while (script_data_.find(url) == script_data_.end()) {
- // If waiting script hasn't been added yet though all data are received,
- // that means something went wrong.
- if (are_all_data_added_) {
- waiting_url_ = GURL();
- return false;
- }
- // This is possible to be waken up spuriously, so that it's necessary to
- // check if the entry is really added.
- waiting_cv_.Wait();
- }
- waiting_url_ = GURL();
- // TODO(shimazu): Keep the status for each entries instead of using IsValid().
- const auto& data = script_data_[url];
- return !data || data->IsValid();
-}
-
-std::unique_ptr<ThreadSafeScriptContainer::Data>
-ThreadSafeScriptContainer::TakeOnWorkerThread(const GURL& url) {
- base::AutoLock lock(lock_);
- DCHECK(base::ContainsKey(script_data_, url))
- << "Script should be added before calling Take.";
- return std::move(script_data_[url]);
-}
-
-void ThreadSafeScriptContainer::OnAllDataAddedOnIOThread() {
- base::AutoLock lock(lock_);
- are_all_data_added_ = true;
- waiting_cv_.Broadcast();
-}
-
-ThreadSafeScriptContainer::~ThreadSafeScriptContainer() = default;
-
-} // namespace content
diff --git a/chromium/content/renderer/service_worker/thread_safe_script_container.h b/chromium/content/renderer/service_worker/thread_safe_script_container.h
deleted file mode 100644
index c0e8d6dbff2..00000000000
--- a/chromium/content/renderer/service_worker/thread_safe_script_container.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_SERVICE_WORKER_THREAD_SAFE_SCRIPT_CONTAINER_H_
-#define CONTENT_RENDERER_SERVICE_WORKER_THREAD_SAFE_SCRIPT_CONTAINER_H_
-
-#include <map>
-#include <memory>
-
-#include "base/memory/ref_counted.h"
-#include "base/synchronization/condition_variable.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_installed_scripts_manager.h"
-
-namespace content {
-
-// ThreadSafeScriptContainer stores the scripts of a service worker for
-// startup. This container is created for each service worker. The IO thread
-// adds scripts to the container, and the worker thread takes the scripts.
-//
-// This class uses explicit synchronization because it needs to support
-// synchronous importScripts() from the worker thread.
-//
-// This class is RefCounted because there is no ordering guarantee of lifetime
-// of its owners, i.e. WebServiceWorkerInstalledScriptsManagerImpl and its
-// Internal class. WebSWInstalledScriptsManagerImpl is destroyed earlier than
-// Internal if the worker is terminated before all scripts are streamed, and
-// Internal is destroyed earlier if all of scripts are received before finishing
-// script evaluation.
-class CONTENT_EXPORT ThreadSafeScriptContainer
- : public base::RefCountedThreadSafe<ThreadSafeScriptContainer> {
- public:
- using Data = blink::WebServiceWorkerInstalledScriptsManager::RawScriptData;
-
- REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
- ThreadSafeScriptContainer();
-
- enum class ScriptStatus {
- // The script data has been received.
- kReceived,
- // The script data has been received but it has already been taken.
- kTaken,
- // Receiving the script has failed.
- kFailed,
- // The script data has not been received yet.
- kPending
- };
-
- // Called on the IO thread.
- void AddOnIOThread(const GURL& url, std::unique_ptr<Data> data);
-
- // Called on the worker thread.
- ScriptStatus GetStatusOnWorkerThread(const GURL& url);
-
- // Removes the script. After calling this, ScriptStatus for the
- // script will be kPending.
- // Called on the worker thread.
- void ResetOnWorkerThread(const GURL& url);
-
- // Waits until the script is added. The thread is blocked until the script is
- // available or receiving the script fails. Returns false if an error happens
- // and the waiting script won't be available forever.
- // Called on the worker thread.
- bool WaitOnWorkerThread(const GURL& url);
-
- // Called on the worker thread.
- std::unique_ptr<Data> TakeOnWorkerThread(const GURL& url);
-
- // Called if no more data will be added.
- // Called on the IO thread.
- void OnAllDataAddedOnIOThread();
-
- private:
- friend class base::RefCountedThreadSafe<ThreadSafeScriptContainer>;
- ~ThreadSafeScriptContainer();
-
- // |lock_| protects |waiting_cv_|, |script_data_|, |waiting_url_| and
- // |are_all_data_added_|.
- base::Lock lock_;
- // |waiting_cv_| is signaled when a script whose url matches to |waiting_url|
- // is added, or OnAllDataAdded is called. The worker thread waits on this, and
- // the IO thread signals it.
- base::ConditionVariable waiting_cv_;
- std::map<GURL, std::unique_ptr<Data>> script_data_;
- GURL waiting_url_;
- bool are_all_data_added_;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_SERVICE_WORKER_THREAD_SAFE_SCRIPT_CONTAINER_H_
diff --git a/chromium/content/renderer/service_worker/thread_safe_script_container_unittest.cc b/chromium/content/renderer/service_worker/thread_safe_script_container_unittest.cc
deleted file mode 100644
index a6853ed06c3..00000000000
--- a/chromium/content/renderer/service_worker/thread_safe_script_container_unittest.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/service_worker/thread_safe_script_container.h"
-
-#include "base/bind.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-using ScriptStatus = ThreadSafeScriptContainer::ScriptStatus;
-
-class ThreadSafeScriptContainerTest : public testing::Test {
- public:
- ThreadSafeScriptContainerTest()
- : writer_thread_("writer_thread"),
- reader_thread_("reader_thread"),
- writer_waiter_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED),
- reader_waiter_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED),
- container_(base::MakeRefCounted<ThreadSafeScriptContainer>()) {}
-
- protected:
- void SetUp() override {
- ASSERT_TRUE(writer_thread_.Start());
- ASSERT_TRUE(reader_thread_.Start());
- writer_task_runner_ = writer_thread_.task_runner();
- reader_task_runner_ = reader_thread_.task_runner();
- }
-
- void TearDown() override {
- writer_thread_.Stop();
- reader_thread_.Stop();
- }
-
- base::WaitableEvent* AddOnWriterThread(
- const GURL& url,
- ThreadSafeScriptContainer::Data** out_data) {
- writer_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- [](scoped_refptr<ThreadSafeScriptContainer> container,
- const GURL& url, ThreadSafeScriptContainer::Data** out_data,
- base::WaitableEvent* waiter) {
- auto data = ThreadSafeScriptContainer::Data::Create(
- blink::WebString::FromUTF8("utf-8") /* encoding */,
- blink::WebVector<blink::WebVector<char>>() /* script_text */,
- blink::WebVector<blink::WebVector<char>>() /* meta_data */);
- *out_data = data.get();
- container->AddOnIOThread(url, std::move(data));
- waiter->Signal();
- },
- container_, url, out_data, &writer_waiter_));
- return &writer_waiter_;
- }
-
- base::WaitableEvent* OnAllDataAddedOnWriterThread() {
- writer_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(
- [](scoped_refptr<ThreadSafeScriptContainer> container,
- base::WaitableEvent* waiter) {
- container->OnAllDataAddedOnIOThread();
- waiter->Signal();
- },
- container_, &writer_waiter_));
- return &writer_waiter_;
- }
-
- base::WaitableEvent* GetStatusOnReaderThread(const GURL& url,
- ScriptStatus* out_status) {
- reader_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(
- [](scoped_refptr<ThreadSafeScriptContainer> container,
- const GURL& url, ScriptStatus* out_status,
- base::WaitableEvent* waiter) {
- *out_status = container->GetStatusOnWorkerThread(url);
- waiter->Signal();
- },
- container_, url, out_status, &reader_waiter_));
- return &reader_waiter_;
- }
-
- base::WaitableEvent* WaitOnReaderThread(const GURL& url, bool* out_exists) {
- reader_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- [](scoped_refptr<ThreadSafeScriptContainer> container,
- const GURL& url, bool* out_exists, base::WaitableEvent* waiter) {
- *out_exists = container->WaitOnWorkerThread(url);
- waiter->Signal();
- },
- container_, url, out_exists, &reader_waiter_));
- return &reader_waiter_;
- }
-
- base::WaitableEvent* TakeOnReaderThread(
- const GURL& url,
- ThreadSafeScriptContainer::Data** out_data) {
- reader_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- [](scoped_refptr<ThreadSafeScriptContainer> container,
- const GURL& url, ThreadSafeScriptContainer::Data** out_data,
- base::WaitableEvent* waiter) {
- auto data = container->TakeOnWorkerThread(url);
- *out_data = data.get();
- waiter->Signal();
- },
- container_, url, out_data, &reader_waiter_));
- return &reader_waiter_;
- }
-
- private:
- base::Thread writer_thread_;
- base::Thread reader_thread_;
-
- scoped_refptr<base::SingleThreadTaskRunner> writer_task_runner_;
- scoped_refptr<base::SingleThreadTaskRunner> reader_task_runner_;
-
- base::WaitableEvent writer_waiter_;
- base::WaitableEvent reader_waiter_;
-
- scoped_refptr<ThreadSafeScriptContainer> container_;
-};
-
-TEST_F(ThreadSafeScriptContainerTest, WaitExistingKey) {
- const GURL kKey("https://example.com/key");
- {
- ScriptStatus result = ScriptStatus::kReceived;
- GetStatusOnReaderThread(kKey, &result)->Wait();
- EXPECT_EQ(ScriptStatus::kPending, result);
- }
-
- ThreadSafeScriptContainer::Data* added_data;
- {
- bool result = false;
- base::WaitableEvent* pending_wait = WaitOnReaderThread(kKey, &result);
- // This should not be signaled until data is added.
- EXPECT_FALSE(pending_wait->IsSignaled());
- base::WaitableEvent* pending_write = AddOnWriterThread(kKey, &added_data);
- pending_wait->Wait();
- pending_write->Wait();
- EXPECT_TRUE(result);
- }
-
- {
- ScriptStatus result = ScriptStatus::kFailed;
- GetStatusOnReaderThread(kKey, &result)->Wait();
- EXPECT_EQ(ScriptStatus::kReceived, result);
- }
-
- {
- ThreadSafeScriptContainer::Data* taken_data;
- TakeOnReaderThread(kKey, &taken_data)->Wait();
- EXPECT_EQ(added_data, taken_data);
- }
-
- {
- ScriptStatus result = ScriptStatus::kFailed;
- GetStatusOnReaderThread(kKey, &result)->Wait();
- // The record of |kKey| should be exist though it's already taken.
- EXPECT_EQ(ScriptStatus::kTaken, result);
- }
-
- {
- bool result = false;
- WaitOnReaderThread(kKey, &result)->Wait();
- // Waiting for |kKey| should succeed.
- EXPECT_TRUE(result);
-
- ThreadSafeScriptContainer::Data* taken_data;
- TakeOnReaderThread(kKey, &taken_data)->Wait();
- // |taken_data| should be nullptr because it's already taken.
- EXPECT_EQ(nullptr, taken_data);
- }
-
- // Finish adding data.
- OnAllDataAddedOnWriterThread()->Wait();
-
- {
- bool result = false;
- WaitOnReaderThread(kKey, &result)->Wait();
- // The record has been already added, so Wait shouldn't fail.
- EXPECT_TRUE(result);
-
- ThreadSafeScriptContainer::Data* taken_data;
- TakeOnReaderThread(kKey, &taken_data)->Wait();
- // |taken_data| should be nullptr because it's already taken.
- EXPECT_EQ(nullptr, taken_data);
- }
-}
-
-TEST_F(ThreadSafeScriptContainerTest, WaitNonExistingKey) {
- const GURL kKey("https://example.com/key");
- {
- ScriptStatus result = ScriptStatus::kReceived;
- GetStatusOnReaderThread(kKey, &result)->Wait();
- EXPECT_EQ(ScriptStatus::kPending, result);
- }
-
- {
- bool result = true;
- base::WaitableEvent* pending_wait = WaitOnReaderThread(kKey, &result);
- // This should not be signaled until OnAllDataAdded is called.
- EXPECT_FALSE(pending_wait->IsSignaled());
- base::WaitableEvent* pending_on_all_data_added =
- OnAllDataAddedOnWriterThread();
- pending_wait->Wait();
- pending_on_all_data_added->Wait();
- // Aborted wait should return false.
- EXPECT_FALSE(result);
- }
-
- {
- bool result = true;
- WaitOnReaderThread(kKey, &result)->Wait();
- // Wait fails immediately because OnAllDataAdded is called.
- EXPECT_FALSE(result);
- }
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/service_worker/web_service_worker_impl.cc b/chromium/content/renderer/service_worker/web_service_worker_impl.cc
deleted file mode 100644
index 75f91c13248..00000000000
--- a/chromium/content/renderer/service_worker/web_service_worker_impl.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/service_worker/web_service_worker_impl.h"
-
-#include <utility>
-
-#include "base/macros.h"
-#include "content/renderer/service_worker/service_worker_context_client.h"
-#include "content/renderer/service_worker/service_worker_provider_context.h"
-#include "content/renderer/service_worker/web_service_worker_provider_impl.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_proxy.h"
-#include "third_party/blink/public/platform/web_runtime_features.h"
-#include "third_party/blink/public/platform/web_string.h"
-
-using blink::WebString;
-
-namespace content {
-
-namespace {
-
-class ServiceWorkerHandleImpl : public blink::WebServiceWorker::Handle {
- public:
- explicit ServiceWorkerHandleImpl(scoped_refptr<WebServiceWorkerImpl> worker)
- : worker_(std::move(worker)) {}
- ~ServiceWorkerHandleImpl() override {}
-
- blink::WebServiceWorker* ServiceWorker() override { return worker_.get(); }
-
- private:
- scoped_refptr<WebServiceWorkerImpl> worker_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandleImpl);
-};
-
-void OnTerminated(
- std::unique_ptr<WebServiceWorkerImpl::TerminateForTestingCallback>
- callback) {
- callback->OnSuccess();
-}
-
-} // namespace
-
-// static
-scoped_refptr<WebServiceWorkerImpl>
-WebServiceWorkerImpl::CreateForServiceWorkerGlobalScope(
- blink::mojom::ServiceWorkerObjectInfoPtr info) {
- scoped_refptr<WebServiceWorkerImpl> impl =
- new WebServiceWorkerImpl(std::move(info), nullptr /* provider_context */);
- return impl;
-}
-
-// static
-scoped_refptr<WebServiceWorkerImpl>
-WebServiceWorkerImpl::CreateForServiceWorkerClient(
- blink::mojom::ServiceWorkerObjectInfoPtr info,
- base::WeakPtr<ServiceWorkerProviderContext> provider_context) {
- DCHECK(provider_context);
- scoped_refptr<WebServiceWorkerImpl> impl =
- new WebServiceWorkerImpl(std::move(info), std::move(provider_context));
- return impl;
-}
-
-void WebServiceWorkerImpl::StateChanged(
- blink::mojom::ServiceWorkerState new_state) {
- state_ = new_state;
-
- // TODO(nhiroki): This is a quick fix for http://crbug.com/507110
- DCHECK(proxy_);
- if (proxy_)
- proxy_->DispatchStateChangeEvent();
-}
-
-void WebServiceWorkerImpl::SetProxy(blink::WebServiceWorkerProxy* proxy) {
- proxy_ = proxy;
-}
-
-blink::WebServiceWorkerProxy* WebServiceWorkerImpl::Proxy() {
- return proxy_;
-}
-
-blink::WebURL WebServiceWorkerImpl::Url() const {
- return info_->url;
-}
-
-blink::mojom::ServiceWorkerState WebServiceWorkerImpl::GetState() const {
- return state_;
-}
-
-void WebServiceWorkerImpl::PostMessageToServiceWorker(
- blink::TransferableMessage message) {
- host_->PostMessageToServiceWorker(std::move(message));
-}
-
-void WebServiceWorkerImpl::TerminateForTesting(
- std::unique_ptr<TerminateForTestingCallback> callback) {
- host_->TerminateForTesting(
- base::BindOnce(&OnTerminated, std::move(callback)));
-}
-
-// static
-std::unique_ptr<blink::WebServiceWorker::Handle>
-WebServiceWorkerImpl::CreateHandle(scoped_refptr<WebServiceWorkerImpl> worker) {
- if (!worker)
- return nullptr;
- return std::make_unique<ServiceWorkerHandleImpl>(std::move(worker));
-}
-
-WebServiceWorkerImpl::WebServiceWorkerImpl(
- blink::mojom::ServiceWorkerObjectInfoPtr info,
- base::WeakPtr<ServiceWorkerProviderContext> provider_context)
- : binding_(this),
- info_(std::move(info)),
- state_(info_->state),
- proxy_(nullptr),
- is_for_client_(provider_context),
- context_for_client_(std::move(provider_context)) {
- DCHECK_NE(blink::mojom::kInvalidServiceWorkerVersionId, info_->version_id);
- host_.Bind(std::move(info_->host_ptr_info));
- binding_.Bind(std::move(info_->request));
-
- if (is_for_client_) {
- context_for_client_->AddServiceWorkerObject(info_->version_id, this);
- } else {
- ServiceWorkerContextClient::ThreadSpecificInstance()
- ->AddServiceWorkerObject(info_->version_id, this);
- }
-}
-
-WebServiceWorkerImpl::~WebServiceWorkerImpl() {
- if (is_for_client_) {
- if (context_for_client_) {
- context_for_client_->RemoveServiceWorkerObject(info_->version_id);
- }
- } else {
- if (ServiceWorkerContextClient::ThreadSpecificInstance()) {
- ServiceWorkerContextClient::ThreadSpecificInstance()
- ->RemoveServiceWorkerObject(info_->version_id);
- }
- }
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/service_worker/web_service_worker_impl.h b/chromium/content/renderer/service_worker/web_service_worker_impl.h
deleted file mode 100644
index 8e183fa77f5..00000000000
--- a/chromium/content/renderer/service_worker/web_service_worker_impl.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_IMPL_H_
-#define CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_IMPL_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/strings/string16.h"
-#include "content/common/content_export.h"
-#include "mojo/public/cpp/bindings/associated_binding.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker.h"
-#include "third_party/blink/public/web/web_frame.h"
-
-namespace blink {
-class WebServiceWorkerProxy;
-}
-
-namespace content {
-
-class ServiceWorkerProviderContext;
-
-// WebServiceWorkerImpl represents a ServiceWorker object in JavaScript.
-// https://w3c.github.io/ServiceWorker/#serviceworker-interface
-//
-// Only one WebServiceWorkerImpl can exist at a time to represent a given
-// service worker in a given execution context. This is because the standard
-// requires JavaScript equality between ServiceWorker objects in the same
-// execution context that represent the same service worker.
-//
-// This class is ref counted and owned by WebServiceWorker::Handle, which is
-// passed to Blink. Generally, Blink keeps only one Handle to an instance of
-// this class. However, since //content can't know if Blink already has a
-// Handle, it passes a new Handle whenever passing this class to Blink. Blink
-// discards the new Handle if it already has one.
-// Also, this class is referred but not owned by ServiceWorkerProviderContext
-// (for service worker client contexts) and ServiceWorkerContextClient (for
-// service worker execution contexts). These are tracking WebServiceWorker to
-// ensure the uniqueness of ServiceWorker objects, and this class adds/removes
-// the reference in the ctor/dtor.
-//
-// When a blink::mojom::ServiceWorkerObjectInfo arrives at the renderer,
-// if there is no WebServiceWorkerImpl which represents the ServiceWorker, a
-// new WebServiceWorkerImpl is created using the
-// blink::mojom::ServiceWorkerObjectInfo, otherwise reuse the existing one.
-//
-// WebServiceWorkerImpl holds a Mojo connection (|host_|). The connection keeps
-// the ServiceWorkerObjectHost in the browser process alive, which in turn keeps
-// the relevant ServiceWorkerVersion alive.
-class CONTENT_EXPORT WebServiceWorkerImpl
- : public blink::mojom::ServiceWorkerObject,
- public blink::WebServiceWorker,
- public base::RefCounted<WebServiceWorkerImpl> {
- public:
- static scoped_refptr<WebServiceWorkerImpl> CreateForServiceWorkerGlobalScope(
- blink::mojom::ServiceWorkerObjectInfoPtr info);
- static scoped_refptr<WebServiceWorkerImpl> CreateForServiceWorkerClient(
- blink::mojom::ServiceWorkerObjectInfoPtr info,
- base::WeakPtr<ServiceWorkerProviderContext> provider_context);
-
- // Implements blink::mojom::ServiceWorkerObject.
- void StateChanged(blink::mojom::ServiceWorkerState new_state) override;
-
- // blink::WebServiceWorker overrides.
- void SetProxy(blink::WebServiceWorkerProxy* proxy) override;
- blink::WebServiceWorkerProxy* Proxy() override;
- blink::WebURL Url() const override;
- blink::mojom::ServiceWorkerState GetState() const override;
- void PostMessageToServiceWorker(blink::TransferableMessage message) override;
- void TerminateForTesting(
- std::unique_ptr<TerminateForTestingCallback> callback) override;
-
- // Creates WebServiceWorker::Handle object that owns a reference to the given
- // WebServiceWorkerImpl object.
- static std::unique_ptr<blink::WebServiceWorker::Handle> CreateHandle(
- scoped_refptr<WebServiceWorkerImpl> worker);
-
- private:
- friend class base::RefCounted<WebServiceWorkerImpl>;
- WebServiceWorkerImpl(
- blink::mojom::ServiceWorkerObjectInfoPtr info,
- base::WeakPtr<ServiceWorkerProviderContext> provider_context);
- ~WebServiceWorkerImpl() override;
-
- // Both |host_| and |binding_| are bound on the main
- // thread for service worker clients (document), and are bound on the service
- // worker thread for service worker execution contexts.
- //
- // |host_| keeps the Mojo connection to the
- // browser-side ServiceWorkerObjectHost, whose lifetime is bound
- // to |host_| via the Mojo connection.
- blink::mojom::ServiceWorkerObjectHostAssociatedPtr host_;
- // |binding_| keeps the Mojo binding to serve its other Mojo endpoint (i.e.
- // the caller end) held by the content::ServiceWorkerObjectHost in the browser
- // process.
- mojo::AssociatedBinding<blink::mojom::ServiceWorkerObject> binding_;
-
- blink::mojom::ServiceWorkerObjectInfoPtr info_;
- blink::mojom::ServiceWorkerState state_;
- blink::WebServiceWorkerProxy* proxy_;
-
- // True means |this| is for service worker client contexts, otherwise |this|
- // is for service worker execution contexts.
- const bool is_for_client_;
- // For service worker client contexts, |this| is tracked (not owned) in
- // |context_for_client_->controllee_state_->workers_|.
- // For service worker execution contexts, |context_for_client_| is
- // null and |this| is tracked (not owned) in
- // |ServiceWorkerContextClient::ThreadSpecificInstance()->context_->workers_|.
- base::WeakPtr<ServiceWorkerProviderContext> context_for_client_;
-
- DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerImpl);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_IMPL_H_
diff --git a/chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.cc b/chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.cc
deleted file mode 100644
index 8533648caaf..00000000000
--- a/chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.cc
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h"
-
-#include "base/barrier_closure.h"
-#include "base/memory/ptr_util.h"
-#include "base/stl_util.h"
-#include "base/threading/thread_checker.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-
-namespace content {
-
-namespace {
-
-// Receiver is a class to read a Mojo data pipe. Received data are stored in
-// chunks. Lives on the IO thread. Receiver is owned by Internal via
-// BundledReceivers. It is created to read the script body or metadata from a
-// data pipe, and is destroyed when the read finishes.
-class Receiver {
- public:
- using BytesChunk = blink::WebVector<char>;
-
- Receiver(mojo::ScopedDataPipeConsumerHandle handle,
- uint64_t total_bytes,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : handle_(std::move(handle)),
- watcher_(FROM_HERE,
- mojo::SimpleWatcher::ArmingPolicy::MANUAL,
- std::move(task_runner)),
- remaining_bytes_(total_bytes) {}
-
- void Start(base::OnceClosure callback) {
- if (!handle_.is_valid()) {
- std::move(callback).Run();
- return;
- }
- callback_ = std::move(callback);
- // base::Unretained is safe because |watcher_| is owned by |this|.
- MojoResult rv = watcher_.Watch(
- handle_.get(), MOJO_HANDLE_SIGNAL_READABLE,
- base::Bind(&Receiver::OnReadable, base::Unretained(this)));
- DCHECK_EQ(MOJO_RESULT_OK, rv);
- watcher_.ArmOrNotify();
- }
-
- void OnReadable(MojoResult) {
- // It isn't necessary to handle MojoResult here since BeginReadDataRaw()
- // returns an equivalent error.
- const void* buffer = nullptr;
- uint32_t bytes_read = 0;
- MojoResult rv =
- handle_->BeginReadData(&buffer, &bytes_read, MOJO_READ_DATA_FLAG_NONE);
- switch (rv) {
- case MOJO_RESULT_BUSY:
- case MOJO_RESULT_INVALID_ARGUMENT:
- NOTREACHED();
- return;
- case MOJO_RESULT_FAILED_PRECONDITION:
- // Closed by peer.
- OnCompleted();
- return;
- case MOJO_RESULT_SHOULD_WAIT:
- watcher_.ArmOrNotify();
- return;
- case MOJO_RESULT_OK:
- break;
- default:
- // mojo::BeginReadDataRaw() should not return any other values.
- // Notify the error to the browser by resetting the handle even though
- // it's in the middle of data transfer.
- OnCompleted();
- return;
- }
-
- if (bytes_read > 0)
- chunks_.emplace_back(static_cast<const char*>(buffer), bytes_read);
-
- rv = handle_->EndReadData(bytes_read);
- DCHECK_EQ(rv, MOJO_RESULT_OK);
- CHECK_GE(remaining_bytes_, bytes_read);
- remaining_bytes_ -= bytes_read;
- watcher_.ArmOrNotify();
- }
-
- bool is_running() const { return handle_.is_valid(); }
- bool has_received_all_data() const { return remaining_bytes_ == 0; }
-
- blink::WebVector<BytesChunk> TakeChunks() {
- DCHECK(!is_running());
- return blink::WebVector<BytesChunk>(std::move(chunks_));
- }
-
- private:
- void OnCompleted() {
- handle_.reset();
- watcher_.Cancel();
- if (!has_received_all_data())
- chunks_.clear();
- DCHECK(callback_);
- std::move(callback_).Run();
- }
-
- base::OnceClosure callback_;
- mojo::ScopedDataPipeConsumerHandle handle_;
- mojo::SimpleWatcher watcher_;
-
- // std::vector is internally used because blink::WebVector is immutable and
- // cannot append data.
- std::vector<BytesChunk> chunks_;
- uint64_t remaining_bytes_;
-};
-
-using RawScriptData =
- blink::WebServiceWorkerInstalledScriptsManager::RawScriptData;
-
-// BundledReceivers is a helper class to wait for the end of reading body and
-// meta data. Lives on the IO thread.
-class BundledReceivers {
- public:
- BundledReceivers(mojo::ScopedDataPipeConsumerHandle meta_data_handle,
- uint64_t meta_data_size,
- mojo::ScopedDataPipeConsumerHandle body_handle,
- uint64_t body_size,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : meta_data_(std::move(meta_data_handle), meta_data_size, task_runner),
- body_(std::move(body_handle), body_size, std::move(task_runner)) {}
-
- // Starts reading the pipes and invokes |callback| when both are finished.
- void Start(base::OnceClosure callback) {
- base::RepeatingClosure wait_all_closure =
- base::BarrierClosure(2, std::move(callback));
- meta_data_.Start(wait_all_closure);
- body_.Start(std::move(wait_all_closure));
- }
-
- Receiver* meta_data() { return &meta_data_; }
- Receiver* body() { return &body_; }
-
- private:
- Receiver meta_data_;
- Receiver body_;
-};
-
-// Internal lives on the IO thread. This receives
-// blink::mojom::ServiceWorkerScriptInfo for all installed scripts and then
-// starts reading the body and meta data from the browser. This instance will be
-// kept alive as long as the Mojo's connection is established.
-class Internal : public blink::mojom::ServiceWorkerInstalledScriptsManager {
- public:
- // Called on the IO thread.
- // Creates and binds a new Internal instance to |request|.
- static void Create(
- scoped_refptr<ThreadSafeScriptContainer> script_container,
- blink::mojom::ServiceWorkerInstalledScriptsManagerRequest request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- mojo::MakeStrongBinding(
- std::make_unique<Internal>(std::move(script_container),
- std::move(task_runner)),
- std::move(request));
- }
-
- Internal(scoped_refptr<ThreadSafeScriptContainer> script_container,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : script_container_(std::move(script_container)),
- task_runner_(std::move(task_runner)),
- weak_factory_(this) {}
-
- ~Internal() override {
- DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
- // Wake up a waiting thread so it does not wait forever. If the script has
- // not been added yet, that means something went wrong. From here,
- // script_container_->Wait() will return false if the script hasn't been
- // added yet.
- script_container_->OnAllDataAddedOnIOThread();
- }
-
- // Implements blink::mojom::ServiceWorkerInstalledScriptsManager.
- // Called on the IO thread.
- void TransferInstalledScript(
- blink::mojom::ServiceWorkerScriptInfoPtr script_info) override {
- DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
- GURL script_url = script_info->script_url;
- auto receivers = std::make_unique<BundledReceivers>(
- std::move(script_info->meta_data), script_info->meta_data_size,
- std::move(script_info->body), script_info->body_size, task_runner_);
- receivers->Start(base::BindOnce(&Internal::OnScriptReceived,
- weak_factory_.GetWeakPtr(),
- std::move(script_info)));
- DCHECK(!base::ContainsKey(running_receivers_, script_url));
- running_receivers_[script_url] = std::move(receivers);
- }
-
- // Called on the IO thread.
- void OnScriptReceived(blink::mojom::ServiceWorkerScriptInfoPtr script_info) {
- DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
- const GURL& script_url = script_info->script_url;
- auto iter = running_receivers_.find(script_url);
- DCHECK(iter != running_receivers_.end());
- std::unique_ptr<BundledReceivers> receivers = std::move(iter->second);
- DCHECK(receivers);
- if (!receivers->body()->has_received_all_data() ||
- !receivers->meta_data()->has_received_all_data()) {
- script_container_->AddOnIOThread(script_url,
- RawScriptData::CreateInvalidInstance());
- running_receivers_.erase(iter);
- return;
- }
-
- auto script_data = RawScriptData::Create(
- blink::WebString::FromUTF8(script_info->encoding),
- receivers->body()->TakeChunks(), receivers->meta_data()->TakeChunks());
- for (const auto& entry : script_info->headers) {
- script_data->AddHeader(blink::WebString::FromUTF8(entry.first),
- blink::WebString::FromUTF8(entry.second));
- }
- script_container_->AddOnIOThread(script_url, std::move(script_data));
- running_receivers_.erase(iter);
- }
-
- private:
- THREAD_CHECKER(io_thread_checker_);
- std::map<GURL, std::unique_ptr<BundledReceivers>> running_receivers_;
- scoped_refptr<ThreadSafeScriptContainer> script_container_;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- base::WeakPtrFactory<Internal> weak_factory_;
-};
-
-} // namespace
-
-// static
-std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManager>
-WebServiceWorkerInstalledScriptsManagerImpl::Create(
- blink::mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {
- auto script_container = base::MakeRefCounted<ThreadSafeScriptContainer>();
- blink::mojom::ServiceWorkerInstalledScriptsManagerHostPtr manager_host_ptr(
- std::move(installed_scripts_info->manager_host_ptr));
- std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManager> manager =
- base::WrapUnique<WebServiceWorkerInstalledScriptsManagerImpl>(
- new WebServiceWorkerInstalledScriptsManagerImpl(
- std::move(installed_scripts_info->installed_urls),
- script_container, std::move(manager_host_ptr)));
- io_task_runner->PostTask(
- FROM_HERE,
- base::BindOnce(&Internal::Create, script_container,
- std::move(installed_scripts_info->manager_request),
- io_task_runner));
- return manager;
-}
-
-WebServiceWorkerInstalledScriptsManagerImpl::
- WebServiceWorkerInstalledScriptsManagerImpl(
- std::vector<GURL>&& installed_urls,
- scoped_refptr<ThreadSafeScriptContainer> script_container,
- blink::mojom::ServiceWorkerInstalledScriptsManagerHostPtr manager_host)
- : installed_urls_(installed_urls.begin(), installed_urls.end()),
- script_container_(std::move(script_container)),
- manager_host_(
- blink::mojom::ThreadSafeServiceWorkerInstalledScriptsManagerHostPtr::
- Create(std::move(manager_host))) {}
-
-WebServiceWorkerInstalledScriptsManagerImpl::
- ~WebServiceWorkerInstalledScriptsManagerImpl() = default;
-
-bool WebServiceWorkerInstalledScriptsManagerImpl::IsScriptInstalled(
- const blink::WebURL& script_url) const {
- return base::ContainsKey(installed_urls_, script_url);
-}
-
-std::unique_ptr<RawScriptData>
-WebServiceWorkerInstalledScriptsManagerImpl::GetRawScriptData(
- const blink::WebURL& script_url) {
- TRACE_EVENT1("ServiceWorker",
- "WebServiceWorkerInstalledScriptsManagerImpl::GetRawScriptData",
- "script_url", script_url.GetString().Utf8());
- if (!IsScriptInstalled(script_url))
- return nullptr;
-
- ThreadSafeScriptContainer::ScriptStatus status =
- script_container_->GetStatusOnWorkerThread(script_url);
- // If the script has already been taken, request the browser to send the
- // script.
- if (status == ThreadSafeScriptContainer::ScriptStatus::kTaken) {
- script_container_->ResetOnWorkerThread(script_url);
- (*manager_host_)->RequestInstalledScript(script_url);
- status = script_container_->GetStatusOnWorkerThread(script_url);
- }
-
- // If the script has not been received at this point, wait for arrival by
- // blocking the worker thread.
- if (status == ThreadSafeScriptContainer::ScriptStatus::kPending) {
- // Wait for arrival of the script.
- const bool success = script_container_->WaitOnWorkerThread(script_url);
- // It can fail due to an error on Mojo pipes.
- if (!success)
- return RawScriptData::CreateInvalidInstance();
- status = script_container_->GetStatusOnWorkerThread(script_url);
- DCHECK_NE(ThreadSafeScriptContainer::ScriptStatus::kPending, status);
- }
-
- if (status == ThreadSafeScriptContainer::ScriptStatus::kFailed)
- return RawScriptData::CreateInvalidInstance();
- DCHECK_EQ(ThreadSafeScriptContainer::ScriptStatus::kReceived, status);
-
- return script_container_->TakeOnWorkerThread(script_url);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h b/chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h
deleted file mode 100644
index 5054d4830a0..00000000000
--- a/chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_INSTALLED_SCRIPTS_MANAGER_IMPL_H_
-#define CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_INSTALLED_SCRIPTS_MANAGER_IMPL_H_
-
-#include <set>
-#include <vector>
-
-#include "base/single_thread_task_runner.h"
-#include "content/renderer/service_worker/thread_safe_script_container.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom.h"
-#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_installed_scripts_manager.h"
-
-namespace content {
-
-class CONTENT_EXPORT WebServiceWorkerInstalledScriptsManagerImpl final
- : public blink::WebServiceWorkerInstalledScriptsManager {
- public:
- // Called on the main thread.
- static std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManager> Create(
- blink::mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info,
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
-
- ~WebServiceWorkerInstalledScriptsManagerImpl() override;
-
- // WebServiceWorkerInstalledScriptsManager implementation.
- bool IsScriptInstalled(const blink::WebURL& script_url) const override;
- std::unique_ptr<RawScriptData> GetRawScriptData(
- const blink::WebURL& script_url) override;
-
- private:
- WebServiceWorkerInstalledScriptsManagerImpl(
- std::vector<GURL>&& installed_urls,
- scoped_refptr<ThreadSafeScriptContainer> script_container,
- blink::mojom::ServiceWorkerInstalledScriptsManagerHostPtr manager_host);
-
- const std::set<GURL> installed_urls_;
- scoped_refptr<ThreadSafeScriptContainer> script_container_;
-
- scoped_refptr<
- blink::mojom::ThreadSafeServiceWorkerInstalledScriptsManagerHostPtr>
- manager_host_;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_SERVICE_WORKER_WEB_SERVICE_WORKER_INSTALLED_SCRIPTS_MANAGER_IMPL_H_
diff --git a/chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl_unittest.cc b/chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl_unittest.cc
deleted file mode 100644
index 5b24150a2c1..00000000000
--- a/chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl_unittest.cc
+++ /dev/null
@@ -1,417 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h"
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-class BrowserSideSender
- : blink::mojom::ServiceWorkerInstalledScriptsManagerHost {
- public:
- BrowserSideSender() : binding_(this) {}
- ~BrowserSideSender() override = default;
-
- blink::mojom::ServiceWorkerInstalledScriptsInfoPtr CreateAndBind(
- const std::vector<GURL>& installed_urls) {
- EXPECT_FALSE(manager_.is_bound());
- EXPECT_FALSE(body_handle_.is_valid());
- EXPECT_FALSE(meta_data_handle_.is_valid());
- auto scripts_info = blink::mojom::ServiceWorkerInstalledScriptsInfo::New();
- scripts_info->installed_urls = installed_urls;
- scripts_info->manager_request = mojo::MakeRequest(&manager_);
- binding_.Bind(mojo::MakeRequest(&scripts_info->manager_host_ptr));
- return scripts_info;
- }
-
- void TransferInstalledScript(const GURL& script_url,
- int64_t body_size,
- int64_t meta_data_size) {
- EXPECT_FALSE(body_handle_.is_valid());
- EXPECT_FALSE(meta_data_handle_.is_valid());
- auto script_info = blink::mojom::ServiceWorkerScriptInfo::New();
- script_info->script_url = script_url;
- EXPECT_EQ(MOJO_RESULT_OK,
- mojo::CreateDataPipe(nullptr, &body_handle_, &script_info->body));
- EXPECT_EQ(MOJO_RESULT_OK, mojo::CreateDataPipe(nullptr, &meta_data_handle_,
- &script_info->meta_data));
- script_info->body_size = body_size;
- script_info->meta_data_size = meta_data_size;
- manager_->TransferInstalledScript(std::move(script_info));
- }
-
- void PushBody(const std::string& data) {
- PushDataPipe(data, body_handle_.get());
- }
-
- void PushMetaData(const std::string& data) {
- PushDataPipe(data, meta_data_handle_.get());
- }
-
- void FinishTransferBody() { body_handle_.reset(); }
-
- void FinishTransferMetaData() { meta_data_handle_.reset(); }
-
- void ResetManager() { manager_.reset(); }
-
- void WaitForRequestInstalledScript(const GURL& script_url) {
- waiting_requested_url_ = script_url;
- base::RunLoop loop;
- requested_script_closure_ = loop.QuitClosure();
- loop.Run();
- }
-
- private:
- void RequestInstalledScript(const GURL& script_url) override {
- EXPECT_EQ(waiting_requested_url_, script_url);
- ASSERT_TRUE(requested_script_closure_);
- std::move(requested_script_closure_).Run();
- }
-
- void PushDataPipe(const std::string& data,
- const mojo::DataPipeProducerHandle& handle) {
- // Send |data| with null terminator.
- ASSERT_TRUE(handle.is_valid());
- uint32_t written_bytes = data.size() + 1;
- MojoResult rv = handle.WriteData(data.c_str(), &written_bytes,
- MOJO_WRITE_DATA_FLAG_NONE);
- ASSERT_EQ(MOJO_RESULT_OK, rv);
- ASSERT_EQ(data.size() + 1, written_bytes);
- }
-
- base::OnceClosure requested_script_closure_;
- GURL waiting_requested_url_;
-
- blink::mojom::ServiceWorkerInstalledScriptsManagerPtr manager_;
- mojo::Binding<blink::mojom::ServiceWorkerInstalledScriptsManagerHost>
- binding_;
-
- mojo::ScopedDataPipeProducerHandle body_handle_;
- mojo::ScopedDataPipeProducerHandle meta_data_handle_;
-
- DISALLOW_COPY_AND_ASSIGN(BrowserSideSender);
-};
-
-class WebServiceWorkerInstalledScriptsManagerImplTest : public testing::Test {
- public:
- WebServiceWorkerInstalledScriptsManagerImplTest()
- : io_thread_("io thread"),
- worker_thread_("worker thread"),
- worker_waiter_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED) {}
-
- protected:
- using RawScriptData =
- blink::WebServiceWorkerInstalledScriptsManager::RawScriptData;
-
- void SetUp() override {
- ASSERT_TRUE(io_thread_.Start());
- ASSERT_TRUE(worker_thread_.Start());
- io_task_runner_ = io_thread_.task_runner();
- worker_task_runner_ = worker_thread_.task_runner();
- }
-
- void TearDown() override {
- io_thread_.Stop();
- worker_thread_.Stop();
- }
-
- void CreateInstalledScriptsManager(
- blink::mojom::ServiceWorkerInstalledScriptsInfoPtr
- installed_scripts_info) {
- installed_scripts_manager_ =
- WebServiceWorkerInstalledScriptsManagerImpl::Create(
- std::move(installed_scripts_info), io_task_runner_);
- }
-
- base::WaitableEvent* IsScriptInstalledOnWorkerThread(const GURL& script_url,
- bool* out_installed) {
- worker_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- [](blink::WebServiceWorkerInstalledScriptsManager*
- installed_scripts_manager,
- const blink::WebURL& script_url, bool* out_installed,
- base::WaitableEvent* waiter) {
- *out_installed =
- installed_scripts_manager->IsScriptInstalled(script_url);
- waiter->Signal();
- },
- installed_scripts_manager_.get(), script_url, out_installed,
- &worker_waiter_));
- return &worker_waiter_;
- }
-
- base::WaitableEvent* GetRawScriptDataOnWorkerThread(
- const GURL& script_url,
- std::unique_ptr<RawScriptData>* out_data) {
- worker_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- [](blink::WebServiceWorkerInstalledScriptsManager*
- installed_scripts_manager,
- const blink::WebURL& script_url,
- std::unique_ptr<RawScriptData>* out_data,
- base::WaitableEvent* waiter) {
- *out_data =
- installed_scripts_manager->GetRawScriptData(script_url);
- waiter->Signal();
- },
- installed_scripts_manager_.get(), script_url, out_data,
- &worker_waiter_));
- return &worker_waiter_;
- }
-
- private:
- // Provides SingleThreadTaskRunner for this test.
- const base::MessageLoop message_loop_;
-
- base::Thread io_thread_;
- base::Thread worker_thread_;
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
- scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner_;
-
- base::WaitableEvent worker_waiter_;
-
- std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManager>
- installed_scripts_manager_;
-
- DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerInstalledScriptsManagerImplTest);
-};
-
-TEST_F(WebServiceWorkerInstalledScriptsManagerImplTest, GetRawScriptData) {
- const GURL kScriptUrl = GURL("https://example.com/installed1.js");
- const GURL kUnknownScriptUrl = GURL("https://example.com/not_installed.js");
-
- BrowserSideSender sender;
- CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
-
- {
- bool result = false;
- IsScriptInstalledOnWorkerThread(kScriptUrl, &result)->Wait();
- // IsScriptInstalled returns correct answer even before script transfer
- // hasn't been started yet.
- EXPECT_TRUE(result);
- }
-
- {
- bool result = true;
- IsScriptInstalledOnWorkerThread(kUnknownScriptUrl, &result)->Wait();
- // IsScriptInstalled returns correct answer even before script transfer
- // hasn't been started yet.
- EXPECT_FALSE(result);
- }
-
- {
- std::unique_ptr<RawScriptData> script_data;
- const std::string kExpectedBody = "This is a script body.";
- const std::string kExpectedMetaData = "This is a meta data.";
- base::WaitableEvent* get_raw_script_data_waiter =
- GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data);
-
- // Start transferring the script. +1 for null terminator.
- sender.TransferInstalledScript(kScriptUrl, kExpectedBody.size() + 1,
- kExpectedMetaData.size() + 1);
- sender.PushBody(kExpectedBody);
- sender.PushMetaData(kExpectedMetaData);
- // GetRawScriptData should be blocked until body and meta data transfer are
- // finished.
- EXPECT_FALSE(get_raw_script_data_waiter->IsSignaled());
- sender.FinishTransferBody();
- sender.FinishTransferMetaData();
-
- // Wait for the script's arrival.
- get_raw_script_data_waiter->Wait();
- ASSERT_TRUE(script_data);
- EXPECT_TRUE(script_data->IsValid());
- ASSERT_EQ(1u, script_data->ScriptTextChunks().size());
- ASSERT_EQ(kExpectedBody.size() + 1,
- script_data->ScriptTextChunks()[0].size());
- EXPECT_STREQ(kExpectedBody.data(),
- script_data->ScriptTextChunks()[0].Data());
- ASSERT_EQ(1u, script_data->MetaDataChunks().size());
- ASSERT_EQ(kExpectedMetaData.size() + 1,
- script_data->MetaDataChunks()[0].size());
- EXPECT_STREQ(kExpectedMetaData.data(),
- script_data->MetaDataChunks()[0].Data());
- }
-
- {
- std::unique_ptr<RawScriptData> script_data;
- const std::string kExpectedBody = "This is another script body.";
- const std::string kExpectedMetaData = "This is another meta data.";
-
- // Request the same script again.
- base::WaitableEvent* get_raw_script_data_waiter =
- GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data);
-
- // It should call a Mojo IPC "RequestInstalledScript()" to the browser.
- sender.WaitForRequestInstalledScript(kScriptUrl);
-
- // Start transferring the script. +1 for null terminator.
- sender.TransferInstalledScript(kScriptUrl, kExpectedBody.size() + 1,
- kExpectedMetaData.size() + 1);
- sender.PushBody(kExpectedBody);
- sender.PushMetaData(kExpectedMetaData);
- // GetRawScriptData should be blocked until body and meta data transfer are
- // finished.
- EXPECT_FALSE(get_raw_script_data_waiter->IsSignaled());
- sender.FinishTransferBody();
- sender.FinishTransferMetaData();
-
- // Wait for the script's arrival.
- get_raw_script_data_waiter->Wait();
- ASSERT_TRUE(script_data);
- EXPECT_TRUE(script_data->IsValid());
- ASSERT_EQ(1u, script_data->ScriptTextChunks().size());
- ASSERT_EQ(kExpectedBody.size() + 1,
- script_data->ScriptTextChunks()[0].size());
- EXPECT_STREQ(kExpectedBody.data(),
- script_data->ScriptTextChunks()[0].Data());
- ASSERT_EQ(1u, script_data->MetaDataChunks().size());
- ASSERT_EQ(kExpectedMetaData.size() + 1,
- script_data->MetaDataChunks()[0].size());
- EXPECT_STREQ(kExpectedMetaData.data(),
- script_data->MetaDataChunks()[0].Data());
- }
-}
-
-TEST_F(WebServiceWorkerInstalledScriptsManagerImplTest,
- EarlyDisconnectionBody) {
- const GURL kScriptUrl = GURL("https://example.com/installed1.js");
- const GURL kUnknownScriptUrl = GURL("https://example.com/not_installed.js");
-
- BrowserSideSender sender;
- CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
-
- {
- std::unique_ptr<RawScriptData> script_data;
- const std::string kExpectedBody = "This is a script body.";
- const std::string kExpectedMetaData = "This is a meta data.";
- base::WaitableEvent* get_raw_script_data_waiter =
- GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data);
-
- // Start transferring the script.
- // Body is expected to be 100 bytes larger than kExpectedBody, but sender
- // only sends kExpectedBody and a null byte (kExpectedBody.size() + 1 bytes
- // in total).
- sender.TransferInstalledScript(kScriptUrl, kExpectedBody.size() + 100,
- kExpectedMetaData.size() + 1);
- sender.PushBody(kExpectedBody);
- sender.PushMetaData(kExpectedMetaData);
- // GetRawScriptData should be blocked until body and meta data transfer are
- // finished.
- EXPECT_FALSE(get_raw_script_data_waiter->IsSignaled());
- sender.FinishTransferBody();
- sender.FinishTransferMetaData();
-
- // Wait for the script's arrival.
- get_raw_script_data_waiter->Wait();
- // script_data->IsValid() should return false since the data pipe for body
- // gets disconnected during sending.
- ASSERT_TRUE(script_data);
- EXPECT_FALSE(script_data->IsValid());
- }
-
- {
- std::unique_ptr<RawScriptData> script_data;
- GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data)->Wait();
- // |script_data| should be invalid since the data wasn't received on the
- // renderer process.
- ASSERT_TRUE(script_data);
- EXPECT_FALSE(script_data->IsValid());
- }
-}
-
-TEST_F(WebServiceWorkerInstalledScriptsManagerImplTest,
- EarlyDisconnectionMetaData) {
- const GURL kScriptUrl = GURL("https://example.com/installed1.js");
- const GURL kUnknownScriptUrl = GURL("https://example.com/not_installed.js");
-
- BrowserSideSender sender;
- CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
-
- {
- std::unique_ptr<RawScriptData> script_data;
- const std::string kExpectedBody = "This is a script body.";
- const std::string kExpectedMetaData = "This is a meta data.";
- base::WaitableEvent* get_raw_script_data_waiter =
- GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data);
-
- // Start transferring the script.
- // Meta data is expected to be 100 bytes larger than kExpectedMetaData, but
- // sender only sends kExpectedMetaData and a null byte
- // (kExpectedMetaData.size() + 1 bytes in total).
- sender.TransferInstalledScript(kScriptUrl, kExpectedBody.size() + 1,
- kExpectedMetaData.size() + 100);
- sender.PushBody(kExpectedBody);
- sender.PushMetaData(kExpectedMetaData);
- // GetRawScriptData should be blocked until body and meta data transfer are
- // finished.
- EXPECT_FALSE(get_raw_script_data_waiter->IsSignaled());
- sender.FinishTransferBody();
- sender.FinishTransferMetaData();
-
- // Wait for the script's arrival.
- get_raw_script_data_waiter->Wait();
- // script_data->IsValid() should return false since the data pipe for meta
- // data gets disconnected during sending.
- ASSERT_TRUE(script_data);
- EXPECT_FALSE(script_data->IsValid());
- }
-
- {
- std::unique_ptr<RawScriptData> script_data;
- GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data)->Wait();
- // |script_data| should be invalid since the data wasn't received on the
- // renderer process.
- ASSERT_TRUE(script_data);
- EXPECT_FALSE(script_data->IsValid());
- }
-}
-
-TEST_F(WebServiceWorkerInstalledScriptsManagerImplTest,
- EarlyDisconnectionManager) {
- const GURL kScriptUrl = GURL("https://example.com/installed1.js");
- const GURL kUnknownScriptUrl = GURL("https://example.com/not_installed.js");
-
- BrowserSideSender sender;
- CreateInstalledScriptsManager(sender.CreateAndBind({kScriptUrl}));
-
- {
- std::unique_ptr<RawScriptData> script_data;
- base::WaitableEvent* get_raw_script_data_waiter =
- GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data);
-
- // Reset the Mojo connection before sending the script.
- EXPECT_FALSE(get_raw_script_data_waiter->IsSignaled());
- sender.ResetManager();
-
- // Wait for the script's arrival.
- get_raw_script_data_waiter->Wait();
- // |script_data| should be nullptr since no data will arrive.
- ASSERT_TRUE(script_data);
- EXPECT_FALSE(script_data->IsValid());
- }
-
- {
- std::unique_ptr<RawScriptData> script_data;
- // This should not be blocked because data will not arrive anymore.
- GetRawScriptDataOnWorkerThread(kScriptUrl, &script_data)->Wait();
- // |script_data| should be invalid since the data wasn't received on the
- // renderer process.
- ASSERT_TRUE(script_data);
- EXPECT_FALSE(script_data->IsValid());
- }
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc
index f4ddf8af5be..eab60bfbf49 100644
--- a/chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc
+++ b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc
@@ -11,9 +11,9 @@
#include "base/trace_event/trace_event.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/renderer/service_worker/service_worker_provider_context.h"
-#include "content/renderer/service_worker/web_service_worker_impl.h"
+#include "content/renderer/service_worker/service_worker_type_converters.h"
#include "content/renderer/service_worker/web_service_worker_registration_impl.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h"
@@ -70,6 +70,7 @@ void WebServiceWorkerProviderImpl::SetClient(
void WebServiceWorkerProviderImpl::RegisterServiceWorker(
const WebURL& web_pattern,
const WebURL& web_script_url,
+ blink::mojom::ScriptType script_type,
blink::mojom::ServiceWorkerUpdateViaCache update_via_cache,
std::unique_ptr<WebServiceWorkerRegistrationCallbacks> callbacks) {
DCHECK(callbacks);
@@ -98,8 +99,13 @@ void WebServiceWorkerProviderImpl::RegisterServiceWorker(
TRACE_EVENT_ASYNC_BEGIN2(
"ServiceWorker", "WebServiceWorkerProviderImpl::RegisterServiceWorker",
this, "Scope", pattern.spec(), "Script URL", script_url.spec());
+
+ // TODO(asamidoi): Create this options in
+ // ServiceWorkerContainer::RegisterServiceWorker() and pass it as an argument
+ // in this function instead of blink::mojom::ScriptType and
+ // blink::mojom::ServiceWorkerUpdateViaCache.
auto options = blink::mojom::ServiceWorkerRegistrationOptions::New(
- pattern, update_via_cache);
+ pattern, script_type, update_via_cache);
context_->container_host()->Register(
script_url, std::move(options),
base::BindOnce(&WebServiceWorkerProviderImpl::OnRegistered,
@@ -194,8 +200,7 @@ void WebServiceWorkerProviderImpl::SetController(
for (blink::mojom::WebFeature feature : features)
provider_client_->CountFeature(feature);
provider_client_->SetController(
- WebServiceWorkerImpl::CreateHandle(
- context_->GetOrCreateServiceWorkerObject(std::move(controller))),
+ controller.To<blink::WebServiceWorkerObjectInfo>(),
should_notify_controller_change);
}
@@ -205,11 +210,8 @@ void WebServiceWorkerProviderImpl::PostMessageToClient(
if (!provider_client_)
return;
- scoped_refptr<WebServiceWorkerImpl> source_worker =
- context_->GetOrCreateServiceWorkerObject(std::move(source));
provider_client_->DispatchMessageEvent(
- WebServiceWorkerImpl::CreateHandle(std::move(source_worker)),
- std::move(message));
+ source.To<blink::WebServiceWorkerObjectInfo>(), std::move(message));
}
void WebServiceWorkerProviderImpl::CountFeature(
@@ -219,10 +221,6 @@ void WebServiceWorkerProviderImpl::CountFeature(
provider_client_->CountFeature(feature);
}
-int WebServiceWorkerProviderImpl::provider_id() const {
- return context_->provider_id();
-}
-
void WebServiceWorkerProviderImpl::OnRegistered(
std::unique_ptr<WebServiceWorkerRegistrationCallbacks> callbacks,
blink::mojom::ServiceWorkerErrorType error,
diff --git a/chromium/content/renderer/service_worker/web_service_worker_provider_impl.h b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.h
index 9c73253eee5..5bfc62442b1 100644
--- a/chromium/content/renderer/service_worker/web_service_worker_provider_impl.h
+++ b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.h
@@ -12,7 +12,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "third_party/blink/public/common/message_port/transferable_message.h"
+#include "third_party/blink/public/common/messaging/transferable_message.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h"
@@ -41,6 +41,7 @@ class CONTENT_EXPORT WebServiceWorkerProviderImpl
void RegisterServiceWorker(
const blink::WebURL& web_pattern,
const blink::WebURL& web_script_url,
+ blink::mojom::ScriptType script_type,
blink::mojom::ServiceWorkerUpdateViaCache update_via_cache,
std::unique_ptr<WebServiceWorkerRegistrationCallbacks>) override;
void GetRegistration(
@@ -54,8 +55,7 @@ class CONTENT_EXPORT WebServiceWorkerProviderImpl
bool ValidateScopeAndScriptURL(const blink::WebURL& pattern,
const blink::WebURL& script_url,
blink::WebString* error_message) override;
- // Sets the ServiceWorkerContainer#controller for this provider. It's not
- // used when this WebServiceWorkerProvider is for a service worker context.
+ // Sets the ServiceWorkerContainer#controller for this provider.
void SetController(blink::mojom::ServiceWorkerObjectInfoPtr controller,
const std::set<blink::mojom::WebFeature>& features,
bool should_notify_controller_change);
@@ -67,8 +67,6 @@ class CONTENT_EXPORT WebServiceWorkerProviderImpl
// feature. It is counted as if it were a feature usage from the page.
void CountFeature(blink::mojom::WebFeature feature);
- int provider_id() const;
-
private:
void OnRegistered(
std::unique_ptr<WebServiceWorkerRegistrationCallbacks> callbacks,
diff --git a/chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc b/chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc
index bd98361eb53..733d66d4ddb 100644
--- a/chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc
+++ b/chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc
@@ -11,7 +11,7 @@
#include "content/common/service_worker/service_worker_types.h"
#include "content/renderer/service_worker/service_worker_context_client.h"
#include "content/renderer/service_worker/service_worker_provider_context.h"
-#include "content/renderer/service_worker/web_service_worker_impl.h"
+#include "content/renderer/service_worker/service_worker_type_converters.h"
#include "content/renderer/service_worker/web_service_worker_provider_impl.h"
#include "third_party/blink/public/platform/modules/service_worker/web_navigation_preload_state.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
@@ -60,13 +60,13 @@ void DidGetNavigationPreloadState(
WebServiceWorkerRegistrationImpl::QueuedTask::QueuedTask(
QueuedTaskType type,
- const scoped_refptr<WebServiceWorkerImpl>& worker)
- : type(type), worker(worker) {}
+ blink::mojom::ServiceWorkerObjectInfoPtr info)
+ : type(type), info(std::move(info)) {}
-WebServiceWorkerRegistrationImpl::QueuedTask::QueuedTask(
- const QueuedTask& other) = default;
+WebServiceWorkerRegistrationImpl::QueuedTask::QueuedTask(QueuedTask&& other) =
+ default;
-WebServiceWorkerRegistrationImpl::QueuedTask::~QueuedTask() {}
+WebServiceWorkerRegistrationImpl::QueuedTask::~QueuedTask() = default;
// static
scoped_refptr<WebServiceWorkerRegistrationImpl>
@@ -106,11 +106,11 @@ void WebServiceWorkerRegistrationImpl::RunQueuedTasks() {
DCHECK(proxy_);
for (const QueuedTask& task : queued_tasks_) {
if (task.type == INSTALLING)
- proxy_->SetInstalling(WebServiceWorkerImpl::CreateHandle(task.worker));
+ proxy_->SetInstalling(task.info.To<blink::WebServiceWorkerObjectInfo>());
else if (task.type == WAITING)
- proxy_->SetWaiting(WebServiceWorkerImpl::CreateHandle(task.worker));
+ proxy_->SetWaiting(task.info.To<blink::WebServiceWorkerObjectInfo>());
else if (task.type == ACTIVE)
- proxy_->SetActive(WebServiceWorkerImpl::CreateHandle(task.worker));
+ proxy_->SetActive(task.info.To<blink::WebServiceWorkerObjectInfo>());
else if (task.type == UPDATE_FOUND)
proxy_->DispatchUpdateFoundEvent();
}
@@ -257,32 +257,26 @@ WebServiceWorkerRegistrationImpl::~WebServiceWorkerRegistrationImpl() {
void WebServiceWorkerRegistrationImpl::SetInstalling(
blink::mojom::ServiceWorkerObjectInfoPtr info) {
- scoped_refptr<WebServiceWorkerImpl> service_worker =
- GetOrCreateServiceWorkerObject(std::move(info));
if (proxy_)
- proxy_->SetInstalling(WebServiceWorkerImpl::CreateHandle(service_worker));
+ proxy_->SetInstalling(info.To<blink::WebServiceWorkerObjectInfo>());
else
- queued_tasks_.push_back(QueuedTask(INSTALLING, service_worker));
+ queued_tasks_.emplace_back(INSTALLING, std::move(info));
}
void WebServiceWorkerRegistrationImpl::SetWaiting(
blink::mojom::ServiceWorkerObjectInfoPtr info) {
- scoped_refptr<WebServiceWorkerImpl> service_worker =
- GetOrCreateServiceWorkerObject(std::move(info));
if (proxy_)
- proxy_->SetWaiting(WebServiceWorkerImpl::CreateHandle(service_worker));
+ proxy_->SetWaiting(info.To<blink::WebServiceWorkerObjectInfo>());
else
- queued_tasks_.push_back(QueuedTask(WAITING, service_worker));
+ queued_tasks_.emplace_back(WAITING, std::move(info));
}
void WebServiceWorkerRegistrationImpl::SetActive(
blink::mojom::ServiceWorkerObjectInfoPtr info) {
- scoped_refptr<WebServiceWorkerImpl> service_worker =
- GetOrCreateServiceWorkerObject(std::move(info));
if (proxy_)
- proxy_->SetActive(WebServiceWorkerImpl::CreateHandle(service_worker));
+ proxy_->SetActive(info.To<blink::WebServiceWorkerObjectInfo>());
else
- queued_tasks_.push_back(QueuedTask(ACTIVE, service_worker));
+ queued_tasks_.emplace_back(ACTIVE, std::move(info));
}
void WebServiceWorkerRegistrationImpl::RefreshVersionAttributes() {
@@ -291,23 +285,6 @@ void WebServiceWorkerRegistrationImpl::RefreshVersionAttributes() {
SetActive(std::move(info_->active));
}
-scoped_refptr<WebServiceWorkerImpl>
-WebServiceWorkerRegistrationImpl::GetOrCreateServiceWorkerObject(
- blink::mojom::ServiceWorkerObjectInfoPtr info) {
- scoped_refptr<WebServiceWorkerImpl> service_worker;
- if (is_for_client_) {
- if (provider_context_for_client_) {
- service_worker =
- provider_context_for_client_->GetOrCreateServiceWorkerObject(
- std::move(info));
- }
- } else if (ServiceWorkerContextClient::ThreadSpecificInstance()) {
- service_worker = ServiceWorkerContextClient::ThreadSpecificInstance()
- ->GetOrCreateServiceWorkerObject(std::move(info));
- }
- return service_worker;
-}
-
void WebServiceWorkerRegistrationImpl::OnUpdated(
std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks,
blink::mojom::ServiceWorkerErrorType error,
@@ -321,22 +298,21 @@ void WebServiceWorkerRegistrationImpl::OnUpdated(
base::WrapRefCounted(this)));
}
-void WebServiceWorkerRegistrationImpl::SetVersionAttributes(
- int changed_mask,
+void WebServiceWorkerRegistrationImpl::SetServiceWorkerObjects(
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
blink::mojom::ServiceWorkerObjectInfoPtr installing,
blink::mojom::ServiceWorkerObjectInfoPtr waiting,
blink::mojom::ServiceWorkerObjectInfoPtr active) {
- ChangedVersionAttributesMask mask(changed_mask);
- DCHECK(mask.installing_changed() || !installing);
- if (mask.installing_changed()) {
+ DCHECK(changed_mask->installing || !installing);
+ if (changed_mask->installing) {
SetInstalling(std::move(installing));
}
- DCHECK(mask.waiting_changed() || !waiting);
- if (mask.waiting_changed()) {
+ DCHECK(changed_mask->waiting || !waiting);
+ if (changed_mask->waiting) {
SetWaiting(std::move(waiting));
}
- DCHECK(mask.active_changed() || !active);
- if (mask.active_changed()) {
+ DCHECK(changed_mask->active || !active);
+ if (changed_mask->active) {
SetActive(std::move(active));
}
}
@@ -350,7 +326,7 @@ void WebServiceWorkerRegistrationImpl::UpdateFound() {
if (proxy_)
proxy_->DispatchUpdateFoundEvent();
else
- queued_tasks_.push_back(QueuedTask(UPDATE_FOUND, nullptr));
+ queued_tasks_.emplace_back(UPDATE_FOUND, nullptr);
}
} // namespace content
diff --git a/chromium/content/renderer/service_worker/web_service_worker_registration_impl.h b/chromium/content/renderer/service_worker/web_service_worker_registration_impl.h
index e57e36208f4..ed0a5766e9c 100644
--- a/chromium/content/renderer/service_worker/web_service_worker_registration_impl.h
+++ b/chromium/content/renderer/service_worker/web_service_worker_registration_impl.h
@@ -27,7 +27,6 @@ class WebServiceWorkerRegistrationProxy;
namespace content {
-class WebServiceWorkerImpl;
class ServiceWorkerProviderContext;
// WebServiceWorkerRegistrationImpl represents a ServiceWorkerRegistration
@@ -120,16 +119,13 @@ class CONTENT_EXPORT WebServiceWorkerRegistrationImpl
// the {installing,waiting,active} service worker object infos from |info_|.
void RefreshVersionAttributes();
- scoped_refptr<WebServiceWorkerImpl> GetOrCreateServiceWorkerObject(
- blink::mojom::ServiceWorkerObjectInfoPtr info);
-
void OnUpdated(std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks,
blink::mojom::ServiceWorkerErrorType error,
const base::Optional<std::string>& error_msg);
// Implements blink::mojom::ServiceWorkerRegistrationObject.
- void SetVersionAttributes(
- int changed_mask,
+ void SetServiceWorkerObjects(
+ blink::mojom::ChangedServiceWorkerObjectsMaskPtr changed_mask,
blink::mojom::ServiceWorkerObjectInfoPtr installing,
blink::mojom::ServiceWorkerObjectInfoPtr waiting,
blink::mojom::ServiceWorkerObjectInfoPtr active) override;
@@ -146,11 +142,11 @@ class CONTENT_EXPORT WebServiceWorkerRegistrationImpl
struct QueuedTask {
QueuedTask(QueuedTaskType type,
- const scoped_refptr<WebServiceWorkerImpl>& worker);
- QueuedTask(const QueuedTask& other);
+ blink::mojom::ServiceWorkerObjectInfoPtr info);
+ QueuedTask(QueuedTask&& other);
~QueuedTask();
QueuedTaskType type;
- scoped_refptr<WebServiceWorkerImpl> worker;
+ blink::mojom::ServiceWorkerObjectInfoPtr info;
};
void RunQueuedTasks();
diff --git a/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc b/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc
index 34ff87e85b0..8b9dfc03744 100644
--- a/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc
+++ b/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -10,12 +10,12 @@
#include "base/feature_list.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/scoped_child_process_reference.h"
#include "content/common/possibly_associated_wrapper_shared_url_loader_factory.h"
#include "content/common/url_loader_factory_bundle.h"
#include "content/public/common/appcache_info.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/origin_util.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/renderer/content_renderer_client.h"
@@ -33,7 +33,7 @@
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
-#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/messaging/message_port_channel.h"
#include "third_party/blink/public/common/privacy_preferences.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
@@ -88,8 +88,11 @@ class WebServiceWorkerNetworkProviderForSharedWorker
public:
WebServiceWorkerNetworkProviderForSharedWorker(
std::unique_ptr<ServiceWorkerNetworkProvider> provider,
- bool is_secure_context)
- : provider_(std::move(provider)), is_secure_context_(is_secure_context) {}
+ bool is_secure_context,
+ std::unique_ptr<NavigationResponseOverrideParameters> response_override)
+ : provider_(std::move(provider)),
+ is_secure_context_(is_secure_context),
+ response_override_(std::move(response_override)) {}
// Blink calls this method for each request starting with the main script,
// we tag them with the provider id.
@@ -97,7 +100,15 @@ class WebServiceWorkerNetworkProviderForSharedWorker
auto extra_data = std::make_unique<RequestExtraData>();
extra_data->set_service_worker_provider_id(provider_->provider_id());
extra_data->set_initiated_in_secure_context(is_secure_context_);
+ if (response_override_) {
+ DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
+ DCHECK_EQ(blink::mojom::RequestContextType::SHARED_WORKER,
+ request.GetRequestContext());
+ extra_data->set_navigation_response_override(
+ std::move(response_override_));
+ }
request.SetExtraData(std::move(extra_data));
+
// If the provider does not have a controller at this point, the renderer
// expects subresource requests to never be handled by a controlling service
// worker, so set |skip_service_worker| to skip service workers here.
@@ -105,7 +116,7 @@ class WebServiceWorkerNetworkProviderForSharedWorker
// controller (i.e., via claim()) on the browser-side could handle the
// request and break the assumptions of the renderer.
if (request.GetRequestContext() !=
- blink::WebURLRequest::kRequestContextSharedWorker &&
+ blink::mojom::RequestContextType::SHARED_WORKER &&
provider_->IsControlledByServiceWorker() ==
blink::mojom::ControllerServiceWorkerMode::kNoController) {
request.SetSkipServiceWorker(true);
@@ -144,7 +155,7 @@ class WebServiceWorkerNetworkProviderForSharedWorker
// If the request is for the main script, use the script_loader_factory.
if (provider_->script_loader_factory() &&
request.GetRequestContext() ==
- blink::WebURLRequest::kRequestContextSharedWorker) {
+ blink::mojom::RequestContextType::SHARED_WORKER) {
// TODO(crbug.com/796425): Temporarily wrap the raw
// mojom::URLLoaderFactory pointer into SharedURLLoaderFactory.
return std::make_unique<WebURLLoaderImpl>(
@@ -189,8 +200,17 @@ class WebServiceWorkerNetworkProviderForSharedWorker
private:
std::unique_ptr<ServiceWorkerNetworkProvider> provider_;
const bool is_secure_context_;
+ std::unique_ptr<NavigationResponseOverrideParameters> response_override_;
};
+// "ForSharedWorker" is to avoid collisions in Jumbo builds.
+bool IsOutOfProcessNetworkServiceForSharedWorker() {
+ return base::FeatureList::IsEnabled(network::features::kNetworkService) &&
+ !base::FeatureList::IsEnabled(features::kNetworkServiceInProcess) &&
+ !base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSingleProcess);
+}
+
} // namespace
EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
@@ -204,8 +224,10 @@ EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
service_worker_provider_info,
int appcache_host_id,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
- script_loader_factory_info,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
+ main_script_loader_factory,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle,
+ mojom::ControllerServiceWorkerInfoPtr controller_info,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider)
@@ -221,6 +243,20 @@ EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService) ||
appcache_host_id == kAppCacheNoHostId);
+ if (main_script_load_params) {
+ response_override_ =
+ std::make_unique<NavigationResponseOverrideParameters>();
+ response_override_->url_loader_client_endpoints =
+ std::move(main_script_load_params->url_loader_client_endpoints);
+ response_override_->response = main_script_load_params->response_head;
+ // TODO(nhiroki): Set |response_override_->redirects|.
+ // (https://crbug.com/715632)
+ response_override_->redirect_responses =
+ main_script_load_params->redirect_response_heads;
+ response_override_->redirect_infos =
+ main_script_load_params->redirect_infos;
+ }
+
impl_ = blink::WebSharedWorker::Create(this);
if (pause_on_start) {
// Pause worker context when it starts and wait until either DevTools client
@@ -229,32 +265,48 @@ EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
}
service_worker_provider_info_ = std::move(service_worker_provider_info);
- script_loader_factory_info_ = std::move(script_loader_factory_info);
+ main_script_loader_factory_ = std::move(main_script_loader_factory);
+ controller_info_ = std::move(controller_info);
// Make the factory bundle.
- loader_factories_ = base::MakeRefCounted<HostChildURLLoaderFactoryBundle>(
- impl_->GetTaskRunner(blink::TaskType::kInternalLoading));
+ subresource_loader_factories_ =
+ base::MakeRefCounted<HostChildURLLoaderFactoryBundle>(
+ impl_->GetTaskRunner(blink::TaskType::kInternalLoading));
// In some tests |render_thread| could be null.
if (RenderThreadImpl* render_thread = RenderThreadImpl::current()) {
- loader_factories_->Update(render_thread->blink_platform_impl()
- ->CreateDefaultURLLoaderFactoryBundle()
- ->PassInterface(),
- base::nullopt /* subresource_overrides */);
+ subresource_loader_factories_->Update(
+ render_thread->blink_platform_impl()
+ ->CreateDefaultURLLoaderFactoryBundle()
+ ->PassInterface(),
+ base::nullopt /* subresource_overrides */);
}
- if (subresource_loaders) {
- loader_factories_->Update(std::make_unique<ChildURLLoaderFactoryBundleInfo>(
- std::move(subresource_loaders)),
- base::nullopt /* subresource_overrides */);
- }
+ // |factory_bundle| is provided in the
+ // ServiceWorkerServicification or NetworkService case.
+ DCHECK(factory_bundle ||
+ !blink::ServiceWorkerUtils::IsServicificationEnabled());
+ if (factory_bundle) {
+ // If the network service crashes, then self-destruct so clients don't get
+ // stuck with a worker with a broken loader. Self-destruction is effectively
+ // the same as the worker's process crashing.
+ // The default factory might not be to the network service if a feature like
+ // AppCache set itself to the default, but treat a connection error as fatal
+ // anyway so clients don't get stuck.
+ if (IsOutOfProcessNetworkServiceForSharedWorker()) {
+ default_factory_connection_error_handler_holder_.Bind(
+ std::move(factory_bundle->default_factory_info()));
+ default_factory_connection_error_handler_holder_->Clone(
+ mojo::MakeRequest(&factory_bundle->default_factory_info()));
+ default_factory_connection_error_handler_holder_
+ .set_connection_error_handler(base::BindOnce(
+ &EmbeddedSharedWorkerStub::Terminate, base::Unretained(this)));
+ }
- // It is important to understand the default factory of |loader_factories_|.
- // |loader_factories_| was made from CreateDefaultURLLoaderFactoryBundle,
- // which does not set a default factory, and |subresource_loaders|, whose
- // default factory is the direct network factory (as SharedWorkerHost sets it
- // that way). Therefore, the default factory either does not exist or is the
- // direct network factory. So we don't need to call CloneWithoutDefault() to
- // bypass features like AppCache, unlike the bundle created for a frame.
+ subresource_loader_factories_->Update(
+ std::make_unique<ChildURLLoaderFactoryBundleInfo>(
+ std::move(factory_bundle)),
+ base::nullopt /* subresource_overrides */);
+ }
impl_->StartWorkerContext(
url_, blink::WebString::FromUTF8(name_),
@@ -263,7 +315,7 @@ EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
devtools_worker_token,
blink::PrivacyPreferences(renderer_preferences_.enable_do_not_track,
renderer_preferences_.enable_referrers),
- loader_factories_,
+ subresource_loader_factories_,
content_settings.PassInterface().PassHandle(),
interface_provider.PassInterface().PassHandle());
@@ -339,10 +391,11 @@ EmbeddedSharedWorkerStub::CreateServiceWorkerNetworkProvider() {
std::unique_ptr<ServiceWorkerNetworkProvider> provider =
ServiceWorkerNetworkProvider::CreateForSharedWorker(
std::move(service_worker_provider_info_),
- std::move(script_loader_factory_info_), loader_factories_);
+ std::move(main_script_loader_factory_), std::move(controller_info_),
+ subresource_loader_factories_);
return std::make_unique<WebServiceWorkerNetworkProviderForSharedWorker>(
- std::move(provider), IsOriginSecure(url_));
+ std::move(provider), IsOriginSecure(url_), std::move(response_override_));
}
void EmbeddedSharedWorkerStub::WaitForServiceWorkerControllerInfo(
@@ -380,25 +433,17 @@ EmbeddedSharedWorkerStub::CreateWorkerFetchContext(
if (blink::ServiceWorkerUtils::IsServicificationEnabled())
container_host_ptr_info = context->CloneContainerHostPtrInfo();
- // We know |loader_factories_|'s default factory is not a feature like
- // AppCache, so it's OK to call Clone() and not CloneWithoutDefault() to get
- // the fallback factory. We don't want to call CloneWithoutDefault() because
- // the default is a NetworkService-backed factory with auto-reconnect
- // when NetworkService is enabled (it will support auto-reconnect once
- // https://crbug.com/848256 is addressed). See comments in the constructor.
- //
- // TODO(falken): We might need to set the default factory of
- // |loader_factories_| to AppCache if requests from this shared worker are
- // supposed to go through AppCache.
+ // Make the factory used for service worker network fallback. Omit the default
+ // factory in case it is for a non-network factory like AppCache.
std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory =
- loader_factories_->Clone();
+ subresource_loader_factories_->CloneWithoutDefaultFactory();
auto worker_fetch_context = std::make_unique<WebWorkerFetchContextImpl>(
std::move(renderer_preferences_), std::move(preference_watcher_request_),
std::move(worker_client_request),
std::move(worker_client_registry_ptr_info),
- std::move(container_host_ptr_info), loader_factories_->Clone(),
- std::move(fallback_factory),
+ std::move(container_host_ptr_info),
+ subresource_loader_factories_->Clone(), std::move(fallback_factory),
GetContentClient()->renderer()->CreateURLLoaderThrottleProvider(
URLLoaderThrottleProviderType::kWorker),
GetContentClient()
@@ -449,14 +494,15 @@ void EmbeddedSharedWorkerStub::Connect(int connection_request_id,
}
void EmbeddedSharedWorkerStub::Terminate() {
- // After this we wouldn't get any IPC for this stub.
+ // After this we should ignore any IPC for this stub.
running_ = false;
impl_->TerminateWorkerContext();
}
void EmbeddedSharedWorkerStub::BindDevToolsAgent(
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host,
blink::mojom::DevToolsAgentAssociatedRequest request) {
- impl_->BindDevToolsAgent(request.PassHandle());
+ impl_->BindDevToolsAgent(host.PassHandle(), request.PassHandle());
}
} // namespace content
diff --git a/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.h b/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.h
index 85dc8d5d78a..d75fdd9a28b 100644
--- a/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.h
+++ b/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.h
@@ -10,7 +10,6 @@
#include "base/macros.h"
#include "base/unguessable_token.h"
-#include "content/child/scoped_child_process_reference.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/common/shared_worker/shared_worker.mojom.h"
#include "content/common/shared_worker/shared_worker_host.mojom.h"
@@ -21,6 +20,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/service_manager/public/mojom/interface_provider.mojom.h"
+#include "third_party/blink/public/mojom/shared_worker/shared_worker_main_script_load_params.mojom.h"
#include "third_party/blink/public/platform/web_content_security_policy.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -41,9 +41,11 @@ class MessagePortChannel;
}
namespace content {
+
class HostChildURLLoaderFactoryBundle;
class URLLoaderFactoryBundleInfo;
class WebApplicationCacheHostImpl;
+struct NavigationResponseOverrideParameters;
// A stub class to receive IPC from browser process and talk to
// blink::WebSharedWorker. Implements blink::WebSharedWorkerClient.
@@ -68,8 +70,10 @@ class EmbeddedSharedWorkerStub : public blink::WebSharedWorkerClient,
service_worker_provider_info,
int appcache_host_id,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
- script_loader_factory_info,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
+ main_script_loader_factory,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ mojom::ControllerServiceWorkerInfoPtr controller_info,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider);
@@ -104,6 +108,7 @@ class EmbeddedSharedWorkerStub : public blink::WebSharedWorkerClient,
mojo::ScopedMessagePipeHandle port) override;
void Terminate() override;
void BindDevToolsAgent(
+ blink::mojom::DevToolsAgentHostAssociatedPtrInfo host,
blink::mojom::DevToolsAgentAssociatedRequest request) override;
mojo::Binding<mojom::SharedWorker> binding_;
@@ -121,7 +126,6 @@ class EmbeddedSharedWorkerStub : public blink::WebSharedWorkerClient,
std::pair<int /* connection_request_id */, blink::MessagePortChannel>;
std::vector<PendingChannel> pending_channels_;
- ScopedChildProcessReference process_ref_;
const int appcache_host_id_;
WebApplicationCacheHostImpl* app_cache_host_ = nullptr; // Not owned.
@@ -129,13 +133,27 @@ class EmbeddedSharedWorkerStub : public blink::WebSharedWorkerClient,
// ServiceWorkerProviderHost on the browser.
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info_;
+
// NetworkService: The URLLoaderFactory used for loading the shared worker
- // script.
- network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory_info_;
+ // main script.
+ network::mojom::URLLoaderFactoryAssociatedPtrInfo main_script_loader_factory_;
+
+ // NetworkService:
+ mojom::ControllerServiceWorkerInfoPtr controller_info_;
+
+ // S13nServiceWorker: The factory bundle used for loading subresources for
+ // this shared worker.
+ scoped_refptr<HostChildURLLoaderFactoryBundle> subresource_loader_factories_;
+
+ // NetworkService (PlzWorker): The response override parameters used for
+ // taking a resource pre-requested by the browser process.
+ std::unique_ptr<NavigationResponseOverrideParameters> response_override_;
- // S13nServiceWorker: The factory bundle used for loads from this shared
- // worker.
- scoped_refptr<HostChildURLLoaderFactoryBundle> loader_factories_;
+ // Out-of-process NetworkService:
+ // Detects disconnection from the default factory of the loader factory bundle
+ // used by this worker (typically the network service).
+ network::mojom::URLLoaderFactoryPtr
+ default_factory_connection_error_handler_holder_;
DISALLOW_COPY_AND_ASSIGN(EmbeddedSharedWorkerStub);
};
diff --git a/chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc b/chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc
index a8c429de2bb..74468218315 100644
--- a/chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc
+++ b/chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc
@@ -31,8 +31,10 @@ void SharedWorkerFactoryImpl::CreateSharedWorker(
service_worker_provider_info,
int appcache_host_id,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
- script_loader_factory_ptr_info,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
+ main_script_loader_factory,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ mojom::ControllerServiceWorkerInfoPtr controller_info,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider) {
@@ -41,9 +43,10 @@ void SharedWorkerFactoryImpl::CreateSharedWorker(
std::move(info), pause_on_start, devtools_worker_token,
renderer_preferences, std::move(preference_watcher_request),
std::move(content_settings), std::move(service_worker_provider_info),
- appcache_host_id, std::move(script_loader_factory_ptr_info),
- std::move(subresource_loaders), std::move(host), std::move(request),
- std::move(interface_provider));
+ appcache_host_id, std::move(main_script_loader_factory),
+ std::move(main_script_load_params),
+ std::move(subresource_loader_factories), std::move(controller_info),
+ std::move(host), std::move(request), std::move(interface_provider));
}
} // namespace content
diff --git a/chromium/content/renderer/shared_worker/shared_worker_factory_impl.h b/chromium/content/renderer/shared_worker/shared_worker_factory_impl.h
index 42433c91128..0f137e0f070 100644
--- a/chromium/content/renderer/shared_worker/shared_worker_factory_impl.h
+++ b/chromium/content/renderer/shared_worker/shared_worker_factory_impl.h
@@ -32,8 +32,10 @@ class SharedWorkerFactoryImpl : public mojom::SharedWorkerFactory {
service_worker_provider_info,
int appcache_host_id,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
- script_loader_factory_ptr_info,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
+ main_script_loader_factory,
+ blink::mojom::SharedWorkerMainScriptLoadParamsPtr main_script_load_params,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ mojom::ControllerServiceWorkerInfoPtr controller_info,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider) override;
diff --git a/chromium/content/renderer/skia_benchmarking_extension.cc b/chromium/content/renderer/skia_benchmarking_extension.cc
index 40200bbf4b8..ae5dd66b9b8 100644
--- a/chromium/content/renderer/skia_benchmarking_extension.cc
+++ b/chromium/content/renderer/skia_benchmarking_extension.cc
@@ -285,9 +285,14 @@ void SkiaBenchmarking::GetOpTimings(gin::Arguments* args) {
}
v8::Local<v8::Object> result = v8::Object::New(isolate);
- result->Set(v8::String::NewFromUtf8(isolate, "total_time"),
+ result->Set(v8::String::NewFromUtf8(isolate, "total_time",
+ v8::NewStringType::kInternalized)
+ .ToLocalChecked(),
v8::Number::New(isolate, total_time.InMillisecondsF()));
- result->Set(v8::String::NewFromUtf8(isolate, "cmd_times"), op_times);
+ result->Set(v8::String::NewFromUtf8(isolate, "cmd_times",
+ v8::NewStringType::kInternalized)
+ .ToLocalChecked(),
+ op_times);
args->Return(result);
}
@@ -303,9 +308,13 @@ void SkiaBenchmarking::GetInfo(gin::Arguments* args) {
return;
v8::Local<v8::Object> result = v8::Object::New(isolate);
- result->Set(v8::String::NewFromUtf8(isolate, "width"),
+ result->Set(v8::String::NewFromUtf8(isolate, "width",
+ v8::NewStringType::kInternalized)
+ .ToLocalChecked(),
v8::Number::New(isolate, picture->layer_rect.width()));
- result->Set(v8::String::NewFromUtf8(isolate, "height"),
+ result->Set(v8::String::NewFromUtf8(isolate, "height",
+ v8::NewStringType::kInternalized)
+ .ToLocalChecked(),
v8::Number::New(isolate, picture->layer_rect.height()));
args->Return(result);
diff --git a/chromium/content/renderer/stats_collection_controller.cc b/chromium/content/renderer/stats_collection_controller.cc
index d528f49e513..8a62df4a494 100644
--- a/chromium/content/renderer/stats_collection_controller.cc
+++ b/chromium/content/renderer/stats_collection_controller.cc
@@ -22,59 +22,6 @@
namespace content {
-namespace {
-
-bool CurrentRenderViewImpl(RenderViewImpl** out) {
- blink::WebLocalFrame* web_frame =
- blink::WebLocalFrame::FrameForCurrentContext();
- if (!web_frame)
- return false;
-
- blink::WebView* web_view = web_frame->View();
- if (!web_view)
- return false;
-
- RenderViewImpl* render_view_impl =
- RenderViewImpl::FromWebView(web_view);
- if (!render_view_impl)
- return false;
-
- *out = render_view_impl;
- return true;
-}
-
-// Encodes a WebContentsLoadTime as JSON.
-// Input:
-// - |load_start_time| - time at which page load started.
-// - |load_stop_time| - time at which page load stopped.
-// - |result| - returned JSON.
-// Example return value:
-// {'load_start_ms': 1, 'load_duration_ms': 2.5}
-// either value may be null if a web contents hasn't fully loaded.
-// load_start_ms is represented as milliseconds since the unix epoch.
-void ConvertLoadTimeToJSON(
- const base::Time& load_start_time,
- const base::Time& load_stop_time,
- std::string *result) {
- base::DictionaryValue item;
-
- if (load_start_time.is_null()) {
- item.Set("load_start_ms", std::make_unique<base::Value>());
- } else {
- item.SetDouble("load_start_ms", (load_start_time - base::Time::UnixEpoch())
- .InMillisecondsF());
- }
- if (load_start_time.is_null() || load_stop_time.is_null()) {
- item.Set("load_duration_ms", std::make_unique<base::Value>());
- } else {
- item.SetDouble("load_duration_ms",
- (load_stop_time - load_start_time).InMillisecondsF());
- }
- base::JSONWriter::Write(item, result);
-}
-
-} // namespace
-
// static
gin::WrapperInfo StatsCollectionController::kWrapperInfo = {
gin::kEmbedderNativeGin
@@ -106,11 +53,10 @@ StatsCollectionController::~StatsCollectionController() {}
gin::ObjectTemplateBuilder StatsCollectionController::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin::Wrappable<StatsCollectionController>::GetObjectTemplateBuilder(
- isolate)
+ isolate)
.SetMethod("getHistogram", &StatsCollectionController::GetHistogram)
.SetMethod("getBrowserHistogram",
- &StatsCollectionController::GetBrowserHistogram)
- .SetMethod("tabLoadTiming", &StatsCollectionController::GetTabLoadTiming);
+ &StatsCollectionController::GetBrowserHistogram);
}
std::string StatsCollectionController::GetHistogram(
@@ -135,20 +81,4 @@ std::string StatsCollectionController::GetBrowserHistogram(
return histogram_json;
}
-std::string StatsCollectionController::GetTabLoadTiming() {
- RenderViewImpl* render_view_impl = nullptr;
- bool result = CurrentRenderViewImpl(&render_view_impl);
- DCHECK(result);
-
- StatsCollectionObserver* observer =
- render_view_impl->GetStatsCollectionObserver();
- DCHECK(observer);
-
- std::string tab_timing_json;
- ConvertLoadTimeToJSON(
- observer->load_start_time(), observer->load_stop_time(),
- &tab_timing_json);
- return tab_timing_json;
-}
-
} // namespace content
diff --git a/chromium/content/renderer/stats_collection_observer.cc b/chromium/content/renderer/stats_collection_observer.cc
deleted file mode 100644
index f2c45bf461c..00000000000
--- a/chromium/content/renderer/stats_collection_observer.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/stats_collection_observer.h"
-
-#include "base/time/time.h"
-#include "content/renderer/render_view_impl.h"
-
-namespace content {
-
-StatsCollectionObserver::StatsCollectionObserver(RenderViewImpl* render_view)
- : RenderViewObserver(render_view) {
-}
-
-StatsCollectionObserver::~StatsCollectionObserver() {
-}
-
-void StatsCollectionObserver::DidStartLoading() {
- DCHECK(start_time_.is_null());
- start_time_ = base::Time::Now();
-}
-
-void StatsCollectionObserver::DidStopLoading() {
- DCHECK(stop_time_.is_null());
- stop_time_ = base::Time::Now();
-
- // Stop observing so we don't get called again.
- RenderViewImpl* impl = static_cast<RenderViewImpl*>(render_view());
- impl->RemoveObserver(this);
-}
-
-void StatsCollectionObserver::OnDestruct() {
- delete this;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/stats_collection_observer.h b/chromium/content/renderer/stats_collection_observer.h
deleted file mode 100644
index e1b73233120..00000000000
--- a/chromium/content/renderer/stats_collection_observer.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_STATS_COLLECTION_OBSERVER_H_
-#define CONTENT_RENDERER_STATS_COLLECTION_OBSERVER_H_
-
-#include "base/macros.h"
-#include "base/time/time.h"
-#include "content/public/renderer/render_view_observer.h"
-
-namespace content {
-
-class RenderViewImpl;
-
-// Collect timing information for page loads.
-// If a Renderview performs multiple loads, only the first one is recorded.
-class StatsCollectionObserver : public RenderViewObserver {
- public:
- explicit StatsCollectionObserver(RenderViewImpl* render_view);
- ~StatsCollectionObserver() override;
-
- // RenderViewObserver implementation
- void DidStartLoading() override;
- void DidStopLoading() override;
-
- // Timing for the page load start and stop. These functions may return
- // a null time value under various circumstances.
- const base::Time& load_start_time() { return start_time_; }
- const base::Time& load_stop_time() { return stop_time_; }
-
- private:
- // RenderViewObserver implementation.
- void OnDestruct() override;
-
- base::Time start_time_;
- base::Time stop_time_;
-
- DISALLOW_COPY_AND_ASSIGN(StatsCollectionObserver);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_STATS_COLLECTION_OBSERVER_H_
diff --git a/chromium/content/renderer/v8_value_converter_impl.cc b/chromium/content/renderer/v8_value_converter_impl.cc
index 13f3e8a442a..730b6603490 100644
--- a/chromium/content/renderer/v8_value_converter_impl.cc
+++ b/chromium/content/renderer/v8_value_converter_impl.cc
@@ -95,7 +95,7 @@ class V8ValueConverterImpl::FromV8ValueState {
// hash (key) in the map, because two objects can have the same hash.
bool AddToUniquenessCheck(v8::Local<v8::Object> handle) {
int hash;
- Iterator iter = GetIteratorInMap(handle, &hash);
+ auto iter = GetIteratorInMap(handle, &hash);
if (iter != unique_map_.end())
return false;
@@ -105,7 +105,7 @@ class V8ValueConverterImpl::FromV8ValueState {
bool RemoveFromUniquenessCheck(v8::Local<v8::Object> handle) {
int unused_hash;
- Iterator iter = GetIteratorInMap(handle, &unused_hash);
+ auto iter = GetIteratorInMap(handle, &unused_hash);
if (iter == unique_map_.end())
return false;
unique_map_.erase(iter);
@@ -126,7 +126,7 @@ class V8ValueConverterImpl::FromV8ValueState {
// hash. Different hash obviously means different objects, but two objects
// in a couple of thousands could have the same identity hash.
std::pair<Iterator, Iterator> range = unique_map_.equal_range(*hash);
- for (Iterator it = range.first; it != range.second; ++it) {
+ for (auto it = range.first; it != range.second; ++it) {
// Operator == for handles actually compares the underlying objects.
if (it->second == handle)
return it;
@@ -258,8 +258,9 @@ v8::Local<v8::Value> V8ValueConverterImpl::ToV8ValueImpl(
case base::Value::Type::STRING: {
std::string val;
CHECK(value->GetAsString(&val));
- return v8::String::NewFromUtf8(
- isolate, val.c_str(), v8::String::kNormalString, val.length());
+ return v8::String::NewFromUtf8(isolate, val.c_str(),
+ v8::NewStringType::kNormal, val.length())
+ .ToLocalChecked();
}
case base::Value::Type::LIST:
@@ -325,8 +326,9 @@ v8::Local<v8::Value> V8ValueConverterImpl::ToV8Object(
v8::Maybe<bool> maybe = result->CreateDataProperty(
context,
- v8::String::NewFromUtf8(isolate, key.c_str(), v8::String::kNormalString,
- key.length()),
+ v8::String::NewFromUtf8(isolate, key.c_str(),
+ v8::NewStringType::kNormal, key.length())
+ .ToLocalChecked(),
child_v8);
if (!maybe.IsJust() || !maybe.FromJust())
LOG(ERROR) << "Failed to set property with key " << key;
diff --git a/chromium/content/renderer/web_ui_extension.cc b/chromium/content/renderer/web_ui_extension.cc
index dd7b5fd5880..6c05d14378b 100644
--- a/chromium/content/renderer/web_ui_extension.cc
+++ b/chromium/content/renderer/web_ui_extension.cc
@@ -74,13 +74,16 @@ void WebUIExtension::Install(blink::WebLocalFrame* frame) {
v8::Local<v8::Object> chrome = GetOrCreateChromeObject(isolate,
context->Global());
- chrome->Set(gin::StringToSymbol(isolate, "send"),
- gin::CreateFunctionTemplate(
- isolate, base::Bind(&WebUIExtension::Send))->GetFunction());
+ chrome->Set(
+ gin::StringToSymbol(isolate, "send"),
+ gin::CreateFunctionTemplate(isolate, base::Bind(&WebUIExtension::Send))
+ ->GetFunction(context)
+ .ToLocalChecked());
chrome->Set(gin::StringToSymbol(isolate, "getVariableValue"),
gin::CreateFunctionTemplate(
isolate, base::Bind(&WebUIExtension::GetVariableValue))
- ->GetFunction());
+ ->GetFunction(context)
+ .ToLocalChecked());
}
// static
diff --git a/chromium/content/renderer/web_ui_extension_data.cc b/chromium/content/renderer/web_ui_extension_data.cc
index 43cf15ec347..9d8c5ed379d 100644
--- a/chromium/content/renderer/web_ui_extension_data.cc
+++ b/chromium/content/renderer/web_ui_extension_data.cc
@@ -18,8 +18,7 @@ WebUIExtensionData::~WebUIExtensionData() {
}
std::string WebUIExtensionData::GetValue(const std::string& key) const {
- std::map<std::string, std::string>::const_iterator it =
- variable_map_.find(key);
+ auto it = variable_map_.find(key);
if (it == variable_map_.end())
return std::string();
return it->second;
diff --git a/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc b/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc
index 0e2a4a96bd2..819db24a97a 100644
--- a/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc
+++ b/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc
@@ -9,6 +9,7 @@
#include "components/viz/common/gl_helper.h"
#include "gpu/command_buffer/client/context_support.h"
#include "services/ws/public/cpp/gpu/context_provider_command_buffer.h"
+#include "third_party/skia/include/gpu/GrContext.h"
namespace content {
@@ -75,9 +76,12 @@ void WebGraphicsContext3DProviderImpl::OnContextLost() {
context_lost_callback_.Run();
}
-cc::ImageDecodeCache* WebGraphicsContext3DProviderImpl::ImageDecodeCache() {
- if (image_decode_cache_)
- return image_decode_cache_.get();
+cc::ImageDecodeCache* WebGraphicsContext3DProviderImpl::ImageDecodeCache(
+ SkColorType color_type) {
+ DCHECK(GetGrContext()->colorTypeSupportedAsImage(color_type));
+ auto cache_iterator = image_decode_cache_map_.find(color_type);
+ if (cache_iterator != image_decode_cache_map_.end())
+ return cache_iterator->second.get();
// This denotes the allocated GPU memory budget for the cache used for
// book-keeping. The cache indicates when the total memory locked exceeds this
@@ -87,11 +91,16 @@ cc::ImageDecodeCache* WebGraphicsContext3DProviderImpl::ImageDecodeCache() {
// TransferCache is used only with OOP raster.
const bool use_transfer_cache = false;
- image_decode_cache_ = std::make_unique<cc::GpuImageDecodeCache>(
- provider_.get(), use_transfer_cache, kN32_SkColorType,
- kMaxWorkingSetBytes, provider_->ContextCapabilities().max_texture_size,
- cc::PaintImage::kDefaultGeneratorClientId);
- return image_decode_cache_.get();
+ auto insertion_result = image_decode_cache_map_.insert(
+ std::pair<SkColorType, std::unique_ptr<cc::ImageDecodeCache>>(
+ color_type, std::make_unique<cc::GpuImageDecodeCache>(
+ provider_.get(), use_transfer_cache, color_type,
+ kMaxWorkingSetBytes,
+ provider_->ContextCapabilities().max_texture_size,
+ cc::PaintImage::kDefaultGeneratorClientId)));
+ DCHECK(insertion_result.second);
+ cache_iterator = insertion_result.first;
+ return cache_iterator->second.get();
}
} // namespace content
diff --git a/chromium/content/renderer/webgraphicscontext3d_provider_impl.h b/chromium/content/renderer/webgraphicscontext3d_provider_impl.h
index 2199c641c17..3948bceb4c8 100644
--- a/chromium/content/renderer/webgraphicscontext3d_provider_impl.h
+++ b/chromium/content/renderer/webgraphicscontext3d_provider_impl.h
@@ -6,6 +6,7 @@
#define CONTENT_RENDERER_WEBGRAPHICSCONTEXT3D_PROVIDER_IMPL_H_
#include "base/compiler_specific.h"
+#include "base/containers/flat_map.h"
#include "base/memory/ref_counted.h"
#include "components/viz/common/gpu/context_provider.h"
#include "content/common/content_export.h"
@@ -50,7 +51,7 @@ class CONTENT_EXPORT WebGraphicsContext3DProviderImpl
void SetLostContextCallback(base::RepeatingClosure) override;
void SetErrorMessageCallback(
base::RepeatingCallback<void(const char*, int32_t)>) override;
- cc::ImageDecodeCache* ImageDecodeCache() override;
+ cc::ImageDecodeCache* ImageDecodeCache(SkColorType) override;
ws::ContextProviderCommandBuffer* context_provider() const {
return provider_.get();
@@ -63,7 +64,8 @@ class CONTENT_EXPORT WebGraphicsContext3DProviderImpl
scoped_refptr<ws::ContextProviderCommandBuffer> provider_;
std::unique_ptr<viz::GLHelper> gl_helper_;
base::RepeatingClosure context_lost_callback_;
- std::unique_ptr<cc::ImageDecodeCache> image_decode_cache_;
+ base::flat_map<SkColorType, std::unique_ptr<cc::ImageDecodeCache>>
+ image_decode_cache_map_;
DISALLOW_COPY_AND_ASSIGN(WebGraphicsContext3DProviderImpl);
};
diff --git a/chromium/content/renderer/worker_thread_registry.cc b/chromium/content/renderer/worker_thread_registry.cc
index e5204cd74e2..1984cd2f9fb 100644
--- a/chromium/content/renderer/worker_thread_registry.cc
+++ b/chromium/content/renderer/worker_thread_registry.cc
@@ -129,7 +129,7 @@ base::TaskRunner* WorkerThreadRegistry::GetTaskRunnerFor(int worker_id) {
bool WorkerThreadRegistry::PostTask(int id, base::OnceClosure closure) {
DCHECK(id > 0);
base::AutoLock locker(task_runner_map_lock_);
- IDToTaskRunnerMap::iterator found = task_runner_map_.find(id);
+ auto found = task_runner_map_.find(id);
if (found == task_runner_map_.end())
return false;
return found->second->PostTask(FROM_HERE, std::move(closure));
diff --git a/chromium/content/renderer/worker_thread_registry_unittest.cc b/chromium/content/renderer/worker_thread_registry_unittest.cc
index 6dcfbd1dd67..275630a2a5f 100644
--- a/chromium/content/renderer/worker_thread_registry_unittest.cc
+++ b/chromium/content/renderer/worker_thread_registry_unittest.cc
@@ -5,7 +5,7 @@
#include "content/renderer/worker_thread_registry.h"
#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "content/public/renderer/worker_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -19,7 +19,7 @@ class WorkerThreadRegistryTest : public testing::Test {
WorkerThreadRegistry task_runner_;
private:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment_;
};
class MockObserver : public WorkerThread::Observer {
diff --git a/chromium/content/shell/BUILD.gn b/chromium/content/shell/BUILD.gn
index 9df50e24a3c..ea2d8125787 100644
--- a/chromium/content/shell/BUILD.gn
+++ b/chromium/content/shell/BUILD.gn
@@ -67,7 +67,7 @@ source_set("layout_test_utils") {
]
}
-static_library("content_shell_lib") {
+jumbo_static_library("content_shell_lib") {
testonly = true
sources = [
"android/shell_manager.cc",
@@ -224,6 +224,15 @@ static_library("content_shell_lib") {
"utility/shell_content_utility_client.h",
]
+ jumbo_excluded_sources = [
+ # IPC uses multiple inclusions in different macro contexts to
+ # generate the code. This is not compatible with jumbo
+ # compilations since all other files need the "clean" version of
+ # the message headers.
+ "common/layout_test/layout_test_messages.cc",
+ "common/shell_messages.cc",
+ ]
+
configs += [
":content_shell_lib_warnings",
"//build/config:precompiled_headers",
@@ -334,7 +343,7 @@ static_library("content_shell_lib") {
"//components/crash/content/app:test_support",
"//components/crash/content/browser",
]
- deps += [ "//third_party/fuchsia-sdk:policy" ]
+ deps += [ "//third_party/fuchsia-sdk/sdk:policy" ]
}
# Annoyingly, this target and layouttest_support have circular includes.
@@ -358,8 +367,8 @@ static_library("content_shell_lib") {
if (is_win) {
sources += [
- "common/v8_breakpad_support_win.cc",
- "common/v8_breakpad_support_win.h",
+ "common/v8_crashpad_support_win.cc",
+ "common/v8_crashpad_support_win.h",
]
}
@@ -429,6 +438,8 @@ static_library("content_shell_lib") {
if (is_chromeos) {
deps += [
"//chromeos",
+ "//services/ws/test_ws:lib",
+ "//services/ws/test_ws:mojom",
"//ui/wm:test_support",
]
}
@@ -450,6 +461,8 @@ static_library("content_shell_lib") {
}
grit("content_shell_resources_grit") {
+ testonly = true
+
# External code should depend on ":resources" instead.
visibility = [ ":*" ]
source = "shell_resources.grd"
@@ -470,6 +483,8 @@ grit("content_shell_resources_grit") {
}
copy("copy_shell_resources") {
+ testonly = true
+
sources = [
"$target_gen_dir/shell_resources.pak",
]
@@ -483,6 +498,8 @@ copy("copy_shell_resources") {
}
group("resources") {
+ testonly = true
+
public_deps = [
":copy_shell_resources",
]
@@ -495,6 +512,8 @@ group("resources") {
}
repack("pak") {
+ testonly = true
+
sources = [
"$root_gen_dir/content/app/resources/content_resources_100_percent.pak",
"$root_gen_dir/content/app/strings/content_strings_en-US.pak",
@@ -664,6 +683,7 @@ if (is_mac) {
}
bundle_data("content_shell_framework_resources") {
+ testonly = true
sources = [
"$root_out_dir/content_shell.pak",
"resources/missingImage.png",
@@ -908,8 +928,14 @@ mojom("mojo_bindings") {
}
service_manifest("content_shell_packaged_services_manifest_overlay") {
+ testonly = true
+
source = "//content/shell/browser/content_shell_packaged_services_manifest_overlay.json"
packaged_services = [ "//services/test/echo:manifest" ]
+
+ if (is_chromeos) {
+ packaged_services += [ "//services/ws/test_ws:manifest" ]
+ }
}
group("content_shell_crash_test") {
diff --git a/chromium/content/shell/android/BUILD.gn b/chromium/content/shell/android/BUILD.gn
index 20334067e43..4babaa61e0a 100644
--- a/chromium/content/shell/android/BUILD.gn
+++ b/chromium/content/shell/android/BUILD.gn
@@ -150,6 +150,7 @@ android_aidl("content_javatests_aidl") {
}
android_assets("content_shell_assets") {
+ testonly = true
sources = [
"$root_out_dir/content_shell.pak",
]
diff --git a/chromium/content/shell/common/layout_test.mojom b/chromium/content/shell/common/layout_test.mojom
index ae4e13d4527..be9a11b6dff 100644
--- a/chromium/content/shell/common/layout_test.mojom
+++ b/chromium/content/shell/common/layout_test.mojom
@@ -51,7 +51,7 @@ struct LayoutTestDump {
interface LayoutTestControl {
CaptureDump() => (LayoutTestDump result);
- [Sync] CompositeWithRaster() => ();
+ CompositeWithRaster() => ();
// Dumps the frame's contents into a string.
DumpFrameLayout() => (string frame_layout_dump);
diff --git a/chromium/content/shell/common/layout_test/OWNERS b/chromium/content/shell/common/layout_test/OWNERS
index ef88cc78b08..b8d55faa184 100644
--- a/chromium/content/shell/common/layout_test/OWNERS
+++ b/chromium/content/shell/common/layout_test/OWNERS
@@ -1,3 +1,5 @@
+per-file *_messages.cc=set noparent
+per-file *_messages.cc=file://ipc/SECURITY_OWNERS
per-file *_messages*.h=set noparent
per-file *_messages*.h=file://ipc/SECURITY_OWNERS
per-file *.mojom=set noparent
diff --git a/chromium/content/shell/common/layout_test/layout_test_messages.cc b/chromium/content/shell/common/layout_test/layout_test_messages.cc
index afb5b261e86..28ba2105bb4 100644
--- a/chromium/content/shell/common/layout_test/layout_test_messages.cc
+++ b/chromium/content/shell/common/layout_test/layout_test_messages.cc
@@ -4,30 +4,36 @@
// Get basic type definitions.
#define IPC_MESSAGE_IMPL
+#undef CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_MESSAGES_H_
#include "content/shell/common/layout_test/layout_test_messages.h"
// Generate constructors.
#include "ipc/struct_constructor_macros.h"
+#undef CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_MESSAGES_H_
#include "content/shell/common/layout_test/layout_test_messages.h"
// Generate destructors.
#include "ipc/struct_destructor_macros.h"
+#undef CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_MESSAGES_H_
#include "content/shell/common/layout_test/layout_test_messages.h"
// Generate param traits write methods.
#include "ipc/param_traits_write_macros.h"
namespace IPC {
+#undef CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_MESSAGES_H_
#include "content/shell/common/layout_test/layout_test_messages.h"
} // namespace IPC
// Generate param traits read methods.
#include "ipc/param_traits_read_macros.h"
namespace IPC {
+#undef CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_MESSAGES_H_
#include "content/shell/common/layout_test/layout_test_messages.h"
} // namespace IPC
// Generate param traits log methods.
#include "ipc/param_traits_log_macros.h"
namespace IPC {
+#undef CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_MESSAGES_H_
#include "content/shell/common/layout_test/layout_test_messages.h"
} // namespace IPC
diff --git a/chromium/content/shell/common/layout_test/layout_test_messages.h b/chromium/content/shell/common/layout_test/layout_test_messages.h
index bb578680743..04acc0b0e04 100644
--- a/chromium/content/shell/common/layout_test/layout_test_messages.h
+++ b/chromium/content/shell/common/layout_test/layout_test_messages.h
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// no-include-guard-because-multiply-included
+#ifndef CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_MESSAGES_H_
+#define CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_MESSAGES_H_
+
#include <string>
#include <vector>
@@ -63,3 +65,5 @@ IPC_MESSAGE_CONTROL1(
// Sent by secondary test window to notify the test has finished.
IPC_MESSAGE_CONTROL0(LayoutTestHostMsg_TestFinishedInSecondaryRenderer)
+
+#endif // CONTENT_SHELL_COMMON_LAYOUT_TEST_LAYOUT_TEST_MESSAGES_H_
diff --git a/chromium/content/shell/common/layout_test/layout_test_switches.cc b/chromium/content/shell/common/layout_test/layout_test_switches.cc
index 8aa83ee7444..262a246de90 100644
--- a/chromium/content/shell/common/layout_test/layout_test_switches.cc
+++ b/chromium/content/shell/common/layout_test/layout_test_switches.cc
@@ -20,10 +20,6 @@ const char kAndroidStdinPort[] = "android-stdin-port";
const char kAndroidStdoutPort[] = "android-stdout-port";
#endif // defined(OS_ANDROID)
-// Check whether all system dependencies for running layout tests are met.
-// TODO(tkent): Rename this to "check-web-test-sys-deps".
-const char kCheckLayoutTestSysDeps[] = "check-layout-test-sys-deps";
-
// When specified to "enable-leak-detection" command-line option,
// causes the leak detector to cause immediate crash when found leak.
const char kCrashOnFailure[] = "crash-on-failure";
@@ -60,6 +56,11 @@ const char kRunWebTests[] = "run-web-tests";
// http://dev.chromium.org/blink/runtime-enabled-features.
const char kStableReleaseMode[] = "stable-release-mode";
+// Test files are in //third_party/blink/web_tests, not in
+// //third_party/WebKit/LayoutTests.
+// TODO(tkent): Remove this flag after the move.
+const char kTestsInBlink[] = "tests-in-blink";
+
// Enable pixel dumps via "real" surface readbacks, instead of synchronously
// compositing and reading back pixels.
const char kEnableDisplayCompositorPixelDump[] =
diff --git a/chromium/content/shell/common/layout_test/layout_test_switches.h b/chromium/content/shell/common/layout_test/layout_test_switches.h
index 6fb69476b73..ebbf47c59b3 100644
--- a/chromium/content/shell/common/layout_test/layout_test_switches.h
+++ b/chromium/content/shell/common/layout_test/layout_test_switches.h
@@ -20,7 +20,6 @@ extern const char kAndroidStderrPort[];
extern const char kAndroidStdinPort[];
extern const char kAndroidStdoutPort[];
#endif // defined(OS_ANDROID)
-extern const char kCheckLayoutTestSysDeps[];
extern const char kCrashOnFailure[];
extern const char kCustomDevToolsFrontend[];
extern const char kDebugDevTools[];
@@ -31,6 +30,7 @@ extern const char kEnableLeakDetection[];
extern const char kEncodeBinary[];
extern const char kRunWebTests[];
extern const char kStableReleaseMode[];
+extern const char kTestsInBlink[];
extern const char kEnableDisplayCompositorPixelDump[];
} // namespace switches
diff --git a/chromium/content/shell/common/shell_messages.cc b/chromium/content/shell/common/shell_messages.cc
index 3eae912b154..bc5cbcfc7aa 100644
--- a/chromium/content/shell/common/shell_messages.cc
+++ b/chromium/content/shell/common/shell_messages.cc
@@ -4,30 +4,36 @@
// Get basic type definitions.
#define IPC_MESSAGE_IMPL
+#undef CONTENT_SHELL_COMMON_SHELL_MESSAGES_H_
#include "content/shell/common/shell_messages.h"
// Generate constructors.
#include "ipc/struct_constructor_macros.h"
+#undef CONTENT_SHELL_COMMON_SHELL_MESSAGES_H_
#include "content/shell/common/shell_messages.h"
// Generate destructors.
#include "ipc/struct_destructor_macros.h"
+#undef CONTENT_SHELL_COMMON_SHELL_MESSAGES_H_
#include "content/shell/common/shell_messages.h"
// Generate param traits write methods.
#include "ipc/param_traits_write_macros.h"
namespace IPC {
+#undef CONTENT_SHELL_COMMON_SHELL_MESSAGES_H_
#include "content/shell/common/shell_messages.h"
} // namespace IPC
// Generate param traits read methods.
#include "ipc/param_traits_read_macros.h"
namespace IPC {
+#undef CONTENT_SHELL_COMMON_SHELL_MESSAGES_H_
#include "content/shell/common/shell_messages.h"
} // namespace IPC
// Generate param traits log methods.
#include "ipc/param_traits_log_macros.h"
namespace IPC {
+#undef CONTENT_SHELL_COMMON_SHELL_MESSAGES_H_
#include "content/shell/common/shell_messages.h"
} // namespace IPC
diff --git a/chromium/content/shell/common/shell_messages.h b/chromium/content/shell/common/shell_messages.h
index ab7755403b2..16f4d8ed848 100644
--- a/chromium/content/shell/common/shell_messages.h
+++ b/chromium/content/shell/common/shell_messages.h
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// no-include-guard-because-multiply-included
+#ifndef CONTENT_SHELL_COMMON_SHELL_MESSAGES_H_
+#define CONTENT_SHELL_COMMON_SHELL_MESSAGES_H_
+
#include <string>
#include <vector>
@@ -70,3 +72,5 @@ IPC_MESSAGE_ROUTED2(ShellViewHostMsg_SendBluetoothManualChooserEvent,
std::string /* argument */)
IPC_MESSAGE_ROUTED1(ShellViewHostMsg_SetPopupBlockingEnabled,
bool /* block_popups */)
+
+#endif // CONTENT_SHELL_COMMON_SHELL_MESSAGES_H_
diff --git a/chromium/content/shell/common/shell_switches.cc b/chromium/content/shell/common/shell_switches.cc
index de877107f61..569ee5b6fc7 100644
--- a/chromium/content/shell/common/shell_switches.cc
+++ b/chromium/content/shell/common/shell_switches.cc
@@ -10,9 +10,6 @@
namespace switches {
-// Tells Content Shell that it's running as a content_browsertest.
-const char kContentBrowserTest[] = "browser-test";
-
// Makes Content Shell use the given path for its data directory.
const char kContentShellDataPath[] = "data-path";
@@ -42,10 +39,6 @@ const char kContentShellHostWindowSize[] = "content-shell-host-window-size";
// Hides toolbar from content_shell's host window.
const char kContentShellHideToolbar[] = "content-shell-hide-toolbar";
-// Forces all navigations to go through the browser process (in a
-// non-PlzNavigate way).
-const char kContentShellAlwaysFork[] = "content-shell-always-fork";
-
std::vector<std::string> GetSideloadFontFiles() {
std::vector<std::string> files;
const base::CommandLine& command_line =
diff --git a/chromium/content/shell/common/shell_switches.h b/chromium/content/shell/common/shell_switches.h
index 0215d011f15..b8bc4d7c908 100644
--- a/chromium/content/shell/common/shell_switches.h
+++ b/chromium/content/shell/common/shell_switches.h
@@ -12,7 +12,6 @@
namespace switches {
-extern const char kContentBrowserTest[];
extern const char kContentShellDataPath[];
extern const char kCrashDumpsDir[];
extern const char kExposeInternalsForTesting[];
@@ -20,7 +19,6 @@ extern const char kIsolateSitesForTesting[];
extern const char kRegisterFontFiles[];
extern const char kContentShellHostWindowSize[];
extern const char kContentShellHideToolbar[];
-extern const char kContentShellAlwaysFork[];
// Returns list of extra font files to be made accessible to the renderer.
std::vector<std::string> GetSideloadFontFiles();
diff --git a/chromium/content/shell/common/v8_breakpad_support_win.h b/chromium/content/shell/common/v8_breakpad_support_win.h
deleted file mode 100644
index a10f34a49db..00000000000
--- a/chromium/content/shell/common/v8_breakpad_support_win.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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.
-
-#ifndef CONTENT_SHELL_COMMON_V8_BREAKPAD_SUPPORT_WIN_H_
-#define CONTENT_SHELL_COMMON_V8_BREAKPAD_SUPPORT_WIN_H_
-
-namespace v8_breakpad_support {
-
-// Hook up V8 to breakpad.
-void SetUp();
-
-} // namespace v8_breakpad_support
-
-#endif // CONTENT_SHELL_COMMON_V8_BREAKPAD_SUPPORT_WIN_H_
diff --git a/chromium/content/shell/common/v8_breakpad_support_win.cc b/chromium/content/shell/common/v8_crashpad_support_win.cc
index 584b3ad1868..33eab60a86d 100644
--- a/chromium/content/shell/common/v8_breakpad_support_win.cc
+++ b/chromium/content/shell/common/v8_crashpad_support_win.cc
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/shell/common/v8_breakpad_support_win.h"
+#include "content/shell/common/v8_crashpad_support_win.h"
#include <windows.h>
#include "base/logging.h"
#include "gin/public/debug.h"
-namespace v8_breakpad_support {
+namespace v8_crashpad_support {
void SetUp() {
#ifdef _WIN64
@@ -29,4 +29,4 @@ void SetUp() {
#endif
}
-} // namespace v8_breakpad_support
+} // namespace v8_crashpad_support
diff --git a/chromium/content/shell/common/v8_crashpad_support_win.h b/chromium/content/shell/common/v8_crashpad_support_win.h
new file mode 100644
index 00000000000..159349f4d33
--- /dev/null
+++ b/chromium/content/shell/common/v8_crashpad_support_win.h
@@ -0,0 +1,15 @@
+// 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.
+
+#ifndef CONTENT_SHELL_COMMON_V8_CRASHPAD_SUPPORT_WIN_H_
+#define CONTENT_SHELL_COMMON_V8_CRASHPAD_SUPPORT_WIN_H_
+
+namespace v8_crashpad_support {
+
+// Hook up V8 to crashpad.
+void SetUp();
+
+} // namespace v8_crashpad_support
+
+#endif // CONTENT_SHELL_COMMON_V8_CRASHPAD_SUPPORT_WIN_H_
diff --git a/chromium/content/shell/test_runner/BUILD.gn b/chromium/content/shell/test_runner/BUILD.gn
index c94c5eb9631..dafd192bcfd 100644
--- a/chromium/content/shell/test_runner/BUILD.gn
+++ b/chromium/content/shell/test_runner/BUILD.gn
@@ -3,12 +3,13 @@
# found in the LICENSE file.
import("//build/config/features.gni")
+import("//build/config/jumbo.gni")
import("//build/config/ui.gni")
if (is_android) {
import("//build/config/android/config.gni")
}
-component("test_runner") {
+jumbo_component("test_runner") {
testonly = true
# See comment at the top of //content/BUILD.gn for why this is disabled in
@@ -119,6 +120,7 @@ component("test_runner") {
"//services/device/public/mojom",
"//skia",
"//third_party/blink/public:blink",
+ "//third_party/blink/public:test_support",
"//ui/display",
"//ui/events:dom_keycode_converter",
"//ui/events:events_base",
diff --git a/chromium/content/test/BUILD.gn b/chromium/content/test/BUILD.gn
index 862228af120..90fe9629b09 100644
--- a/chromium/content/test/BUILD.gn
+++ b/chromium/content/test/BUILD.gn
@@ -47,6 +47,8 @@ jumbo_static_library("test_support") {
"../browser/background_fetch/background_fetch_test_data_manager.h",
"../browser/background_fetch/mock_background_fetch_delegate.cc",
"../browser/background_fetch/mock_background_fetch_delegate.h",
+ "../browser/fileapi/file_system_chooser_test_helpers.cc",
+ "../browser/fileapi/file_system_chooser_test_helpers.h",
"../browser/media/session/mock_media_session_observer.cc",
"../browser/media/session/mock_media_session_observer.h",
"../browser/service_worker/embedded_worker_test_helper.cc",
@@ -311,6 +313,7 @@ jumbo_static_library("test_support") {
"//ipc",
"//media/mojo/clients",
"//media/mojo/interfaces",
+ "//services/media_session/public/cpp/test:test_support",
"//services/media_session/public/mojom",
"//third_party/blink/public:blink",
"//third_party/blink/public:test_support",
@@ -386,6 +389,7 @@ jumbo_static_library("test_support") {
"//ui/gl",
"//ui/gl:test_support",
"//ui/resources",
+ "//ui/shell_dialogs:shell_dialogs",
"//ui/surface",
"//url",
"//url/mojom:url_mojom_gurl",
@@ -420,6 +424,15 @@ jumbo_static_library("test_support") {
]
}
+ if (use_atk) {
+ sources +=
+ [ "../browser/accessibility/accessibility_event_recorder_auralinux.cc" ]
+ configs += [
+ "//build/config/linux/atk",
+ "//build/config/linux:atspi2",
+ ]
+ }
+
if (use_glib) {
configs += [ "//build/config/linux:glib" ]
}
@@ -532,7 +545,6 @@ jumbo_static_library("browsertest_support") {
"//gin",
"//media",
"//net",
- "//services/catalog:lib",
"//skia",
"//testing/gtest",
"//ui/accessibility:ax_enums_mojo",
@@ -546,10 +558,6 @@ jumbo_static_library("browsertest_support") {
deps += [ "//content/public/browser" ]
}
- if (is_chromeos) {
- deps += [ ":content_browsertests_catalog_source" ]
- }
-
if (use_aura && toolkit_views) {
deps += [ "//ui/views" ]
}
@@ -725,7 +733,6 @@ test("content_browsertests") {
"../browser/blob_storage/blob_storage_browsertest.cc",
"../browser/blob_storage/blob_url_browsertest.cc",
"../browser/bookmarklet_browsertest.cc",
- "../browser/browser_side_navigation_browsertest.cc",
"../browser/browser_thread_browsertest.cc",
"../browser/browsing_data/browsing_data_remover_impl_browsertest.cc",
"../browser/browsing_data/clear_site_data_handler_browsertest.cc",
@@ -754,6 +761,7 @@ test("content_browsertests") {
# These tests have incorrect threading (https://crbug.com/860547).
#"../browser/fileapi/file_system_url_loader_factory_browsertest.cc",
+ "../browser/fileapi/file_system_chooser_browsertest.cc",
"../browser/fileapi/fileapi_browsertest.cc",
"../browser/find_request_manager_browsertest.cc",
"../browser/font_unique_name_lookup/font_unique_name_browsertest.cc",
@@ -778,6 +786,7 @@ test("content_browsertests") {
"../browser/keyboard_lock_browsertest.h",
"../browser/keyboard_lock_browsertest_mac.mm",
"../browser/loader/cors_file_origin_browsertest.cc",
+ "../browser/loader/cors_origin_access_list_browsertest.cc",
"../browser/loader/cross_site_document_blocking_browsertest.cc",
"../browser/loader/loader_browsertest.cc",
"../browser/loader/prefetch_browsertest.cc",
@@ -806,6 +815,7 @@ test("content_browsertests") {
"../browser/memory/memory_coordinator_impl_browsertest.cc",
"../browser/message_port_provider_browsertest.cc",
"../browser/mojo_sandbox_browsertest.cc",
+ "../browser/navigation_browsertest.cc",
"../browser/net/accept_header_browsertest.cc",
"../browser/net_info_browsertest.cc",
"../browser/network_service_browsertest.cc",
@@ -847,6 +857,7 @@ test("content_browsertests") {
"../browser/security_exploit_browsertest.cc",
"../browser/service_manager/service_manager_context_browsertest.cc",
"../browser/service_worker/service_worker_browsertest.cc",
+ "../browser/service_worker/service_worker_tls_browsertest.cc",
"../browser/session_history_browsertest.cc",
"../browser/shape_detection/shape_detection_browsertest.cc",
"../browser/shared_worker/worker_browsertest.cc",
@@ -856,7 +867,6 @@ test("content_browsertests") {
"../browser/site_per_process_mac_browsertest.mm",
"../browser/snapshot_browsertest.cc",
"../browser/storage_partition_impl_browsertest.cc",
- "../browser/top_document_isolation_browsertest.cc",
"../browser/tracing/background_tracing_manager_browsertest.cc",
"../browser/tracing/memory_instrumentation_browsertest.cc",
"../browser/tracing/memory_tracing_browsertest.cc",
@@ -891,6 +901,7 @@ test("content_browsertests") {
"../browser/webrtc/webrtc_stress_source_switch_browsertest.cc",
"../browser/webrtc/webrtc_video_capture_browsertest.cc",
"../browser/webrtc/webrtc_video_capture_service_browsertest.cc",
+ "../browser/webrtc/webrtc_video_capture_service_enumeration_browsertest.cc",
"../browser/webrtc/webrtc_webcam_browsertest.cc",
"../browser/webrtc/webrtc_webcam_browsertest.h",
"../browser/webui/web_ui_mojo_browsertest.cc",
@@ -1028,7 +1039,11 @@ test("content_browsertests") {
"//ppapi/proxy:ipc",
"//ppapi/shared_impl:test_support",
]
- data_deps += [ "//ppapi:ppapi_tests" ]
+ data_deps += [
+ "//ppapi:corb_test_plugin",
+ "//ppapi:power_saver_test_plugin",
+ "//ppapi:ppapi_tests",
+ ]
if (is_mac) {
data += [ "$root_out_dir/ppapi_tests.plugin/" ]
}
@@ -1122,6 +1137,7 @@ test("content_browsertests") {
"//content/shell/android:content_shell_jni_headers",
"//testing/android/native_test:native_test_support",
"//ui/android:android",
+ "//ui/touch_selection:touch_selection",
]
android_manifest =
"${target_gen_dir}/content_browsertests_manifest/AndroidManifest.xml"
@@ -1159,7 +1175,6 @@ test("content_browsertests") {
if (is_chromeos) {
deps += [ "//chromeos" ]
- data_deps += [ "//services/ws/test_ws" ]
}
if (use_aura && !is_win) {
@@ -1243,21 +1258,6 @@ test("content_browsertests") {
}
}
-if (is_chromeos) {
- catalog("content_browsertests_catalog") {
- testonly = true
-
- standalone_services = [ "//services/ws/test_ws:manifest" ]
- }
-
- catalog_cpp_source("content_browsertests_catalog_source") {
- testonly = true
-
- catalog = ":content_browsertests_catalog"
- generated_function_name = "content::CreateContentBrowserTestsCatalog"
- }
-}
-
static_library("run_all_unittests") {
testonly = true
sources = [
@@ -1286,6 +1286,7 @@ test("content_unittests") {
sources = [
"../browser/accessibility/browser_accessibility_mac_unittest.mm",
"../browser/accessibility/browser_accessibility_manager_unittest.cc",
+ "../browser/accessibility/browser_accessibility_unittest.cc",
"../browser/accessibility/browser_accessibility_win_unittest.cc",
"../browser/accessibility/one_shot_accessibility_tree_search_unittest.cc",
"../browser/appcache/appcache_database_unittest.cc",
@@ -1375,6 +1376,7 @@ test("content_unittests") {
"../browser/download/download_request_core_unittest.cc",
"../browser/download/save_package_unittest.cc",
"../browser/fileapi/browser_file_system_helper_unittest.cc",
+ "../browser/fileapi/file_system_chooser_unittest.cc",
"../browser/fileapi/file_system_operation_runner_unittest.cc",
"../browser/frame_host/ancestor_throttle_unittest.cc",
"../browser/frame_host/frame_service_base_unittest.cc",
@@ -1465,12 +1467,13 @@ test("content_unittests") {
"../browser/media/media_devices_permission_checker_unittest.cc",
"../browser/media/media_internals_unittest.cc",
"../browser/media/midi_host_unittest.cc",
- "../browser/media/session/audio_focus_manager_unittest.cc",
"../browser/media/session/media_session_controller_unittest.cc",
"../browser/media/session/media_session_controllers_manager_unittest.cc",
"../browser/media/session/media_session_impl_service_routing_unittest.cc",
"../browser/media/session/media_session_impl_uma_unittest.cc",
+ "../browser/media/session/media_session_impl_unittest.cc",
"../browser/media/session/media_session_uma_helper_unittest.cc",
+ "../browser/media/webaudio/audio_context_manager_impl_unittest.cc",
"../browser/memory/memory_coordinator_impl_unittest.cc",
"../browser/memory/memory_monitor_android_unittest.cc",
"../browser/memory/memory_monitor_win_unittest.cc",
@@ -1562,9 +1565,11 @@ test("content_unittests") {
"../browser/renderer_host/text_input_client_mac_unittest.mm",
"../browser/renderer_host/web_database_host_impl_unittest.cc",
"../browser/resolve_proxy_msg_helper_unittest.cc",
+ "../browser/scheduler/browser_task_executor_unittest.cc",
"../browser/scheduler/responsiveness/calculator_unittest.cc",
"../browser/scheduler/responsiveness/watcher_unittest.cc",
"../browser/screen_orientation/screen_orientation_provider_unittest.cc",
+ "../browser/screenlock_monitor/screenlock_monitor_unittest.cc",
"../browser/service_worker/embedded_worker_instance_unittest.cc",
"../browser/service_worker/service_worker_cache_writer_unittest.cc",
"../browser/service_worker/service_worker_context_core_unittest.cc",
@@ -1588,6 +1593,7 @@ test("content_unittests") {
"../browser/service_worker/service_worker_registration_unittest.cc",
"../browser/service_worker/service_worker_request_handler_unittest.cc",
"../browser/service_worker/service_worker_script_loader_factory_unittest.cc",
+ "../browser/service_worker/service_worker_single_script_update_checker_unittest.cc",
"../browser/service_worker/service_worker_storage_unittest.cc",
"../browser/service_worker/service_worker_url_request_job_unittest.cc",
"../browser/service_worker/service_worker_version_unittest.cc",
@@ -1618,6 +1624,7 @@ test("content_unittests") {
"../browser/web_contents/web_contents_view_mac_unittest.mm",
"../browser/web_contents/web_drag_dest_mac_unittest.mm",
"../browser/web_contents/web_drag_source_mac_unittest.mm",
+ "../browser/web_package/origins_list_unittest.cc",
"../browser/web_package/signed_exchange_cert_fetcher_unittest.cc",
"../browser/web_package/signed_exchange_certificate_chain_unittest.cc",
"../browser/web_package/signed_exchange_envelope_unittest.cc",
@@ -1625,6 +1632,7 @@ test("content_unittests") {
"../browser/web_package/signed_exchange_prologue_unittest.cc",
"../browser/web_package/signed_exchange_signature_header_field_unittest.cc",
"../browser/web_package/signed_exchange_signature_verifier_unittest.cc",
+ "../browser/web_package/signed_exchange_utils_unittest.cc",
"../browser/webrtc/webrtc_internals_message_handler_unittest.cc",
"../browser/webrtc/webrtc_internals_unittest.cc",
"../browser/websockets/websocket_manager_unittest.cc",
@@ -1647,6 +1655,7 @@ test("content_unittests") {
"../common/content_switches_internal_unittest.cc",
"../common/cursors/webcursor_unittest.cc",
"../common/dom_storage/dom_storage_map_unittest.cc",
+ "../common/input/actions_parser_unittest.cc",
"../common/input/event_with_latency_info_unittest.cc",
"../common/input/gesture_event_stream_validator_unittest.cc",
"../common/input/synthetic_web_input_event_builders_unittest.cc",
@@ -1656,7 +1665,6 @@ test("content_unittests") {
"../common/manifest_util_unittest.cc",
"../common/media/media_devices_unittest.cc",
"../common/mime_sniffing_throttle_unittest.cc",
- "../common/notifications/notification_struct_traits_unittest.cc",
"../common/origin_util_unittest.cc",
"../common/page_state_serialization_unittest.cc",
"../common/page_zoom_unittest.cc",
@@ -1687,7 +1695,6 @@ test("content_unittests") {
"../renderer/dom_storage/local_storage_cached_areas_unittest.cc",
"../renderer/dom_storage/mock_leveldb_wrapper.cc",
"../renderer/dom_storage/mock_leveldb_wrapper.h",
- "../renderer/fileapi/webfilewriter_base_unittest.cc",
"../renderer/gpu/frame_swap_message_queue_unittest.cc",
"../renderer/gpu/layer_tree_view_unittest.cc",
"../renderer/gpu/queue_message_swap_promise_unittest.cc",
@@ -1784,8 +1791,6 @@ test("content_unittests") {
"../renderer/service_worker/service_worker_provider_context_unittest.cc",
"../renderer/service_worker/service_worker_subresource_loader_unittest.cc",
"../renderer/service_worker/service_worker_timeout_timer_unittest.cc",
- "../renderer/service_worker/thread_safe_script_container_unittest.cc",
- "../renderer/service_worker/web_service_worker_installed_scripts_manager_impl_unittest.cc",
"../renderer/skia_benchmarking_extension_unittest.cc",
"../renderer/v8_value_converter_impl_unittest.cc",
"../renderer/worker_thread_registry_unittest.cc",
@@ -1908,6 +1913,7 @@ test("content_unittests") {
"//services/proxy_resolver/:lib",
"//services/service_manager/public/cpp:service_test_support",
"//services/service_manager/public/cpp/test:test_support",
+ "//services/video_capture/public/cpp:mocks",
"//services/video_capture/public/mojom",
"//skia",
"//sql",
@@ -1936,6 +1942,7 @@ test("content_unittests") {
"//third_party/webrtc/modules/video_coding:video_codec_interface",
"//third_party/webrtc/pc:libjingle_peerconnection",
"//third_party/webrtc/rtc_base:rtc_base",
+ "//third_party/webrtc/rtc_base:timeutils",
"//third_party/webrtc/stats:rtc_stats_test_utils",
"//third_party/webrtc_overrides",
"//third_party/webrtc_overrides:init_webrtc",
@@ -1951,6 +1958,7 @@ test("content_unittests") {
"//ui/events/blink",
"//ui/gfx:test_support",
"//ui/gfx/geometry",
+ "//ui/gfx/geometry/mojo:struct_traits",
"//ui/gfx/ipc",
"//ui/gfx/ipc/skia",
"//ui/gl",
@@ -1979,8 +1987,6 @@ test("content_unittests") {
"../browser/renderer_host/pepper/pepper_printing_host_unittest.cc",
"../browser/renderer_host/pepper/pepper_proxy_lookup_helper_unittest.cc",
"../browser/renderer_host/pepper/quota_reservation_unittest.cc",
- "../renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc",
- "../renderer/media/pepper/video_track_to_pepper_adapter_unittest.cc",
"../renderer/pepper/event_conversion_unittest.cc",
"../renderer/pepper/host_var_tracker_unittest.cc",
"../renderer/pepper/mock_resource.h",
@@ -2012,6 +2018,7 @@ test("content_unittests") {
# Screen capture unit tests.
if (is_linux || is_mac || is_win) {
+ defines += [ "ENABLE_SCREEN_CAPTURE=1" ]
deps += [
"//media/capture:test_support",
"//third_party/libyuv",
@@ -2034,8 +2041,14 @@ test("content_unittests") {
}
}
if (is_win) {
- deps += [ "//third_party/iaccessible2" ]
- libs = [ "dwrite.lib" ]
+ deps += [
+ "//third_party/blink/public/common",
+ "//third_party/iaccessible2",
+ ]
+ libs = [
+ "dwrite.lib",
+ "wtsapi32.lib",
+ ]
}
if (is_mac) {
deps += [
@@ -2063,7 +2076,6 @@ test("content_unittests") {
"../renderer/media/android/stream_texture_wrapper_impl_unittest.cc",
]
sources -= [
- "../browser/media/session/audio_focus_manager_unittest.cc",
"../browser/tracing/tracing_ui_unittest.cc",
"../browser/webui/url_data_manager_backend_unittest.cc",
]
diff --git a/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.cc b/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.cc
index 51eab091720..84cd39bd511 100644
--- a/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.cc
+++ b/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.cc
@@ -15,13 +15,13 @@
#include "content/child/child_process_sandbox_support_impl_linux.h"
#include "content/child/child_thread_impl.h"
#include "services/service_manager/public/cpp/connector.h"
-#include "third_party/blink/public/platform/linux/web_fallback_font.h"
+#include "third_party/blink/public/platform/linux/out_of_process_font.h"
#include "third_party/blink/public/platform/linux/web_sandbox_support.h"
#endif
namespace blink {
class WebSandboxSupport;
-struct WebFallbackFont;
+struct OutOfProcessFont;
struct WebFontRenderStyle;
} // namespace blink
@@ -44,7 +44,10 @@ class UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport
void GetFallbackFontForCharacter(
blink::WebUChar32 character,
const char* preferred_locale,
- blink::WebFallbackFont* fallbackFont) override;
+ blink::OutOfProcessFont* fallbackFont) override;
+ void MatchFontByPostscriptNameOrFullFontName(
+ const char* font_unique_name,
+ blink::OutOfProcessFont* uniquely_matched_font) override;
void GetWebFontRenderStyleForStrike(const char* family,
int size,
bool is_bold,
@@ -58,7 +61,7 @@ class UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport
// here.
base::Lock unicode_font_families_mutex_;
// Maps unicode chars to their fallback fonts.
- std::map<int32_t, blink::WebFallbackFont> unicode_font_families_;
+ std::map<int32_t, blink::OutOfProcessFont> unicode_font_families_;
sk_sp<font_service::FontLoader> font_loader_;
#endif // defined(OS_MACOSX)
};
@@ -103,9 +106,9 @@ bool UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport::LoadFont(
void UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport::
GetFallbackFontForCharacter(blink::WebUChar32 character,
const char* preferred_locale,
- blink::WebFallbackFont* fallback_font) {
+ blink::OutOfProcessFont* fallback_font) {
base::AutoLock lock(unicode_font_families_mutex_);
- const std::map<int32_t, blink::WebFallbackFont>::const_iterator iter =
+ const std::map<int32_t, blink::OutOfProcessFont>::const_iterator iter =
unicode_font_families_.find(character);
if (iter != unicode_font_families_.end()) {
fallback_font->name = iter->second.name;
@@ -133,6 +136,14 @@ void UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport::
device_scale_factor, out);
}
+void UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport::
+ MatchFontByPostscriptNameOrFullFontName(
+ const char* font_unique_name,
+ blink::OutOfProcessFont* uniquely_matched_font) {
+ content::MatchFontByPostscriptNameOrFullFontName(
+ font_loader_, font_unique_name, uniquely_matched_font);
+}
+
#endif
} // namespace content
diff --git a/chromium/content/utility/utility_main.cc b/chromium/content/utility/utility_main.cc
index a1f19198fbb..c32aa0ed6dd 100644
--- a/chromium/content/utility/utility_main.cc
+++ b/chromium/content/utility/utility_main.cc
@@ -89,7 +89,9 @@ int UtilityMain(const MainFunctionParams& parameters) {
#endif
ChildProcess utility_process;
- utility_process.set_main_thread(new UtilityThreadImpl());
+ base::RunLoop run_loop;
+ utility_process.set_main_thread(
+ new UtilityThreadImpl(run_loop.QuitClosure()));
// Both utility process and service utility process would come
// here, but the later is launched without connection to service manager, so
@@ -123,7 +125,7 @@ int UtilityMain(const MainFunctionParams& parameters) {
}
#endif
- base::RunLoop().Run();
+ run_loop.Run();
#if defined(LEAK_SANITIZER)
// Invoke LeakSanitizer before shutting down the utility thread, to avoid
diff --git a/chromium/content/utility/utility_thread_impl.cc b/chromium/content/utility/utility_thread_impl.cc
index 57c3bfc105e..8dca0d935d0 100644
--- a/chromium/content/utility/utility_thread_impl.cc
+++ b/chromium/content/utility/utility_thread_impl.cc
@@ -59,15 +59,17 @@ void CreateResourceUsageReporter(mojom::ResourceUsageReporterRequest request) {
}
#endif // !defined(OS_ANDROID)
-UtilityThreadImpl::UtilityThreadImpl()
- : ChildThreadImpl(ChildThreadImpl::Options::Builder()
+UtilityThreadImpl::UtilityThreadImpl(base::RepeatingClosure quit_closure)
+ : ChildThreadImpl(std::move(quit_closure),
+ ChildThreadImpl::Options::Builder()
.AutoStartServiceManagerConnection(false)
.Build()) {
Init();
}
UtilityThreadImpl::UtilityThreadImpl(const InProcessChildThreadParams& params)
- : ChildThreadImpl(ChildThreadImpl::Options::Builder()
+ : ChildThreadImpl(base::DoNothing(),
+ ChildThreadImpl::Options::Builder()
.AutoStartServiceManagerConnection(false)
.InBrowserProcess(params)
.Build()) {
diff --git a/chromium/content/utility/utility_thread_impl.h b/chromium/content/utility/utility_thread_impl.h
index 5aad58e72c1..fea5aae5640 100644
--- a/chromium/content/utility/utility_thread_impl.h
+++ b/chromium/content/utility/utility_thread_impl.h
@@ -33,7 +33,7 @@ class FontLoaderMac;
class UtilityThreadImpl : public UtilityThread,
public ChildThreadImpl {
public:
- UtilityThreadImpl();
+ explicit UtilityThreadImpl(base::RepeatingClosure quit_closure);
// Constructor used when running in single process mode.
explicit UtilityThreadImpl(const InProcessChildThreadParams& params);
~UtilityThreadImpl() override;